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
Prepsal jsem jeste posledni program z kapitoly 15 do smycky. Takze jsem to stahnul ze 168 bajtu na 90 bajtu.
ENTRY_POINT equ $8000 ROM_CLS equ $0DAF org ENTRY_POINT BLINK_BIT equ %10000000 INTENSITY_BIT equ %01000000 BLACK_COLOR equ %000 BLUE_COLOR equ %001 RED_COLOR equ %010 MAGENTA_COLOR equ %011 GREEN_COLOR equ %100 CYAN_COLOR equ %101 YELLOW_COLOR equ %110 WHITE_COLOR equ %111 start: call ROM_CLS ; smazání obrazovky a otevření kanálu číslo 2 (screen) ld BC, str_keys_size ; 3:10 print Length of string ld DE, str_keys ; 3:10 print Address of string call 0x203C ; 3:17 print Print our string with ZX 48K ROM ld bc, 0xfef0 ; adresa portu, ze kterého budeme číst údaje ld hl, 0x5800 ; adresa, od které budeme měnit barvové atributy keypress: in a, (c) ; vlastní čtení z portu (5 bitů) ld e, 5 ; počet atributů + počet testovaných kláves 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 l dec e jr nz, next_key ; opakovat celou smyčku 5x ld a, l add a, 32-5 ld l, a rlc b jp keypress ; další test stisku kláves str_keys: ; layout klávesnice z pohledu čipů ZX Spectra NEW_LINE equ 13 DB "^ZXCV", NEW_LINE DB "ASDFG", NEW_LINE DB "QWERT", NEW_LINE DB "12345", NEW_LINE DB "09876", NEW_LINE DB "POIUY", NEW_LINE DB $7f, "LKJH", NEW_LINE DB "_", $60, "MNB" str_keys_size equ $-str_keys end ENTRY_POINT
PS: U Fuse mam problem, ze me to nebere u ceske klavesnice cisla a naopak u anglicke to v basicu vyvolava spatne prikazy.
PPS: Jinak muj notebook zvladne ASDW (asi optimalizovano) + napriklad C+K+T a + space
One ten kod je napsany velmi chytre a vysledek vypada efektivne. V podstate nezjistuje co si zmackl, ve smyslu ze zjistujes co ti uzivatel stiskl a mas znak.
50x za vterinu ti probehne prekresleni obrazovky.
Pres to jedno prekresleni ti hodnekrat probehne ta smycka co ti nastavi atribut pri stisku.
Takze nic dalsiho nemusis a obraz bude vypadat stabilne.
Jestli pred zacatkem stisku tam probehne nejaky zakmit co by pri spatnem zpusobu cteni vyvolal opakovane zmacknuti, zda je tlacitko stale drzeno nebo opakovane rychle mackano atd. Vubec nic te nemusi zajimat, v nejhorsim moznem scenari ti to jednou blikne na 1/50s pri stisku a jednou pri uvolneni.
PS: Ke vsemu to ani netestujeme na realnem ZX, ale emulatoru.
Tak me napadlo - nektere spectracke hry se pri ovladani klavesnici daji ovladat hodne kombinacemi klaves. Myslel jsem si, ze je to tak naprogramovano, ale ted me napada, jestli tu klavesnici nectou nejakym trikem - ze napriklad povoli vic adresovych linek zaraz a proste se nesnazi o rozeznani vsech klaves, ale jen toho, ve kterem radku (0-4) jsou. Je to tak?
K te hadance v 14. kapitole se jeste nikdo nevyjadril:
.)08Z an( utkat 23=)01-41(*8=01*8-)7*8+7*8( o kedelsyv olilamops ela ,utjab 6=)2+8*2(-8*3 olirtesu yb oT .enitur v taled edub es H a rtsiger L nej ivatsan ecazilaicini ez ,kat ot tiledzor a "0085x0 lh" s i taledu sezum elhot elA
. ":noitceted_sserpyek" az denh sitsimu ot dukop cebuv tadirp olemen ot yb ytkat a x8 salov ot zydk ,utjab 8*2 tirtesu olem ot yb ezkaT
."ef$+trop*652,cb,dl" ohisjenvitkefe itizuop otsim itumjyv an enevarpirp ecnokod sam zu ot ezotorP
.yniturbus od inezolv a ecazilaicini z "ef$ ,c dl" ytondoh intnatsnok itumjyv ilsym an sam ez ,milsym is aJ
Jen zpusob jak nekomu nechtene nevyzradit mozne reseni hadanky. a mel sanci si na to prijit sam. Kdybych to chtel "sifrovat" tak bych zvolil
-<<<--<++<---<--<---<+++<+++++++++[>----->+>->>>---->+>-><[>++++++++++++<<]>-]>[.>]
=
+++++++++[>++>+++++>+++++++>++++>++++++>+>+>++++>++>++++[-<]>]>+[>--->>+>>+++++>+>+++>+++>++<[>++++++<<]>-]>[.>]
=
++[<-<<<<++<<<<<+++[>+]>-------]<++++[<-<---<++<-<<-<---<+<--[>]<-]<+<+<-<<<-<-<<[.>]
=
++[<+<+<+<+++<+<+<+<+<+++[>]<-------]++++[<-<---<++<-<<-<---<+<--[>]<-]<+<+<-<<<-<-<<[.>]
To by pak bylo o neco slozitejsi, zvlast kdybych nechal jen nejkratsi reseni, to by uz nebylo tak zadarmo a spustu lidi by to vyselektovalo (az na ty co by nasli francouzske stranky).
Zkouším si příklady, a všiml jsem si že v prvních dvou příkladech se před in a, (c) vkládá do regisru C hodnota F0 a v posledním FE. Funguje obojí, zkoušel jsem i jiné hodnoty: F2 funguje, F1 nefunguje. (adresa musí být sudá?) Jaká je tedy správná hodnota portu?
Jestli jsem to ze schématu správně pochopil, tak jde o osmibitovou adresu vstupního portu který je součástí ULA a využívá se triku že vyšší část adresní sběrnice se použije pro výběr sloupce, což je pěkný trik.
Zkusil jsem si napsat podprogram pro získání kodu klavesy. V akumulátoru je vrácen poziční kod - není to nijak zvlášt optimalizované. Formát je 5 bitů sloupec a 3 bity číslo řádku.
keyb: push bc ;A - kod klavesy push de ld d,8 ;pocitadlo radku ld c,0xF0 ;adresa portu ld b,0xFE ;adresa prvniho radku keyb01: in a,(c) ;nacteni portu cpl ;negace and 0x1F ;nastaveni hornich bitu jp nz,keyb02 ;je stisknuta ld a,b ;adresa dalsiho radku rla ld b,a dec d ;pocitadlo radku jp nz,keyb01 ;dalsi radek pop de pop bc ret ;neni stisknuta zadna (A=00) keyb02: rla ;nalezena prvni stisknuta klavesa rla ;posun o 3 bity rla dec d add a,d ;pricteni cisla radku pop de pop bc ret ;stisknuta klavesa (A=sssssrrr)
Pro otestovvání kodů klaves jsem využil "print_hex_number"
ENTRY_POINT equ $8000 ROM_OPEN_CHANNEL equ $1601 AT equ $16 ;------------------------------------------------------------------------------- GOTO_XY macro X,Y ld A, AT ; řídicí kód pro specifikaci pozice psaní rst 0x10 ; zavolání rutiny v ROM ld A, Y ; y-ová souřadnice rst 0x10 ; zavolání rutiny v ROM ld A, X ; x-ová souřadnice rst 0x10 ; zavolání rutiny v ROM endm ;------------------------------------------------------------------------------- ZNAK_XY macro X,Y,kod ld A, AT ; řídicí kód pro specifikaci pozice psaní rst 0x10 ; zavolání rutiny v ROM ld A, Y ; y-ová souřadnice rst 0x10 ; zavolání rutiny v ROM ld A, X ; x-ová souřadnice rst 0x10 ; zavolání rutiny v ROM ld A, kod ; kód znaku '*' pro tisk rst 0x10 ; zavolání rutiny v ROM endm ;------------------------------------------------------------------------------- org ENTRY_POINT start: ld A,2 ; číslo kanálu call ROM_OPEN_CHANNEL ; otevření kanálu číslo 2 (screen) main: GOTO_XY 5,5 call keyb call print_hex_number jp main ;------------------------------------------------------------------------------- keyb: push bc ;A - kod klavesy push de ld d,8 ;pocitadlo radku ld c,0xF0 ;adresa portu ld b,0xFE ;adresa prvniho radku keyb01: in a,(c) ;nacteni portu cpl ;negace and 0x1F ;nastaveni hornich bitu jp nz,keyb02 ;je stisknuta ld a,b ;adresa dalsiho radku rla ld b,a dec d ;pocitadlo radku jp nz,keyb01 ;dalsi radek pop de pop bc ret ;neni stisknuta zadna (A=00) keyb02: rla ;nalezena prvni stisknuta klavesa rla ;posun o 3 bity rla dec d add a,d ;pricteni cisla radku pop de pop bc ret ;stisknuta klavesa (A=sssssrrr) ;------------------------------------------------------------------------------- print_hex_number: push AF ; uschovat A pro pozdější využití rrca ; rotace o čtyři bity doprava rrca rrca rrca and $0f ; zamaskovat horní čtyři bity call print_hex_digit; vytisknout hexa číslici pop AF ; obnovit A and $0f ; zamaskovat horní čtyři bity call print_hex_digit; vytisknout hexa číslici ret ; a návrat z podprogramu ;------------------------------------------------------------------------------- print_hex_digit: cp 0x0a ; test, jestli je číslice menší než 10 jr c, print_0_to_9 ; ok, hodnota je menší než 10, budeme tedy tisknout desítkovou číslici add A, 65-10-48 ; ASCII kód znaku 'A', ovšem začínáme od desítky, ne od nuly (+ update pro další ADD) print_0_to_9: add A, 48 ; ASCII kód znaku '0' rst 0x10 ; zavolání rutiny v ROM pro tisk jednoho znaku ret ; návrat ze subrutiny ;------------------------------------------------------------------------------- end ENTRY_POINT
No a ještě jeden program: klávesy E, S, D, X pohybují znakem po obrazovce
ENTRY_POINT equ $8000 ROM_OPEN_CHANNEL equ $1601 ROM_CLS equ $0DAF AT equ $16 X0 equ 15 Y0 equ 10 XMIN equ 0 XMAX equ 31 YMIN equ 0 YMAX equ 21 ZNAK equ "#" MEZERA equ " " ;------------------------------------------------------------------------------- GOTO_XY macro X,Y ld A, AT ; řídicí kód pro specifikaci pozice psaní rst 0x10 ; zavolání rutiny v ROM ld A, Y ; y-ová souřadnice rst 0x10 ; zavolání rutiny v ROM ld A, X ; x-ová souřadnice rst 0x10 ; zavolání rutiny v ROM endm ;------------------------------------------------------------------------------- ZNAK_XY macro X,Y,kod ld A, AT ; řídicí kód pro specifikaci pozice psaní rst 0x10 ; zavolání rutiny v ROM ld A, Y ; y-ová souřadnice rst 0x10 ; zavolání rutiny v ROM ld A, X ; x-ová souřadnice rst 0x10 ; zavolání rutiny v ROM ld A, kod ; kód znaku '*' pro tisk rst 0x10 ; zavolání rutiny v ROM endm ;------------------------------------------------------------------------------- org ENTRY_POINT start: call ROM_CLS ld h,X0 ;pocatecni nastaveni X,Y ld l,Y0 ZNAK_XY h,l,ZNAK main: call delay m01: call keyb cp 0x26 call z,vpravo cp 0x16 call z,vlevo cp 0x25 call z,nahoru cp 0x27 call z,dolu jp main ;------------------------------------------------------------------------------- keyb: push bc ;A - kod klavesy push de ld d,8 ;pocitadlo radku ld c,0xF0 ;adresa portu ld b,0xFE ;adresa prvniho radku keyb01: in a,(c) ;nacteni portu cpl ;negace and 0x1F ;nastaveni hornich bitu jp nz,keyb02 ;je stisknuta ld a,b ;adresa dalsiho radku rla ld b,a dec d ;pocitadlo radku jp nz,keyb01 ;dalsi radek pop de pop bc ret ;neni stisknuta zadna (A=00) keyb02: rla ;nalezena prvni stisknuta klavesa rla ;posun o 3 bity rla dec d add a,d ;pricteni cisla radku pop de pop bc ret ;stisknuta klavesa (A=sssssrrr) ;------------------------------------------------------------------------------- vpravo: ZNAK_XY h,l,MEZERA ld a,h cp XMAX jr Z,vp0 inc h vp0: ZNAK_XY h,l,ZNAK ret ;------------------------------------------------------------------------------- vlevo: ZNAK_XY h,l,MEZERA ld a,h cp XMIN jr Z,vl0 dec h vl0: ZNAK_XY h,l,ZNAK ret ;------------------------------------------------------------------------------- dolu: ZNAK_XY h,l,MEZERA ld a,l cp YMAX jr Z,do0 inc l do0: ZNAK_XY h,l,ZNAK ret ;------------------------------------------------------------------------------- nahoru: ZNAK_XY h,l,MEZERA ld a,l cp YMIN jr Z,na0 dec l na0: ZNAK_XY h,l,ZNAK ret ;------------------------------------------------------------------------------- delay: push bc push de ld d,40 ld e,0 d01: dec e jr nz, d01 dec d jr nz, d01 pop de pop bc ret end ENTRY_POINT
Ta keyb rutina jde napsat mnohem kratsi
;------------------------------------------------------------------------------- keyb: push bc ;A - kod klavesy push de ld d,7 ;pocitadlo radku ld bc,0xFEF0 ;adresa prvniho radku & adresa portu keyb01: in a,(c) ;nacteni portu cpl ;negace add a,a ;posun o 3 bity add a,a add a,a jp nz,keyb02 ;je stisknuta dec d ;pocitadlo radku rl b ; 0xFE->FD->FB->F7->EF->DF->BF->7F jp c,keyb01 ;dalsi radek ld d,a ;neni stisknuta zadna (D=A=00) keyb02: add a,d ;pricteni cisla radku pop de pop bc ret ;stisknuta klavesa (A=sssssrrr)
A u toho CASE vetveni ktera klavesa je stiskla muzes usetrit taky nejake bajty kdyz mas rozdily mezi vetvemi nekdy jedna.
Misto:
cp 0x26 call z,vpravo cp 0x16 call z,vlevo cp 0x25 call z,nahoru cp 0x27 call z,dolu
To napis:
sub 0x16 call z,vlevo ; 0x16 cp 0x25-0x16 call z,nahoru ; 0x25 dec a call z,vpravo ; 0x26 dec a call z,dolu ; 0x27
Ale mas tam chybu, ze v tech podrutinach prepisujes registr A. Takze ti to funguje jen nahodou.
Kdyz se nad tim zamyslis, tak ten zpusob cteni klavesnice neni idealni. Protoze najdes prvni stisklou klavesu a ukoncis cteni klavesnice, ale ty pro tu hru spis potrebujes zjistit i vic klaves, napriklad nahoru+doprava+fire. Takze bud nejake 40 bitove pole a nebo jeste lepe pro kazdou konkretni klavesu mit znovu cteni. Mas tam 4 az 5 klaves.
Nejak takto treba na 110 bajtu (z puvodnich 203):
ENTRY_POINT equ $8000 ROM_CLS equ $0DAF AT equ $16 X0 equ 15 Y0 equ 10 XMIN equ 0 XMAX equ 31 YMIN equ 0 YMAX equ 21 ZNAK equ "#" MEZERA equ " " org ENTRY_POINT start: call ROM_CLS ld hl,256*X0+Y0 ;pocatecni nastaveni X,Y ld de,ZNAK*257 ;D=E=znak call print_yx_hl_e main: halt halt ld bc,0xFB02 ; Q call checkpress call nz,nahoru ld b,0xFD ; A, C=0x02 call checkpress call nz,dolu ld bc,0xDF04 ; O call checkpress call nz,vlevo ld c,0x02 ; P, B=0xEF call checkpress call nz,vpravo jr main ;------------------------------------------------------------------------------- ;in: ;B=0x7F C= ..BNMs_. ;B=0xBF C= ..HJKLe. ;B=0xDF C= ..YUIOP. ;B=0xEF C= ..67890. ;B=0xF7 C= ..54321. ;B=0xFB C= ..TREWQ. ;B=0xFD C= ..GFDSA. ;B=0xFE C= ..VCXZc. ;out: nz=press checkpress: in a,(c) ;nacteni portu cpl ;negace add a,a ;posun o 3 bity and c ret ;------------------------------------------------------------------------------- vpravo: ld a,h cp XMAX ret Z call print_yx_hl_space inc h ld e,d jr print_yx_hl_e ;------------------------------------------------------------------------------- vlevo: if (XMIN=0) inc h dec h else ld a,h cp XMIN endif ret Z call print_yx_hl_space dec h ld e,d jr print_yx_hl_e ;------------------------------------------------------------------------------- dolu: ld a,l cp YMAX ret Z call print_yx_hl_space inc l ld e,d jr print_yx_hl_e ;------------------------------------------------------------------------------- nahoru: if (XMIN=0) inc l dec l else ld a,l cp YMIN endif ret Z call print_yx_hl_space dec l ld e,d jr print_yx_hl_e ;------------------------------------------------------------------------------- print_yx_hl_space: ld E,' ' ; 1e20 print_yx_hl_e: ld A, AT ; řídicí kód pro specifikaci pozice psaní rst 0x10 ; zavolání rutiny v ROM ld A, L ; y-ová souřadnice rst 0x10 ; zavolání rutiny v ROM ld A, H ; x-ová souřadnice rst 0x10 ; zavolání rutiny v ROM ld A, E ; kód znaku '*' pro tisk rst 0x10 ; zavolání rutiny v ROM ret ;------------------------------------------------------------------------------- end ENTRY_POINT
PS: Ja zase pouzivam v C masku klavesy co chci tisknout vynasobenou dvema. V emulatorou to funguje, ale na realnem ZX netusim... Z toho obrazku obvodu a ze jsou pri nejakych kombinacich vyvolany duchove je uz mimo muj level. Proste HW...
Nemám s Z80 tolik zkušeností a ani neznám všechny instrukce, tak jsem si nebyl jistý jak to vlastně je. Jestli můžu instrukce rotací použít i na jiný instrukce než akumulátor. Je nějaká rozumná tabulka s instrukcemi? Když jsem to na internetu hledal, tak na mne vylezla buď moc podrobná (odstavec na každou instrukci) nebo zas jen tabulka kde zjistím maximálně hex kod. Používám to od p. Tišnovského co je v lekcích, ale je to po kouskách a myslím že ne kompletní.
To že přečtu jen jednu klávesu je mi jasný, neměl jsem v tuhle chvíli ambice to udělat líp. S tím že v podprogramech přepisuju A máš pravdu, nevšimnul jsem si toho. Funguje to jen proto, že kódy zvolených kláves jsou větší než souřadnice X.Y.
Ja osobne pouzivam 5. odkaz uvedeny v clanku v odkazech.
Asi pred pul rokem prosel web nejakym designovym updatem a uz to neni ono. Plus ma (nebo mel) tam asi nejake drobne chyby, ze ma spatne zacervenene instrukce.
Popisky jsou v nahledu. Nekdy je stejne potreba vetsi popisek, protoze nektere instrukce jsou matouci.
Nejdulezitejsi je prvni tabulka, protoze je bez prefixu, takze nejkratsi instrukce a nejrychlejsi.
Pak muze byt uzitecna CB a ED.
Zbytek v nejakych specialnich pripadech, bud slozity algoritmus, nebo mas vsechno obsazene, ale je otazka zda to nejde napsat jinak.
Nekdy instrukce, ktere vypadaji jako kopie z prvni tabulky se ale lisi priznaky (ruzne posuny a rotace A).
Ale treba LD (adr),HL ma dve varianty "22 lo hi" a "ED 63 lo hi". Uplne zbytecne, ale... nekdy by se to treba mohlo hodit kdyz provadis nektere triky, kdy se snazis eliminovat nejaky skok, nebo se snazis mit 2 kody v sobe, jen posunuty o bajt (Z80 ti to skoro okamzite ale slouci diky tomu jak ma udelane opcody).
PS: U keyb si pouzil 3x "rla" a fungovalo ti to protoze si pred prvni "rla" mel vynulovany carry po "and" a pri druhem a tretim, protoze jsi mel vynulovany carry, protoze si zaroven tim "and" odmazal 3 nejvyssi bity z A.
Pokud by si ale rovnou pouzil "add A,A", nemusel bys carry resit, kdyz tam chces jen nuly.
PPS: Dobra prace.
Protoze prvni je spatne a je to mysleno jako oprava. Narazil jsem na to v nejakem dalsim kodu.
Prvni dela:
rl b ; 0xFE->FC->F8->F0->E0->C0->80->00
"rl b" = "adc b,b", ale v kodu je vzdy vynulovany carry takze je to "add b,b" (Pak ze Z80 umi pocitat jen s A(HL)).
Premyslel jsem proc to fungovalo a dospel jsem k nazoru, ze...
Tomu prvne predhodite spravnou hodnotu a on otestuje stisk klaves na radku 0xFE a zjisti ze je nejaka stiskla a ukonci se a nebo neni zadna stiskla a pokracuje.
Dalsi hodnota je 0xFC a program provede znovu kontrolu jako v FE kde nic neni pokud to nahodou neni stiskle prave v ten moment (opakovane zmacknuti Z (3.bit 0xFE) by asi melo obcas vyvolat stisk S (3.bit 0xFD)) a provede kontrolu i pro 0xFD (dela asi proste zaroven kontrolu 0xFE a 0xFD kdyz ma dva bity nulove)
Atd pro zbytek.