Intro od środka
część 1 część 2 część 3

Tomek "Scrap" Michniewicz
tomko1@wp.pl

W poprzednim odcinku pisałem o tym, jak w przykładowym intrze zmienić parę rzeczy. Szukaliśmy adresu startowego i bloku, gdzie znajduje się tekst scrolla. Mam nadzieję, że mniej więcej załapałeś, o co w tym chodzi. Dziś ciąg dalszy - zmiana napisu i muzyki, oraz trochę o czcionce. Tak więc zaczynamy!

1. Napis
Odpal jeszcze raz intro. Możesz zmienić teraz tekst scrolla. Żeby zachować zmiany, które wprowadziłeś, możesz zrobić dwie rzeczy:

  • zapisać stan pamięci emulatora - w Vice w menu Snapshot\Save snapshot image, który potem odtwarzamy przez Snapshot\Load snapshot image.

  • zapisać dowolny obszar pamięci z linii poleceń monitora (mam nadzieję, że już nie mylisz tego narzędzia z TYM monitorem, który masz przed sobą :). Służy do tego komenda save [nazwa_pliku] [adres_startowy] [adres_końcowy], w naszym przypadku save "x:\intro" 800 3600. Potem do pamięci intro ładujemy komendą load "x:\intro" 800 (patrz poprzedni odcinek).

Już wiesz, jak zapisywać swoją pracę (nie jest to zapis w formacie *.d64 lub *.t64, które powinien obsługiwać każdy porządny emulator, ale tym zajmiemy się w następnym odcinku). Co widać? Napis na dole to pojawiające się na przemian: 1ST DIVISION MANAGER i RELEASED ON 23.02.93. Pamiętasz, co mówiliśmy o szukaniu tekstu? Ja spróbowałbym tak: hunt 800 ffff "23". Dlaczego? Liczba 23 pojawia się w napisie i można ją znaleźć bezpośrednio w pamięci. Tam gdzie będzie ona, tam będzie napis. Aha, rozkaz hunt [adres_startowy] [adres_końcowy] [wartość] powoduje szukanie w podanym przedziale pamięci zadanej wartości i wypisuje adresy, pod którymi ją odnalazł. U mnie były dwie: 202c i c67b. Zobaczmy, co jest trochę wcześniej. Znana już komenda m 2000.

>C:2000 31 13 14 20 04 09 16 09 13 09 0f 0e 1.. ........
>C:200c 20 0d 01 0e 01 07 05 12 00 00 00 00 ............
>C:2018 00 00 00 00 00 00 00 00 12 05 0c 05 ............
>C:2024 01 13 05 04 20 0f 0e 20 32 33 2e 30 .... .. 23.0
>C:2030 32 2e 39 33 00 00 00 00 00 00 00 00 2.93........
>C:203c 00 00 00 00 ff ff ff 00 00 00 ff ff ............
>C:2048 ff aa aa aa ff ff ff aa aa aa aa aa ............
>C:2054 aa 55 55 55 aa aa aa 55 55 55 55 55 .UUU...UUUUU
>C:2060 55 55 55 55 55 55 55 55 55 55 55 55 UUUUUUUUUUUU
>C:206c 55 55 55 55 55 55 55 55 55 55 55 55 UUUUUUUUUUUU
>C:2078 55 55 55 55 55 55 55 00 00 00 00 00 UUUUUUU.....
>C:2084 00 00 00 00 00 00 00 00 00 00 00 00 ............
>C:2090 00 00 00 00 00 00 00 00 00 00 00 00 ............
(C:$209c)

Tego właśnie szukaliśmy. Treść napisu znajduje się w pamięci od adresu $2000 do $2033, czyli 51 znaków. Wystarczy zmodyfikować ten obszar pamięci (patrz poprzedni odcinek) i mamy już swój napis na dole. :)

