Amigás trainer írása

Ló nagyot mindenkibe.

Ma trainert fogunk csinálni Amigán, mert végülis miért ne, nem?

(Nem látszanak a képek? Klikk ide.)

A kiszemelt játék az 1988-as Pandora (kalandjáték némi akcióval), amiben egy tékozló űrállomás visszatér földközelbe és a menetközben kissé megkattant fedélzeti kompjúter viccből szeretné megszórni a Földet némi mutáns spórával, lehetőleg még ebéd előtt. Főhősünk - valami noname zsoldos - azért érkezik az űrállomásra, hogy kiderítse, hogy mi a fene folyik itt, majd miután kiderítette, "levegőbe repítse" az egész űrállomást. (Ugye ez már repül és nem levegőben...)

Indítsuk el a játékot. Shift+F12-vel hívjuk be a debuggert.

Kezdetnek keressük meg az időt, mert az folyamatosan csökken, tehát azt rögtön tudjuk is keresni. A WinUAE debuggerében az "S" paranccsal (Note: minden parancs case-dependent!) lehet kimenteni a memória egyes részeit, kezdőcímtől egy megadott hosszig. A játék 512 kB-os Amigákra volt fejlesztve, tehát nekünk a Chip RAM tartomány első 512 kB-ja kell. (A dump-ok a WinUAE könyvtárába kerülnek. Minden értéket hexában kell megadni.)

S pandora0 0 80000

Mivel a változást csak több dump-pal tudjuk vizsgálni, ezért tovább kell engedni a programot a "g" paranccsal, majd miután az idő csökkent egy picit, megint Shift+F12-vel behívni, majd csinálni egy újabb dump-ot, mondjuk "pandora1" néven. Aztán megismételni a folyamatot párszor.
A dumpok összehasonlítására mindenki olyan módszert használ, amilyet akar, én írtam magamnak a célra egy programot, aki akarja, használja, viszont én a leírásban ezt fogom használni.
Amint látszik a játékban, az idő 9999-ről mászik szépen visszafelé. Mivel egy byte-on 9999-et vajmi kevés eséllyel lehet eltárolni, így kézenfekvő, hogy 16-bites értékeket kell keresnünk, valamint - mivel Amigán vagyunk - big-endian értékekről beszélünk.

mdsc -b16b -dec pandora0 pandora1 pandora2 pandora3 pandora4 pandora5 pandora6 pandora7

Az eredmény:

00003c82: 39234, 39207, 39188, 39169, 39048, 38995, 38978, 38951
000586fe: 9773, 9711, 9660, 9609, 9555, 9419, 9372, 9314
00059480: 1453, 1439, 1391, 1339, 1291, 1191, 1105, 993
00059b76: 9773, 9711, 9660, 9609, 9555, 9419, 9372, 9314
00059dbe: 9773, 9711, 9660, 9609, 9555, 9419, 9372, 9314
0005b944: 9773, 9711, 9660, 9609, 9555, 9419, 9372, 9314
0005c216: 9773, 9711, 9660, 9609, 9555, 9419, 9372, 9314

Látunk összesen hét db címet, de ebből ötön ugyanaz a szekvencia látszik, aminek semmi értelme, tehát kizárhatjuk. Marad tehát a $3c82-es és a $59480-as cím, viszont egyik sem úgy néz ki, mintha 9800-9999 közti értékek lennének ott tárolva. Kivéve, hogy a régi gépeken nem volt ritka, hogy számlálókat BCD módon kezeltek. Egyrészt mert így egyszerű volt kiírni, másrészt meg mert a processzorok ezt hardware-ből támogatták. Tehát nézzük meg az értékeket hexában:

mdsc -hex -b16b -dec pandora0 pandora1 pandora2 pandora3 pandora4 pandora5 pandora6 pandora7

Eredmény:

00003c82: 9942, 9927, 9914, 9901, 9888, 9853, 9842, 9827
000586fe: 262d, 25ef, 25bc, 2589, 2553, 24cb, 249c, 2462
00059480: 05ad, 059f, 056f, 053b, 050b, 04a7, 0451, 03e1
00059b76: 262d, 25ef, 25bc, 2589, 2553, 24cb, 249c, 2462
00059dbe: 262d, 25ef, 25bc, 2589, 2553, 24cb, 249c, 2462
0005b944: 262d, 25ef, 25bc, 2589, 2553, 24cb, 249c, 2462
0005c216: 262d, 25ef, 25bc, 2589, 2553, 24cb, 249c, 2462

Így már mindjárt látszik, aminek látszania kell. Próbáljuk "megfagyasztani" a címet, ami úgy néz ki, hogy

