Jeste jsem to nedocetl do konce.
Budu uplne ignorovat pouzivani djnz pro pripady, kdy se to na nahradit jr, protoze se to pouzije 256x a uvnitr smycky je nejaky registr menen tak, ze nastavi zero flag prave a jedine ve stejnou dobu co by se ukoncila smycka.
Ale dovolil jsem si upravit tu rutinu pro 14. kapitolu. Z puvodnich 53 bajtu na 38 bajtu.
Jedna z podminek je bud pouzit nejaka makra a nebo slevit z prehlednosti a nepouzivat nejake globalni konstanty jako je adresa tech fontu. Protoze puvodni rutina uplne ignoruje ze je polozena v pameti na adresu delitelnou 256...
Pak jsem upravil tu funkci pro vypsani znaku tak, aby vracela v DE adresu nasledujiciho znaku (vcetne prelezeni pres tretiny obrazovky), prijde me to jako pouzitelnejsi navrh, nez muset po kazdem vypsanem znaku hledat kde je nasledujici adresa.
Puvodni:
SCREEN_ADR equ $4000 CHAR_ADR equ $3c00 ENTRY_POINT equ $8000 org ENTRY_POINT start: ld de, SCREEN_ADR ; 3:10 adresa pro zápis ld a, 'A' ; 2:7 kód vykreslovaného znaku call draw_char ; 3:17 zavolat subrutinu pro vykreslení znaku ld de, SCREEN_ADR+1 ; 3:10 adresa pro zápis ld a, 'B' ; 2:7 kód vykreslovaného znaku call draw_char ; 3:17 zavolat subrutinu pro vykreslení znaku ld de, SCREEN_ADR+128+31 ; 3:10 adresa pro zápis ld a, '?' ; 2:7 kód vykreslovaného znaku call draw_char ; 3:17 zavolat subrutinu pro vykreslení znaku finish: ret ; 1:10 ukončit program draw_char: ld hl, CHAR_ADR ; 3:10 adresa, od níž začínají masky znaků ld b, 0 ; 2:7 ld c, a ; 1:4 kód znaku je nyní ve dvojici BC sla c ; 2:8 rl b ; 2:8 2*bc sla c ; 2:8 rl b ; 2:8 4*bc sla c ; 2:8 rl b ; 2:8 vynásobení BC osmi add hl, bc ; 1:11 přičíst adresu k offsetu masky znaku ld b, 8 ; 2:7 počitadlo zapsaných bajtů loop: ld a, (hl) ; 1:7 načtení jednoho bajtu z masky ld (de), a ; 1:7 zápis hodnoty na adresu (DE) inc hl ; 1:6 posun na další bajt masky inc d ; 1:4 posun na definici dalšího obrazového řádku djnz loop ; 2:8/13 vnitřní smyčka: blok s osmi zápisy ret ; 1:10 end ENTRY_POINT
Nove:
SCREEN_ADR equ $4000 CHAR_ADR equ $3c00 ENTRY_POINT equ $8000 org ENTRY_POINT start: ld DE, SCREEN_ADR ; 3:10 adresa pro zápis ld A, 'A' ; 2:7 kód vykreslovaného znaku call draw_char ; 3:17 zavolat subrutinu pro vykreslení znaku ld A, 'B' ; 2:7 kód vykreslovaného znaku call draw_char ; 3:17 zavolat subrutinu pro vykreslení znaku ld E, SCREEN_ADR+4*32+31 ; 2:7 adresa pro zápis (jsme stale v prvni tretine obrazovky) ld A, '?' ; 2:7 kód vykreslovaného znaku ; call draw_char ; 3:17 zavolat subrutinu pro vykreslení znaku finish: ; ret ; 1:10 ukončit program ; Input: DE = adresa znaku pro zapis, A = znak ; Output: DE = adresa nasledujiciho znaku (muze pretect do atributu) ; Pollutes: B = 0, C = hi(old_DE),HL draw_char: ld BC, 0x3C00 ; 3:10 adresa, od níž začínají masky znaků ld H, C ; 1:4 ld L, A ; 1:4 kód znaku je nyní ve dvojici HL add HL, HL ; 1:11 2x add HL, HL ; 1:11 4x add HL, HL ; 1:11 8x add HL, BC ; 1:11 ld B, 0x08 ; 2:7 počitadlo zapsaných bajtů ld C, D ; 1:4 loop: ld A,(HL) ; 1:7 načtení jednoho bajtu z masky ld (DE),A ; 1:7 zápis hodnoty na adresu (DE) inc L ; 1:4 posun na další bajt masky inc D ; 1:4 posun na definici dalšího obrazového řádku djnz loop ; 2:8/13 vnitřní smyčka: blok s osmi zápisy ld D, C ; 1:4 inc DE ; 1:6 ret ; 1:10 end ENTRY_POINT
PS: Jinak me uplne dostal ten vypis u jr/djnz, kdy jsem si myslel ze 0 ukazuje pred tu instrukci a ona ukazuje za ni. Uplne jsem si to pletl s $, ktera ukazuje prave pred (na prave provadenou/zapisovanou) instrukci. Takze $ je neco jako 0xFE.