Diky za clanek! Jeste jsem to nedocetl, ale nedalo mi ukazat u tretiho prikladu maly trik.
To ze jsi to dal do maker, je asi prehlednejsi co to ma delat, ale ne jak to dela a pak ti snadno uniknou optimalizace.
Takhle to vypada kdyz provedu makra:
next_key:
srl a ; přesunout kód stisku klávesy do příznaku carry
jr nc, key_pressed ; test stisku klávesy
ld (hl), WHITE_COLOR << 3
inc hl
jr next ; test další klávesy
key_pressed:
ld (hl), INTENSITY_BIT | (RED_COLOR << 3)
inc hl
next:
djnz next_key ; opakovat celou smyčku 5x
1 bajt usetrim kdyz zamenim dvoubajtove "srl a" za treba "rra", pokud me zajima jen carry.
1 bajt usetrim kdyz si uvedomim, ze obe vetve provadi spolecny kod "inc hl"
next_key:
rra ; přesunout kód stisku klávesy do příznaku carry
jr nc, key_pressed ; test stisku klávesy
ld (hl), WHITE_COLOR << 3
jr next ; test další klávesy
key_pressed:
ld (hl), INTENSITY_BIT | (RED_COLOR << 3)
next:
inc hl
djnz next_key ; opakovat celou smyčku 5x
Tim jsem se dostal do situace, kdy obe vetve maji jen 2 bajty a tak lze proves jeste dalsi optimalizaci a usetrit jeden bajt tim, ze zamenim "jr next" za 3 bajtovy jp. Trik je v tom, ze nastavim priznaky tak, ze se nikdy neprovede a adresa skoku bude kod druhe vetve. Podobneho efektu lze docilit ze si zaspinim nejaky dvouregistr napr "ld DE,xxxx", ale tady mam jasne definovany stav priznaku takze to jde udelat ciste.
next_key:
rra ; přesunout kód stisku klávesy do příznaku carry
jr nc, key_pressed ; test stisku klávesy
ld (hl), WHITE_COLOR << 3
db 0xD2 ; jp nc,nn
key_pressed:
ld (hl), INTENSITY_BIT | (RED_COLOR << 3)
next:
inc hl
djnz next_key ; opakovat celou smyčku 5x
Tohle by se dalo jeste prepsat, ze zrusim uplne to "jr nc" a "jp" a umistim za prvni vetev, ktera se vykona vzdy opacny priznak, aby se druha vetev vykonala jen kdyz ma. Tim by se usetril dalsi bajt.
next_key:
rra ; přesunout kód stisku klávesy do příznaku carry
ld (hl), WHITE_COLOR << 3
jr c, next ; test stisku klávesy
ld (hl), INTENSITY_BIT | (RED_COLOR << 3)
next:
inc hl
djnz next_key ; opakovat celou smyčku 5x
Tohle ma ale hacek! Bude to videt, protoze sahame do atributove pameti v nahodnem case a nekdy trefime paprsek a tak se nam muze u zobrazeni objevit bila cara. Bude se to chvet. Udelame 3 barvy v jednom znaku, kdybychom to spravne sesynchronizovali s paprskem.
Pekne, tohle je jako evoluce toho posledniho reseni, aby to neblikalo? .)
Kdyz se zameni registr A za napr. E tak to bude funkcni, protoze A si drzi stav toho radku/sloupce matice klaves..
Porovnal jsem to s predposlednim, protoze oba maji 11 bajtu a JP reseni je rychlejsi.
JP:
White: 7+10+10=27
Red: 12+10=22
White: 7+12+7=26
Red: 7+7+7+7=28
Jo mas pravdu, dobry postreh. Dopredu vedet, ktere vetve jsou pravdepodobnejsi je dalsi informace diky ktere muze mit clovek navrh nad prekladaci (aspon na Z80, pokud to neni neco jako java).
Ale realne v tomto pripade to nic nezmeni, protoze se ten atribut stejne prepise...ted to jeste spocitat
;[: 8*(52+225)=2216+200?] 1448x pomala vetev ;[: 8*(52+250)=2416+200?] 1337x rychla vetev
nez se to jednou prekresli na obrazovce.
Tohle teda plati pro tu moji verzi ve smycce. To +200 si cucam z prstu, protoze nemam tuseni o kolik se to zpomali tim ze se saha pod 0x8000.
Dal jsem, ze misto ld (HL),nn 2:10 to je 2:15. A 5*(5*8)=200
Pridal jsem do kodu mensi zpomaleni o 176 taktu pro nastaveni barvy pozadi
ld A, 7 ; 2:7 zx_border
and B ; 1:4 zx_border
out (254),A ; 2:11 zx_border 0=blk,1=blu,2=red,3=mag,4=grn,5=cyn,6=yel,7=wht
;[: 8*(52+225)=2216+200?+176] 70000/2592=27.007x
;[: 8*(52+250)=2416+200?+176] 70000/2792=25.072x
jp keypress ; 3:10 další test stisku kláves
A vysledek je asi 22x a 20x? oproti vypoctu 27x a 25x.
Fast:
https://ibb.co/bmRqnYk
Slow:
https://ibb.co/18GVBkS
PS: U te slow (puvodni verze) je zajimavy efekt jak se stiskne klavesa. Bez ni se ty pruhy pomalu pohybuji nahoru a po stisku to zacne ruzne klesat a nebo zase stoupat.
18. 5. 2023, 21:55 editováno autorem komentáře