w <a fagyasztott cím sorszáma> <cím> <hossz (egy cím esetén 1)> <művelet ("F" mint faggyá'le)> <érték[.b/.w/.l, attól függően, hogy milyen széles az érték, de egyértelmű esetekben elhagyható (pl. ami nagyobb, mint 65535 az tuti .l)]>

Tehát:

w 0 3c82 1 F ffff

Most már van örök időnk.

Nézzük most a másik rögtön szembetűnő tulajdonságot, az életerőt. Hogy megtaláljuk, csökkenteni kéne egy kicsit. Ehhez mondjuk keveredjünk bunyóba, az itt kolbászoló "szimpatikus" huligánnal, aki nem tudom, hogy került fel egy kutatóállomásra, de mindenesetre azt a szerepkört tölti be, hogy egy irídiumbuzogánnyal veri szét az állomás berendezését, meg azokat, akik az útjába kerülnek. (A Mir-en tuti rögtön agyonverték volna az oroszok...)

A harc kezdetén mentsünk dump-ot, majd tegyük ugyanezt minden ütése után. Ha agyonvert minket, akkor:

mdsc -dec pandora0 pandora1 pandora2 pandora3 pandora4 pandora5
00003ba9: 180, 135, 115, 91, 56, 18
0005c35f: 95, 74, 53, 32, 11, 0
00071bed: 169, 128, 32, 16, 1, 0
00071c15: 169, 128, 32, 16, 1, 0
00071f5c: 248, 195, 192, 144, 16, 7

Itt megint van kettő olyan cím, amin ugyanaz van, azokat azért zárhatjuk ki, viszont van két olyan is, ami nem nullával végződik, márpedig hagytuk magunkat kinyírni, tehát azzal kell. (Egyelőre feltételezvén, hogy a játék nem valami trükkös módon tárolja az életerőt.) Marad tehát a $5c35f cím, ami mellett az is szól, hogy minden lépésben ugyanannyival - 21-gyel - csökkent; kivéve persze az utolsó lépést, dehát negatívba nem mehet az életerő. Fagyasszunk.

w 1 5c35f 1 F 7f

Fagyasztás után látszik, hogy még kinyiffanás után is azt írja ki, hogy "GOOD". (Induláskor, ha megmoccanunk, kinyúvadunk, mert nem mászkálhatunk az állomáson ID nélkül, mert agyonsokkol minket. Ezért meg kell várni, amíg a beléptetőtiszt odajön és a kezünkbe adja a sajátját. Beszélni már nem tud, mert az állomás ad neki pár Ampert, azt meg nem szeretik a beléptetőtisztek. Bezzeg, ha villanyszerelő lett volna...)

Most már van örök életünk is. (A játékban a maximum életerő 95 pont ($5f), de maga a játék 127-ig ($7f) kezeli; a 95 feletti érték ugyanúgy "GOOD"-ként jelenik meg, csak tovább tart, mire lemegy "FAIR"-be. Ha ennél nagyobb értéket adunk meg, akkor azonnal kinyúvadunk. (Negatívba ment az életerő.) Ha nullát, akkor csak kiírja, hogy "DEAD", de mászkálhatunk tovább, viszont, ha harcba keveredünk, akkor instant kámpec.)

A bunyó közben feltűnhetett a "HIT" feliratú doboz, meg a benne szaladgászó csík. A bunyó itt úgy megy, hogy az idővel megy felfele a hitpower, tehát minél később ütünk, annál nagyobbat ütünk, viszont az első két szakaszban még nem lehet ütni, az utolsó kettőben (vörös vagy sárga színnel jelöli a gép) meg már nem lehet ütni, csak a középső ötödben. Azt viszont minél tovább hagytuk futni, annál nagyobbat ütünk. Persze a fegyverünktől is függ, hogy végül mekkora lesz az ütés, mert egy fényszablyával nyilván nagyobbat lehet odasózni, mint egy Shakespeare kötettel (igen, mindkettő van a játékban); az utóbbiból inkább célszerű felolvasni az ellenfeleknek, garantált instant exitus lethalis... (Bár van olyan állat a játékban, aki direkt kéri.) Azonfelül a fegyver függvénye az is, hogy milyen gyorsan töltődik a csík, pl. az említett fényszablya baromi lassan, a "sokkostor" meg eszméletlen sebességgel; akinél ilyen van, az majdnem garantáltan agyon fog bennünket verni, mert hiába üt viszonylag kicsit (a többi fegyverhez képest, mert amúgy azért ez se piskóta), ha másodpercenként háromszor húz ránk vele...
Keressük tehát meg a hitpower-t. Miután újrakezdtünk, keveredjünk ismét bunyóba a huligánnal, most már amúgy sem fog tudni minket kinyúvasztani. Várjuk meg, amíg a csík felfut a maximumra, majd újrakezdi, akkor Shift+F12, dump, majd vissza és hagyjuk felfele futni, menetközben dump-okat készítve. Aztán:

mdsc -inc pandora0 pandora1 pandora2 pandora3
00003be3: 5, 7, 8, 9
00003cab: 4, 18, 30, 38
00003cad: 1, 5, 9, 11
00059939: 24, 156, 196, 220
00059aad: 24, 156, 196, 220
00059ab1: 18, 150, 194, 218
0005acbd: 17, 19, 37, 49
0005b3cf: 152, 174, 192, 204
0005b4a1: 152, 174, 192, 204
0005b4a5: 152, 174, 192, 204
0005b531: 172, 177, 195, 207
0005b541: 85, 90, 108, 120
0005b679: 172, 177, 195, 207
0005b67d: 172, 176, 194, 206
0005bb41: 54, 124, 142, 154
0005bb51: 25, 95, 113, 125
0005bb93: 78, 114, 132, 144
0005bc3d: 62, 106, 142, 158
0005bf01: 54, 124, 142, 154
0005bf05: 50, 124, 142, 154
0005bf3f: 78, 114, 132, 144
0005bf43: 76, 112, 130, 142
0005bfc1: 62, 106, 142, 158
0005bfc5: 60, 104, 140, 158
00072e58: 2, 4, 128, 132
00072f9c: 79, 97, 128, 193

Itt sok értéket találtunk (akinek jó reflexei vannak, az megpróbálkozhat sűrűbb "mintavétellel" is). Az ismétlődők nyilván itt se játszanak, amúgy meg a szokásos trial and error. Tróbáljuk meg az elsőt fagyasztani arra a maximumra, ami a listában látszik:

w 2 3be3 1 F 9

Nem nyert, ez valami offset volt, nem a hitpower. Nézzük a következőt:

w 2 3cab 1 F 26

Talált. A probléma csak az, hogy a vörösben már nem lehet ütni. Pár tipp és megvan a középső ötöd felső határa.

w 2 3cab 1 F 18

Lezúztuk a huligánt. Nem kár érte. Kultúrember amúgy sem járkál magentában.

Namármost, a játékban van még egy lézerpuska is, kemény öt darab töltettel. Ezzel bárkit ki lehet ugyan nyúvasztani, de van egyvalaki, akit csak ezzel: a tolvajt (az is mit keres egy űrállomáson), aki huligán kollégájától egy köpésnyire északra szaladgászik jobbról balra, majd vissza és ha keresztülmegy rajtunk, kimarja ami a kezünkben volt. Ha nem volt semmi, akkor nem történt semmi, ha az utolsó ID-nk volt, akkor megszívtuk. Nos, ő nem verekszik velünk (ha fegyver van nálunk, azt is ellopja), tehát csak a lézerfegyverrel lehet kinyírni. (Három lövés.) Ami érdekes, hogy amit ellop, az utána nem lesz nála, hiába nyírjuk ki. Varázslatosan eladta valami láthatatlan orgazdának menet közben, vagy megette, vagy átteleportálta az ettől a folyosótól északra levő szobában dekkoló bankárnak (és az mit keres egy űrbázison; pénzt?), vagy nem tudom mit csinált vele... (A bankárt feltétlen nyírjuk ki, egyrészt mert jól esik, másrészt meg mert ugyanúgy "becsületpont" jár érte, mint a tolvajért, ami számít egynémelyik karakternél, ha csereberélni akarunk velük. Nem, ez nem vicc. (A huligánért miért nem jár?))
De ez mellékes. Mint mondtam a puskát bárki ellen lehet használni. Először is menjünk be érte a biztonsági tiszthez és szedjük fel a kék asztalról.

Utána csináljunk dump-ot, majd minden lövés után egyet.

mdsc -dec pandora0 pandora1 pandora2 pandora3 pandora4 pandora5
0001924e: 5, 4, 3, 2, 1, 0

Ez gyors volt. Fagyasszunk.

w 3 01924e 1 F ff

Most már végtelen lézerünk van.

Nos, akkor megvannak a címeink és az értékeink. Itt az idő, hogy kódolni kezdjünk.

Az Amigának van kettő darab CIA chipje, fejenként kettő darab timerrel, továbbá van 7 szintű megszakításrendszere, aminek a vektorait $64-től $7c-ig találjuk a memóriában. Ha visszanézünk a legelső képre, ott pont a nullás lap van a dump window-ban és lehet látni, hogy a level 3-as interruptot leszámítva csupa olyan cím van beírva rájuk, ami KickStart címekre mutat, vagyis a játék nem használja őket. A CIA A tud 2-es szintű (alacsony prioritású) megszakítást generálni, a CIA B pedig 6-ost (magas prioritású); mivel ez egy trainer, aminek folyton írnia kell bizonyos címeket, így célszerű az utóbbit használni ($78-as cím). (Működne a másik is, csak abba belerondíthatna a használt VBlank level 3-as interrupt, ami magasabb prioritású.)
Akkor tehát, vannak címeink és értékeink:

HitPowerAddr	equ		$00003cab
MaxHitPower	equ		$18
HealthAddr	equ		$0005c35f
MaxHealth	equ		$5f
TimeAddr	equ		$00003c82
MaxTime		equ		$999a
LaserShotsAddr	equ		$0001924e
MaxLaserShots	equ		$05

Ezeket kellene kódból a helyükre rakni:

		move.b		#MaxHitPower,HitPowerAddr
		move.b		#MaxHealth,HealthAddr
		move.w		#MaxTime,TimeAddr
		move.b		#MaxLaserShots,LaserShotsAddr

Tulajdonképpen a lényegi rész ennyi is, csak vissza kéne térni az interruptból, amihez törölni kell a CIA B megszakítás flagjét (olvasással), valamint törölni a chipset megszakítás kérelmét jelző flag-et is:

		tst.b		CIAB+CIAICR
		move.w		#EXTER,CUSTOM+INTREQ
		rte

Ehhez persze kellenek a használt system konstansok is:

CUSTOM		equ		$DFF000
INTREQ		equ		$09C
EXTER		equ		$2000
CIAB		equ		$BFD000
CIAICR		equ		$D00

Na, első körben egy hunkless, nyers binárist fogunk forgatni, hogy teszteljük a koncepciót. Erre a célra ott van pl. a vasm:

vasmm68k_mot pat.s -Fbin -nosym -o pat -L pat.txt

A kapott "pat" binárist másoljuk be a WinUAE könyvtárába, indítsuk el a játékot, majd kérjük a debuggert. Ott töltsük be a binárisunkat a $100-as címre:

L pat 100

Csekkoljuk le, hogy minden oké-e:

dg 100

A jelek szerint igen. Akkor most leheljük életre a timert, a debuggerből. Először is állítsuk be a 6-os megszakítási vektort a rutinunk címére.

W 78 100.l

Utána az INTENA regiszterben engedélyezzük a külső megszakításokat (ebbe a regiszterbe úgy kell írni, hogy ha simán beírunk egy flag-et, akkor töröljük, ha viszont a legfelső flaggel együtt írjuk be, akkor épp engedélyezzük, tehát ez itt a $2000-es + $8000-es flag-eket jelenti):

W dff09a a000

Állítsuk be a CIA timert, mondjuk 2048 ciklusra:

W BFD400 0
W BFD500 8

Állítsuk be a timer megszakításait az A timerre:

W BFDD00 81

Végül indítsuk el a timert, folyamatos módban:

W BFDE00 1

A cucc működik.

Ami azt illeti, már túl jól, mert akkor sem halunk meg, ha belesétálunk az elektromos kerítésbe.

Ilyenkor, ha nálunk van az az ID, ami azt a kerítést nyitja, akkor space-szel átválthatunk a tárgyakhoz és kézbevehetjük, vagy marad az F7, ami újrakezdi a játékot. Mindenesetre, az sem ártana, ha a trainerünk funkcióit ki-be lehetne kapcsolgatni a játék alatt.
Erre mondjuk megfelelnek az F2-től F5-ig terjedő gombok (az F1 a pause). Bele lehet rakni egy billentyűzetfigyelőt a rutinunkba is, de egyszerűbb felhasználni a játékét. A billentyűzetről bejövő adatok a CIA A soros regiszterében kötnek ki ($bfec01-es cím), viszont 68000-esen a mindenféle regiszterbe írkálásokat többnyire offsetekkel szokták használni, mert kevesebb helyet foglal és regiszterből gyorsabb is. Azaz, először ne erre a címre, hanem a CIA A báziscímére ($bfe001) keressünk. A keresés a "s" paranccsal történik:

s bfe001

Eredmény

000107F9 00010865 0005BFDC 0005D7E3 0005E3F1 0006D7E3 0006E3F1 001107F9 00110865 0015BFDC 0015D7E3 0015E3F1 0016D7E3 0016E3F1

Nézzük először az első címet. (Mivel a kapott címek magukat az értékeket jelölik, itt mindig célszerű levonni hármat, (vagy ötöt), hogy az utasítás kezdőértékét kapjuk meg.)

dg 107f6

Ennek köze nincs a billentyűzetfigyeléshez. Ez - ha jól látom - azt nézi, hogy az egér jobb gombja nyomva van-e, vagy sem, legalábbis, akkor állít be igazat (-1) egy címre, ha a CIA A A portján a hetedik bit nulla, (pontosabban: ha, a regiszterben egy pozitív szám van).
Nézzük a következőt.

dg 10862

Megvan. Ez betölti a0 címregiszterbe a báziscímet, majd $c00-val offsetelve (a CIA-k soros regisztere) olvas egyet, utána pedig dekódolja (jobbra forgatás egyel és negálás), majd kimenti a6-ot $222-val offsetelve. Ez pedig a $3c1e-es címet jelenti. (a6 tartalma itt mindig ugyanannyi, valószínűleg a játék egyik adatterületének báziscíme.)
Ha kicsikét kaparászunk visszafele, akkor megtalálhatjuk $10858-nál az egész billentyűzetfigyelő rutint:

		move.w		INTREQR(a5),d0
		btst		#bPORTS,d0
		beq		pKDAT
		lea		CIAA,a0
		moveq		#0,d0
		lea		$397c,a1
		move.b		CIASDR(a0),d0
		ror.b		#1,d0
		not.b		d0
		bclr		#7,d0
		seq		(a1,d0.l,0)
		bne		pKDAT
		move.b		d0,$222(a6)
pKDAT:		move.b		#SPMODE,CIACRA(a0)
		mulu.w		#1,d0
		mulu.w		#1,d0
		mulu.w		#1,d0
		mulu.w		#1,d0
		mulu.w		#1,d0
		mulu.w		#1,d0
		mulu.w		#1,d0
		mulu.w		#1,d0
		mulu.w		#1,d0
		mulu.w		#1,d0
		mulu.w		#1,d0
		mulu.w		#1,d0
		mulu.w		#1,d0
		mulu.w		#1,d0
		mulu.w		#1,d0
		mulu.w		#1,d0
		mulu.w		#1,d0
		mulu.w		#1,d0
		mulu.w		#1,d0
		clr.b		CIACRA(a0)
		move.w		#RBF|PORTS|TBE,INTREQ(a5)
		rts

Ez az INTREQR regiszterből lekéri, hogy van-e I/O megszakítás-e, vagy sincs és ha van, akkor egyrészt kiírja $3c1e-re a leütött billentyű kódját, valamint beállítja -1-re a $397c báziscímet a kód értékével offsetelve. Utána pedig pulzáló kimeneti módba kapcsolja a soros regisztert, majd vár...processzorból. Szorzással. Aztán lekapcsolja a vonal rángatását, törli a flag-eket és kiszáll.
A kimenő értékeket le is csekkolhatjuk. Játékon belül tenyereljünk rá először a Shift-re, aztán mondjuk az F3-ra (így az F3 lesz az aktív, nem a Shift) és utána az F12-re. Utána nézzük meg az érintett memóriaterületeket.

mg 397c

$52 byte-tal (F3 kódja) odébb, ott van a -1.

mg 3c1e

És ott van a kód is a helyén.
Akkor helyben vagyunk. Írjuk át a trainert, hogy csak akkor írja az értékeket, ha az van beállítva neki.

HitPowerHack:	cmp.b		#0,THitPowerAddr
		beq		HealthHack
		move.b		#MaxHitPower,HitPowerAddr
HealthHack:	cmp.b		#0,THealthAddr
		beq		TimeHack
		move.b		#MaxHealth,HealthAddr
TimeHack:	cmp.b		#0,TTimeAddr
		beq		LaserShotsHack
		move.w		#MaxTime,TimeAddr
LaserShotsHack:	cmp.b		#0,TLaserShotsAddr
		beq		KeyboardHnd
		move.b		#MaxLaserShots,LaserShotsAddr

Ehhez kellenek a változók is:

THitPower:	dc.b		0
THealth:	dc.b		0
TTime:		dc.b		0
TLaserShots:	dc.b		0

Valamint, mivel ez abszolút címen lesz, ezért a címeket is ki kéne számíttatni az assemblerrel.

TORG		equ		$00000100
THitPowerAddr	equ		THitPower+TORG
THealthAddr	equ		THealth+TORG
TTimeAddr	equ		TTime+TORG
TLaserShotsAddr	equ		TLaserShots+TORG

Akkor a trainer maga már tudja is, amit kell, most már csak azt kéne lekezelni, hogy a billentyűzettel ezt a négy címet írni lehessen, hogy ki-vagy-be. Illetve, akkor már F6-ra kinullázhatjuk az időt, hogy lássuk mi történik, ha lejár. (Egyébként semmi. Kiírja a gép, hogy megérkeztünk, Pandora teleszórta az atmoszférát mocsokkal és mingyán kipusztul az emberiség. A játék megy tovább. Ez csak akkor számít, ha sikerült elpusztítani a bázist, de időn túl, olyankor az a konklúzió, hogy az emberiség jövője bizonytalan.)

ReadKeyboard:	move.l		d0,-(a7)
		move.b		KeystrokeAddr,d0

CheckF2:	cmp.b		#BtnF2,d0
		bne		CheckF3
		eor.b		#1,THitPowerAddr
		bra		SetKbdWait

CheckF3:	cmp.b		#BtnF3,d0
		bne		CheckF4
		eor.b		#1,THealthAddr
		bra		SetKbdWait

CheckF4:	cmp.b		#BtnF4,d0
		bne		CheckF5
		eor.b		#1,TTimeAddr
		bra		SetKbdWait

CheckF5:	cmp.b		#BtnF5,d0
		bne		CheckF6
		eor.b		#1,TLaserShotsAddr
		bra		SetKbdWait

CheckF6:	cmp.b		#BtnF6,d0
		bne		RestoreD0
		move.w		#$0001,TimeAddr

Ehhez is kellenek a konstansok, hogy honnan is olvassa a billentyűzet kódját, meg az ellenőrizendő kódok.

KeystrokeAddr	equ		$00003c1e
BtnF2		equ		$51
BtnF3		equ		$52
BtnF4		equ		$53
BtnF5		equ		$54
BtnF6		equ		$55

Ezen túl, a kiszálló kódot kell még módosítani, hogy egyrészt a d0-át vissza is töltse, másrészt meg, hogy kitörölje a beolvasott kódot, nehogy ismétlés legyen.

RestoreD0:	move.l		(a7)+,d0

AckInterrupt:	clr.b		KeystrokeAddr
		tst.b		CIAB+CIAICR
		move.w		#EXTER,CUSTOM+INTREQ
		rte

Itt biztos feltűnt pár embernek, hogy van két db. nem létező címke a kódban, a KeyboardHnd és a SetKbdWait. Az oka az, hogy a következő interruptig ugyanaz a kód még egyszer be fog jönni, azaz egy kört meg kell várni.
Ez felel az átugrásért:

KeyboardHnd:	cmp.b		#0,KeyboardWAddr
		beq		ReadKeyboard
		subq		#1,KeyboardWAddr
		bra		AckInterrupt

Ez pedig az acknowledge, hogy a következőt skippeljük:

SetKbdWait:	move.b		#$01,KeyboardWAddr

Kell a változó is

KeyboardW	dc.b		0

És a címe is:

KeyboardWAddr	equ		KeyboardW+TORG

És így...

...már működik a ki-be kapcsolgatása a trainernek.

Ha viszont újrakezdjük a játékot (nem reset, csak game over), akkor azt vesszük észre, hogy nem működik többé. Hiába kapcsoljuk be, pl. az örök időt, az állhatatosan csökken. (Life in a nutshell.)

Ha kinyitjuk a debuggert, akkor látjuk, hogy az INTENA regiszterben $4030 van $6030 helyett. Valami lekapcsolja a külső megszakításokat. (Ami nem meglepő, lévén a játék nem használja.)
Mint kitisztáztuk fentebb, a megszakítások regiszterébe úgy írunk, hogy ami flag-eket beleírunk, azt, ha a legfölső SET/CLR flag-gel együtt írjuk be, akkor bekapcsoljuk, különben meg ki. Mit jelent ez? Azt, hogy ha $4030 van a regiszterben, azt $c030-cal kapcsolták be.

s c030
000036DE 00010518 000109B1 0001771B 00019F3F 00022BDA 00022BF2 00030BF1 0003498E 0003E2C4 0003E560 0003E74F 0003E99F 0003F25F 000498C4 000498C6 0004BD20 0005390F 00053FDF 00053FEB 00053FED 0005444B 0005D989 000682B2 0006D989 00072C0A 00072DEA

...vagy hasonló lista; egy része minden keresésnél ugyanaz, egy része meg nem. Néha hosszabb, néha rövidebb... Nézzük az első címet.

dg 36dc
dg 36da

Hát itt valami marhaság van. Valószínűleg adat, vagy szemét. Next.

dg 10516

Meg is van. Írjuk át $e030-ra:

W 10518 e0

Ezután a már ismertetett módszerrel a timert indítsuk újra.

És most már nem áll meg újrakezdés után.

Kell tehát a kódunk elejére egy patcher, ami figyeli ezt az értéket és ha a helyére került, akkor megpatcheli, majd utána átírja a megszakítás címét, mert patchelni csak egyszer kell.

InterruptCode:	cmp.b		#ChkPatchIRM,PatchAddr
		bne		AckInterrupt
		move.b		#PatchedIRM,PatchAddr
		move.l		#(HitPowerHack-InterruptCode)+TORG,L6IV

Ehhez persze kellenek az idevágó konstansok is:

L6IV		equ		$78
PatchAddr	equ		$10518
ChkPatchIRM	equ		(SETCLR|INTEN)>>8
PatchedIRM	equ		(SETCLR|INTEN|EXTER)>>8

SETCLR		equ		$8000
INTEN		equ		$4000

Miután kireseteltük a gépet, betöltöttük ismét a játékot, meg a debuggerben a helyére a kódot és elindítottuk a timert, minden működik. És nem áll le az első játékújrakezdésnél.

Itt az idő, hogy az eddig kézzel betöltött kódból önbetöltő trainert faragjunk.
Kezdetnek tegyünk az eddigi interrupt kód legelejére és legvégére egy-egy 32-bitre történő igazítást és a végére egy címkét is. Eleje:

		align		2
InterruptCode:	cmp.b		#ChkPatchIRM,PatchAddr

Vége:

KeyboardW	dc.b		0
		align		2
InterruptEnd:

Erre azért van szükség, mert így lehet 32-bitenként másolni. Tegyük ezt a kód legelejére:

DoTheCopy:	lea		InterruptCode,a0
		movea.l		#TORG,a1
		move.l		#(InterruptEnd-InterruptCode)>>2,d0
RCopyLoop:	move.l		(a0)+,(a1)+
		dbra		d0,RCopyLoop

Most pedig felparaméterezzük a timert, ugyanúgy, mint a debuggerben, csak itt előtte tiltani kell a megszakításokat, utána meg engedni. Debuggerben a fagyott állapot miatt nem volt rá szükség:

		move.l		#CIAB,a1
		move.w		#EXTER,INTENA(a2)
		move.b		#$7f,CIAICR(a1)
		move.b		#0,CIACRA(a1)
		tst.b		CIAICR(a1)
		move.w		#EXTER,INTREQ(a2)
		move.l		#TORG,L6IV
		move.b		#CIAICR_SC|CIAICR_TA,CIAICR(a1)
		move.b		#$00,CIATAL(a1)
		move.b		#$08,CIATAH(a1)
		move.b		#1,CIACRA(a1)
		move.w		#SETCLR|EXTER,INTENA(a2)

Konstansok:

INTENA		equ		$09A

CIAA		equ		$BFE001
CIATAL		equ		$400
CIATAH		equ		$500
CIASDR		equ		$C00
CIAICR		equ		$D00
CIACRA		equ		$E00
CIAICR_SC	equ		$80
CIAICR_TA	equ		$01

Illetve még egy dolog hibádzik: ki is kell szállni a programból, kinullázva a d0-át, mert különben a DOS közli, hogy elpusztult a program, a visszatérő hibakód meg valami marha nagy "véletlenszám".

		moveq		#0,d0
		rts

És ezután jön az igazítás és az interrupt rutin.
Ezt most le kéne forgatni, de ezt már úgy, hogy programba, nem headless binárisba.:

vasmm68k_mot pat.s -Fhunkexe -kick1hunks -nosym -o pat -L pat.txt

Pakoljuk be az S:startup-sequence-be a játék elé a programunkat, aztán uccu.
Hát, ez nem működik...
Nézzük meg, hogy a helyén van-e:

dg 00100

A kód a helyén van, de az interrupt le van tiltva.

dg 10516

Hát nem csoda. Nincs megpatchelve. Ez azt jelenti, hogy az interruptunk nem tudott lefutni akkor, amikor az már a helyén volt. Valami menetközben letiltotta, vagy race condition?
Nézzük meg, hogy a cracktro letilt-e valamit:

Nem. Itt még minden oké. Akkor a decruncher? Tudjátok, amikor össze vissza villódzik a kép:

Nocsak. Az interruptok ugyan le vannak tiltva, de globálisan, a mi flag-ünkhöz nem nyúlt. Disassembly és kérjünk egy breakpoint-ot, így látni fogjuk, amikor visszaadja a vezérlést:

dg 100
f 100

A decrunch lezárultával a flagek visszakapcsoltak és él a rutinunk.

Léptessük végig, amíg kiszáll, nézzük hova tér vissza.

A KickStartba. Köszi... Viszont az legalább látszik, hogy a megszakítási vektort ($78) nem piszkálta el.
Itt, ha hagyjuk futni, akkor egyszer még visszajön, de akkor sem történik semmi, majd végleg kiszáll. Hova lett a patchelendő rész?

s c030
000104F3 00019AA8 0001D63C 00020518 000209B1 0002771B 00029F3F 00032BDA 00032BF2

Ha megnézzük disassemblyvel, az első két címen marhaság van, a harmadiknál meg az opkód része. De mi a helyzet a negyedikkel?

dg 00020516

Aha. Szóval betöltés közben ez még itt van, valószínűleg ide cruncholja ki, majd innen copyzza át a másik helyre. Tehát módosul patchelendő címünk is:

PatchAddr	equ		$20518

Assemble, reboot, és:

A trainerünk működik.

Akkor tkp. megvagyunk, legalábbis a dolog trainer részével. Hogy az örök klasszikussal éljek: "kb. így fest a dolog gatyában". Most jön az az "esztétikai" része, a menü. (Igazából, tekintve, hogy a funkciógombokkal a játékon belül is kapcsolgathatóak a cuccok, így ez tényleg csak azért van, hogy "traineresebb" legyen...)
Aki a múltkor nehezményezte, hogy assemblyben való hw-banging helyett C-s rendszerbarát programozás volt, az most örülhet, mert az előbbi következik. Ami egyébként - nem győzöm hangsúlyozni: - továbbra is kerülendő; itt is azért "engedhető meg", mert a trainer lefutása után a játék úgyis lezúzza az OS-t, akkor meg mindegy.

Mielőtt bármit csinálnánk, a programba ágyazott copperlistánkat át kell másolni valahova a Chip RAM-ba.

		lea		Copper(pc),a0
		movea.l		#CopperAddr,a1
		move.w		#CopperLength>>2,d0
CopyCopper:	move.l		(a0)+,(a1)+
		dbra		d0,CopyCopper

És akkor már egy screen clear is:

		movea.l		#FirstPlane,a0
		move.w		#(PlaneLength<<1)>>2,d0
		moveq		#0,d1
ScreenClr:	move.l		d1,(a0)+
		dbra		d0,ScreenClr

A copperlistát azért nem közvetlenül a programból címeztük be, mert ha van Fast RAM és a program oda töltődik be, akkor nem fog működni, mert a custom chipek - nomen est omen - csak a Chip RAM-ot látják, azaz a copperlistát se fogják.
A copperlista és a síkok cuccainak konstansai:

PlaneLength	equ		((WIDTH*HEIGHT)/8)
CopperLength	equ		(CopperEnd-Copper)
SecondPlane	equ		($7e800-PlaneLength)
FirstPlane	equ		(SecondPlane-PlaneLength)
CopperAddr	equ		(FirstPlane-CopperLength)

$7e800-ig fogjuk használni a memóriát, mert az utolsó 6 kB a system supervisor stack.
Aztán, nyissuk meg a graphics.library-t és rángassuk ki belőle a mostani copperlista címét, mert kiszálláskor kelleni fog.

		lea		CUSTOM,a2

		move.l		$4,a6
		lea		graphics_lib(pc),a1
		jsr		OldOpenLibrary(a6)
		move.l		d0,a1
		move.l		38(a1),CopperBackup
		jsr		CloseLibrary(a6)

Ehhez kell a library nevének stringje és a backup változó (note the alignment!)

graphics_lib:	dc.b		"graphics.library",0
		align		2
CopperBackup:	dc.l		0

valamint a library nyitó és záró offsetek.


OldOpenLibrary	equ		-408
CloseLibrary	equ		-414

Ha ezzel megvagyunk, akkor tiltsuk le a multitaskot, majd írjuk felül a copperlistát.

		jsr		Forbid(a6)
		move.l		#CopperAddr,COP1LCH(a2)

Idevágó két konstans:


COP1LCH		equ		$080
Forbid		equ		-132

Eztán jön a DMA flagjeinek backupolása, majd beállítása a DMACON és DMACONR regisztereken keresztül.

		move.w		#SETCLR,d3
		or.w		DMACONR(a2),d3
		move.w		d3,DMABackup
		move.w		#$7fff,DMACON(a2)
		move.w		#SETCLR|DMA_ENABLED,DMACON(a2)

A backup változót szúrjuk be a másik mögé

DMABackup:	dc.w		0

Konstansok:

DMACONR		equ		$002
DMACON		equ		$096
DMAEN		equ		$0200
BPLEN		equ		$0100
COPEN		equ		$0080
DMA_ENABLED	equ		DMAEN|BPLEN|COPEN

És akkor a copperlista (note the alignment!):

		align		2
Copper:		dc.w		BPL1PTH,(FirstPlane>>16)
		dc.w		BPL1PTL,(FirstPlane&$ffff)
		dc.w		BPL2PTH,(SecondPlane>>16)
		dc.w		BPL2PTL,(SecondPlane&$ffff)
		dc.w		BPL1MOD,$0000
		dc.w		BPL2MOD,$0000
		dc.w		BPLCON0,(BPUx*2)|COLOR
		dc.w		BPLCON1,$0000
		dc.w		BPLCON2,$0000
		dc.w		DIWSTRT,X|(Y<<8)
		dc.w		DIWSTOP,((X+WIDTH)-256)|(((Y+HEIGHT)-256)<<8)
		dc.w		DDFSTRT,(X/2-RES)
		dc.w		DDFSTOP,(X/2-RES)+(8*((WIDTH/16)-1))
		dc.w		COLOR00,$0000
		dc.w		COLOR01,$00f0
		dc.w		COLOR02,$0080
		dc.w		COLOR03,$0fff
		dc.w		$ffff,$fffe
CopperEnd:

és konstansai:

WIDTH		equ		320
HEIGHT		equ		256
X		equ		129
Y		equ		44
RES		equ		8		;8 = lores, 4 = hires, 2 = super-hires

Kis magyarázat: a BPLxPTx regiszterekbe kerülnek a bitsíkok kezdőcímei, a BPLxMOD regiszterekbe a sorok modulói (hogy hány byte kell a sor végén, hogy a következő sor kezdőcímét megkapjuk), ami nulla, mert sorfolytonos. A BPLCON0 regiszterben állítjuk be, hogy 2-bites (4-színű) színes képet kérünk (COLOR flag), noha emulátorból ez pont mindegy, de RGB használata esetén is, sőt, pont A500/A2000 gépeken, amikre a játék készült szintén mindegy, mert ott a kompozit is szürke lesz. Mindegy, kapcsoljuk be. :P A másik két BPLCONx a prioritásokat szabályozza; itt érdektelen, nulla.
A DIWSTRT és DIWSTOP határozzák meg, hogy hány pixelt jelenítsen meg a képernyőn és hol. Az alsó nyolc bit a vízszintes koordináta, a felső a függőleges. Viszont a stop regiszterben a koordinátákból ki van vonva 256 pixel. Tehát a vízszintes felbontás az ($c1-$81)+256=320, a függőleges meg ($2c-$2c)+256=256. (Thx, Angry Retired Bastard.)
A DDFSTRT és DDFSTOP állítják be, hogy az elektronsugár melyik vízszintes pozíciójától kezdje olvasni az adatokat és meddig. A $38 (56) és $D0 (208) a PAL szabvány, 208-56=152 bit, per 8, az 19, plusz egy fetch az 16-bit 20x olvasva, az 320 pixel. (Thx, ross.)
A COLORXX regiszterek meg nem szorulnak magyarázatra. (De a múltkor amúgy is ki lettek vesézve az Amiga színregiszterei.) A végén pedig a copperlista lezárója.
Idevágó regisztercím és flag konstansok:

BPL1PTH		equ		$0E0
BPL1PTL		equ		$0E2
BPL2PTH		equ		$0E4
BPL2PTL		equ		$0E6
BPLCON0		equ		$100
BPLCON1		equ		$102
BPLCON2		equ		$104
BPL1MOD		equ		$108
BPL2MOD		equ		$10A
DIWSTRT		equ		$08E
DIWSTOP		equ		$090
DDFSTRT		equ		$092
DDFSTOP		equ		$094
COLOR00		equ		$180
COLOR01		equ		$182
COLOR02		equ		$184
COLOR03		equ		$186

COLOR		equ		$0200
BPUx		equ		$1000

Mi kell még? A billentyűzet és az egér. Billentyűzet:

		lea		CIAA+CIASDR,a1
		clr.b		(a1)
ReadKbd:	move.b		(a1),d0
		ror.b		#1,d0
		not.b		d0
		bmi.b		CheckMouse
		clr.b		(a1)

Ez ugyanúgy beolvassa a kódot a soros regiszterből, mint a játékban és ugyanúgy kell lekezelni és a változókat írni (kivéve az egy körös skip-et), ld. fentebb, nem copyzom be még egyszer.
Ha a billentyűzet lekezelése megvan, jöhet az egér, ami az A portot olvasgatja, aminek a hatodik bitje a left button. Ha lenyomódik, kiszáll.

CheckMouse:	btst		#6,-CIASDR(a1)
		bne.b		ReadKbd

Ez után jöhet az interrupt kódját copyzó rutin (DoTheCopy), majd a timer felprogramozása, aztán végül, kiszállás előtt lehet visszaállítani a képernyőt és visszakapcsolni a multitaszkot. Ezt a legvégére kell írni, közvetlenül a d0 nullázása és az rts előtt.

Exit:		move.w		#$7fff,DMACON(a2)
		move.l		CopperBackup,COP1LCH(a2)
		move.w		DMABackup,DMACON(a2)
		jsr		Permit(a6)

A Permit címe:

Permit		equ		-138

Van még valami? Semmi, azon túl, hogy írkálunk a képernyőre. Ehhez kell egy fontset, amit a programba ágyazunk és vagy Blitterrel, vagy CPU-val a képernyőre hányunk betűnként (én ez utóbbit tettem). Írogathatunk üzeneteket, valamint, amikor a gombok hatására valamelyik flag bebillen, akkor lehet jelezni a változást (pl. On/Off, vagy ilyesmi).

Ezt vagy tíz éve rajzoltam, de sose használtam fel, mostanáig. Ebből még annyit, hogy csak 32-127-ig használtam a karaktereket, mert másra nem volt szükség. Mivel a múltkor már tisztáztuk, hogy hogy működik az Amiga videómemóriája és a képsíkok és nem a Blitterrel rajzoltam, hogy bármi új lenne benne, erre most nem pazarolnám már a helyet.

Még itt egy képernyőkép a már futó trainerről.

És nagyjából ennyi.
A trainer letölthető innen, a játékot inkább nem linkelem be, mert nem tudom, mennyire érzékeny trey az abandonware-re, de fent van az is a honlapon. (Use the searchbox, Luke.)

Köszöntem a figyelmet, remélem, aránylag kevés agykárosodással túléltétek.

Hozzászólások

Ez nagyon élvezetes és tanulságos volt.

"Maradt még 2 kB-om. Teszek bele egy TCP-IP stacket és egy bootlogót. "

Amigára talán még nincs Pegazus, lehet azt kéne használni :) Kár hogy a 90-es évek elején eladtam :(

SWp0rn! Még többet!

Sajnos az Amigával már csak kesőn találkoztam, mire a PC-k letarolták a világot. De szeretnék komolyabban megismerkedni vele. Szerencsére sikerült egy jó állapotban lévő 500+ gépet beszereznem a többi Commodore masinám mellé.

nem tudom tudsz-e rola de nem latszanak a kepek, legyszi fixald!

Szakmai hozzáértés híján? Hogyan? Ha egy pirinyó szakmai hozzáértésed is lenne, már bekapcsoltad volna a mixed-contentet, vagy felraktál volna egy HTTPS-everywhere-t és problem solved. De te ehelyett inkább picsogsz, hogy nem látod a képeket, ami nem meglepő, mert tőled ennyi tellik. Valahányszor szakmai vitába keverednénk, te picsagyorsan kihátrálsz, hogy neked nem igazából a szakmai résszel volt bajod, abban egyetértesz velem, stb. Szerintem ne erőlködj.

BTW, ezt már rég meg akartam kérdezni: ha neked a nicked a nevedből van, akkor miért nem NagyArZ a nicked? Jobban passzolna.

Igen, elfogytál, mert semmi érdemi választ nem tudtál adni sem arra, hogy
  a) miért nem kapcsolod be a mixed-contentet,
