OldComp.cz https://oldcomp.cz/ |
|
Macro FORTH https://oldcomp.cz/viewtopic.php?f=124&t=8564 |
Stránka 31 z 40 |
Autor: | _dworkin [ 24.05.2023, 03:48 ] |
Předmět příspěvku: | Re: Macro FORTH |
Rozhodl jsem se ze to napisi sem, i kdyz to mozna patri do ZX Spectrum Hardware a nebo mozna do ZX Spectrum Software programovani, ale vlastne to patri i sem. Jak je to vlastne se ctenim klaves na gumakovi. Na netu se uvadi neco jako ze volas Kód: LD BC,0xFBFE IN A,(C) a to ti ma do A nacist ???TRWEQ. Kde u pismen je 1 kdy to neni stiskle a pokud je tak je tam nula. Otazniky jsou 101 u emulatoru Fuse. Takze kdyz neni nic stisknuto ukazuje to 0xBF. PS: Premyslim, ze bych udelal nejake prime testy stisku klavesy, protoze pro hru se to hodi kdyz to umi registrovat stisk vic klaves. Neco jako slovo PRESSKEY_Q a vraci to boolean. Kód: dworkin@dw-A15:~/Programovani/ZX/Forth/Pasmo_test$ ../check_word.sh 'PRESSKEY_Q' push DE ; 1:11 press_q ( -- bool ) ex DE, HL ; 1:4 press_q ld BC, 0xFBFE ; 3:10 press_q in A,(C) ; 2:12 press_q rrca ; 1:4 press_q ccf ; 1:4 press_q sbc HL, HL ; 2:15 press_q ; seconds: 0 ;[11:60] Otazka c. 1: Jak moc se da spolehnout na to, ze nejvyssi bitu jsou 101? Otazka c. 2: Proc je v registru C hodnota 0xFE? Tzn. proc je to port 0xFE? Kdyz tam muze byt asi cokoliv co ma nulty bit nulovy? Koliduje to pak s necim? S nejakym pripojenym hardwarem? Otazka c. 3: Pokud budu cist port pres Kód: IN A,(0xFE) tak me to cte vsech 8 radku najednou? Protoze neodesilam zadny horni bajt? Otazka c. 4: Jak je to s temi duchy? Na netu je lepsi obrazek nez ten na rootu (protoze ten ma prehazene cisla "radku") https://retrocomputing.stackexchange.com/questions/16235/how-zx-spectrum-avoided-key-ghosting Příloha: V odkazu je napsano, ze kdyz se stiskne zaroven A+S+Z tak to vyvola CapsLock. Plati tohle i pro jakoukoliv klavesu z tech 4 kdyz ostatni tri budou zmacknute? Napriklad S+A+CapsLock vyvola Z? Muze byt ten ctverec i vetsi? 2+3+4+R+F vyvola EDWS? A musi to byt vedle sebe? Q+W+Z vyvola CapsLock? Otazka c.5: Jak moc je to nekompatibilni s dalsimi varianty ZX. Nektere maji vic tlacitek atd. PS: Chtel bych napsat nejaka slova ve Forthu co primo zjistuji zda je tlacitko stiskle, protoze se to hodi pro hry kdy vetsinou chces vedet i vic klaves najednou. Bud hraji dva a nebo napriklad chces vedet FIRE+neco, pripadne NAHORU+DOLEVA treba. Kód: dworkin@dw-A15:~/Programovani/ZX/Forth/Pasmo_test$ ../check_word.sh 'PRESSKEY_Q'
push DE ; 1:11 press_q ( -- bool ) ex DE, HL ; 1:4 press_q ld BC, 0xFBFE ; 3:10 press_q in A,(C) ; 2:12 press_q rrca ; 1:4 press_q ccf ; 1:4 press_q sbc HL, HL ; 2:15 press_q ; seconds: 0 ;[11:60] |
Autor: | Busy [ 24.05.2023, 06:43 ] |
Předmět příspěvku: | Re: Macro FORTH |
_dworkin píše: Otazka c. 1: Jak moc se da spolehnout na to, ze nejvyssi bitu jsou 101? Nijak. Na nejaky konkretny stav tych troch bitov sa nespoliehaj._dworkin píše: Otazka c. 2: Proc je v registru C hodnota 0xFE? Tzn. proc je to port 0xFE? Pretoze navrhari sa tak rozhodli._dworkin píše: Kdyz tam muze byt asi cokoliv co ma nulty bit nulovy? Koliduje to pak s necim? S nejakym pripojenym hardwarem? Ano, koliduje, s (temer) uplne vsetkym ! 128 a AY sa aktivuje ak je A1=0, ZX printer zase pri A2=0, ... a stary tradicny interface s 8255 pri A7=0._dworkin píše: Otazka c. 3: Pokud budu cist port pres RTFM ! Kód: IN A,(0xFE) tak me to cte vsech 8 radku najednou? Protoze neodesilam zadny horni bajt?Pozri datasheet k Z80. Pri IN A,(cislo) predstavuje cislo nizsi bajt adresy a vyssi bajt adresy sa berie z A. _dworkin píše: Otazka c. 4: Jak je to s temi duchy? Vola sa to maticovy jav. Ak stlacis tri klavesy nachadzajuce sa na troch vrcholoch lubovolneho (lubovolne velkeho) obdlznika, tak sa ti automaticky "stlaci" aj stvrty vrchol obdlnika. To preto, lebo nastane elektricke spojenie cez tie tri realne stacene vrcholy a potom sa to javi ako keby bol elektricky spojeny aj ten stvrty vrchol._dworkin píše: Otazka c.5: Jak moc je to nekompatibilni s dalsimi varianty ZX. Nektere maji vic tlacitek atd. Zakladnych 40 klaves je plne kompatibilnych na vsetkych klonoch ZX Spektra a da sa na to spolahnut. Viac klaves ma napr. +2A/+3 ale to iba ULA pomocou nich simuluje stlacanie shiftovych klaves, takze sotftware sa o to uz starat nemusi.Btw. ked uz pisem, napadlo ma, ze stale cakam odpoved na tuto moju otazku: Busy píše: _dworkin píše: Antony/DTA píše: Ale hodnota 0x0180 bude vyhodnotená nesprávne. Jakto?Tady to splnuje ze HI=rlca(LO) Ma to byt HI=rlca(LO), alebo to ma byt to co si napisal predtym: "cislo se kterym na ktere se to testuje ma HI bajt dvojnasobek LO bajtu" ??? Pretoze to su dve rozne veci... |
Autor: | _dworkin [ 24.05.2023, 16:13 ] |
Předmět příspěvku: | Re: Macro FORTH |
Diky za odpovedi s temi porty. Busy píše: Btw. ked uz pisem, napadlo ma, ze stale cakam odpoved na tuto moju otazku: Busy píše: _dworkin píše: Antony/DTA píše: Ale hodnota 0x0180 bude vyhodnotená nesprávne. Jakto?Tady to splnuje ze HI=rlca(LO) Ma to byt HI=rlca(LO), alebo to ma byt to co si napisal predtym: "cislo se kterym na ktere se to testuje ma HI bajt dvojnasobek LO bajtu" ??? Pretoze to su dve rozne veci... Busy píše: (alebo som odpoved v tej zaplave siahodlnych prispevkov iba prehliadol ?) Nasel jsem to na str. 29 a ted uplne nevim na co se ptas. Ale jsem si jisty ze spatne formulovana odpoved vyvolala jen dalsi zmateni. Napr. co myslim tim HI zda reg. H nebo horni bajt testovaneho cisla a nebo horni bajt konstanty. Uloha je ze mas napsat program ktery testuje 16 bitove cislo na konstantu. Ty znas dopredu tu konstantu a tak muzes s ohledem na jeji hodnotu optimalizovat ten kod. Pokud se nepletu tak v te uloze to mas navic stizene tim, ze mas odstranit tu testovanou hodnotu z HL a natahnout to HL hodnotu co je v DE a do DE nacist prvni hodnotu ze zasobniku. Na foru jsem resil pripad kdy ta konstanta je treba 0x4020. Takze hi(const) = 2*lo(const) -> 0x40=2*0x20. S tim, ze reseni s "2*" ma nejake problemy (viz ta diskuze) a ze je lepsi to resit, kdyz to jde jako hi(const)=rlca(lo(const)) -> 0x40=rlca(0x20). Protoze tady drzime v A spravnou hodnotu i kdyz uz odstranime HL. RLCA metoda: Kód: ld A, L rlca cp H zrusime HL atd. odskok pokud je to nenulove -> FALSE jeste nemame vyhrano protoze jsme to testovali jen relativne ale vime z v A je H cp 0x40 nenulove -> FALSE nulove -> TRUE RLCA metoda (je snazsi a) funguje pro vsechny nasobky dvou pokud je 7. bit konstanty nulovy. Ty metody maji 85% prunik nad nekteryma hodnotama. RLCA neumi jako 2x metoda 0x40A0 ale zase umi stejny pocet pripadu s napr. 0x41A0. ADD A,A metoda s chybou: Kód: ld A, L add A,A Chyba: vypadl nam 7. bit a museli bychom pridat na tomto miste odskok podle toho zda ma byt nebo nema carry --> v obou pripadech existuji efektivnejsi metody cp H zrusime HL atd. odskok pokud je to nenulove -> FALSE jeste nemame vyhrano protoze jsme to testovali jen relativne ale vime z v A je H cp 0x40 nenulove -> FALSE nulove -> TRUE ADD A,A metoda bez komplikaci ruseni HL: Kód: ld A, L cp 0x20 odskok pokud je to nenulove -> FALSE add A,A cp H ; stale zname H tak je to stejne efektivni jako rlca metoda nenulove -> FALSE nulove -> TRUE ADD A,A metoda s rusenim HL: Kód: nacteme L do A cp 0x20 ...nemuzeme jeste udelat odskok protoze kdyz vycistime HL tak uz neporovname zda A+A=H tak jinak: Kód: ld A, L cp 0x20 ld A, H zrusime HL atd. odskok pokud je to nenulove -> FALSE cp 0x40 nenulove -> FALSE nulove -> TRUE ...ale to uz neni 2* metoda, ale jedna z pomalejsich univerzalnich. tak jeste jinak: Kód: ld A, L cp 0x20 jr nz, vycisti add A,A cp H ; stale zname H vycisti: zrusime HL atd. nenulove -> FALSE nulove -> TRUE ...ale tohle je taky pomalejsi i kdyz to tak nemusi vypadat. U absolutniho odskoku je to jasne u relativniho si staci vzit pripad kdy se to pouziva pro "IF CONST <> HL" Kód: ld A, L cp 0x20 jr nz, vycisti ; 33 add A,A cp H ; stale zname H vycisti: zrusime HL atd. jp z, ELSE ; 36 TRUE: ... jp ENDIF ELSE: ... ENDIF: oproti: Kód: ld A, L rlca cp H zrusime HL atd. jr nz, TRUE ; 24 cp 0x40 jp z, ELSE ; 33 TRUE: ... jp ENDIF ELSE: ... ENDIF: PS: Vsechny primo uvedene hodnoty jako 0x4020 jsou ty konstanty na ktere se to testuje. "Neznama" testovana hodnota je H a L. PPS: Nevim zda si tam najdes tu odpoved co si chtel slyset, kdyby ne tak upresni otazku. |
Autor: | _dworkin [ 25.05.2023, 14:20 ] | ||
Předmět příspěvku: | Re: Macro FORTH | ||
Zkousel jsem nejake moc nepouzivane priznaky Z80 a jsem trochu zmateny. in A,(C) nastavuje ve FUSE emulatoru P/V bit pokud je stiskla nejaka klavesa. Nenasel jsem k tomu dokumentaci, takze z chovani: Kdyz neni nic stiskle a vraci to v A 0xBF tak je tam nula pri stisku jakekoliv klavesy z te rady nastavi (A=AF,B7,BB,BD,BE) P/V na 1. Pokud se stisknou 2 zaroven ( napr A7, AB, AD) tak to vraci zase nulu. ==> Z toho me vychazi ze tady (instrukce IN) ten priznak zjistuje zda je soucet jednicek sudy v akumulatoru. U toho se me ale (instrukce IN) nastavuje i 3. bit priznaku! A, F 3. bit AF=1 B7=0 ??? BB=1 BD=1 BE=1 Zkousel jsem i nasledujici "add A,A" a tam to taky nekdy meni 3. a i 5. bit. ld A,0xAF add a,a ; = 0x5E vynuluje 5. bit ld A,0x6E add a,a ; =0xDC take vynuluje 5. bit PS: Instrukce "add" me zajimala pro priznak H pro rychlou detekci 3. a 2. bitu lezicich uprostred registru, ale k tomu se neda snadno dostat... :/ PPS: A "add" evidetne nastavuje "P/V" na preteceni (spravny vysledek mel byt mensi jak -128 a nebo vetsi jak 127) coz mam v tomhle pripade porad. Aspon to tak pise neoficialni dokumentace na netu.
|
Autor: | Mikes21 [ 25.05.2023, 15:31 ] |
Předmět příspěvku: | Re: Macro FORTH |
Podle dokumentace bity F3 a F5 nejsou pouzite. To ale nevylucuje, ze nemaji v realu nejaky side efekt. Mozna trochu napovi stranka http://www.z80.info/z80sflag.htm, podle ktere instrukce LDI/LDIR/LDD/LDIR a CPI/CPIR/CPD/CPDR (a dalsi) odrazi stav zpracovavaneho bytu. Mozna se to tyka i samostatne IN instrukce. Urcite by slo take nakouknout do schematu z reverzniho zdokumentovani navrhu kremikoveho cipu. A pak je taky velkou otazkou, jak to je implementovano v emulatorech nebo VHDL implenetacich 'noveho' CPU. Pro realne projekty bych to ale nebral moc smerodatne |
Autor: | l00k [ 25.05.2023, 15:33 ] |
Předmět příspěvku: | Re: Macro FORTH |
už to tu psal jednou Busy, na nejvyšší 3 bity se nespoléhej při testu kláves, je třeba je odmaskovat a pak teprve řešit nějaké příznaky |
Autor: | _dworkin [ 25.05.2023, 16:21 ] |
Předmět příspěvku: | Re: Macro FORTH |
Mikes21 píše: Podle dokumentace bity F3 a F5 nejsou pouzite. To ale nevylucuje, ze nemaji v realu nejaky side efekt. Mozna trochu napovi stranka http://www.z80.info/z80sflag.htm, podle ktere instrukce LDI/LDIR/LDD/LDIR a CPI/CPIR/CPD/CPDR (a dalsi) odrazi stav zpracovavaneho bytu. Mozna se to tyka i samostatne IN instrukce. Urcite by slo take nakouknout do schematu z reverzniho zdokumentovani navrhu kremikoveho cipu. A pak je taky velkou otazkou, jak to je implementovano v emulatorech nebo VHDL implenetacich 'noveho' CPU. Pro realne projekty bych to ale nebral moc smerodatne Jsem slepy... 3. a 5. bit by mely bit kopie tech samych bitu z akumulatoru. 0xA7 = 10(1)0 (0)111 to u 3. bitu sedi 0xDC = 11(0)1 (1)100 to taky u 5. bitu sedi PS: Je to teda nedokumentovane, ale budu predpokladat ze minimalne pro vetsinu gumaku to bude tak. Teoreticky bych tak mohl mit moznost ulozit na zasobnik konkretni 16 bitove cislo kdybych vedel co mam v A + nejaka operace. Hmm.. minimalne po "xor a + push af" Z+P tam mit 0x0044. Uf! "and a" nastavuje H!!! primo z definice. Takze z nuloveho A po "and A + push AF" tam bude 0x0054 |
Autor: | _dworkin [ 28.05.2023, 03:23 ] |
Předmět příspěvku: | Re: Macro FORTH |
Protoze jsem trosku pracoval na tom cteni klavesnice tak jsem se dival jsem na ty IN instrukce a na webu co pouzivam to neni tak jasne jak to Busy popsal. https://clrhome.org/table/ Kód: Opcode: DB n Bytes: 2 Cycles: 11 C unaffected N unaffected P/V unaffected H unaffected Z unaffected S unaffected A byte from port n is written to A. http://z80-heaven.wikidot.com/instructions-set:in Tam k tomu neni v podstate vubec nic... .) Takze se radeji znovu ujistim, delaji tyhle dva kody to same? Kód: dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'TESTKEY IF' ld B, H ; 1:4 testkey if ( mask -- ) ld C, 0xFE ; 2:7 testkey if in A,(C) ; 2:12 testkey if and L ; 1:4 testkey if ex DE, HL ; 1:4 testkey if pop DE ; 1:10 testkey if jp nz, else101 ; 3:10 testkey if ; seconds: 0 ;[11:51] Kód: dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'TESTKEY IF' ld A, H ; 1:4 testkey if ( mask -- ) in A,(0xFE) ; 2:11 testkey if and L ; 1:4 testkey if ex DE, HL ; 1:4 testkey if pop DE ; 1:10 testkey if jp nz, else101 ; 3:10 testkey if ; seconds: 0 ;[ 9:43] A treba: Kód: dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(__TESTKEY_Q) TESTKEY_ZF' ld BC, 0xFBFE ; 3:10 0xFB01 testkey ( -- ) set zf == press "Q" in A,(C) ; 2:12 0xFB01 testkey and 0x01 ; 2:7 0xFB01 testkey ; seconds: 1 ;[ 7:29] Kód: dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(__TESTKEY_Q) TESTKEY_ZF' ld A, 0xFB ; 2:7 0xFB01 testkey ( -- ) set zf == press "Q" in A,(0xFE) ; 2:11 0xFB01 testkey and 0x01 ; 2:7 0xFB01 testkey ; seconds: 0 ;[ 6:25] A jeste me dostalo, ze ta "in a,(c)" varianta je i pro jine registry nez "A" + jedna nedokumentovana co jen nastavuje priznaky. To jsem uplne zazdil. PS: Jinak jsem prejmenoval to slovo na zjisteni zda je klavesa stiskla na TESTKEY, protoze ve Forth standartu se to snazi resit pres slova KEY (to by melo nacitat jen znaky a specialni je mozne nahradit kombinaci znaku) a EKEY (to by melo nacitat i specialni znaky, tzn. napriklad s kodem mensim jak mezera). A ani jedno slovo se teda moc nehodi, protoze delaji neco jine nez test stisku. PPS: Zrusil jsem a smazal vsechny slova jako TESTKEY_Q (PRESSKEY_Q), protoze to nebyl dobry napad a spatne by se me to pak kombinovalo napr. s IF. Musel bych vytvorit nasobek tech slov s IF,WHILE,UNTIL atd. Takze 40*5 slov... Takze jsem zavedl to, ze TESTKEY nacita parametr z TOS. Horni bajt je co se posila do portu a dolni bajt je maska co se provede s nactenym bajtem. To mi umoznuje otestovat vsechny klavesy a nebo i kombinaci klaves. Zavedl jsem pro ty konstanty masek makra jako __TESTKEY_Q co vraci 0xFBFE. Tim jsem si uvolnil cestu i pro slova jako PUSH_TESTKEY(__TESTKEY_Q), ktere je uplnou nahradou za TESTKEY_Q. Takze pro IF me stacilo udelat jen TESTKEY_IF a PUSH_TESTKEY_IF. Dalsi vyhoda je ze existuje to slovo co testuje klavesu jako promennou. PPPS: Kdyby to nekoho zajimalo tak makra specialni klavesy se jmenuji: __TESTKEY_SYMBOL_SHIFT __TESTKEY_SPACE __TESTKEY_ENTER __TESTKEY_CAPS_SHIFT PPPPS: Jo a v tech ukazkach jsou slova jako TESTKEY_ZF a IF_ZF.... hmmm o tom se asi nechci moc zminovat, jsou to takove pokusy jak si usetrit praci se spojovanim slov. Vytvoril jsem varianty u IF hned ctyri IF_ZF,IF_NZF,IF_CR a IF_NCF. TESTKEY ma jen TESTKEY_ZF a PUSH_TESTKEY_ZF. Nedoporucuji pouzivat. .)) Minimalne proto, ze uz mam (uploadnu zitra) TESTKEY_IF a PUSH_TESTKEY_IF a minimalne to druhe je efektivnejsi, protoze dokaze pro vsechny klavesy co maji masku na nultem bitu pouzit carry, ktery se efektivneji testuje. Kód: dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(__TESTKEY_P) TESTKEY_ZF IF_ZF'
ld A, 0xDF ; 2:7 0xDF01 testkey ( -- ) set zf == press "P" in A,(0xFE) ; 2:11 0xDF01 testkey and 0x01 ; 2:7 0xDF01 testkey jp nz, else101 ; 3:10 if ; seconds: 1 ;[ 9:35] dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(__TESTKEY_P) TESTKEY IF' ld A, 0xDF ; 2:7 0xDF01 testkey if ( -- ) if press "P" in A,(0xFE) ; 2:11 0xDF01 testkey if rrca ; 1:4 0xDF01 testkey if jp c, else101 ; 3:10 0xDF01 testkey if ; seconds: 1 ;[ 8:32] |
Autor: | Busy [ 28.05.2023, 09:47 ] |
Předmět příspěvku: | Re: Macro FORTH |
_dworkin píše: Kód: Opcode: DB n Bytes: 2 Cycles: 11 C unaffected N unaffected P/V unaffected H unaffected Z unaffected S unaffected A byte from port n is written to A. Kdezto naproti tomu vsetkych osem dalsich IN r,(c) (po prefixe ED) riadne nastavuju priznaky podla nacitaneho udaja. Teda okrem CY ktore nemenia (kedze tam nejake pretecenie cez osem bitov z principu nie je). _dworkin píše: http://z80-heaven.wikidot.com/instructions-set:in Pozeram to a tam je nastavovanie flagov popisane.Tam k tomu neni v podstate vubec nic... .) _dworkin píše: Takze se radeji znovu ujistim, delaji tyhle dva kody to same? Ano, tieto dva kody robia to iste. Maju sice iny pocet bajtov a trvaju iny cas, ale funkcionalita je taka ista.Kód: dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'TESTKEY IF' ld B, H ; 1:4 testkey if ( mask -- ) ld C, 0xFE ; 2:7 testkey if in A,(C) ; 2:12 testkey if and L ; 1:4 testkey if ex DE, HL ; 1:4 testkey if pop DE ; 1:10 testkey if jp nz, else101 ; 3:10 testkey if ; seconds: 0 ;[11:51] Kód: dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'TESTKEY IF' ld A, H ; 1:4 testkey if ( mask -- ) in A,(0xFE) ; 2:11 testkey if and L ; 1:4 testkey if ex DE, HL ; 1:4 testkey if pop DE ; 1:10 testkey if jp nz, else101 ; 3:10 testkey if ; seconds: 0 ;[ 9:43] _dworkin píše: A treba: Ano, aj tieto dva kody maju taku istu funkcionalitu.Kód: dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(__TESTKEY_Q) TESTKEY_ZF' ld BC, 0xFBFE ; 3:10 0xFB01 testkey ( -- ) set zf == press "Q" in A,(C) ; 2:12 0xFB01 testkey and 0x01 ; 2:7 0xFB01 testkey ; seconds: 1 ;[ 7:29] Kód: dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(__TESTKEY_Q) TESTKEY_ZF' ld A, 0xFB ; 2:7 0xFB01 testkey ( -- ) set zf == press "Q" in A,(0xFE) ; 2:11 0xFB01 testkey and 0x01 ; 2:7 0xFB01 testkey ; seconds: 0 ;[ 6:25] _dworkin píše: A jeste me dostalo, ze ta "in a,(c)" varianta je i pro jine registry nez "A" + jedna nedokumentovana co jen nastavuje priznaky. To jsem uplne zazdil. Obcas raz za cas je dobre si prejst cely instrukcny subor Z80. Je celkom vysoka sanca, ze tam objavis nejake poklady, ktore ti skratia (taktovo aj bajtovo) programatorsky zivot (resp. tu jeho cast ked pises a vykonavas program)
|
Autor: | _dworkin [ 28.05.2023, 13:17 ] |
Předmět příspěvku: | Re: Macro FORTH |
Diky za odpoved. Pro me byla dulezita ta cast ze ty kody jsou ekvivaletni, protoze jsem potreboval overit to ze "in A,(port)" posila do horniho bajtu portu "port" tu hodnotu co je v A a pak nasledne odpoved lezi zase v tom A. To je ta cast co nejak nemohu najit na tech webovych strankach. PS: Nakonec overeno 3x. https://www.zilog.com/docs/z80/um0080.pdf Příloha:
|
Autor: | Busy [ 28.05.2023, 20:56 ] |
Předmět příspěvku: | Re: Macro FORTH |
_dworkin píše: Diky za odpoved. Pro me byla dulezita ta cast ze ty kody jsou ekvivaletni, protoze jsem potreboval overit to ze "in A,(port)" posila do horniho bajtu portu "port" tu hodnotu co je v A a pak nasledne odpoved lezi zase v tom A. To je ta cast co nejak nemohu najit na tech webovych strankach. Ano. Uz som chcel napisat, preco pozeras vseliake stranky, ked oficialna dokumentacia od Zilog-a je volne dostupna
PS: Nakonec overeno 3x. |
Autor: | _dworkin [ 29.05.2023, 20:32 ] |
Předmět příspěvku: | Re: Macro FORTH |
Dodelal jsem ty testy klaves. Mel jsem k tomu jeste dve vyhrady. Jedna byla, co se stane kdyz nekdo bude chtit cist treba dvojici klaves najednou a mel jsem pocit, ze to nebude spravne fungovat. Kód: dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(__TESTKEY_P) TESTKEY' O a P dohromady:push DE ; 1:11 0xDF01 testkey ( -- bool ) true == press "P" ex DE, HL ; 1:4 0xDF01 testkey ld A, 0xDF ; 2:7 0xDF01 testkey in A,(0xFE) ; 2:11 0xDF01 testkey rrca ; 1:4 0xDF01 testkey ccf ; 1:4 0xDF01 testkey sbc HL, HL ; 2:15 0xDF01 testkey ; seconds: 0 ;[10:56] dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(__TESTKEY_O) TESTKEY' push DE ; 1:11 0xDF02 testkey ( -- bool ) true == press "O" ex DE, HL ; 1:4 0xDF02 testkey ld A, 0xDF ; 2:7 0xDF02 testkey in A,(0xFE) ; 2:11 0xDF02 testkey rrca ; 1:4 0xDF02 testkey rrca ; 1:4 0xDF02 testkey ccf ; 1:4 0xDF02 testkey sbc HL, HL ; 2:15 0xDF02 testkey ; seconds: 1 ;[11:60] Kód: dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(0xFE03) TESTKEY' push DE ; 1:11 0xFE03 testkey ( -- bool ) true == press "???" ex DE, HL ; 1:4 0xFE03 testkey ld A, 0xFE ; 2:7 0xFE03 testkey in A,(0xFE) ; 2:11 0xFE03 testkey and 0x03 ; 2:7 0xFE03 testkey sub 0x01 ; 2:7 0xFE03 testkey sbc HL, HL ; 2:15 0xFE03 testkey ; seconds: 0 ;[12:62] Ale diky tomu ze bitove je TRUE nula to funguje pekne, po "and maska" je nula jen v pripade, ze vsechny klavesy jsou stiskle. Kdyby to bylo naopak tak jeste musim udelat "cp maska" nebo jeste lepe "sub maska" a pak odcitat tu jednicku kvuli carry. Druhy problem jsem mel ze jsem sice udelal ty kombinace s IF, WHILE a UNTIL jak pro TESTKEY tak s PUSH_TESTKEY, ale... Co kdyz to nekdo bude chtit znegovat, neco jako IF NOT PRESS("Q") THEN... Tak se to najednou bude chovat neoptimalizovane. Bude se to prekladat samostatne jako slovo za slovem a to jen kvuli tomu, ze chci u jedne instrukce skoku otocit priznak... Hledal jsem jak se dela ve Forthu NOT, protoze jsem sklerotik a nic jsem nenasel. Nasel jsem teda INVERSE co otaci vsechny bity a funguje pro spravne udelany TRUE jako 0xFFFF a FALSE jako 0x0000, ale ne kdyz to true bude jako cokoliv od nuly. A pak jsem to nasel misto slova NOT se pouzije za podminkou slovo 0=, ktere dela presne co chci. Stejne jako <>0 dostane libovolnou hodnotu do 0xFFFF a 0x0000, tak 0= to navic otoci jako NOT (zneguje, ale pozor NEGATE je ve Forthu aritmeticke otoceni znamenka). Takze jsem udelal dalsich 7 slov pro: TESTKEY_0EQ TESTKEY_0EQ_IF TESTKEY_0EQ_WHILE TESTKEY_0EQ_UNTIL PUSH_TESTKEY_0EQ_IF PUSH_TESTKEY_0EQ_WHILE PUSH_TESTKEY_0EQ_UNTIL Pak jsem mel pocit, ze mam zase problem s temi kombinacemi klaves, zvlast u TESTKEY_0EQ. Kód: dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'TESTKEY _0EQ' ld A, H ; 1:4 testkey 0= ( mask -- bool ) in A,(0xFE) ; 2:11 testkey 0= and L ; 1:4 testkey 0= add A, 0xFF ; 2:7 testkey 0= sbc HL, HL ; 2:15 testkey 0= ; seconds: 0 ;[ 8:41] Ale i po testech to vypada dobre. Jen v pripade ze je vse zmackle tam po vymaskovani bude nula a pri pricteni 0xFF zadne carry nebude a vysledek bude FALSE. Dnes jsem pridal pomocne masky pro Sinclair1 a Sinclair2 a Cursor joysticky. Kdyz jsem se dival na ten Kempston tak je to jiny port a vysledek je navic TRUE je jednickovy bit. Krasne vynulovany nahore. Nez delat 5 novych slov, tak to radsi udelam slova co ctou a zapisuji na port. Forth standart asi na to nic nema... Tak jsem premyslel nad nazvem a napadlo me jen: FETCHPORT a STOREPORT To jsem nakonec otocil, protoze parametr je port, takze to vypada nejak takto: "port port@". Studoval jsem zas manual pro zapis na port a pokud se nepletu tak u "out (port),a" je neco jako "ld (256*a+port),a" mysleno ne jako adresa ale sbernice. Description The operand n is placed on the bottom half (A0 through A7) of the address bus to select the I/O device at one of 256 possible ports. The contents of the Accumulator (Register A) also appear on the top half (A8 through A15) of the address bus at this time. Then the byte contained in the Accumulator is placed on the data bus and written to the selected peripheral device. Coz je fakt divne mit to A vyuzito 2x. Pouzil jsem teda jinou variantu "out (c),e" Description The contents of Register C are placed on the bottom half (A0 through A7) of the address bus to select the I/O device at one of 256 possible ports. The contents of Register B are placed on the top half (A8 through A15) of the address bus at this time. Then the byte contained in register r is placed on the data bus and written to the selected peripheral device. Register r identifies any of the CPU registers shown in the following table, which also shows the corresponding three-bit r field for each that appears in the assembled object code. Kód: dnl # ( port -- char )
define({PORTFETCH},{dnl __{}__ADD_TOKEN({__TOKEN_PORTFETCH},{port@},$@){}dnl }){}dnl dnl define({__ASM_TOKEN_PORTFETCH},{dnl __{}define({__INFO},__COMPILE_INFO) __{} ld B, H ; 1:4 __INFO ( port -- char ) __{} ld C, L ; 1:4 __INFO __{} in L,(C) ; 2:12 __INFO __{} ld H, 0x00 ; 2:7 __INFO}){}dnl dnl dnl dnl dnl # ( char port -- ) define({PORTSTORE},{dnl __{}__ADD_TOKEN({__TOKEN_PORTSTORE},{port!},$@){}dnl }){}dnl dnl define({__ASM_TOKEN_PORTSTORE},{dnl __{}define({__INFO},__COMPILE_INFO) __{} ld B, H ; 1:4 __INFO ( char port -- ) __{} ld C, L ; 1:4 __INFO __{} out (C),E ; 2:12 __INFO __{} pop HL ; 1:10 __INFO __{} pop DE ; 1:10 __INFO}){}dnl dnl dnl dnl dnl # ( char port -- char port ) define({_2DUP_PORTSTORE},{dnl __{}__ADD_TOKEN({__TOKEN_2DUP_PORTSTORE},{2dup port!},$@){}dnl }){}dnl dnl define({__ASM_TOKEN_2DUP_PORTSTORE},{dnl __{}define({__INFO},__COMPILE_INFO) __{} ld B, H ; 1:4 __INFO ( char port -- char port ) __{} ld C, L ; 1:4 __INFO __{} out (C),E ; 2:12 __INFO}){}dnl dnl dnl dnl dnl # ( char port -- port ) define({TUCK_PORTSTORE},{dnl __{}__ADD_TOKEN({__TOKEN_TUCK_PORTSTORE},{tuck port!},$@){}dnl }){}dnl dnl define({__ASM_TOKEN_TUCK_PORTSTORE},{dnl __{}define({__INFO},__COMPILE_INFO) __{} ld B, H ; 1:4 __INFO ( char port -- port ) __{} ld C, L ; 1:4 __INFO __{} out (C),E ; 2:12 __INFO __{} pop DE ; 1:10 __INFO}){}dnl |
Autor: | _dworkin [ 29.05.2023, 21:56 ] |
Předmět příspěvku: | Re: Macro FORTH |
Jsem to zamluvil, ale pro to Forth slovo jsem hledal i nejaky ascii symbol, ktery se pouziva ve vyznamu PORT a na nic jsem nenarazil. Protoze ve Forthu by se s tim nebabrali a nahradili to jedinym znakem, coz pro interpret dava smysl. PS: Pro serial jsem nasel neco jako "10101" (vypada to spis jako "|O|Ol"), ale absolutne netusim jak je to v ZX a "port" je kratsi a nazornejsi. PPS: Jeste jsem to teda jeste mohl nazvat IN a OUT, ale to me prislo ze by to mohlo kolidovat. |
Autor: | Busy [ 30.05.2023, 14:19 ] |
Předmět příspěvku: | Re: Macro FORTH |
_dworkin píše: Kdyby to bylo naopak tak jeste musim udelat "cp maska" nebo jeste lepe "sub maska" a pak odcitat tu jednicku kvuli carry. Nemusis. Pouzijes OR masku a nasledne podobny postup len matematicka operacia bude inverzna.Kód: or %11111100 nastavi HL na -1 len ak boli obidva najnizsie bity jednotkove.add a,1 sbc hl,hl _dworkin píše: Studoval jsem zas manual pro zapis na port a pokud se nepletu tak u "out (port),a" je neco jako "ld (256*a+port),a" mysleno ne jako adresa ale sbernice. Ano, proste instrukcie IN/OUT s pevnou 8bit adresou ako vyssi bajt adresy davaju A. Pri IN je to velmi vhodne a prakticke, pri OUT je to trosku fakt divne.Coz je fakt divne mit to A vyuzito 2x. Ale ono je to obecne vzdy lepsie, nez povodna funkcionalita z Intelu 8080 - pri tychto instrukciach vyssi bajt adresy je proste kopiou nizsieho. Tam napr. OUT (#12),A zapise na port #1212 a podobne tak IN A,(#34) precita port #3434. Ak by takto fungovala Z80, tak minimalne klavesnica by musela byt urobena uplne inak (zlozitejsie). |
Autor: | _dworkin [ 02.06.2023, 21:35 ] |
Předmět příspěvku: | Re: Macro FORTH |
Zapracoval jsem na te podpore pro Kempston. Presneji jsem zapracoval na obecnem cteni z portu tak, aby se za urcitych podminek vysledny kod podobal tomu co by udelalo specializovane slovo. Musel jsem pridat podporu mnohem vice veci nez jsem myslel + neco jsem udelal dupicitne, protoze jsem to zapomnel predtim dopsat do readme. Takze jedna z veci co jsem potreboval je vetsi podpora 8 bitove aritmeticke a logicke operace. Pak tu zavrhovanou podporu pro priznaky. Prvne napisi vlastne jak to vypada kdyz nemam jedno slovo a musim to skladat z Forth slov. Kód: PUSH(0x1F) PORTFETCH PUSH(0xFF-2) COR _1CADD_ZF ZF_IF a) Prvni dve slova nactou do TOS hodnotu portu 0x001F. b) Dalsi dve slovo provedou 8 bitovy binarni OR c) 1c+ pricte 8 bitove jednicku a nastavi "zero flag". d) Pak uz muze navazovat cokoliv. add c) Je to mysleno tak ze ta operace odstrani z TOS hodnotu a nastavi specialni promennou zero_flag. To odstraneni je dulezite a musim skontrolovat zda to mam vsude. Kód: dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'AND' ld A, E ; 1:4 and ( x2 x1 -- x ) x = x2 & x1 and L ; 1:4 and ld L, A ; 1:4 and ld A, D ; 1:4 and and H ; 1:4 and ld H, A ; 1:4 and pop DE ; 1:10 and ; seconds: 0 ;[ 7:34] dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'AND_ZF' ld A, E ; 1:4 and ( x2 x1 -- ) set zf: x2 & x1 and L ; 1:4 and jr nz, $+4 ; 2:7/12 and ld A, D ; 1:4 and and H ; 1:4 and pop HL ; 1:10 and pop DE ; 1:10 and ; seconds: 0 ;[ 8:43] dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'OR' ld A, E ; 1:4 or ( x2 x1 -- x ) x = x2 | x1 or L ; 1:4 or ld L, A ; 1:4 or ld A, D ; 1:4 or or H ; 1:4 or ld H, A ; 1:4 or pop DE ; 1:10 or ; seconds: 0 ;[ 7:34] dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'OR_ZF' ld A, L ; 1:4 or ( x2 x1 -- ) set zf: x2 | x1 or H ; 1:4 or or D ; 1:4 or or E ; 1:4 or pop HL ; 1:10 or pop DE ; 1:10 or ; seconds: 0 ;[ 6:36] dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'XOR' ld A, E ; 1:4 xor ( x2 x1 -- x ) x = x2 ^ x1 xor L ; 1:4 xor ld L, A ; 1:4 xor ld A, D ; 1:4 xor xor H ; 1:4 xor ld H, A ; 1:4 xor pop DE ; 1:10 xor ; seconds: 0 ;[ 7:34] dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'XOR_ZF' or A ; 1:4 xor ( x2 x1 -- ) set zf: x2 ^ x1 sbc HL, DE ; 2:15 xor pop HL ; 1:10 xor pop DE ; 1:10 xor ; seconds: 0 ;[ 5:39] dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_1ADD' inc HL ; 1:6 1+ ; seconds: 0 ;[ 1:6] dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_1ADD_ZF' ld A, L ; 1:4 1+ zf ( x -- ) set zf: x + 1 and H ; 1:4 1+ zf inc A ; 1:4 1+ zf set zf ex DE, HL ; 1:4 1+ zf pop DE ; 1:10 1+ zf ; seconds: 0 ;[ 5:26] Pro muj pripad bylo dulezite mit podporu pro 8 bit (ciste kvuli efektivite) Kód: dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'CAND' ld A, E ; 1:4 cand ( x2 x1 -- x3 ) x3 = hi(x1) + lo(x2 & x1) and L ; 1:4 cand ld L, A ; 1:4 cand pop DE ; 1:10 cand ; seconds: 0 ;[ 4:22] dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'HAND' ld A, D ; 1:4 hand ( x2 x1 -- x3 ) x3 = hi(x2 & x1) + lo(x1) and H ; 1:4 hand ld H, A ; 1:4 hand pop DE ; 1:10 hand ; seconds: 0 ;[ 4:22] dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'COR' ld A, E ; 1:4 cor ( x2 x1 -- x3 ) x3 = hi(x1) + lo(x2 | x1) or L ; 1:4 cor ld L, A ; 1:4 cor pop DE ; 1:10 cor ; seconds: 0 ;[ 4:22] dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'HOR' ld A, D ; 1:4 hor ( x2 x1 -- x3 ) x3 = hi(x2 | x1) + lo(x1) or H ; 1:4 hor ld H, A ; 1:4 hor pop DE ; 1:10 hor ; seconds: 0 ;[ 4:22] dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'CXOR' ld A, E ; 1:4 cxor ( x2 x1 -- x3 ) x3 = hi(x1) + lo(x2 ^ x1) xor L ; 1:4 cxor ld L, A ; 1:4 cxor pop DE ; 1:10 cxor ; seconds: 0 ;[ 4:22] dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'HXOR' ld A, D ; 1:4 hxor ( x2 x1 -- x3 ) x3 = hi(x2 ^ x1) + lo(x1) xor H ; 1:4 hxor ld H, A ; 1:4 hxor pop DE ; 1:10 hxor ; seconds: 0 ;[ 4:22] Poznamka: Mozna stoji za povsimnuti ze ve vysledku je tech 8 bitu na ktere se nesaha kopii z x1, protoze je to snazsi o bajt a 4 takty. Ale pokud by na to nekomu zalezelo tak je lepsi reseni to mit z x2, protoze to je pravdepodobne ta neznama a x1 je pravdepodobne konstanta co to ovlivnuje. U vetsiny operaci to jde resit jednim SWAPem navic a kod bude o ten bajt a 4 takty delsi. Ale u odcitani to chce asi dalsi slovo... Koukam ze CADD, HADD, CUSB a HSUB vubec neukazuji, neva jen me to pripomnelo ze jsem tam mel chybu v instrukcich kdy jsem psal neco jako "sub A,L" misto "sub L", a protoze jsem to netestoval tak me pasmo nervalo ze tuhle kombinaci operandu i instrukce nezna. V puvodnim kodu jsem mel spatne popisky protoze... koukam ze je to tady stale blbe. Takze se kouknete treba na posledni HXOR a tam vidite, ze to HI zapominam vynasobit 256, aby to bylo zase 16 bitova hodnota. Porovnejte popis s timhle: Kód: dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_1CADD' inc L ; 1:4 1c+ ( x1 -- x2 ) x2 = 256*hi(x1) + lo(x1 + 1) ; seconds: 0 ;[ 1:4] dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_1CSUB' dec L ; 1:4 1c- ( x1 -- x2 ) x2 = 256*hi(x1) + lo(x1 - 1) ; seconds: 0 ;[ 1:4] dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_1HADD' inc H ; 1:4 1h+ ( x1 -- x2 ) x2 = x1 + 256 ; seconds: 1 ;[ 1:4] dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_1HSUB' dec H ; 1:4 1h- ( x1 -- x2 ) x2 = x1 - 256 ; seconds: 0 ;[ 1:4] No a ja jeste potrebuji to _ZF slovo. (Mozna to prejmenuji nakonec na _SETZ _SETC. I kdyz to druhe nedava presne smysl co to ma delat. Prvni je jako _0EQ_IF_SETZ_ELSE_RESZ_ENDIF, zkracene _SETZ). Jeste si vsimnete ze jsem otocil poradi u slov co to ctou na "ZF_IF". Kde to to ZF_ je neco jako if ZF=0 then TRUE else FALSE endif. Kód: dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_1CADD_ZF' inc L ; 1:4 1c+ zf ( x -- ) set zf: lo(x) c+ 1 ex DE, HL ; 1:4 1c+ zf pop DE ; 1:10 1c+ zf ; seconds: 0 ;[ 3:18] dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_1HADD_ZF' inc H ; 1:4 1h+ zf ( x -- ) set zf: hi(x) c+ 1 ex DE, HL ; 1:4 1h+ zf pop DE ; 1:10 1h+ zf ; seconds: 0 ;[ 3:18] dworkin@dw-A15:~/Programovani/ZX/ Pak jsem postupne pridaval podporu kombinaci slov jako: Kód: dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'OR _1ADD' ld A, E ; 1:4 or ( x2 x1 -- x ) x = x2 | x1 or L ; 1:4 or ld L, A ; 1:4 or ld A, D ; 1:4 or or H ; 1:4 or ld H, A ; 1:4 or pop DE ; 1:10 or inc HL ; 1:6 1+ ; seconds: 0 ;[ 8:40] dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'COR _1ADD' ld A, E ; 1:4 cor 1+ ( x2 x1 -- x3 ) x3 = hi(x1) + lo(x2 | x1) + 1 or L ; 1:4 cor 1+ ld L, A ; 1:4 cor 1+ inc HL ; 1:6 cor 1+ pop DE ; 1:10 cor 1+ ; seconds: 0 ;[ 5:28] dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'COR _1CADD' ld A, E ; 1:4 cor 1c+ ( x2 x1 -- x3 ) x3 = hi(x1) + lo((x2 | x1) + 1) or L ; 1:4 cor 1c+ inc A ; 1:4 cor 1c+ ld L, A ; 1:4 cor 1c+ pop DE ; 1:10 cor 1c+ ; seconds: 0 ;[ 5:26] a podporu prvni casti kde jsem to postupne pridval slovo za slovem. Kód: dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(0x1F) PORTFETCH' push DE ; 1:11 0x1F port@ ( -- char ) ex DE, HL ; 1:4 0x1F port@ xor A ; 1:4 0x1F port@ ld H, A ; 1:4 0x1F port@ in A,(0x1F) ; 2:11 0x1F port@ ld L, A ; 1:4 0x1F port@ ; seconds: 0 ;[ 7:38] dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(0x1F) PORTFETCH PUSH(0xFF-2)' push DE ; 1:11 0x1F port@ 0xFF-2 ( -- char 0xFF-2 ) push HL ; 1:11 0x1F port@ 0xFF-2 xor A ; 1:4 0x1F port@ 0xFF-2 ld D, A ; 1:4 0x1F port@ 0xFF-2 in A,(0x1F) ; 2:11 0x1F port@ 0xFF-2 ld E, A ; 1:4 0x1F port@ 0xFF-2 ld HL, 0x00FD ; 3:10 0x1F port@ 0xFF-2 ; seconds: 1 ;[10:55] To navazuje na Kód: dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'COR _1CADD_ZF' ld A, E ; 1:4 cor 1c+ zf ( x2 x1 -- ) set zf: lo(x2 | x1) c+ 1 or L ; 1:4 cor 1c+ zf inc A ; 1:4 cor 1c+ zf pop HL ; 1:10 cor 1c+ zf pop DE ; 1:10 cor 1c+ zf ; seconds: 41 ;[ 5:32] A dohromady dela: Kód: dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(0x1F) PORTFETCH PUSH(0xFF-2) COR _1CADD_ZF' xor A ; 1:4 0x1F port@ 0xFF-2 cor 1c+ zf ( -- ) set zf: port(0x1F) and 0xFF-2 in A,(0x1F) ; 2:11 0x1F port@ 0xFF-2 cor 1c+ zf or 0xFD ; 2:7 0x1F port@ 0xFF-2 cor 1c+ zf inc A ; 1:4 0x1F port@ 0xFF-2 cor 1c+ zf ; seconds: 0 ;[ 6:26] Kdyz to rozseknu: Kód: dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(0x1F) PORTFETCH PUSH(0xFF-2) __ASM COR _1CADD_ZF' push DE ; 1:11 0x1F port@ 0xFF-2 ( -- char 0xFF-2 ) push HL ; 1:11 0x1F port@ 0xFF-2 xor A ; 1:4 0x1F port@ 0xFF-2 ld D, A ; 1:4 0x1F port@ 0xFF-2 in A,(0x1F) ; 2:11 0x1F port@ 0xFF-2 ld E, A ; 1:4 0x1F port@ 0xFF-2 ld HL, 0x00FD ; 3:10 0x1F port@ 0xFF-2 ld A, E ; 1:4 cor 1c+ zf ( x2 x1 -- ) set zf: lo(x2 | x1) c+ 1 or L ; 1:4 cor 1c+ zf inc A ; 1:4 cor 1c+ zf pop HL ; 1:10 cor 1c+ zf pop DE ; 1:10 cor 1c+ zf ; seconds: 1 ;[15:87] Neco podobneho ale snazsiho je pro cteni jednoho bitu: Kód: dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(0x1F) PORTFETCH __ASM PUSH(0x04) AND' push DE ; 1:11 0x1F port@ ( -- char ) ex DE, HL ; 1:4 0x1F port@ xor A ; 1:4 0x1F port@ ld H, A ; 1:4 0x1F port@ in A,(0x1F) ; 2:11 0x1F port@ ld L, A ; 1:4 0x1F port@ ld A, 0x04 ; 2:7 0x04 and and L ; 1:4 0x04 and ld L, A ; 1:4 0x04 and ld H, 0x00 ; 2:7 0x04 and ; seconds: 0 ;[13:60] dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(0x1F) PORTFETCH PUSH(0x04) AND' push DE ; 1:11 0x1F port@ 0x04 and ( -- x ) x: port(0x1F) | 0x04 ex DE, HL ; 1:4 0x1F port@ 0x04 and ld HL, 0x0004 ; 3:10 0x1F port@ 0x04 and xor A ; 1:4 0x1F port@ 0x04 and in A,(0x1F) ; 2:11 0x1F port@ 0x04 and and L ; 1:4 0x1F port@ 0x04 and ld L, A ; 1:4 0x1F port@ 0x04 and ; seconds: 1 ;[10:48] dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(0x1F) PORTFETCH PUSH(0x04) AND_ZF' xor A ; 1:4 0x1F port@ 0x04 and ( -- ) set zf: port(0x1F) and 0x04 in A,(0x1F) ; 2:11 0x1F port@ 0x04 and and 0x04 ; 2:7 0x1F port@ 0x04 and ; seconds: 0 ;[ 5:22] dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ Tady je nakonec videt kdyz porovname jen vysledne kody: Kód: dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(0x1F) PORTFETCH PUSH(0xFF-4) COR _1CADD_ZF' xor A ; 1:4 0x1F port@ 0xFF-4 cor 1c+ zf ( -- ) set zf: port(0x1F) and 0xFF-4 in A,(0x1F) ; 2:11 0x1F port@ 0xFF-4 cor 1c+ zf or 0xFB ; 2:7 0x1F port@ 0xFF-4 cor 1c+ zf inc A ; 1:4 0x1F port@ 0xFF-4 cor 1c+ zf ; seconds: 0 ;[ 6:26] dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(0x1F) PORTFETCH PUSH(0x04) AND_ZF' xor A ; 1:4 0x1F port@ 0x04 and ( -- ) set zf: port(0x1F) and 0x04 in A,(0x1F) ; 2:11 0x1F port@ 0x04 and and 0x04 ; 2:7 0x1F port@ 0x04 and ; seconds: 1 ;[ 5:22] Ze precejenom je to nastaveni TRUE na bit 1 o neco pomalejsi nez nataveni na TRUE na 0 jako u klavesnice. O to jedno "inc A", ktere se musi davat navic pokud cteme vice "bitu". Porovnani pri cteni z klavesnice pres slovo co to testuje a pres port: Kód: dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(__TESTKEY_O) TESTKEY_ZF' ld A, 0xDF ; 2:7 0xDF02 testkey ( -- ) set zf == press "O" in A,(0xFE) ; 2:11 0xDF02 testkey and 0x02 ; 2:7 0xDF02 testkey ; seconds: 0 ;[ 6:25] dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(0xDFFE) PORTFETCH PUSH(0x02) AND_ZF' ld A, 0xDF ; 2:7 0xDFFE port@ 0x02 and ( -- ) set zf: port(0xDFFE) and 0x02 in A,(0xFE) ; 2:11 0xDFFE port@ 0x02 and and 0x02 ; 2:7 0xDFFE port@ 0x02 and ; seconds: 0 ;[ 6:25] TODO: Opravit ty komentare "H|C+log_op" Pridat optimalizace pro zapis jako DUP_ PUSH_ PUSH2_ + PORTSTORE. Mozna dokonce neco jako misto PUSH_PORTSTORE BC_PORTSTORE. Protoze nemam moc napad jak to udelat kdyz to nekdo chce mit vickrat za sebou (bez toho ze bych pouzil primo tu opakujici instrukci). Hmm... vlastne je asi lepsi na to mit slovo neco jako MOVE kopiruje z adresy na adresu u_word. Tak PORTMOVE? Jen by se jeste musel poresit nazev protoze jedno by kopirovalo na port od adresy n bunek/bajtu a druhe z portu cetlo n bunek/bajtu na adresu. To zni docela pouzitelne. Hmm.. ale asi bych musel jeste resit rychlost a vyporadat se z chybama cteni. Hmm... mozna to neni tak dobry napad, na to nemam kvalifikaci. .) |
Stránka 31 z 40 | Všechny časy jsou v UTC + 1 hodina [ Letní čas ] |
Powered by phpBB® Forum Software © phpBB Group http://www.phpbb.com/ |