Skoki do adresów w tablicy
From Atariki
←Older revision | Newer revision→
Są sytuacje, gdzie chcemy skoczyć pod różny adres w zależności np od wartości rejestru Y. Przykładowym rozwiązaniem jest trzymanie tablicy adresów, podzielonych na lo/hi adres i użycie automodyfikacji kodu (ten sam kod dla JSR i JMP):
lda skoki_lo,y ; 4 cykle sta _skok+1 ; 4 lda skoki_hi,y ; 4 sta _skok+2 ; 4 _skok jsr adres ; 6, lub JMP, 3 cykle
Innym sposobem na wykonanie skoku jest wykorzystanie właściwości rozkazu RTS. Nadal potrzebujemy tablic adresów, podzielonych na lo/hi adres-1 (koniecznie adres pomniejszony o 1). Takie rozwiązanie użyteczne jest w przypadku programów na karcie gdzie nie mamy możliwości automodyfikacji kodu.
lda skoki_hi,y ; 4 cykle pha ; 3 lda skoki_lo,y ; 4 pha ; 3 rts ; 6 = 20 cykli
Dla JSR, w sytuacji, gdy liczba skoków jest ograniczona do 86, możemy stworzyć specjalną dodatkową tablicę, zawierającą nie adresy skoków, ale rozkazy JMP, tzn:
skoki jmp skok1 ; 3 cykle jmp skok2 ... jmp skokN ; max N to 86
Jeśli ten kod umieścimy tak, że skoki rozpoczynają się na początku strony, możemy użyć następującej konstrukcji:
lda mul3,y ; 4 cykle sta _skok+1 ; 4 _skok jsr skoki ; 6
W ten sposób zaoszczędzamy 5 cykli, bo unikamy lda/sta (-8 cykli) ale dodajemy pośredni jmp (+3), kosztem dodatkowej pamięci.
Dla JMP, możemy to zrobić jeszcze inaczej, używając rozkazu JMP (adres). Nasza tablica skoki powinna zawierać po kolei adresy docelowe, czyli:
skoki dta a(skok1) dta a(skok2) ... dta a(skokN) ; max N to 128
I teraz nasz kod zamieniamy na
tya ; 2 cykle asl @ ; 2, mnożymy przez 2 sta _skok+1 ; 4 _skok jmp (skoki) ; 5
Oszczędzamy 6 cykli, bo usuwamy lda/sta (-8 cykli), ale zwiększamy koszt JMP z 3 do 5 (+2).
Można także użyć rozkazu BNE
lda mul3,y ; 4 cykle sta _skok+1 ; 4 _skok bne $FF ; 3 jmp skok0 ; 3 cykle jmp skok1 ... jmp skokN ; max N to 42