vagy
  b) miért nem teszel fel egy HTTPS-everywhere-t,
ha te szakmailag akkora überszakértő vagy, ill. arra sem, hogy
  a) miért nem illúzió a HTTPS által adott biztonság
és
  b) miért nem vezet a netsemlegesség kinyírásához.

Ehelyett maradt ez a már hatvannyolcezerszer megcáfolt hazugsághalom, holott, ha eddig nem írtam le nem csak a belinkelt FAQ-ban, de hupos válaszkommentekben is hatvannyolcezerszer, hogy ha lenne hozzáférésem, már rég megcsináltam volna, hogy a biccsegés abbamaradjon, akkor egyszer sem.

Tehát te vagy egy retardált write-only analfabéta vagy, aki picsog, mert nem képes egy ilyen piszlicsáré problémát sem megoldani (erre mondtam, hogy: chluser 222 NagyArZ), vagy egy figyelemkurwa troll, aki hazudozik.

Köszi! Még amigás korszakom előtt c64-en csináltam hasonlókat kölyökként. Mivel nem volt emulátor, se action replay (még soha nem is hallottam ilyenekről), ezért a peccselendő játéknál a TV képcsövén jelöltem meg azt a karaktert vagy karaktereket filctollal, ahol pl. az életek száma volt, majd ez alapján már tudtam offszetcímet számolni, amely alapján már meg tudtam keresni a játék kódjában a releváns gépi kódú utasításokat, ami már elvezetett a peccselendő kódrészlethez. Ha minden összeállt, akkor készítettem el a játék "elé" a cracktro-t. Persze, ez a megoldás ingame nem műkdött. :) Aztán kijöttek olyan játékok, amelyekről már körülményesebb volt eltávolítani a decruncereket (risk rémlik), lévén a tömörítésen kívül védelmi funkciót is kezdtek ellátni, viszont a pure játék kódjának elemzéséhez szükség volt a kicsomagolásukra. Írtam egy crunchert is a cél érdekében, plusz egy olyan disassembler/debuggert, amely kvázi emulátor volt, mert az éppen végrehajtott gépi kódú utasítást kiemeltem a környezetéből és a debuggerem saját "testében" hajtottam végre egy malom nevezetű területen. Ezért lassú volt, de akkor újszerű és védelmek ellen kiváló. Ésígytovább...

