Skoki do adresów w tablicy

From Atariki

(Różnice między wersjami)
Jump to: navigation, search
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
Personal tools