Z kapitoly 7:
Poznámka2: dokážete přijít na to, za jakých podmínek a zda vůbec NEbude vykreslovací rutina korektní?
Moje reseni: Emork ohot ez es ejurtesoen yndaz z ujarko ykvozarbo, kat ot etsej ezles v udohcerp nitert a ot zu ej aklev teslob, ezotorp yt ejarko es ijad tiser i mit ez es ilserkyv avon akvozarbo. Ela aretkolam arh am ukvozarbo nej rtinvu ynitert.
Jinak ten kod:
draw_sprite: ld hl, SPRITE_ADR ; 3:10 adresa, od níž začíná maska spritu push de ; 1:11 call draw_8_lines ; 3:17 vykreslit prvních 8 řádků spritu pop de ; 1:10 add_e 32 ; 3:15 zvýšit E o hodnotu 32 push de ; 1:11 call draw_8_lines ; 3:17 vykreslit druhých 8 řádků spritu pop de ; 1:10 add_e 32 ; 3:15 zvýšit E o hodnotu 32 call draw_8_lines ; 3:17 vykreslit třetích 8 řádků spritu ret ; 1:10 návrat z podprogramu ;[23:143] draw_8_lines: ld b, 8 ; 2:7 počitadlo zapsaných řádků 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 e ; 1:4 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 e ; 1:4 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 dec e ; 1:4 korekce - posun zpět pod první osmici pixelů dec e ; 1:4 dtto djnz loop ; 2:13/8 vnitřní smyčka: blok s 3x osmi zápisy ret ; 1:10 návrat z podprogramu ;[19:756=7+8*93-5+10]
By sel napsat rychleji a mensi:
draw_sprite: ... ;[23:143] draw_8_lines: ld bc, 8*(256+2) ; 3:10 počitadlo zapsaných řádků loop: ldi ; 2:16 [DE++] = [HL++]; BC-- ldi ; 2:16 [DE++] = [HL++]; BC-- 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 dec e ; 1:4 korekce dec e ; 1:4 korekce inc d ; 1:4 posun na definici dalšího obrazového řádku djnz loop ; 2:13/8 vnitřní smyčka: blok s 3x osmi zápisy ret ; 1:10 návrat z podprogramu ;[16:631=10+8*77-5+10]
A pokud by me restit i ten zasadni problem s korektnosti tak by sel udelat jeste mensi, pokud bude automaticky vracet spravne nastavene DE.
draw_sprite: ld hl, SPRITE_ADR ; 3:10 adresa, od níž začíná maska spritu call draw_8_lines ; 3:17 vykreslit prvních 8 řádků spritu call draw_8_lines ; 3:17 vykreslit druhých 8 řádků spritu call draw_8_lines ; 3:17 vykreslit třetích 8 řádků spritu ret ; 1:10 návrat z podprogramu ;[13:71] draw_8_lines: ld bc, 8*(256+2) ; 3:10 počitadlo zapsaných řádků loop: ldi ; 2:16 [DE++] = [HL++]; BC-- ldi ; 2:16 [DE++] = [HL++]; BC-- 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 dec e ; 1:4 korekce dec e ; 1:4 korekce inc d ; 1:4 posun na definici dalšího obrazového řádku djnz loop ; 2:13/8 vnitřní smyčka: blok s 3x osmi zápisy ld a, e ; 1:4 add a, 32 ; 2:7 ld e, a ; 1:4 ret c ; 1:5/11 ld a, d ; 1:4 sub 8 ; 2:7 ld d, a ; 1:4 ret ; 1:10 návrat z podprogramu ;[25:647/666 =10+8*77-5+26/10+8*77-5+45]
A kdyz uz spamuji tak rovnou pridam muj skript nakompilaci asm zdrojaku a rovnou spusteni v emulatoru. S tim ze jde parametrem i menit adresa na jakou se to zkompiluje. Staci mit v kodu neco jako:
ifdef __ORG org __ORG else org 0x8000 endif
kde 0x8000 je default ale skript nastavuje __ORG kdyz mu ho zadate. Tim mu i reknete ze to ma spustit v emulatoru a nejen kompilovat binarku.
Neni ani potreba definovat nejaky entry point. Protoze se to zkompiluje jako binarka a pres zmakebas to vytvari z basic loaderu tapku. Loader je nastaven na testovani rychlosti programu.
No ja pri tom narazil na to ze inc/dec reg_8bit nastavuje vlajku p/v! Myslel jsem, ze podteceni nemam jak pomoci inc/dec zjistit a ono to jde... (preteceni je jasne, to se nastavi zero)
A to ani pokud je to v A. Takze jsem celou dobu delal SUB 0x01 misto DEC A... lol. Musim vyzkouset.
Jinak jsem ten kod jeste vylepsil kdyz jsem se na nej ted kouknul. Protoze to pricitani 32 se da udelat pres registr C kdyz je volny.
draw_8_lines: ld bc, 8*(256+3)+32-3 ; 3:10 počitadlo zapsaných řádků ld a, e ; 1:4 save E loop: ldi ; 2:16 [DE++] = [HL++]; BC-- ldi ; 2:16 [DE++] = [HL++]; BC-- 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 dec e ; 1:4 korekce dec e ; 1:4 korekce inc d ; 1:4 posun na definici dalšího obrazového řádku djnz loop ; 2:13/8 vnitřní smyčka: blok s 3x osmi zápisy ld a, e ; 1:4 add a, c ; 1:4 ld e, a ; 1:4 ret c ; 1:5/11 ld a, d ; 1:4 sub 8 ; 2:7 ld d, a ; 1:4 ret ; 1:10 návrat z podprogramu ;[24:644/663 =10+8*77-5+26/10+8*77-5+45]
...a pak vyzkousel 3x ldi a vysla uplne nejlepsi rutina jenze... mela drobnou chybku na krase...
Ale i pres opravu te chybky je to nejlepsi reseni. A pokud mas ramecek okolo obrazovky tak muzes ten fix zrusit.
draw_sprite: ld hl, SPRITE_ADR ; 3:10 adresa, od níž začíná maska spritu call draw_8_lines ; 3:17 vykreslit prvních 8 řádků spritu call draw_8_lines ; 3:17 vykreslit druhých 8 řádků spritu call draw_8_lines ; 3:17 vykreslit třetích 8 řádků spritu ret ; 1:10 návrat z podprogramu ;[13:71] draw_8_lines: ld bc, 8*(256+3)+32-2 ; 3:10 počitadlo zapsaných řádků ld a, e ; 1:4 save E loop: ld e, a ; 1:4 load E ldi ; 2:16 [DE++] = [HL++]; BC-- ldi ; 2:16 [DE++] = [HL++]; BC-- ldi ; 2:16 [DE++] = [HL++]; BC-- dec de ; 1:6 fix fail pri tisku posledniho znaku v tretine! ldi zvedne D pro kazdy radek... inc d ; 1:4 posun na definici dalšího obrazového řádku djnz loop ; 2:13/8 vnitřní smyčka: blok s 3x osmi zápisy ld a, e ; 1:4 add a, c ; 1:4 ld e, a ; 1:4 ret c ; 1:5/11 ld a, d ; 1:4 sub 8 ; 2:7 ld d, a ; 1:4 ret ; 1:10 návrat z podprogramu ;[24:632/651 =10+8*75-5+26/10+8*75-5+45]
...ale ldi je ti stejne k nicemu pokud budes delat nejake xor .)))
26. 7. 2023, 00:47 editováno autorem komentáře
Vsechno jinak! .) Tak z "detects overflow" z https://clrhome.org/table/ se v originalnim manualu k Z80 vyklubalo ze pokud pred odectenim obsahuje registr hodnotu 0x80, tak se ten priznak nastavi, v ostatnich 255 pripadech se vynuluje.
Takze to dela neco jineho... ale zase existuje dalsi zpusob jak rychle testovat hodnoty 0x80 (dec) nebo 0x7F (inc).
Pridava dalsi slozitost pro hledani optimalnich reseni...
Existuje testovani bitu... 2:8 pokud nas zajima jen 7. bit
Rotace 2:8 pokud nas zajima 0. nebo 7. bit
"sla reg" by u 0x80 nastavila ZERO a CARRY, ale to nejde testovat najednou takze bez pouziti A snad:
rlc reg 2:8
dec reg 1:4
nastavi ZERO jen pri puvodni hodnote 0x80
ld A,reg 1:4
xor 0x80 2:7 nastavi ZERO
atd. atd.