Érdekes megoldás! :) Felmerült bennem pár kérdés:

Ez a trükk mennyire általános, hogy a változókat IT-ből időnként visszaállítják? (Számomra ez ilyen igazi "dirty hack" fíling. ;) ) Logikusabbnak hangzana az, hogy a változókat módosító kódot keresem meg / peccselem, hogy ne csinálják a dolgukat. Illetve ez a 2048 ciklusonként futtatott IT nem sűrű egy kissé? Nem lenne elég ennek mondjuk frémenként csak 1× futnia?

Aztán ami még érdekelne, hogy anno ezeket hogy csinálták? Amikor még nem volt kéznél egy emulátor, ahol szabadon garázdálkodok a gép belsejében, hanem volt az egy szem A500-am, azzal kellett / lehetett megoldani mindent. Én ugyan nem találkoztam vele, de mintha A500-hoz létezett volna ilyen "Action-Replay" szerű hardverbővítés, meg az újabb AMIGÁkban ha van a CPU-ban MMU, ott már szoftverből is lehet csinálni ezt-azt. De ha ezek nincsenek, csak egy sima alapgépem, hogyan álljak neki..? :) (A kérdés nyilván teoretikus; a mai eszközök mellett a régi megoldással minek is álla neki az ember...)

Ez a trükk mennyire általános, hogy a változókat IT-ből időnként visszaállítják?

