Po przerwie znowu wracam do Z80, znowu do prób zastępowania indexowania typowego dla 6502 takim powiedzmy "pseudo-indexowaniem" w Z80.
Mam przykładowy kod, ktory zwiększa dynamicznie prędkość animacji przeciwników używając dwie zmienne na jednego przeciwnika.
Jedna to sam licznik animacji, a drugi to ustawienie prędkości tego licznika (SetTimer).
Chodzi o to, aby nie robić wielu takich osobnych funkcji, ale użyć jednej, która będzie zmieniała kolejność bajtu wg. indexu
(uzywam do tego celu osobnej zmiennej "indexregister1").
Napisalem jedna, indexowana funkcje dla wszystkich przeciwnikow (nie testowane, bo robie to na "brudno"),
kod jest oczywiscie mniejszy rozmiarowo niz wiele osobnych, ale tez zjada wiecej cykli cpu bo i tak musi byc wywolany wiele razy,
ale tu chodzi o sam fakt i przyklad takiego rozwiazania, wiec bede prosil o analize i jakies uwagi

Bo zapewne da sie to samo zrobic niebo lepiej...

IndexRegister1 DB ; zmienne w ram
ENEMY00_Animation_Timer DB
ENEMY01_Animation_Timer DB
ENEMY02_Animation_Timer DB
ENEMY03_Animation_Timer DB
(...)
ENEMY31_Animation_Timer DB
(...)
ENEMY00_Animation_SetTimer DB
ENEMY01_Animation_SetTimer DB
ENEMY02_Animation_SetTimer DB
ENEMY03_Animation_SetTimer DB
(...)
ENEMY31_Animation_SetTimer DB
(...)
Przykladowy, prosty kod sterujacy licznikiem animacji, osobny dla kazdego przeciwnika:
LD A,(ENEMY00_Animation_Timer)
LD B,A
LD A,(ENEMY00_Animation_SetTimer)
ADD A,B
LD (ENEMY00_Animation_Timer),A
...
LD A,(ENEMY01_Animation_Timer)
LD B,A
LD A,(ENEMY01_Animation_SetTimer)
ADD A,B
LD (ENEMY01_Animation_Timer),A
(...)
Teraz proba indexowania tych zmiennych o index zawarty w zmiennej IndexRegister1:
TimerAnimacji:
LD HL,ENEMY00_Animation_Timer
LD A,(IndexRegister1)
LD E,A
ADD HL,DE
LD A,(HL)
LD B,A ; Teraz w B mam adres ENEMY00_Animation_Timer zwiekszony o IndexRegister1
LD HL,ENEMY00_Animation_SetTimer ; Podobnie jak wyzej ale indexuje zmienna SetTimer
LD A,(IndexRegister1)
LD E,A
ADD HL,DE
LD A,(HL)
LD C,A ; Teraz w C mam adres ENEMY00_Animation_SetTimer zwiekszony o IndexRegister1
ADD C,B ; Dodaje SetTimer do Timer
LD HL,ENEMY00_Animation_Timer ;EDIT: tu moge na poczatku zachowac wynik HL do np. IX/IY i teraz nie wyliczac znowu tylko przeniesc do HL...
LD A,(IndexRegister1)
LD E,A
ADD HL,DE ; Teraz w B mam 'znowu" bajt ENEMY00_Animation_Timer zwiekszony o IndexRegister1
LD A,C ; Wynik dodawania mialem zachowany w C wiec musze go przeniesc do A aby zapisac pod adres wskazany w HL
LD (HL),A ; Zapisz wynik pod adres bajtu ENEMY00_Animation_Timer zwiekszonego o adres indexu czyli odpowiedniego Enemy..
RET
Teraz wystarczy ustawic index o numer danego przeciwnika i wywolac:
ld d,0 ; oczywiscie d musze miec wyzerowane
LD A,31 ; wywolaj kod licznika dla ENEMY31
LD (IndexRegister1),A
CALL TimerAnimacji