OldComp.cz

Komunitní diskuzní fórum pro fanoušky historických počítačů


Právě je 28.03.2024, 23:39

Všechny časy jsou v UTC + 1 hodina [ Letní čas ]




Odeslat nové téma Odpovědět na téma  [ Příspěvků: 585 ]  Přejít na stránku Předchozí  1 ... 28, 29, 30, 31, 32, 33, 34 ... 39  Další
Autor Zpráva
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 24.05.2023, 03:48 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
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:
zx_keyboard_hw.png
zx_keyboard_hw.png [ 63.86 KiB | Zobrazeno 999 krát ]

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]

_________________
Z80 Forth compiler (ZX Spectrum 48kb): https://codeberg.org/DW0RKiN/M4_FORTH


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 24.05.2023, 06:43 
Offline
Óm Nejvyšší

Registrován: 22.05.2013, 21:14
Příspěvky: 3642
Bydliště: Bratislava
Has thanked: 371 times
Been thanked: 788 times
_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
Kód:
IN A,(0xFE)
tak me to cte vsech 8 radku najednou? Protoze neodesilam zadny horni bajt?
RTFM ! :)
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)
No moment moment. Aky teda musi byt vztah medzi HI a 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...
(alebo som odpoved v tej zaplave siahodlnych prispevkov iba prehliadol ?)


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 24.05.2023, 16:13 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
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)
No moment moment. Aky teda musi byt vztah medzi HI a 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.

_________________
Z80 Forth compiler (ZX Spectrum 48kb): https://codeberg.org/DW0RKiN/M4_FORTH


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 25.05.2023, 14:20 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
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.


Přílohy:
flag.png
flag.png [ 1.03 KiB | Zobrazeno 908 krát ]

_________________
Z80 Forth compiler (ZX Spectrum 48kb): https://codeberg.org/DW0RKiN/M4_FORTH
Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 25.05.2023, 15:31 
Online
Pan Štábní

Registrován: 11.11.2013, 10:29
Příspěvky: 1198
Has thanked: 360 times
Been thanked: 304 times
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 ;-)

_________________
Sharp MZ-800++, MZ-1500++, MZ-2500++, SM-B-80T, MK-14_replica, HP-85, ZX-80+replica, ZX81, ZX-Spectrum+replica++, PMI-80+replica, SAM coupe++, PMD-85-2A+3, Didaktik-M, SORD-M5, TI-57, TI-59+PC-100, TI99/4A, ZetaV2+ppp, ZX-uno, Petr


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 25.05.2023, 15:33 
Offline
Profík

Registrován: 26.11.2018, 16:59
Příspěvky: 580
Bydliště: Holešov
Has thanked: 13 times
Been thanked: 90 times
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


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 25.05.2023, 16:21 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
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

_________________
Z80 Forth compiler (ZX Spectrum 48kb): https://codeberg.org/DW0RKiN/M4_FORTH


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 28.05.2023, 03:23 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
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]

_________________
Z80 Forth compiler (ZX Spectrum 48kb): https://codeberg.org/DW0RKiN/M4_FORTH


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 28.05.2023, 09:47 
Offline
Óm Nejvyšší

Registrován: 22.05.2013, 21:14
Příspěvky: 3642
Bydliště: Bratislava
Has thanked: 371 times
Been thanked: 788 times
_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.
Ano, tato instrukcia IN A,(adresa) pochadza este z Intelu 8080 a ziadne priznaky nenastavuje.
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
Tam k tomu neni v podstate vubec nic... .)
Pozeram to a tam je nastavovanie flagov popisane.
_dworkin píše:
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]
Ano, tieto dva kody robia to iste. Maju sice iny pocet bajtov a trvaju iny cas, ale funkcionalita je taka ista.
_dworkin píše:
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]
Ano, aj tieto dva kody maju taku istu funkcionalitu.
_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) ;)


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 28.05.2023, 13:17 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
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:
in_a_(n).png
in_a_(n).png [ 31.62 KiB | Zobrazeno 727 krát ]

_________________
Z80 Forth compiler (ZX Spectrum 48kb): https://codeberg.org/DW0RKiN/M4_FORTH


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 28.05.2023, 20:56 
Offline
Óm Nejvyšší

Registrován: 22.05.2013, 21:14
Příspěvky: 3642
Bydliště: Bratislava
Has thanked: 371 times
Been thanked: 788 times
_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.

PS: Nakonec overeno 3x.
Ano. Uz som chcel napisat, preco pozeras vseliake stranky, ked oficialna dokumentacia od Zilog-a je volne dostupna :)


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 29.05.2023, 20:32 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
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'
    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]
O a P dohromady:
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

_________________
Z80 Forth compiler (ZX Spectrum 48kb): https://codeberg.org/DW0RKiN/M4_FORTH


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 29.05.2023, 21:56 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
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.

_________________
Z80 Forth compiler (ZX Spectrum 48kb): https://codeberg.org/DW0RKiN/M4_FORTH


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 30.05.2023, 14:19 
Offline
Óm Nejvyšší

Registrován: 22.05.2013, 21:14
Příspěvky: 3642
Bydliště: Bratislava
Has thanked: 371 times
Been thanked: 788 times
_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
add a,1
sbc hl,hl
nastavi HL na -1 len ak boli obidva najnizsie bity jednotkove.
_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.
Coz je fakt divne mit to A vyuzito 2x.
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.

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).


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 02.06.2023, 21:35 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
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. .)

_________________
Z80 Forth compiler (ZX Spectrum 48kb): https://codeberg.org/DW0RKiN/M4_FORTH


Nahoru
 Profil  
 
Zobrazit příspěvky za předchozí:  Seřadit podle  
Odeslat nové téma Odpovědět na téma  [ Příspěvků: 585 ]  Přejít na stránku Předchozí  1 ... 28, 29, 30, 31, 32, 33, 34 ... 39  Další

Všechny časy jsou v UTC + 1 hodina [ Letní čas ]


Kdo je online

Uživatelé procházející toto fórum: Žádní registrovaní uživatelé a 2 návštevníků


Nemůžete zakládat nová témata v tomto fóru
Nemůžete odpovídat v tomto fóru
Nemůžete upravovat své příspěvky v tomto fóru
Nemůžete mazat své příspěvky v tomto fóru
Nemůžete přikládat soubory v tomto fóru

Hledat:
Přejít na:  
Založeno na phpBB® Forum Software © phpBB Group
Český překlad – phpBB.cz