Ripowanie i odgrywanie SIDów
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.
|