Skoki do adresów w tablicy
From Atariki
Wersja z dnia 09:44, 6 maj 2008 KMK (Dyskusja | wkład) (przeniesienie) ← Previous diff |
Aktualna wersja Xxl (Dyskusja | wkład) (inny sposob) |
||
Linia 1: | Linia 1: | ||
- | ===Skoki do adresów w tablicy=== | ||
Są sytuacje, gdzie chcemy skoczyć pod różny adres w zależności np od wartości rejestru Y. | 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): | + | 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): |
<pre> | <pre> | ||
lda skoki_lo,y ; 4 cykle | lda skoki_lo,y ; 4 cykle | ||
Linia 51: | Linia 50: | ||
</pre> | </pre> | ||
Oszczędzamy 6 cykli, bo usuwamy lda/sta (-8 cykli), ale zwiększamy koszt JMP z 3 do 5 (+2). | 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 | ||
+ | |||
+ | <pre> | ||
+ | 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 | ||
+ | </pre> | ||
+ | |||
[[Kategoria:Niezbędnik kodera]] | [[Kategoria:Niezbędnik kodera]] |
Aktualna wersja
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