Kurs 01
--------

Jako pierwszą bierzemy na warsztat grę River Raid. Jest to wspaniała gra i napewno każdy z Was kiedyś
się w nią zagrywał. Czy nie zastanawiało Was nigdy ile w tej grze jest etapów? Przeszkadzała Wam w tym
znikoma liczba żyć? Od dzisiaj ten problem przestanie istnieć!

Po pierwsze pokaże Wam jak ułatwić sobie życie w emulatorze. Jest to podstawa do prawdziwego łamania
gier. A więc tak:

Odpalamy emulator Atari800Win PLus z grą River Raid (grę ściągnijcie z naszego serwisu). Naszym oczom ukazuje się
niebieska rzeka i masa statków przeplatana z helikopterkami. To jest po prostu wspaniałe, więc zanim zabierzecie się
do pracy pograjcie trochę w ramach relaksu :). Zabawa, zabawą, a tu robota czeka, więc naciskamy Start i czekamy do
momentu, kiedy plansza zjedzie na dół i życia zmienią się z 4 na 3. Oczywiście jeszcze nie startujcie. Z menu emulatora
wybierzcie Misc->Cheat options... Naszym oczom ukaże się sympatyczny panelik, na którym można zdziałać naprawdę niesamowite
rzeczy. Spróbójmy np. wcisnąć 'Disable sprite collisions detection'. Po małej zabawie z resztą przycisków bedziemy mogli
latać dosłownie po wszystkim, ale to żadna frajda :). Bardziej interesuje nas dolna część paneliku. Zajmuję się ona przeszukiwaniem pamięci w celu znalezienia adresu, pod którym liczba nr 1 zmieniła sie na liczbę nr 2. Jak się zapewne
bystrzy czytelnicy domyśleli w pierwszym okienku wprowadzimy aktualną liczbę naszych żyć, czyli 3. Wciśnijmy jeszcze 'Memo'
i wracamy do gry. Wiem, że pierwszy most to niezbyt odpowiednie miejsce na stracenie naszego pierwszego życia, ale będziemy
musieli się w tym wypadku poświecić. Gdy nasza liczba życ osiągnie wartość 2, wróćmy do naszego paneliku i w drugim okienku
wpiszmy również 2. Teraz wciśniejcie 'Search'. I nagle coś pojawiło się w prawym okienku. Ktoś by mogł spytać - "Co to #@$@
jest?!", dlatego chciałbym to pokrótce wyjaśnić. $ - jest to znak oznaczający, że cyfry po tym znaku będą wchodziły w skład
liczby szesnastkowej, a 006a oznacza liczbę szesnastkową. W nawiasie po prawej możemy zaobserwować tą samą liczbę tylko w
systemie dziesiętnym. Atari posiada przeważnie 64Kb pamięci, więc i gry wykorzystują tylko ten przedział $0-$ffff. Ta
liczba, która się nam ukazała przedstawia adres w pamięci, gdzie autorzy umieścili liczbę żyć. Zaznaczmy teraz ten adres
i opcje 'Lock in' "ptaszkiem". W pole obok 'Lock in' wpiszcie np. 5 i powróćcie spowrotem do gry. O! Mamy 5 żyć! Spróbójcie
się rozbić to zobaczycie, że liczba się nie zmniejszy.

Pokazałem Wam jak bawić się w emulatorze, ale teraz dopiero zaczyna się kurs. Naszym następnym zadaniem jest zedytować
grę w pamięci komputera, tak żeby nie ubywała nam liczba żyć. Po pierwsze musimy się trochę namyślić i przewidzieć jak
autor gry zapisał operacje zmniejszania żyć w programie. Mi pierwsza rzecz jaka przychodzi do głowy to:

DEC $6A   ;zmniejszenie zawartości adresu o 1

Instrukcja zmniejsza po prostu wartość adresu $6A (czyli adres z liczbą żyć) o 1. Po przetłumaczeniu tej instrukcji na kod
maszynowy otrzymujemy dwa bajty: C66A. Jeśli nie wiesz w tym momencie o czym mówie to odsyłam do lektury Tajemnic Atari i
instrukcji Quick Assembler'a. Powinniśmy teraz przeszukać całą pamięć programu w poszukiwaniu tych bajtów. Jak już może
się domyśliłeś po załadowaniu gry, cały jej kod jest przechowywany w pamięci dlatego znajdziemy w niej instrukcje
zmniejszania liczby żyć o 1. Wracamy do emulatora i naciskamy F8. Ukaże się potężny monitor pamięci. Radzę się zaznajomić
z jego opcjami bo jest naprawde bardzo przydatny. Żeby otrzymać listę wszystkich opcji wraz z opisem wpiszcie '?'. Teraz
nagramy stan całej pamięci River Raid'a do pliku, żeby go potem spokojnie przeglądać. Piszemy:

write 0 ffff rivermem.dat

Ta komenda nagra pamięć z zakresu $0000 do $FFFF do pliku rivermem.dat w katalogu z grą. Chciałem jeszcze dodać, że
wychodzi się z monitora poleceniem 'cont'. Otwórzmy powstały plik w Hex
Workshop. Hoho, ile śmiesznych numerków - najciekawsze jest to, że każdy z nich spełnia w grze jakąś funkcję :). Dobra,
zaciskamy kciuki i szukamy w hex'ach C66A... ... ... dupa! Hmmm, nie znalazl. Musicie być przygotowani na taką ewentualność,
ale nie poddawajcie się. Pomyślmy zatem jeszcze raz. Autor wiedział, że pierwsza instrukcja jaka by nam wpadła do głowy
byłoby to, dlatego troche ją zmodyfikował. Może najpierw wczytuje zawartość adresu $6A do rejestru, zmniejsza go o 1, a
potem zwraca spowrotem na miejsce?! Tak, to by brzmiało sensownie. Załóżmy, że użyłby w tym celu akumulatora. Wyglądałoby to mniej więcej tak:

LDA $6A   ;wczytanie do akumulatora aktualnej liczby żyć
SEC       ;ustawienie znacznika C (niezbędne przed odejmowaniem za pomocą SBC)
SBC #$01  ;odjęcie liczby 1 od akumulatora
STA $6A   ;wstawienie zawartości akumulatora pod adres l. żyć

Kod: A56A38E901856A

Szukamy, szukamy... nie ma :(. Programista mogł użyć tej metody, ale niekoniecznie akumulatora. Mógł użyć rejestru X lub Y,
dlatego rozpatrzmy dwie możliwości:

LDX $6A   ;wczytanie do rejestru X aktualnej liczby żyć
DEX       ;zmniejszenie rejestru X o 1
STX $6A   ;wstawienie zawartości rej. X pod adres l. żyć

Kod: A66ACA856A

LDY $6A
DEY
STY $6A

Kod: A46A88846A

Niektórzy pewnie zauważyli, że w pierwszym przykładzie użyłem intstukcji SBC, a w następnych DEX i DEY. Teraz wyjaśniam -
SBC może być użyte tylko z akumulatorem, bo nie ma swojego odpowiednika jak DEX czy DEY, a rejestry X i Y nie mogą być
użyte z SBC :) proste. Mam nadzieję, że wszystko co piszę jest jasne. Szukamy więc pierwszego kodu... nie ma :(. Szukamy
drugiego... JEST! EUREKA! Teraz możemy być pewni, że jest to jedyna instrukcja w kodzie odpowiedzialna za zmniejszanie
liczby żyć. Teraz, gdy najtrudniejsze jest już za nami, mamy czas na trochę własnej inwencji tzn. Jak zmodyfikować ten
kawałek kodu, żeby nie ubywało nam żyć. Teraz pokaże Wam potęge instrukcji NOP - instrukcja ta zajmuje jeden bajt i
robi... NIC! dlatego jest to takie piękne. Spójrzcie teraz na ten kod:

LDY $6A
NOP       ;uprzednio było DEY
STY $6A

Co robi ten kod? Ładuje liczbę żyć do Y i bez zmian odstawia ją na miejsce :). Można oczywiście dla zabawy zamienić DEY
np. na INY, co spowoduje dodanie jednego życia przy zderzeniu :), ale to już zależy od Waszego pomysłu. Wracając do
tematu, musimy teraz zamienić bajt z instrukcją DEY ($88) na instrukcję NOP ($EA). Sprawdźmy jeszcze w Hex Workshopie
pod jakim adresem znajduje się ta instrukcja - $A355. Wracamy do naszego monitora pamięci i wydajmy polecenie:

f a355 a355 ea

Spowoduje to wypełnienie przedziału pamięci od $A355 do $A355, czyli 1 bajta, bajtem $EA, czyli instrukcją NOP. Wracamy
do gry i rozbijamy się. Ha, co się stało? Nic się nie stało! Liczba żyć cały czas niezmieniona :). Trainer'a od razu
nie napiszemy, ale jako, że ta wersja River Raid'a nie jest w żaden sposób skompresowana, możemy poddać edycji cały
plik z grą. Otwieramy go w Hex Workshop i szukamy kodu, zmniejszającego liczbę żyć o 1. Jest? Jest. Modyfikujemy go
podobnie jak zrobiliśmy z nim w monitorze pamięci. Zapisz plik powiedzmy jako 'rrcrk.com' i gotowe! Gratulacje!

Właśnie złamałeś swoją pierwszą grę!!!

P.S. Trainer'ami zaczniemy się bawić trochę później jako, że jest to sprawa trochę bardziej skomplikowana. Po pierwsze
musicie poznać język assemblera procesora 6502, żebyście mogli go napisać.

												Black Dot