Azt nem tudom. Amigán egy raklap módon lehet ezt csinálni, mindenki válogathat.

Számomra ez ilyen igazi "dirty hack" fíling. ;)

Ez annak is készült. :) A legegyszerűbb megközelítést választottam.

Logikusabbnak hangzana az, hogy a változókat módosító kódot keresem meg / peccselem, hogy ne csinálják a dolgukat.

Azt is lehet, csak akkor az sokkal több reverse engineering-gel és átalakítással jár, feltéve, ha egy hasonló szintű trainert akar az ember kihozni belőle; nyilván, ha csak annyit akarok, hogy ne fogyjon az életerő/idő/lövés, azt egy-egy sub.w xxx,yyy átírásával el lehet érni.

Illetve ez a 2048 ciklusonként futtatott IT nem sűrű egy kissé? Nem lenne elég ennek mondjuk frémenként csak 1× futnia?

A változók átírásához simán elég lenne, de a billentyűzetfigyelés kisebb mintavételezéssel "lagzani" fog és nem reagál azonnal; sokat próbálgattam, hogy mennyi lenne a célszerű. Többek közt ezért is járna sokkal több átalakítással a kódátírós dolog, hiszen meg kéne patchelni a billentyűzetfigyelő kódot úgy, hogy több kódot kéne belenyomni ugyanakkora adatterületbe, hiszen itt minden fix címen van, nem tologathatom el a végével a következő rutin elejét. Vagy kirakhatom az új rutint oda, ahol van elég hely és odaugraszthatom a régi billentyűzetfigyelő kód legelejéről, de ehhez szabad hely kell, ami nem mindig van, ez a játék is majdnem csurig írta a memóriát.