2. Muzyka (czyli to, co w Commodore najlepsze)
Przyznam się od razu - to, co zawsze podobało mi się w C64 to właśnie muzyka. Takie moje małe skrzywienie :). W większości (dużej większości) przypadków muzyka zapisywana jest w obszarze pamięci od $1000 do $2000. Nie wdając się zbytnio w szczegóły techniczne, kod, który odpowiada za jej odtwarzanie, dzieli się na dwie części - inicjującą (init) i służącą do odgrywania (play). Przeważnie (ale nie zawsze - i tak jest w tym przypadku) pod adresem $1000 jest skok do sekcji inicjującej, a pod $1003 jest skok do części odpowiedzialnej za odgrywanie dźwięków. Mówiąc już generalnie o całym intrze - gdzieś na początku jest wykonywany skok do sekcji init (czyli w asemblerze JSR $1000), a potem co jakiś czas (co kilka milisekund) skok do sekcji play (asembler: JSR $1003). Taka jest filozofia odgrywania muzyki :). Jeżeli tak jest, to można z jednego intra zapisać obszar $1000 - $2000 i wstawić do drugiego intra. Jeżeli adresy init i play się zgadzają, to w drugim intrze będziemy mieli muzykę z pierwszego. Jasne? Tak właśnie możnaby podmienić muzykę w naszym przypadku (bo stworzenie własnej muzyki jest naprawdę trudne:) Są tylko dwie sprawy:

  • osobiście ta muzyczka bardzo mi się podoba, więc nie widzę sensu jej zmieniać :)) Co, tylko ja tak uważam? :)

  • akurat w kodzie tego demka do odgrywania muzyki jest wykonywany skok JSR $1006 (czyli play jest na $1006). Jeśli chciałbyś przenieść muzykę, która ma play na $1003, trzeba ingerować w kod intra. Jak to zrobić? Szukamy rozkazu JSR $1006 poleceniem hunt 0 ffff 20 06 10. ( 20 06 10 to nic innego jak szesnastkowy zapis rozkazu JSR $1006) Dostajemy adres 2d72. Zobaczmy ten fragment kodu rozkazem d 2d72. Oto, co widać:

(C:$2d9d) d 2d72
.C:2d72 20 06 10 JSR $1006
.C:2d75 A9 BA LDA #$BA
.C:2d77 CD 12 D0 CMP $D012
.C:2d7a D0 FB BNE $2D77
.C:2d7c A9 00 LDA #$00
.C:2d7e 8D 21 D0 STA $D021

Wystarczy zmienić zaznaczony fragment na JSR $1003 i to wszystko. Zrobimy to komendą a 2d72. Powoduje to edycję programu (możliwość wpisywania rozkazów asemblerowych) od adresu 2d72. Wpisujemy JSR $1003 i wciskamy dwa razy klawisz Enter. Powinno działać.

3. Czcionka
Nie będę tu opisywał, jak zmienić czcionkę. To bardzo żmudna praca, bo najpierw trzeba ja zaprojektować, potem dokonać wielu obliczeń, potem wpisać dane... brr.. :(. Poniżej tylko kilka uwag, jak to wygląda, może komuś się przyda :). Jedna litera (standardowa) to kwadrat 8x8 pikseli. Każdy rząd w tym kwadracie jest opisywany przez jedną liczbę (bajt). Bajt, jak wiadomo, to 8 bitów. Jeśli bit jest równy 1, to oznacza, że w tym miejscu matrycy 8x8 piksel jest zapalony. Rysunek ilustruje tą ideę.

Stąd wynika, że jedną literę opisuje 8 liczb. Cały alfabet jest zapisywany jako ciąg kolejnych liczb. W tym konkretnym intrze jest trudniej, bo litery są duże, większe niż standardowe 8x8 pikseli. Każda jedna jest opisywana przez 32 liczby. Litera składa się po prostu z czterech pojedynczych znaków 8x8. Jeszcze jedna podpowiedź - do tworzenia czcionek (ale też i muzyki) są specjalne programy. To wielkie ułatwienie. Szukaj ich w dziale Download na C64 Power.

4. Download
Zmieniona wersja intra - tutaj.

5. Podsumowanie
Tu krótka lista wykorzystywanych rozkazów monitora:
m [adres] - wyświetla zawartość pamięci od zaczynając od podanego adresu. Samo m bez adresu wyświetla dalszą zawartość pamięci.
d [adres] - wyświetla kod programu jako ciąg asemblerowych rozkazów poczynając od podanego adresu
save [nazwa_pliku] [adres_startowy] [adres_końcowy] - zapisuje zadany obszar pamięci w pliku na dysku komputera
hunt [adres_startowy] [adres_końcowy] [wartość] - szuka w określonym przedziale pamięci (pamięć w Commodore rozciąga się od $0 do $FFFF) zadanej wartości.
a [adres_startowy] - umożliwia wprowadzenie do pamięci programu w asemblerze rozpoczynając od danego adresu.

 © 1999-2020 Wszystkie prawa zastrzeżone
 Webmaster: Mariusz "Flooder" Młynek