Mat, byłoby genialnie jakbyś jakos to opisał...
Może kiedyś... To jest bardzo rozległy temat

Tzn od czego zaczynasz badanie takiej gry... Rozumiem, ze otwierasz w jakims disassemblerze.
Jak zapewne wszyscy w okolicy wiedzą ja jestem ten stosunkowo nietypowy - używam na co dzień właściwie wyłącznie Linuksa (Windows tylko do grania i odpalania jakichś pokręconych drobiazgów, których inaczej nie da się zrobić). W związku z tym moje narzędzia są... moje

Używam paru gotowych narzędzi i trochę własnych skryptów. W tym konkretnym przypadku procedura była mniej więcej taka:
Zacząłem od przerobienia TZXa na TAPa, bo do TZXów nie mam odpowiedniego narzędzia

Konwersja to tapeconvert z narzędzi do FUSE.
TAPa "rozprułem" na składowe - do tego mam własny skrypt - tapsplit. Skrypt rozkłada TAPa na osobne bloki i zapisuje je w kolejnych TAPach a do tego zrzuca binarne bloki bez nagłówków, sum kontrolnych itp. (to te pliki 0005.bin, 0006.bin itp.)
Wiedziałem wcześniej, że loader siedzi w pliku o długości 256 bajtów więc tym się zająłem. Plik ładuje się od $5000 (20480) i to było potrzebne do disassemblacji. Większość analizy w takich przypadkach robię "na zimno" - tak było i teraz. Do disassemblacji używam PERLowego gotowca z80dis (kiedyś już pisałem na forum skąd go wziąć - to jest pakiet z CPANa), któremu podaje się adres startowy i plik do disassemblacji. Na wylocie dostałem plik loader.asm, z którego pochodził pierwszy cytowany wcześniej kawałek kodu. Kod uruchamiany jest od początku ładowania a więc...
W loaderze na początku mamy ustawienie stosu
5000 318C50 ld sp,0x508C
A dalej 4 kolejne kawałki ładujące bloki danych:
5003 3E1F ld a,0x1F
5005 DD2100C0 ld ix,0xC000
5009 11001B ld de,0x1B00
500C CD3D50 call 0x503D
W akumulatorze mamy wartość do wysłania do portu $7ffd a IX i DE to standardowe parametry dla LD_BYTES - początek i długość bloku do załadowania z taśmy. Sama procedurka ładująca wygląda tak:
503D 01FD7F ld bc,0x7FFD
5040 ED79 out (c),a
5042 37 scf
5043 3EFF ld a,0xFF
5045 14 inc d
5046 08 ex af,af'
5047 15 dec d
5048 F3 di
5049 C36305 jp 0x0563
Najpierw ustawiany jest odpowiedni bank pamięci potem parametry dla procedury łądującej i następuje skok do jej wnętrza - dość dziwnie zresztą, bo trafia w środek instrukcji:
0562 DBFE in a,(0xFE)
0564 1F rra
0565 E620 and 0x20
Po trafieniu w $0563 dostajemy:
0563 FE1F cp 0x1F
0565 E620 and 0x20
Traktuję to tylko jako ciekawostkę - nie ma wpływu na wynik analizy. Procedura ładuje dane i to jest istotne

Po załadowaniu wszystkich kolejnych bloków loader kończy się tak:
5033 01FD7F ld bc,0x7FFD
5036 3E10 ld a,0x10
5038 ED79 out (c),a
503A C3005B jp 0x5B00
Ustawia główny RAM i skacze na początek właściwej gry.
I to właściwie cała analiza - od tego momentu wiemy już co trzeba zrobić i pozostaje tylko kwestia jak

Potrzebny jest nam loader w BASICu i 4 pliki danych. Każdy z tych elementów potrzebny jest w TAPie z normalnym nagłówkiem. Loader w BASICu to oczywiście edytor tekstowy i programik zmakebas - przetwarza on tekst na tokenizowany program i zapisuje do TAPa. Do konwersji plików z czystego bloku binarnego do TAPa używam w takich wypadkach assemblera pasmo - konwersję robi się tak jak wcześniej pokazywałem:
org $c000
incbin "0006.bin"
Kompliacja tego kodu przez
pasmo --tap bank1.asm bank2.tap
Daje wynikowego TAPa z normalnym nagłówkiem ładującego się od podanego w org adresu.
Konwersja głównego bloku (jak również pozostałych dwóch jak się później okazało

) wymagała dodania kawałka kodu przerzucającego dane - całość była równie nieskomplikowana jak zwykłą konwersja:
org 25000
jp move_it
start:
incbin "0005.bin"
move_it:
di
ld a,$10
ld bc,$7ffd
out (c),a
ld sp,$508c
ld hl,start
ld de,$5b00
ld bc,move_it-start
ldir
jp $5b00
Po kompilacji całości dostajemy 5 plików TAP, które po prostu kleimy ze sobą - pod Linuksem prostym cat'em, pod Windows copy ze stosownymi przełącznikami, żeby pliki były traktowane jako binarne. W wyniku dostajemy finalnego TAPa, którego możemy już normalnie wczytać do emulatora.
Ot i cała filozofia