Aztán ami még érdekelne, hogy anno ezeket hogy csinálták? Amikor még nem volt kéznél egy emulátor, ahol szabadon garázdálkodok a gép belsejében, hanem volt az egy szem A500-am, azzal kellett / lehetett megoldani mindent. Én ugyan nem találkoztam vele, de mintha A500-hoz létezett volna ilyen "Action-Replay" szerű hardverbővítés, meg az újabb AMIGÁkban ha van a CPU-ban MMU, ott már szoftverből is lehet csinálni ezt-azt.

Igen, volt Action Replay, de ez csak egy volt a sok közül. Amigán a 7. szintű - nem maszkolható - megszakítást úgy lehetett kiváltani, ha alacsonyra húztad mindhárom IPL lábát a CPU-nak. Ekkor minden más megállt, lévén ez a legmagasabb szintű interrupt, őt nem szakíthatja meg semmi. Ilyenkor a rendszer kvázi "megfagy", csak az a kód működik, amire a $7c címen található vektor ugrasztotta a processzort. Ha az a kód azzal nyit, hogy mindent is lement valahova (movem.l d0-d7/a0-a7,$add4e55), meg kibányássza a veremből a pc és az sr megszakítás előtti értékét, akkor tkp. máris van egy monitorunk. Lehet a dolgot olyan fancy módon is csinálni, mint az AR és a hasonló freezerek, hogy ráül a buszra és egy raklap dolgot csinál, de igazából egy az IPL lábakat és a földet összekötő kapcsoló is elég, meg egy szoftveres monitor, mint pl. a WinUAE-be is beépített HRTmon.

