Ripowanie i odgrywanie SIDów

Maciej "Aze" Kubiak
aze@daper.eu.org

Na początek troszkę podstawowych informacji. Sidek prawie zawsze zbudowany jest tak, że ma w sobie już "wbudowaną" procedurę odgrywającą. Naszym zadaniem jest tylko odpowiednie jej zainicjowanie i "podsycanie" :). Najpierw może parę słów o "ramce", bo jest to najważniejsza sprawa i czesto niezrozumiała.

C64 tworzy grafikę rysując linie od lewego górnego rogu do prawego dolnego - czemu o tym mówię? Bo możemy sobie to w bardzo prosty sposób sprawdzić i użyć jako bardzo dokładnego "zegara". Służy do tego rejestr $d012, w którym znajdziemy numer aktualnie rysowanej linii. Łatwo możemy sprawdzić, o czym mówię: W Turbo Assemblerze wpisujemy coś takiego:

            *=$1000
            lda #$60
Loop1       Cmp $d012
            Bne Loop1 
            Inc $d021
            Lda #$80
Loop2       Cmp $d012
            Bne Loop2
            Jmp $1000

To bardzo prosty programik, który czeka na linię $60 (szesnastkowo!), po czym zmienia kolor ramki, czeka na linię $80 i przywraca kolor ramki. Ten przykładzik pokazuje nam wizualnie, czym jest "ramka". A do czego nam to potrzebne? Aby odegrać naszą muzyczkę, potrzebujemy wywołać funkcję "play" 1 raz w ciągu całej ramki. Pomijam tu muzyczki robione kilka razy na ramkę, ale to temat na następny artykuł. A więc wygląda to mniej więcej tak:

                --------
                Lda #$60 
      Loop1     Cmp $d012
                Bne loop1
                Jsr play
                --------

To malutki wycinek kodu odgrywającego naszą muzykę. Jak widzimy, czekamy na ramkę $60, a następnie skaczemy do play. Jeśli umieścimy to w pętli - nasz programik będzie skakał sobie za każdym razem, gdy rysowana będzie linia $60 do procedury play. OK, to tyle o ramkach. Temat będę kontynuował w innych artykułach, o ile będzie zainteresowanie.

Ripowanie SID-ów jest tematem obszernym jak morze, ale postaram się Wam go przybliżyć i napisać tak, by każdy z Was był w stanie "wyrypać" i odegrać prostego sid-a.

Najważniejszą sprawą jest zlokalizowanie muzyczki. Nie jest to zadanie łatwe, ponieważ nie ma jakiegoś standardu ulokowania sid-a. Niektórzy powiedzą: "przecież muzyczki są pod $1000", zgodzę się, ale nie zawsze tak bywa. Często trzeba będzie przekopać całą pamięć, a szczególnie, kiedy szukamy muzyczki w grach. Dodać muszę, że umiejętność zlokalizowania muzyki przychodzi z doświadczeniem, czasem patrząc na rzędy znaczków, używając monitora w trybie ASCII, wiemy że ten właśnie ekran to część zaka. Może wyda się to teraz niezrozumiałe, ale sami zobaczycie - z czasem intuicyjnie znajdziecie to, czego szukacie. Przeszukując pamięć w trybie ASCII napotkamy rząd znaków, które wygladają mniej więcej tak:

	/258;?CGKOTY^djpw

Wiem, że może wydać się to dziwne, ale zawsze, gdy występuje taki lub podobny ciąg znaków, mamy do czynienia z muzyką. Pamiętam, że zawsze szukałem tego magicznego CGKOTY :). Te nowoczesne muzyczki zaczynają się przeważnie od pełnych adresów, np. $1000, $8000 itp., więc jeśli napotkamy ciąg znaków "CGKOTY" np. pod adresem $1600, możemy być na 80% procent pewni, że sid-ek jest pod $1000. Przejdźmy do odgrywania muzyki. Aby odegrać sid-ka, nie trzeba być mistrzem w programowaniu, ale należy znać chociaż podstawy. Aby nasz sid grał, należy go najpierw zainicjować, robi się to przy pomocy instrukcji lda i jsr. Wytłumaczę na przykładzie:

Muzyczkę mamy pod adresem $1000, więc prawdopodobnie procedura "init" będzie właśnie pod adresem $1000. Jeśli mamy tylko 1 subsong, sprawa jest prosta. Ładujemy do akumulatora wartość #$00 i skaczemy do adresu $1000. W przykładzie wygląda to tak:

    sei        ;włączenie przerwań.
    lda #$00   ;załadowanie 0 do akumulatora
    jsr $1000  ;skok do init

Po czymś takim mamy przygotowany układ SID do odgrywania muzyki. Zapytacie - czemu #$00? Więc jeśli w muzyczce mamy kilka subsongów, np. jest to parę muzyczek z gry, wartość #$00 ustawia nam pierwszą muzyczke, wartość #$01 drugą, itd. Jesteśmy już przygotowani do odegrania, czas na odtworzenie. A więc gramy:

gramy:   lda #$60  ;linia na ekranie
ramka:   cmp $d012 ;porównanie, czy
                    właśnie ta linia wyświetlona?
         bne ramka ;jeśli nie, sprawdzamy dalej
	 jsr $1003 ;play
	 jmp gramy

To najprostsza z możliwych procedura odgrywająca. Zapytacie czemu $1003? I tu zaczynają się schody. Jest tyle różnych formatów muzycznych i każdy z nich ma inaczej ulokowaną procedurę play. Lecz tu nie musimy dużo szukać, ponieważ nie mamy zbyt dużego wyboru w przypadku muzyczki spod adresu $1000. Mamy kilka możliwości, pamiętać należy, że muzyczka w assemblerze wygląda tak:

$1000  jsr $1xxx  ;init
$1003  jsr $1xxx  ;tu może byc play
$1006  jsr $1xxx  ;a może jednak tu?
$1009  jsr $1xxx  ;chyba nie tutaj, ale kto wie?
       rts        ;lub coś w tym stylu :-)

Jak widzimy, nie ma dużego pola manewru. Trzeba próbować, któryś z "jsr-ów" będzie na pewno dobry, a wtedy usłyszymy naszą piękną muzyczkę. Życzę udanych eksperymentów.

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