De ha ezek nincsenek, csak egy sima alapgépem, hogyan álljak neki..? :) (A kérdés nyilván teoretikus; a mai eszközök mellett a régi megoldással minek is álla neki az ember...)

Hát így. :) Alacsonyra húzod a CPU IPL lábait és használsz egy szoftveres monitort.
Vagy, van a másik módszer: disassemblálod a bootblockot, megnézed mit, hogyan és hova tölt be, kigrabbeled azokat a részeket a lemezről, végrehajtod rajta azokat a műveleteket (pl. decrunch), amiket kell, majd utána azt is disassemblálod és így tovább. Csináltam ilyet is pár éve, igaz az nem trainer volt, hanem HD verzió egy játékból, mert trackloaderes volt és nem települt HD-re. Értelemszerűen, ha a cucc nem trackloaderes, akkor nem a bootblockot kell disassemblálni, hanem a programot. :)

Szerkesztve: 2021. 08. 11., sze – 22:28

Köszi a magyarázást! :) (Gondoltam, hogy a jegyzőkönyv kedvéért leírom, hogy a 68000-nak nincs dedikált NMI lába, de valahogy átíródott azóta a poszt. :-D )

A "bootblock disass" és a többiek tényleg a logikus sorrend, csak én nem találkoztam ilyen szoftverekkel. (Az AMIGA programozása sajnos kimaradt eddig az életemből.) A kérdés (ki nem mondott része) inkább erre irányult volna, hogy mik voltak azok a programok, amikkel ilyent az átlag kréker elkövethetett?

(Szerk: válasz akart lenni, nem új hozzászólás.)

Nincs mit. (Még az első 10 percben, miután leesett, hogy ez nem C64 és három darab multiplexelt IRQ láb van; 0.75 kecske voltam aznap, na. :P )

Szerintem a cracker bácsik ritkábban foglalkoztak a bootblock közvetlen disassembly-ével és inkább az NMI/monitor kombóval tolták (már csak azért is, mert a jobb monitorokban is volt disassembler), de ha régi disassemblert keresel, akkor AFAIK a ReSource volt a koronázatlan király, az amúgy elég népes tömegben (AmiNet-en továbbiakat is lehet találni). A lemezek egyes blokkjait pedig pl. a TransDisk nevű programmal lehetett írni/olvasni, vagy egy disk monitorral, pl. a DiskMon-nal.

De ma tényleg nem sok értelme van így csinálni, amikor ott a WinUAE debuggere, meg az IDA disassembler (igen, perfekt viszi az Amigás futtathatókat és a raw dump-ot is).