OldComp.cz

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


Právě je 28.03.2024, 14:06

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 ... 23, 24, 25, 26, 27, 28, 29 ... 39  Další
Autor Zpráva
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 09.12.2022, 06:48 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Opravil jsem soubor https://github.com/DW0RKiN/M4_FORTH/blob/master/M4/divmul/pdiv_mk1.m4
Ktery obsahuje makra na beznamenkove deleni konstantami.
Zapomel jsem ho totiz tokenizovat.
U toho jsem si pohral i s pravidlama tokenu.
Takze se to ted vola u nekterych konstant automaticky pokud predchozi hodnota je ukazatel, jinak se to pokusi spocitat v dobe kompilace (v tokenovych pravidlech).

Pak jsem si vyzkousel zkompilovat znovu nejaky testovaci soubor a dival se co se zmenilo a narazil na problem kdyz se snazite inkrementovat hodnotu ulozenou v pameti.
Příloha:
inc_ptr.png
inc_ptr.png [ 250.29 KiB | Zobrazeno 3274 krát ]

Chyba byla, ze jsem mel v pravidlech PUSH kdyz uz je to PUSHS. Takze se me to nemohlo spojit do __TOKEN_PUSH_FETCH_1ADD_PUSH_STORE.
Podival jsem se na generovany asembler dukladneji a trosku to prepsal u nekterch variant. Pridal jeste inkrementaci o 2 a pak rovnou jeste variantu kdy se to inkrementuje o jakekoliv cislo.
Příloha:
inc_ptr2.png
inc_ptr2.png [ 227.82 KiB | Zobrazeno 3274 krát ]

PS: hmmm... mam tam chybu v tom druhem obrazku. >>>...drow en a tjab ijutnemerknI<<<

_________________
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: 17.12.2022, 08:13 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Rozsiroval jsem podporu pro 8 bitove operace. Ale stale to trochu dre, protoze je M4 Forth v zakladu 16 bitovy. Je tezke uz jen zjistit jakou kombinaci slov musis zapsat, aby to udelalo neco co proste pri prepnuti do pohledu/mysleni ze programuji v asembleru mi nedela problemy.

Doiteroval jsem do faze ze slova ktera budou zacinat s C (jako Char, tak to ma Forth oficialne, jako ze D jako Double je 32 bitove, pokud je zaklad 16 bit), jsou 8 bitova a budou resit jen spodnich 8 bitu slova.
Slova co zacinaji na H budou jako s pocatecnim C, ale budou resit jen hornich 8 bitu slova.
S tim, ze obe varianty pomechaji ty ignorovane bity co uz bylo v TOS predtim.

Delal jsem ruzne CAND, HAND, COR, HOR, CXOR, HXOR, CADD, HADD, CSUB, HSUB, CEQ, HEQ,
ted jsem presel na unsigned pro jednoduchost
CULT, HULT, CULE, HULE, CUGE, HUGE, CUGT, HUGT
a ruzne to kombinoval to s OVER SWAP xxx, _2DUP.

Pak jsem premyslel jak zapsat ze chci napriklad udelat operaci mezi hornim a spodnim bajtem. A to sice zase jde ale ten zapis by byl uz neco jako napriklad OVER 8 RSHIFT AND...
Takze jsem se na to vybodl a udelal makro AND_8REG_8REG() ktere dela neco jako $1 = $1 and $2.

a protoze jsem to chtel trosku osetrit tak jsem tam prehodil makro co testuje zda vstup je validni jmeno registru...
To makro uz mam, ale nemel jsem tam IX a IY rozdelene na horni a spodni cast.
A protoze si uz nic nepamatuji a vim ze na tohle existuji 2 varianty zapisu tak jsem googlil co zere Pasmo. Nakonec jsem nic nenasel a rovnou si teda napsal testovaci program a koukam ze to asi bere IXL IXH atd.
Jen mi to ukazuje tohle...
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/Pasmo_test$ pasmo -d reg_name.asm smaz.bin
0000:DD7C   LD A, IXH
0002:DD7D   LD A, IXL
0004:DD65   LD IXH, L
Emiting raw binary from 0000 to 0005
dworkin@dw-A15:~/Programovani/ZX/Forth/Pasmo_test$ cat reg_name.asm


ld a,ixh
ld a,ixl
ld ixh,ixl
dworkin@dw-A15:~/Programovani/ZX/Forth/Pasmo_test$

To jsem fakt necekal a podle me je to spatne. Podle googlu asi taky. A pokud si vzpominam tak ty IX a IY varianty jsou proste HL varianty s "predponou", takze se nikdy nemohou IXL a IXH setkat s H,L,IYL,IYH. A IYL a IYH setkat s H,L,IXL,IXH. A musi se to prenaset pres dalsi registr.

Aktualizoval jsem teda __IS_REG na
Kód:
dnl # a  --> 1
dnl # Hl --> 1
dnl # aF --> 1
dnl # dh --> 0
dnl # ix --> 1
define({__IS_REG},{dnl
__{}eval(1+regexp({$1},{^\([a-eA-E]\|[Aa][Ff]\|[Bb][Cc]\|[Dd][Ee]\|[Hh][Ll]\|[Ii][Xx]\|[Ii][Xx][HhLl]\|[Ii][Yy]\|[Ii][Yy][HhLl]\)$}))}){}dnl

Pokud tam nekdo predhodi (HL,IXL) tak to ta funkce vezme, zarva az Pasmo.

_________________
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: 17.12.2022, 12:44 
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:
To makro uz mam, ale nemel jsem tam IX a IY rozdelene na horni a spodni cast.
A protoze si uz nic nepamatuji a vim ze na tohle existuji 2 varianty zapisu
Ono tych variant existuje viac. Ja osobne som sa stretol s tymito:
XH XL YH YL ... pouziva napr. MRS uz od roku 1986
HX LX HY LY ... pouziva napr. Prometeus od roku 1993
IXH IXL IYH IYL ... priamo na ZX som to v ziadnom asm nevidel

Cross asemblery (napr. sjasmplus, rasm) na viacbitoch obvykle podporuju vsetky tieto varianty. Pozeral som do PASMO dokumentacie ale tam nepisu ake varianty podporuje, predpokladam ze tiez vsetky. IXH,IXL je podla mna privela pismen a HX,LX mi pride dost odveci (to bolo ucelovo zavedene len kvoli tomu ze to usetrilo zopar bajtov v kompileri na ZX), preto by som navrhoval ako standart podporovat najstarsie a asi aj najpouzivanejsie XH,XL. Alebo idealne vsetky, ak to nie je problem ;)
_dworkin píše:
pokud si vzpominam tak ty IX a IY varianty jsou proste HL varianty s "predponou", takze se nikdy nemohou IXL a IXH setkat s H,L,IYL,IYH. A IYL a IYH setkat s H,L,IXL,IXH.
Ano, je to presne tak ako pises. Ak sa pred instrukciou nachadza bajt #DD tak sa v celej instrukcii namiesto HL pouzije IX (vratane jeho polovic) a podobne tak pri bajte #FD sa pouzije IY. S tym, ze ak sa jedna o akykolvek pristup do pameti cez (HL) tak toto sa zmeni na (IX+d) alebo (IY+d).

Z toho vyplyva, ze nie je mozne pouzivat v jednej instrukcii naraz HL aj IX alebo HL aj IY. Teda, az na jednu vynimku: Ak sa presuva H alebo L do/z pameti adresovanej (HL) tak toto (HL) sa zmeni na (IX+d) ale samotne H alebo L zostane. Napriklad LD H,(HL) sa zmeni na LD H,(IX+d). Proste, navrhari Z80 to urobili tak aby IX alebo IY mohli (indexovo) adresovat pamet a popri tom si mohol pouzivat vsetky bezne osembitove registre (ABCDEHL).

Dalsia vynimka je pri instrukciach po #CB. Ak sa pouzije kombinacia #DD #CB ... tak sa vzdy jedna o pristup do pameti (IX+d). A samozrejme podobne tak s IY.

A este, bajty #DD a #FD pred instrukciami sa odignoruju, ak je to instrukcia po #ED. Vtedy sa vzdy natvrdo pouziva HL. Teda nie je mozne urobit napr. LDIR tak aby cital z IX namiesto HL (co je podla mna velka skoda, pretoze take SBC IX,BC by sa sem-tam hodilo).

Pokial si nebudes isty tym ake instrukcie s IX/IY existuju, alebo ako sa vykona nejaka kombinacia prefixov, tak pozri do mojej tabulky instrukcii. Tam som zachytil vsetky mozne kombinacie prefixov a co dana kombinacia znamena.


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

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Busy dekuji za vysvetleni. Ty jsi uplna chodici encyklopedie, kloubouk dolu.
Ze jsi to jeste vsechno pamatujes, i kdyz to nepouzivas denne.

Pasmo bohuzel neumi jinou variantu nez I+X/Y+H/L.

Lol prave me napadlo ze jsem ten regularni vyraz mel napsat jinak...

Kód:
define({__IS_REG},{dnl
__{}eval(1+regexp({$1},{^\([a-eA-E]\|[Aa][Ff]\|[Bb][Cc]\|[Dd][Ee]\|[Hh][Ll]\|[Ii][Xx]\|[Ii][Xx][HhLl]\|[Ii][Yy]\|[Ii][Yy][HhLl]\)$}))}){}dnl


Kód:
define({__IS_REG},{dnl
__{}eval(1+regexp({$1},{^\([a-eA-E]\|[Aa][Ff]\|[Bb][Cc]\|[Dd][Ee]\|[Hh][Ll]\|[Ii][XxYy]\|[Ii][XxYy][HhLl]\)$}))}){}dnl


Kdyz jsem jako "relativne" maly dostal svuj prvni pocitac ZX Spectrum tak jsem nikoho neznal kdo by mel stejny pocitac. Ani jsem nechodil do zadneho krouzku, takze jak jsem to dostal tak jsem to mel i s temi kazetami co nekdo napiratil. Vubec nevim po kom jsem ho mel. Dostal jsem k tomu tu anglickou prirucku a pak jeste neco v cestine, kde byl vlastne preklad toho anglickeho manualu a jeste na konci neco o strojovem kodu. Ani to nebyla normalni kniha, vypadalo to jako delane pres kopirku. Zadny internet. Neco malo vychazelo v ABC, ale to byly spis jen hry v basicu pro ruzne typy osmibitu. To sis tak mohl krokovat, kdyz si nemel jeste zadny pocitac...
A ted se proste zeptam a dalsi den me odpovis ty... a to nemluvim ani o internetu. To se neda porovnat.

Mimochodem si pamatuji ten den kdy jsem sel na konci skolniho roku ze zakladky s jeste s jednim spoluzakem na navstevu k spoluzakovi, ktery nam nebohym co zadny pocitac nemeli predvadel nejake hry na Amize 500. Muslim ze to byl Turrican. A ukazoval nam jak je v te hre koule a ze ostatni pocitace maji jen kruh a tady je to fakt vystinovane a jaky to ma super zvuk a ze Amiga 500 je proste uplne nejlepsi pocitac na svete a ostatni jsou srot.
Prijdu domu a tam v mem pokoji hraje soused z vedlejsiho vchodu na ZX Spectru pomoci joysticku NODES OF YESOD. Ja mam pocitac. Wow! A neni to tak hrozne, ta hra vypadala dobre. .))) Navic Merkur byl cernobily takze nejaka barevnost se moc neresila. To ze ma ZX Spectrum nejake omezeni jsem ani netusil. Dalsi den jsem odjizdel na pionyrsky tabor a kdyz jsem se vratil tak uz ZX Spectrum moc nejel. .))) Soused odpalil jednu pamet, takze slo nahrat jen jednodussi kratke hry. I kdyz jsem zkousel vsechno, hru za hrou. To byl duvod proc jsem nez se to opravilo zacal si vic hrat z basicem nez jen skoncil u load "". Sorry za oftopic.

_________________
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: 18.12.2022, 09:14 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Oprava [a-eA-E] na [a-ehA-EH]

_________________
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: 19.12.2022, 04:13 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Opravena chyba v PUSH_LSHIFT a PUSH_RSHIFT, kde se me volalo _1LSHIFT atd. misto __ASM_TOKEN_1LSHIFT atd.

Pridal jsem par dalsich slov s predponou H. Teda se zamerenim na osmibite cisla a to vzdy horni bajt.

Vcetne _2DUP_HSTORE.
Normalni FORTH by to resil pres "OVER 8 RSHIFT OVER C!", ktere zduplikuje posledni 2 polozky na zasobniku "number address" a jeste posune number o 8 bitu doprava, takze C! pak uklada hi(number).
Pro srandu jsem to pridal i do tokenovych pravidel... .)
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'OVER PUSH(8) RSHIFT OVER CSTORE __SHOW_TOKEN(1)'
; name: __TOKEN_2DUP_HSTORE
; info: over 8 rshift over c!
;items: 0
;param: ()
                        ;[1:7]      over 8 rshift over c!   ( x addr -- x addr )
    ld  (HL),D          ; 1:7       over 8 rshift over c!
; seconds: 1           ;[ 1:7]

__SHOW_TOKEN(1) ukazuje jake skutecne slovo co to vola, protoze informace za kodem jsou delane z toho co se tam vlozilo ze zdrojaku.

Uploadnu to az zitra rano.

PS: Jinak jak jsem postupne kopicoval C slova a menil je na H slova tak to nejde udelat uplne symetricky. Teda jde, ale nedava to smysl. Kdyz mate slovo "PUSH(char) OVER CSTORE", ktere sebere ze zasobniku adresu a tu zachova a ulozi "char" co mu predlozite tak je to nesmysl delat i pro H verzi.

PPS: Opravil jsem vsechny (doufam) CLE, CGE, HLE, HGE varianty vcetne s kombinaci SWAP OVER atd. Mel jsem tam vsude nastavovane carry, ale misto SBC jsem pouzival stale SUB.

_________________
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.12.2022, 03:30 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Příjemné prožití svátků vánočních, mnoho štěstí, pevné zdraví a spoustu osobních i pracovních úspěchů v novém roce.

PS: Hral jsem si s programky ve slozce benchmark, snazil jsem se v nich ruzne rozsekat ty spojene slova, zda to uz kompiler zvladne najit sam v tokenocych pravidlech. U toho jsem zjistil test pro vypocet Fibonaciho cisla je vlastne spatne a pocita vzdy o hodnotu o jedna vys. Ale je to tak uz v originalnim zdroji. Vcetne C varianty, tak jsem to tak nechal. Na netu jsem nasel i pro vypocet pro hodnotu 40, ale na to potrebujete 32 bit. Tak jsem to zkusil napsat pomoci double a to jsem nemel delat.. .) Protoze jsem zjistil ze tam me to nechtelo spojivat slova. Hlavni problem byl ze ty slova jsou stale psany pro PUSHDOT, neboli vkladane cislo co je 32 bitove a ne pro PUSH2, teda dve 16 bitove cisla, ktere tvori jedno 32 bitove. A prepsani neni tak snadne, protoze tam vznikaji nejake moznosti co jedno cislo, ukazatel nebo nazev promenne nemaji.

A jeste ke vsemu jsem nasel nejake chyby v kodu i u pushdot kdyz jsem se na to dival. Hodil jsem k tomu zatim jen komentar.

Tady to je... darecek... vanocni chyba... :D
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_2DUP_PUSH2_DEQ(0x2100,0x3345)'
if 0
; price: 2556
               ;[20:88/60,78,88,88]_TMP_STACK_INFO
    ld    A, 0x45       ; 2:7       2dup 0x2100 0x3345 d=
    cp    L             ; 1:4       2dup 0x2100 0x3345 d=   x[1] = 0x45
    jr   nz, $+11       ; 2:7/12    2dup 0x2100 0x3345 d=
    ld    A, 0x33       ; 2:7       2dup 0x2100 0x3345 d=
    cp    H             ; 1:4       2dup 0x2100 0x3345 d=   x[2] = 0x33
    jr   nz, $+6        ; 2:7/12    2dup 0x2100 0x3345 d=
    ld    A, 0x21       ; 2:7       2dup 0x2100 0x3345 d=
    xor   D             ; 1:4       2dup 0x2100 0x3345 d=   x[3] = 0x21
    or    E             ; 1:4       2dup 0x2100 0x3345 d=   x[4] = 0
    sub 0x01            ; 2:7       2dup 0x2100 0x3345 d=
    ex   DE, HL         ; 1:4       2dup 0x2100 0x3345 d=
    push HL             ; 1:11      2dup 0x2100 0x3345 d=
    sbc  HL, HL         ; 2:15      2dup 0x2100 0x3345 d=   set flag d1==0x21003345
else
; price: 2440
                     ;[18:88/57,89] 2dup 0x2100 0x3345 d=   ( d1 -- d1 flag )
    ex   DE, HL         ; 1:4       2dup 0x2100 0x3345 d=   # 3th byte zero
    push HL             ; 1:11      2dup 0x2100 0x3345 d=
    ld    A, 0x21       ; 2:7       2dup 0x2100 0x3345 d=
    xor   H             ; 1:4       2dup 0x2100 0x3345 d=   H = 0x21
    or    L             ; 1:4       2dup 0x2100 0x3345 d=   L = 0
    jr   nz, $+10       ; 2:7/12    2dup 0x2100 0x3345 d=
    ld   HL, 0x3345     ; 3:10      2dup 0x2100 0x3345 d=   lo16(0x21003345)
    sbc  HL, DE         ; 2:15      2dup 0x2100 0x3345 d=   HL-lo16(d1)
    jr   nz, $+3        ; 2:7/12    2dup 0x2100 0x3345 d=
    scf                 ; 1:4       2dup 0x2100 0x3345 d=
    sbc  HL, HL         ; 2:15      2dup 0x2100 0x3345 d=   set flag d1==0x21003345
endif
; seconds: 0           ;[38:176]

Problem je ze kdyz tu chybu odstranim tak tu optimalizovanou variantu rovnou muzu zrusit, protoze je pak efektivnejsi uz neco jineho. Nenapada me jak to spravit tak aby to bylo stale "elegantni"...

Napoveda:
jr nz, $+3 ; 2:7/12 2dup 0x2100 0x3345 d= <-- error! 50% carry
...konec napovedy.

Pokud pouzivate Dark reader tak smula... .)

PPS: Tohle je jedine co me zatim napadlo
Kód:
                     ;[19:92/57,92] 2dup 0x2100 0x3345 d=   ( d1 -- d1 flag )
    ex   DE, HL         ; 1:4       2dup 0x2100 0x3345 d=   # 3th byte zero
    push HL             ; 1:11      2dup 0x2100 0x3345 d=
    ld    A, 0x21       ; 2:7       2dup 0x2100 0x3345 d=
    xor   H             ; 1:4       2dup 0x2100 0x3345 d=   H = 0x21
    or    L             ; 1:4       2dup 0x2100 0x3345 d=   L = 0
    jr   nz, $+11       ; 2:7/12    2dup 0x2100 0x3345 d=
    ld   HL, 0x3345     ; 3:10      2dup 0x2100 0x3345 d=   lo16(0x21003345)
    sbc  HL, DE         ; 2:15      2dup 0x2100 0x3345 d=   HL-lo16(d1)
    ld    A, H          ; 1:4       2dup 0x2100 0x3345 d=
    or    L             ; 1:4       2dup 0x2100 0x3345 d=
    sub  0x01           ; 2:7       2dup 0x2100 0x3345 d=
    sbc  HL, HL         ; 2:15      2dup 0x2100 0x3345 d=   set flag d1==0x21003345

                     ;[20:89/54,89] 2dup 0x2100 0x3345 d=   ( d1 -- d1 flag )
    ex   DE, HL         ; 1:4       2dup 0x2100 0x3345 d=   # 3th byte zero
    push HL             ; 1:11      2dup 0x2100 0x3345 d=
    ld    A, 0x21       ; 2:7       2dup 0x2100 0x3345 d=
    xor   H             ; 1:4       2dup 0x2100 0x3345 d=   H = 0x21
    or    L             ; 1:4       2dup 0x2100 0x3345 d=   L = 0
    jr   nz, $+11       ; 2:7/12    2dup 0x2100 0x3345 d=
    ld   HL, 0x3345     ; 3:10      2dup 0x2100 0x3345 d=   lo16(0x21003345)
    sbc  HL, DE         ; 2:15      2dup 0x2100 0x3345 d=   HL-lo16(d1)
    ld    A, H          ; 1:4       2dup 0x2100 0x3345 d=
    or    L             ; 1:4       2dup 0x2100 0x3345 d=
    sub  0x01           ; 2:7       2dup 0x2100 0x3345 d=
    sbc   A, A          ; 1:4       2dup 0x2100 0x3345 d=
    ld    H, A          ; 1:4       2dup 0x2100 0x3345 d=
    ld    L, A          ; 1:4       2dup 0x2100 0x3345 d=   set flag d1==0x21003345

                  ;[21:92/57,75,93] 2dup 0x2100 0x3345 d=   ( d1 -- d1 flag )
    ex   DE, HL         ; 1:4       2dup 0x2100 0x3345 d=   # 3th byte zero
    push HL             ; 1:11      2dup 0x2100 0x3345 d=
    ld    A, 0x21       ; 2:7       2dup 0x2100 0x3345 d=
    xor   H             ; 1:4       2dup 0x2100 0x3345 d=   H = 0x21
    or    L             ; 1:4       2dup 0x2100 0x3345 d=   L = 0
    jr   nz, $+13       ; 2:7/12    2dup 0x2100 0x3345 d=
    ld    A, 0x45       ; 2:7       2dup 0x2100 0x3345 d=
    xor   L             ; 1:4       2dup 0x2100 0x3345 d=   L = 0x45
    jr   nz, $+8        ; 2:7/12    2dup 0x2100 0x3345 d=
    ld    A, 0x33       ; 2:7       2dup 0x2100 0x3345 d=
    xor   H             ; 1:4       2dup 0x2100 0x3345 d=   H = 0x33
    jr   nz, $+3        ; 2:7/12    2dup 0x2100 0x3345 d=
    scf                 ; 1:4       2dup 0x2100 0x3345 d=
    sbc  HL, HL         ; 2:15      2dup 0x2100 0x3345 d=   set flag d1==0x21003345
   
                  ;[22:88/53,71,89] 2dup 0x2100 0x3345 d=   ( d1 -- d1 flag )
    ex   DE, HL         ; 1:4       2dup 0x2100 0x3345 d=   # 3th byte zero
    push HL             ; 1:11      2dup 0x2100 0x3345 d=
    ld    A, 0x21       ; 2:7       2dup 0x2100 0x3345 d=
    xor   H             ; 1:4       2dup 0x2100 0x3345 d=   H = 0x21
    or    L             ; 1:4       2dup 0x2100 0x3345 d=   L = 0
    ld    L, 0x00       ; 2:7       2dup 0x2100 0x3345 d=   L = 0
    jr   nz, $+13       ; 2:7/12    2dup 0x2100 0x3345 d=
    ld    A, 0x45       ; 2:7       2dup 0x2100 0x3345 d=
    xor   L             ; 1:4       2dup 0x2100 0x3345 d=   L = 0x45
    jr   nz, $+8        ; 2:7/12    2dup 0x2100 0x3345 d=
    ld    A, 0x33       ; 2:7       2dup 0x2100 0x3345 d=
    xor   H             ; 1:4       2dup 0x2100 0x3345 d=   H = 0x33
    jr   nz, $+3        ; 2:7/12    2dup 0x2100 0x3345 d=
    dec   L             ; 1:4       2dup 0x2100 0x3345 d=
    ld    H, L          ; 1:4       2dup 0x2100 0x3345 d=   set flag d1==0x21003345

_________________
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.12.2022, 05:31 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Mozna tohle... ?
Kód:
                     ;[19:82/57,84] 2dup 0x2100 0x3345 d=   ( d1 -- d1 flag )
    ex   DE, HL         ; 1:4       2dup 0x2100 0x3345 d=   # 3th byte zero
    push HL             ; 1:11      2dup 0x2100 0x3345 d=
    ld    A, 0x21       ; 2:7       2dup 0x2100 0x3345 d=
    xor   H             ; 1:4       2dup 0x2100 0x3345 d=   H = 0x21
    or    L             ; 1:4       2dup 0x2100 0x3345 d=   L = 0
    jr   nz, $+9        ; 2:7/12    2dup 0x2100 0x3345 d=
    ld   HL, 0x3345     ; 3:10      2dup 0x2100 0x3345 d=   lo16(0x21003345)
    sbc  HL, DE         ; 2:15      2dup 0x2100 0x3345 d=   HL-lo16(d1)
    jr    z, $+4        ; 2:7/12    2dup 0x2100 0x3345 d=
    ld    L, 0x01       ; 2:7       2dup 0x2100 0x3345 d=
    dec   L             ; 1:4       2dup 0x2100 0x3345 d=
    ld    H, L          ; 1:4       2dup 0x2100 0x3345 d=   set flag d1==0x21003345

Sice je to o bajt delsi, ale je to jeste rychlejsi jako ta vadna 18 bajtova varianta a pokud bych pocital cenu tak me vyjde 2436, takze je to jeste levnejsi...

_________________
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.12.2022, 07:14 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Zkousim si plny optimizmu napsat jako jedno slovo tuhle cast kodu co se hodi pro vypocet fibonaciho cisla.
Chci jen prohodit dve 32 bitove cisla a secist je tak, ze prvni cislo se zachova. Takze chci udelat prohozeni "2swap" a pak udelat kopii DNOS "2over" a pak to secist "d+".
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_2SWAP _2OVER DADD'
                        ;[6:67]     2swap   ( d c b a -- b a d c ) # default version can be changed with "define({TYP_2SWAP},{name})", name=fast
    ex  (SP),HL         ; 1:19      2swap   d a . b c
    ex   DE, HL         ; 1:4       2swap   d a . c b
    pop  AF             ; 1:10      2swap   d   . c b     AF = a
    ex  (SP),HL         ; 1:19      2swap   b   . c d
    ex   DE, HL         ; 1:4       2swap   b   . d c
    push AF             ; 1:11      2swap   b a . d c
                        ;[9:93]     2over D+   ( hi2 lo2 hi1 lo1 -- hi2 lo2 hi1+hi2+carry lo1+lo2 )
    pop  BC             ; 1:10      2over D+   lo2
    add  HL, BC         ; 1:11      2over D+
    ex  (SP),HL         ; 1:19      2over D+   hi2
    ex   DE, HL         ; 1:4       2over D+
    adc  HL, DE         ; 2:15      2over D+
    ex   DE, HL         ; 1:4       2over D+
    ex  (SP),HL         ; 1:19      2over D+
    push BC             ; 1:11      2over D+
; seconds: 0           ;[15:160]

Prvni iterace vypada takhle
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_2SWAP_2OVER_DADD'
                        ;[17:123]   2swap 2over d+   ( d2 d1 -- d1 d3 )  d3 = d2 + d1
    ex   DE, HL         ; 1:4       2swap 2over d+   h2 l2 . l1 h1
    ld    C, L          ; 1:4       2swap 2over d+   
    ld    B, H          ; 1:4       2swap 2over d+   h2 l2 . l1 h1   BC = h1
    pop  HL             ; 1:10      2swap 2over d+   h2    . l1 l2   BC = h1
    add  HL, DE         ; 1:11      2swap 2over d+   h2    . l1 l3   BC = h1
    ex  (SP),HL         ; 1:19      2swap 2over d+   l3    . l1 h2   BC = h1
    adc  HL, BC         ; 2:15      2swap 2over d+   l3    . l1 h3   BC = h1
    ld    A, L          ; 1:4       2swap 2over d+
    ex   AF, AF'        ; 1:4       2swap 2over d+
    ld    A, H          ; 1:4       2swap 2over d+
    pop  HL             ; 1:10      2swap 2over d+         . l1 l3   BC = h1
    push BC             ; 1:11      2swap 2over d+   h1    . l1 l3   BC = h1
    push DE             ; 1:11      2swap 2over d+   h1 l1 . l1 l3   BC = h1
    ld    D, A          ; 1:4       2swap 2over d+
    ex   AF, AF'        ; 1:4       2swap 2over d+
    ld    E, A          ; 1:4       2swap 2over d+   h1 l1 . h3 l3   BC = h1
; seconds: 0           ;[17:123]

Zkousim to dal, ale vylepseni je jen nepatrne
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_z2SWAP_2OVER_DADD'
                        ;[16:119]   2swap 2over d+   ( d2 d1 -- d1 d3 )  d3 = d2 + d1
    ex   DE, HL         ; 1:4       2swap 2over d+   h2 l2 . l1 h1
    ex  (SP),HL         ; 1:19      2swap 2over d+   h2 h1 . l1 l2
    add  HL, DE         ; 1:11      2swap 2over d+   h2 h1 . l1 l3
    ld    A, L          ; 1:4       2swap 2over d+
    ex   AF, AF'        ; 1:4       2swap 2over d+
    ld    A, H          ; 1:4       2swap 2over d+
    pop  BC             ; 1:10      2swap 2over d+   h2 -- . l1 l3   BC = h1
    pop  HL             ; 1:10      2swap 2over d+   -- -- . l1 h2   BC = h1
    push BC             ; 1:11      2swap 2over d+   h1 -- . l1 h2   BC = h1
    push DE             ; 1:11      2swap 2over d+   h1 l1 . l1 h2   BC = h1
    ld    D, A          ; 1:4       2swap 2over d+
    ex   AF, AF'        ; 1:4       2swap 2over d+
    ld    E, A          ; 1:4       2swap 2over d+   h1 l1 . l3 h2   BC = h1
    adc  HL, BC         ; 2:15      2swap 2over d+   h1 l1 . l3 h3   BC = h1   
    ex   DE, HL         ; 1:4       2swap 2over d+   h1 l1 . h3 l3   BC = h1
; seconds: 0           ;[16:119]

A pak uz to nejde, at presouvam hodnoty kam chci tak si jen podrazim nohy...

Tak vyzkousim opacnou kombinaci. Secist to se zachovanim DNOS a pak prohodit.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_2OVER DADD _2SWAP'
                        ;[9:93]     2over d+   ( hi2 lo2 hi1 lo1 -- hi2 lo2 hi1+hi2+carry lo1+lo2 )
    pop  BC             ; 1:10      2over d+   lo2
    add  HL, BC         ; 1:11      2over d+
    ex  (SP),HL         ; 1:19      2over d+   hi2
    ex   DE, HL         ; 1:4       2over d+
    adc  HL, DE         ; 2:15      2over d+
    ex   DE, HL         ; 1:4       2over d+
    ex  (SP),HL         ; 1:19      2over d+
    push BC             ; 1:11      2over d+
                        ;[6:67]     2swap   ( d c b a -- b a d c ) # default version can be changed with "define({TYP_2SWAP},{name})", name=fast
    ex  (SP),HL         ; 1:19      2swap   d a . b c
    ex   DE, HL         ; 1:4       2swap   d a . c b
    pop  AF             ; 1:10      2swap   d   . c b     AF = a
    ex  (SP),HL         ; 1:19      2swap   b   . c d
    ex   DE, HL         ; 1:4       2swap   b   . d c
    push AF             ; 1:11      2swap   b a . d c
; seconds: 0           ;[15:160]


A tady se me to podari spojit hned napoprve uplne dokonale, vse do sebe pekne zapada a je na spravnych mistech ani nevim jak...
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_2OVER_DADD_2SWAP'
                        ;[10:97]    2over d+ 2swap   ( d2 d1 -- d3 d2 )  d3 = d2 + d1
    pop  BC             ; 1:10      2over d+ 2swap   h2 -- . h1 l1   BC = l2                       
    add  HL, BC         ; 1:11      2over d+ 2swap   h2 -- . h1 l3   BC = l2
    ex  (SP),HL         ; 1:19      2over d+ 2swap   l3 -- . h1 h2   BC = l2
    ex   DE, HL         ; 1:4       2over d+ 2swap   l3 -- . h2 h1   BC = l2
    adc  HL, DE         ; 2:15      2over d+ 2swap   l3 -- . h2 h3   BC = l2
    ex  (SP),HL         ; 1:19      2over d+ 2swap   h3 -- . h2 l3   BC = l2
    push HL             ; 1:11      2over d+ 2swap   h3 l3 . h2 l3   BC = l2
    ld    L, C          ; 1:4       2over d+ 2swap
    ld    H, B          ; 1:4       2over d+ 2swap   h3 l3 . h2 l2
; seconds: 0           ;[10:97]


Tak vezmu tenhle kod a vyzkousim ho pro prvni pripad a ono to zase krasne funguje!
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_2SWAP_2OVER_DADD'
                        ;[10:97]   2swap 2over d+   ( d2 d1 -- d1 d3 )  d3 = d2 + d1
    ld    C, L          ; 1:4       2swap 2over d+
    ld    B, H          ; 1:4       2swap 2over d+   h2 l2 . h1 l1   BC = l1
    pop  HL             ; 1:10      2swap 2over d+   h2 -- . h1 l2   BC = l1                       
    add  HL, BC         ; 1:11      2swap 2over d+   h2 -- . h1 l3   BC = l1
    ex  (SP),HL         ; 1:19      2swap 2over d+   l3 -- . h1 h2   BC = l1
    adc  HL, DE         ; 2:15      2swap 2over d+   l3 -- . h1 h3   BC = l1
    ex   DE, HL         ; 1:4       2swap 2over d+   l3 -- . h3 h1   BC = l1
    ex  (SP),HL         ; 1:19      2swap 2over d+   h1 -- . h3 l3   BC = l1
    push BC             ; 1:11      2swap 2over d+   h1 l1 . h3 l3   BC = l1
; seconds: 0           ;[10:97]

Vubec nechapu jak to delam, pripomina mi to sachy. Nejaky vzory nauceny, natrenovany, nejake obecne poucky, ale zbytek je proste pracne pocitani a kombinovani do hloubky. A kdyz zvolite na zacatku spatny tah tak to pak nejde... A pritom jsem na to sel uz napoprve dobre, ze jsem si udelal kopii do BC, jen jsem nemel delat to ex DE,HL... a pak jsem se to snazil odstranit, protoze je to kopirovani pracne, ale v konecnem dusledku to usetrilo hodne rezie jinde.

PS: A jeste vtipnejsi je, ze je to jen 9 instrukci za sebou a presto to da dost zabrat.

_________________
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.12.2022, 08:36 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Funkce pro (rychly) vypocet Fibonaciho cisla (bez tabulky) vypada takto
Kód:
    COLON(dfib,( u -- d ))   

        PUSH(0) SWAP
        PUSH(0) SWAP
        PUSH(0) SWAP
        PUSH(1) SWAP
   
        QUESTIONFOR
            _2OVER DADD _2SWAP
        NEXT
        _2NIP
    SEMICOLON


To push swap je trochu bolest, potrebuji ulozit na zasobnik dve double hodnoty. Takze 4 krat 16bit a pritom si zachovat hodnotu v TOS, co ma byt unsigned 16 bitova hodnota jaky clen/rad/stupen? fibonaciho cisla chci. Protoze ?FOR si ten TOS nacte.

Normalni program ve FORTHu by to resil tak ze by si ten TOS ulozil docasne do RAS, ale to je nejhorsi reseni pro moji implementaci.
Kód:
>R 0. 1. R>


Kód:
;   ---  the beginning of a non-recursive function  ---
dfib:                   ;           ( u -- d )
    pop  BC             ; 1:10      : ret
    ld  (dfib_end+1),BC ; 4:20      : ( ret -- )
    push DE             ; 1:11      0 swap 0 swap 0 swap 1 swap   ( x -- 0 0 0 1 x )
    ld   DE, 0          ; 3:10      0 swap 0 swap 0 swap 1 swap
    push DE             ; 1:11      0 swap 0 swap 0 swap 1 swap
    push DE             ; 1:11      0 swap 0 swap 0 swap 1 swap
    push DE             ; 1:11      0 swap 0 swap 0 swap 1 swap
    inc   E             ; 1:4       0 swap 0 swap 0 swap 1 swap
    ld    B, H          ; 1:4       ?for_101
    ld    C, L          ; 1:4       ?for_101
    ex   DE, HL         ; 1:4       ?for_101
    pop  DE             ; 1:10      ?for_101   index
    ld    A, B          ; 1:4       ?for_101
    and   C             ; 1:4       ?for_101
    inc   A             ; 1:4       ?for_101
    jp    z, leave101   ; 3:10      ?for_101   ( index -- )
for101:                 ;           ?for_101
    ld  (idx101),BC     ; 4:20      ?for_101   save index
                        ;[10:97]    2over d+ 2swap   ( d2 d1 -- d3 d2 )  d3 = d2 + d1
    pop  BC             ; 1:10      2over d+ 2swap   h2 -- . h1 l1   BC = l2                       
    add  HL, BC         ; 1:11      2over d+ 2swap   h2 -- . h1 l3   BC = l2
    ex  (SP),HL         ; 1:19      2over d+ 2swap   l3 -- . h1 h2   BC = l2
    ex   DE, HL         ; 1:4       2over d+ 2swap   l3 -- . h2 h1   BC = l2
    adc  HL, DE         ; 2:15      2over d+ 2swap   l3 -- . h2 h3   BC = l2
    ex  (SP),HL         ; 1:19      2over d+ 2swap   h3 -- . h2 l3   BC = l2
    push HL             ; 1:11      2over d+ 2swap   h3 l3 . h2 l3   BC = l2
    ld    L, C          ; 1:4       2over d+ 2swap
    ld    H, B          ; 1:4       2over d+ 2swap   h3 l3 . h2 l2
idx101 EQU $+1          ;           next_101
    ld   BC, 0x0000     ; 3:10      next_101   idx always points to a 16-bit index
    ld    A, B          ; 1:4       next_101
    or    C             ; 1:4       next_101
    dec  BC             ; 1:6       next_101   index--, zero flag unaffected
    jp   nz, for101     ; 3:10      next_101
leave101:               ;           next_101
    pop  AF             ; 1:10      2nip   ( d c b a -- b a )
    pop  AF             ; 1:10      2nip
dfib_end:
    jp   0x0000         ; 3:10      ;
;   ---------  end of non-recursive function  ---------


PS: Opravil jsem chybu v ?FOR, kde se snazil skakat na nazev labelu co uz neexistuje, ted je ve vsech smyckach LEAVE???.

_________________
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.12.2022, 18:57 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Kdyz mam ted ty tokeny a mam univerzalni token PUSHS tak se me pri zapisu
Kód:
>R 0. 1. R>
>R 0 0 0 1 R>
>R uložení_x_čísel_na_zásobník R>
vytvari posloupnost tokenu
TO_R PUSHS R_FROM
a to jde snadno najit v tokenovych pravidlech a muzu pro to vytvorit spojene slovo.

Ma to stale mensi nevyhodu jako PUSH_SWAP, ze to oproti univerzalnimu PUSHS neumi hledat nejlepsi kombinaci pouziti BC,DE,HL. Ale jen pouziva DE, s tim ze si pamatuje co tam bylo predtim.

Pokud by bylo tech parametru fakt hodne a komplikovane tak by bylo lepsi to resit nejak jinak
Kód:
3:16 ld (xxx+1),HL
     DROP_PUSHS()
1:11 push DE
1:4  ex DE,HL
xxx:
3:10 ld HL,0

Kód:
1:11 push HL
1:4  exx
1:10 pop DE
     DROP_PUSHS()
1:11 push DE
1:4  ex DE,HL
1:4  exx
1:11 push DE
1:4  exx
1:19 ex (SP),HL


Takhle to vypadalo predtim (je to 2x to same jen jinak zadany data):
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'TO_R PUSHDOT(0x0005000A) PUSHDOT(0x000B0032) R_FROM'
                        ;[9:65]     to_r   ( c b a -- c b ) ( R: -- a )
    ex  (SP), HL        ; 1:19      to_r   a . b c
    ex   DE, HL         ; 1:4       to_r   a . c b
    exx                 ; 1:4       to_r
    pop  DE             ; 1:10      to_r
    dec  HL             ; 1:6       to_r
    ld  (HL),D          ; 1:7       to_r
    dec   L             ; 1:4       to_r
    ld  (HL),E          ; 1:7       to_r
    exx                 ; 1:4       to_r
    push DE             ; 1:11      0x0005000A. 0x000B0032.
    push HL             ; 1:11      0x0005000A. 0x000B0032.
    ld   HL, 0x0005     ; 3:10      0x0005000A. 0x000B0032.
    push HL             ; 1:11      0x0005000A. 0x000B0032.
    ld   DE, 0x000A     ; 3:10      0x0005000A. 0x000B0032.
    push DE             ; 1:11      0x0005000A. 0x000B0032.
    inc   E             ; 1:4       0x0005000A. 0x000B0032.
    ld    L, 0x32       ; 2:7       0x0005000A. 0x000B0032.
                        ;[9:66]     r_from ( b a -- b a i ) ( R: i -- )
    exx                 ; 1:4       r_from
    ld    E,(HL)        ; 1:7       r_from
    inc   L             ; 1:4       r_from
    ld    D,(HL)        ; 1:7       r_from
    inc  HL             ; 1:6       r_from
    push DE             ; 1:11      r_from
    exx                 ; 1:4       r_from i . b a
    ex   DE, HL         ; 1:4       r_from i . a b
    ex  (SP), HL        ; 1:19      r_from b . a i
; seconds: 1           ;[31:206]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'TO_R PUSHS(5,10,11,50) R_FROM'
                        ;[9:65]     to_r   ( c b a -- c b ) ( R: -- a )
    ex  (SP), HL        ; 1:19      to_r   a . b c
    ex   DE, HL         ; 1:4       to_r   a . c b
    exx                 ; 1:4       to_r
    pop  DE             ; 1:10      to_r
    dec  HL             ; 1:6       to_r
    ld  (HL),D          ; 1:7       to_r
    dec   L             ; 1:4       to_r
    ld  (HL),E          ; 1:7       to_r
    exx                 ; 1:4       to_r
    push DE             ; 1:11      5 10 11 50
    push HL             ; 1:11      5 10 11 50
    ld   HL, 0x0005     ; 3:10      5 10 11 50
    push HL             ; 1:11      5 10 11 50
    ld   DE, 0x000A     ; 3:10      5 10 11 50
    push DE             ; 1:11      5 10 11 50
    inc   E             ; 1:4       5 10 11 50
    ld    L, 0x32       ; 2:7       5 10 11 50
                        ;[9:66]     r_from ( b a -- b a i ) ( R: i -- )
    exx                 ; 1:4       r_from
    ld    E,(HL)        ; 1:7       r_from
    inc   L             ; 1:4       r_from
    ld    D,(HL)        ; 1:7       r_from
    inc  HL             ; 1:6       r_from
    push DE             ; 1:11      r_from
    exx                 ; 1:4       r_from i . b a
    ex   DE, HL         ; 1:4       r_from i . a b
    ex  (SP), HL        ; 1:19      r_from b . a i
; seconds: 1           ;[31:206]


A takhle to vypada ted:
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'TO_R PUSHDOT(0x0005000A) PUSHDOT(0x000B0032) R_FROM'
    push DE             ; 1:11      to_r 0x0005000A. 0x000B0032. r_from   ( x -- 0x0005 0x000A 0x000B 0x0032 x )
    ld   DE, 0x0005     ; 3:10      to_r 0x0005000A. 0x000B0032. r_from
    push DE             ; 1:11      to_r 0x0005000A. 0x000B0032. r_from
    ld    E, 0x0A       ; 2:7       to_r 0x0005000A. 0x000B0032. r_from
    push DE             ; 1:11      to_r 0x0005000A. 0x000B0032. r_from
    inc   E             ; 1:4       to_r 0x0005000A. 0x000B0032. r_from
    push DE             ; 1:11      to_r 0x0005000A. 0x000B0032. r_from
    ld    E, 0x32       ; 2:7       to_r 0x0005000A. 0x000B0032. r_from
; seconds: 0           ;[12:72]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'TO_R PUSHS(5,10,11,50) R_FROM'
    push DE             ; 1:11      to_r 5 10 11 50 r_from   ( x -- 5 10 11 50 x )
    ld   DE, 0x0005     ; 3:10      to_r 5 10 11 50 r_from
    push DE             ; 1:11      to_r 5 10 11 50 r_from
    ld    E, 0x0A       ; 2:7       to_r 5 10 11 50 r_from
    push DE             ; 1:11      to_r 5 10 11 50 r_from
    inc   E             ; 1:4       to_r 5 10 11 50 r_from
    push DE             ; 1:11      to_r 5 10 11 50 r_from
    ld    E, 0x32       ; 2:7       to_r 5 10 11 50 r_from
; seconds: 0           ;[12:72]


Tohle je podle me docela prakticke.

Jeste by to mozna chtelo resit:
Kód:
>R >R ... R> R>

_________________
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: 27.12.2022, 01:20 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Protoze se zasobnik relativnich adres pouziva casto pro odlozeni hodnoty a mezitim se nedela jen PUSHS, ale probiha nejaka funkce:
Kód:
: BENCHME ( xt n -- )
  DUP >R 0 DO
    DUP EXECUTE
    [CHAR] . EMIT
  LOOP
  DROP R> SPACE . ." Iterations." SPACE ;

a bylo by tezke analyzovat co vsechno dela, jake registry pouziva a zda to cele neni v rekurzivni funkci, tak jsem udelal reseni, ktere musi zvolit programator sam. INLINE_VARIABLE. Je to VARIABLE, takze to vytvari misto v pameti, ale na rozdil od obycejneho VARIABLE, ktere alokuje misto v datove sekci na konci, tak tohle alokuje primo v kodu. Presneji to odkazuje do xxx v casti "ld HL,xxx". Takze je to jeste neco jako FETCH.

Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(abc) STORE INLINE_VARIABLE(abc)'
                        ;[5:30]     abc !  push_store(abc)   ( x -- )  addr=abc
    ld   (abc), HL      ; 3:16      abc !  push_store(abc)
    ex   DE, HL         ; 1:4       abc !  push_store(abc)
    pop  DE             ; 1:10      abc !  push_store(abc)

    ...

    push DE             ; 1:11      inline_variable abc
    ex   DE, HL         ; 1:4       inline_variable abc
    db   0x21           ; 3:10      inline_variable abc   ld HL, 0x0000
abc:                    ;           inline_variable abc
    dw   0x0000         ;           inline_variable abc
; seconds: 0           ;[10:55]

A protoze jsem to chtel mit kompatibilni se slovy jako FETCH a STORE tak nazev musi ukazovat primo na data. Pritom nemohu pouzit "abc EQU $+1", protoze by me STORE (teda pasmo pri kompilaci STORE) zarval ze nezna "abc" a reseni ze se to hodi na zacatek nefunguje, protoze tam je ten ukazatel "$", tak jsem tu instrukci rozsekl na DB a DW. Mohl bych to teda delat jeste sloziteji ze "abc EQU label_abc+1"
a misto "abc:" mit "label_abc:", ale to rozseknuti mi prijde lepsi.

PS: Nemate nekdo lepsi navrh na jmeno toho slova? VARIABLE_FETCH? Neco jako "M>" teda M_FROM?

PPS: Oproti reseni "! ... @" to setri 2 bajty (protoze na alokaci se pouzije misto v kodu) a 6 taktu, protoze to misto "ld HL,(name)" pouzije "ld HL, name_value".

PPPS: Novy rok ma peknou binarni hodnotu "0111 1110 0111"

_________________
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: 27.12.2022, 05:09 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Dalsi spam pred novym rokem.
Jak jsem si hral s tim problemem >R ... R> tak jsem si vsiml ze me to generuje zbytecny kod kdyz se zada PUSHS a pak DROP. Je to teda blbost psat... Takze jsem pridal pravidlo kdy vypadava posledni parametr.
Ale neco podobneho ma i situace kdy udelame "adresa STORE PUSHS".
Prvni dva tokeny se spoji do PUSH_STORE(adresa). A na ukazatel "adresa" se ulozi TOS. Tim se vyhazuje ze zasobniku a provede se

ex DE,HL
pop DE

cimz se druhe NOS dostane do TOS a do NOS se nacte dalsi hodnota.
Nasledujici PUSHS udela to same opacne...
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(500) STORE PUSH(100) __SHOW_TOKEN(1) __SHOW_TOKEN(2)'
; name: __TOKEN_PUSH_STORE
; info: 500 !
;items: 1
;param: (500)
;array1: >500<
;array: 500
; name: __TOKEN_PUSHS
; info: 100
;items: 1
;param: (100)
;array1: >100<
;array: 100
                        ;[5:30]     500 !   ( x -- )  addr=500
    ld   (500), HL      ; 3:16      500 !
    ex   DE, HL         ; 1:4       500 !
    pop  DE             ; 1:10      500 !
    push DE             ; 1:11      100
    ex   DE, HL         ; 1:4       100
    ld   HL, 100        ; 3:10      100
; seconds: 0           ;[10:55]

Vznika tak uprostred nadbytecny "zrcadlovy" kod.

Premyslel jsem jak udelat nove slovo, ale pak me doslo ze mam DROP_PUSHS
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'DROP PUSH(100) __SHOW_TOKEN(1) '
; name: __TOKEN_DROP
; info: drop
;items: 0
;param: ()
    ld   HL, 100        ; 3:10      drop 100
; seconds: 0           ;[ 3:10]
a pokud by se me podarilo zapsat to PUSH_STORE nejak fikane tak to mohl udelat jen v pravidlech.

A reseni je DUP PUSH(500) STORE DROP
Jinak receno udelam si kopii hodnoty co se uklada na tu adresu "500" a pote ji zahodim. Takze to generuje ve skutecnosti uplne identicky kod jako PUSH(500) STORE, ale ma to jine tokeny. DUP_PUSH_STORE a DROP
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'DUP PUSH(500) STORE DROP __SHOW_TOKEN(1) '
; name: __TOKEN_DUP
; info: dup
;items: 0
;param: ()
    ld   (500), HL      ; 3:16      dup 500 !
    ex   DE, HL         ; 1:4       drop
    pop  DE             ; 1:10      drop   ( a -- )
; seconds: 0           ;[ 5:30]


Takze dohromady vytvari DUP PUSH(500) STORE DROP PUSH(100)
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(500) STORE PUSH(100) __SHOW_TOKEN(1) __SHOW_TOKEN(2)'
; name: __TOKEN_DUP_PUSH_STORE
; info: 500 !
;items: 1
;param: (500)
;array1: >500<
;array: 500
; name: __TOKEN_DROP
; info:
;items: 0
;param: ()
    ld   (500), HL      ; 3:16      500 !
    ld   HL, 100        ; 3:10       100
; seconds: 0           ;[ 6:26]

Takze do pravidel jsem udelal ze pokud po tokenu __TOKEN_PUSH_STORE nasleduje token __TOKEN_PUSHS tak to predchozi token prepise na __TOKEN_DUP_PUSH_STORE takze se jakoby zachova ukladana hodnota. A pak misto tokenu __TOKEN_PUSHS to prvne jeste prida token __TOKEN_DROP u ktereho ale umazu info a az na konec se prida novy token __TOKEN_PUSHS. V pravidlech druheho kola kdy se spojuje NECO+PUSHS (a ne jako prvne PUSHS+NECO) se spoji DROP+PUSHS. Tam vznikne situace ze se spojuje info z DROP takze prazdny retezec a pak se pridava spojujici mezera a pak info PUSHS, takze je to uskoceny o mezeru doprava.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(500) STORE PUSH(100)'
    ld   (500), HL      ; 3:16      500 !
    ld   HL, 100        ; 3:10       100
; seconds: 0           ;[ 6:26]

Pokud by se stalo ze neco nacte ty hodnoty co jsou za drop, napriklad DO LOOP, tak se proste vygeneruje DROP, jen s prazdnym infem.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(500) STORE PUSH(100) PUSH(300)'
    ld   (500), HL      ; 3:16      500 !
    push DE             ; 1:11       100 300
                        ;[6:20]      100 300   ( -- 100 300 )
    ld   DE, 0x0064     ; 3:10       100 300
    ld   HL, 0x012C     ; 3:10       100 300
; seconds: 0           ;[10:47]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(500) STORE PUSH(100) PUSH(300) DO LOOP'
    ld   (500), HL      ; 3:16      500 !
    ex   DE, HL         ; 1:4       
    pop  DE             ; 1:10         ( a -- )
    ld   BC, 300        ; 3:10      100 300 do_101(xm)
do101save:              ;           100 300 do_101(xm)
    ld  (idx101),BC     ; 4:20      100 300 do_101(xm)
do101:                  ;           100 300 do_101(xm)
                        ;[16:57/58] loop_101   variant +1.default: step one, run 65336x
idx101 EQU $+1          ;           loop_101   idx always points to a 16-bit index
    ld   BC, 0x0000     ; 3:10      loop_101   300.. +1 ..(100), real_stop:0x0064
    inc  BC             ; 1:6       loop_101   index++
    ld    A, B          ; 1:4       loop_101
    xor  0x00           ; 2:7       loop_101   hi(real_stop) first (100<=255)
    jp   nz, do101save  ; 3:10      loop_101   100x false positive
    ld    A, C          ; 1:4       loop_101
    xor  0x64           ; 2:7       loop_101   lo(real_stop)
    jp   nz, do101save  ; 3:10      loop_101   255x false positive if he was first
leave101:               ;           loop_101
exit101:                ;           loop_101
; seconds: 0           ;[28:118]


Prijde mi to celkem zabavne.

Najdu si nesmyslny problem, nejlepe neco fakt obriho. Jako je zjistit jak prevest vyssi programovaci jazyk do asembleru Z80.
Takze si ten problem sam vytvorim.
A pak hledam jak ten problem rozkouskovat na mensi problemy (hadanky/puzzle) ktere jsou mene narocne a pro ty hledam reseni.
Takze si generuji nekonecny pocet problemu ktere mohu resit.
Perpetum mobile.
V tomhle videu od "Jirka vysvetluje veci" se rika neco zajimaveho co se k tomuto asi vztahuje.
https://youtu.be/aaoMRITDMa8?t=57

DO ziskani informaci -> dopamin -> poteseni + zavislost -> opakovani LOOP

Pro vas je zajimava spis vec ohledne informacniho zahlceni. Nemeli byste tohle radsi cist... .)

_________________
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.12.2022, 05:46 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Moc jsem ted kdyz jsem byl doma (v pokoji) neprogramoval. Jen jsem se v praci pri myti nadobi (vanoce a novy rok jsou hrozne) zamyslel nad tim pridanim DUP a DROP mezi tokenova pravidla.
Strasne me to pripomina fyziku, kde do nekterych kvantovych jevu vstupuji virtualni castice. Par castice a anticastice. Neco udelaji a pak zaniknou, pokud se neco nestane a nezacnou byt realne.

To bych pak mohl nazvat ty tokeny __TOKEN_DUP a __TOKEN_DROP virtualnimi tokeny... .)
Token __TOKEN_DUP se vaze k "realnemu" __TOKEN_STORE a vznika __TOKEN_DUP_STORE
a pak se na frontu jeste prida virtualni __TOKEN_DROP, ktery pokud se na nic nenavaze v (druhem pruchodu) tokenovych pravidlech* tak bude nakonec realny, jinak se spoji s nasledujicim "realnym" __TOKEN_PUSHS do __TOKEN_DROP_PUSHS a samostane zanikne.
M*dat! Ctu to ted po sobe a moc smyslu to nedava i kdyz jsem myslel ze to pisi jednoduse. Asi prilis dlouha souveti, nebo je lepsi po sobe nic necist? .)

Ok zeditovano a ted jeste jinak:

Pridavam token __TOKEN_PUSHS.
V tokenovych pravidlech hledam zda se nepoji s necim pred nim. Uz pri pridani, ale jen proto abych kdyz zjistim ze pred nim bylo __TOKEN_PUSH_STORE tak to __TOKEN_PUSHS_STORE zmenim na __TOKEN_DUP_PUSHS_STORE a jeste za to hodim __TOKEN_DROP a az pak pridam do fronty tokenu __TOKEN_PUSHS s kterym nic nedelam.


*Vysvetleni k tem pravidlum: Proste mam pravdila ktera se vytvareji hned kdyz na frontu se prida novy token.
Vetsinou se to jen koukne co bylo pred nim (ted se uz umi koukat v podstate do neomezene hloubky) a bud se to spoji nebo se vytvori ulozi novy token. K tomu jsou ruzna pomocna makra pro ulehceni prace, odkazujici se relativne k poslednimu ulozenemu makru. Vcetne smazani posledniho makra.

Ve chvili kdy se zavola makro ktere z te fronty tokenu zacne generovat nazvy maker, ktere obsahuji uz samostatny kod tak se udela nova promenna (makro), ktera zkopiruje ukazatel posledniho makra a ukazatel se vynuluje (protoze pak mohu zase pouzit vsechny pomocne makra) a projdou se ty makra jeste jednou. Jen uz nemuzu mazat makra, ani pridavat nova. Misto mazani jde jen udelat prazne makro.
Hlavni vyhoda druheho pruchodu je, ze se tam mohou aktivovat pravidla mensi priority. Nekdy se stane ze se proste na nejakou kombinaci tokenu da provest vice pravidel a vytvorit jine komba slov. Ale nektere jsou mnohem vice efektivni. Vetsinou je to tak, ze za daty (PUSHS) je nejake slovo ktere je pouziva jako parametry a to vyrazne zlepsi kod. Pokud to slovo necha nejaka data, protoze jich nepotrebuje tolik, nebo za PUSHS nic do kombinace neni, tak stale se dokaze PUSHS navazat na slovo co bylo pred nim. Jako DROP, DUP atd. A mit to vse v v pravidlech kdy se token pridava tak to nasobne zvysuje pocet pravidel. Kombinace spojeni s PUSHS pred tokenem a kombinace spojeni PUSHS po tokenu.

Cely je to delany aby s co nejmene prace jsem udelal nejlepsi vysledek. A proste jsem jen pridaval dalsi funkcionalitu. V cecku bych to delal jinak, pomaleji ale snadneji na pochopeni a bez rizik vedlejsich ucinku.

Tak a ted proc jsem to znovu vysvetloval.
To STORE -> DUP_STORE + DROP se da udelat i v tech tokenovych pravidlech na konci.
Kdyz najde ze za STORE je PUSHS tak to muze zmenit na DUP_STORE a DROP_PUSHS. Pocet tokenu zustane stejny. Zadne "virtualni" tokeny nevnikaji. K prvnimu tokenu neco pridam a k druhemu pridam opak toho prvniho. V relanem kodu u obou jen neco umazu. A vysledne tokeny jsou pak "neutralni" k pohybu zasobniku.

Pak mi doslo ze, ale ty "virtualni" tokeny jsou takovy pekny pojivo a pokud najdu dalsi slova co nejsou "neutralni" k pohybu zasobniku tak si zase nasobne usetrim pocet pravidel.
Pro stranu X+PUSHS jsem nasel HSTORE a CSTORE, co je to same co STORE jen s H nebo L registrem misto HL. A pak EMIT, co vezme 8 bitu z TOS a vytiskne ho. Dale TYPE_I, co vemze TOS a interpretuje ho jako ukazatel na retezec, ktery je ukoncen tisknutelnym znakem s nastavenym 7. bitem na true.
Pro stranu na ktere je DROP+PUSHS jsem jeste nehledal, ale staci jedno slovo DROP+neco a musel bych zdojnasobit pocet pravidel psat to jen v pravidlech "druheho" radu.

Pak jsem udelal nejake nove chyby... .) protoze jsem nedomyslel vse do dusledku.

U slova EMIT jsem pro snadnost rovnou vytvoril dva tokeny __TOKEN_DUP_EMIT a __TOKEN_DROP. Abych nemusel delat zadna tokenova pravidla. __ASM_TOKEN_EMIT jsem nemazal, protoze ho neco muze volat. Fungovalo to podle ocekavani
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'EMIT'
    ld    A, L          ; 1:4       emit    Pollutes: AF, AF', DE', BC'
    rst   0x10          ; 1:11      emit    with 48K ROM in, this will print char in A
    ex   DE, HL         ; 1:4       emit
    pop  DE             ; 1:10      emit   ( a -- )
; seconds: 0           ;[ 4:29]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'EMIT PUSH(200)'
    ld    A, L          ; 1:4       emit    Pollutes: AF, AF', DE', BC'
    rst   0x10          ; 1:11      emit    with 48K ROM in, this will print char in A
    ld   HL, 200        ; 3:10      emit 200
; seconds: 0           ;[ 5:25]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$

Jen jsem uplne zapomel ze __TOKEN_EMIT muze mit a taky ma vlastni pravidla. Ze se snazi navazat s DUP a PUSH do DUP_EMIT a PUSH_EMIT.
Jenze se uz nenavaze, protoze __TOKEN_EMIT nevznika, vznika jen __TOKEN_DUP_EMIT nasledovany tokenem __TOKEN_DROP.
Takze to chce zrusit vznik dvou tokenu a pridat pravidlo v tokenech a nebo upravit pravidla v tokenech.

Vypada to ze druha varianta je asi spravne...

Protoze i to pravidlo s PUSH_STORE se aktivuje jen pokud vkladam PUSHS a pred nim je PUSH_STORE, tak se to zmeni na DUP_PUSH_STORE, prida DROP a teprve pak ulozi samostatne PUSHS. Ktere se bud cele navaze na pristi token, nebo v druhem pruchodu spoji s DROP.

Pokud teda najdu slovo, co dokaze efektivne zrusit DROP, tak bych musel taky zdvojnasobit pocet pravidel pro kazde slovo ktere konci jako "drop".

Asi bych mel ted vic myslet a hledat nez neco zacnu... hmm... .)) Nebo nedomyslet a pockat jestli me zase neco nedojde casem az me zacne nekde tlacit bota. .)))

Mozna je problem s tim ze ty slova jako PUSH_STORE a EMIT proste nejsou pro moji implementaci navrzena dobre a ja bych spis potreboval slova, ktera nenici vstup, takze jsou "neutralni" na zasobniku a slova jako PUSH_STORE a EMIT rozdelit na DUP_STORE a DUP_EMIT a DROP. Pro me jsou STORE a EMIT jakoby spatne navrzena kombo slova a pak vysledek neni efektivni. Nejsou to nedelitelne celky. A mel jsem se na to tak divat uz od pocatku. Ale koho by to napadlo.

To znamena ze bych mel jeste pridat kombinace slov co nici jak TOS tak NOS. Presneji co maji pohyb na zasobniku "-2" a pak slova co pridaji aspon "+2". Jako STORE + PUSHS --> _2DUP STORE _2DROP PUSHS
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'STORE PUSH(200,300)'
                        ;[5:40]     !   ( x addr -- )
    ld  (HL),E          ; 1:7       !
    inc  HL             ; 1:6       !
    ld  (HL),D          ; 1:7       !
    pop  HL             ; 1:10      !
    pop  DE             ; 1:10      !
                        ;[8:42]     200 300   ( -- 200 300 )
    push DE             ; 1:11      200 300
    push HL             ; 1:11      200 300
    ld   DE, 0x00C8     ; 3:10      200 300
    ld   HL, 0x012C     ; 3:10      200 300
; seconds: 0           ;[13:82]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_2DUP STORE _2DROP PUSH(200,300)'
                        ;[4:26]     2dup ! _2dup_store   ( x addr -- x addr )
    ld  (HL),E          ; 1:7       2dup ! _2dup_store
    inc  HL             ; 1:6       2dup ! _2dup_store
    ld  (HL),D          ; 1:7       2dup ! _2dup_store
    dec  HL             ; 1:6       2dup ! _2dup_store
                        ;[6:20]     2drop 200 300   ( -- 200 300 )
    ld   DE, 0x00C8     ; 3:10      2drop 200 300
    ld   HL, 0x012C     ; 3:10      2drop 200 300
; seconds: 0           ;[10:46]

Hmm... tady _2DUP STORE se snazi nezmenit TOS a vraci ho pomoci "dec HL" do puvodni hodnoty.
Mozna bych mel vytvorit... jine propojeni co ma univerzalni jmeno jako _2DROP ale konkretni kod... Ne! Proste jen rozdelit puvodni kod STORE na SKORO_2DUP_STORE (STACK_NEUTRAL_STORE) a 2DROP. Chce to nejaky rozumny nazev. Dulezity je ten pohyb zasobniku.

Nejak me to nemysli... nebo je to na me uz moc komplikovane.

.....Aaaa tohle bude jeste zajimave. Nic koncim se spamem, puvodne jsem nechtel nakonec ani tohle cele psat. .)))

PS: Pekne ze i kdyz nasleduje jedine PUSH tak se to stale pekne spoji kdyz tam pridame ty "virtualni" tokeny.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'STORE PUSH(300)'
                        ;[5:40]     !   ( x addr -- )
    ld  (HL),E          ; 1:7       !
    inc  HL             ; 1:6       !
    ld  (HL),D          ; 1:7       !
    pop  HL             ; 1:10      !
    pop  DE             ; 1:10      !
    push DE             ; 1:11      300
    ex   DE, HL         ; 1:4       300
    ld   HL, 300        ; 3:10      300
; seconds: 0           ;[10:65]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_2DUP STORE _2DROP PUSH(300)'
                        ;[4:26]     2dup ! _2dup_store   ( x addr -- x addr )
    ld  (HL),E          ; 1:7       2dup ! _2dup_store
    inc  HL             ; 1:6       2dup ! _2dup_store
    ld  (HL),D          ; 1:7       2dup ! _2dup_store
    dec  HL             ; 1:6       2dup ! _2dup_store
    pop  DE             ; 1:10      2drop 300
    ld   HL, 300        ; 3:10      2drop 300
; seconds: 0           ;[ 8:46]

PPS: Jinak jeste k tem tokenovym pravidlum. DUP + EMIT je snazsi delat (naleza se v case co se pridava EMIT) nez DUP + DUP_EMIT + DROP (nalezne to az DROP). Musim se divat o hloubku vice, ale zase tak dramaticky rozdil to neni.

_________________
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: 04.01.2023, 04:43 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Jsem tu jen na skok, mel bych spat, zitra mam celodenni smenu. Takova mala poznamka.
STORE se nakonec "rozpada" na _2DUP_STORE_1ADD a _2DROP.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'STORE'
                        ;[5:40]     !   ( x addr -- )
    ld  (HL),E          ; 1:7       !
    inc  HL             ; 1:6       !
    ld  (HL),D          ; 1:7       !
    pop  HL             ; 1:10      !
    pop  DE             ; 1:10      !
; seconds: 0           ;[ 5:40]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_2DUP STORE _1ADD'
                        ;[3:20]     2dup ! 1+   ( x addr -- x addr+1 )
    ld  (HL),E          ; 1:7       2dup ! 1+
    inc  HL             ; 1:6       2dup ! 1+
    ld  (HL),D          ; 1:7       2dup ! 1+
; seconds: 0           ;[ 3:20]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_2DROP'
    pop  HL             ; 1:10      2drop
    pop  DE             ; 1:10      2drop   ( b a -- )
; seconds: 0           ;[ 2:20]

Tim vypadne to "dec HL" z _2DUP_STORE
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_2DUP STORE'
                        ;[4:26]     2dup !   ( x addr -- x addr )
    ld  (HL),E          ; 1:7       2dup !
    inc  HL             ; 1:6       2dup !
    ld  (HL),D          ; 1:7       2dup !
    dec  HL             ; 1:6       2dup !
; seconds: 0           ;[ 4:26]


Takze to chce predelat tokenove pravidla kde je STORE na _2DUP_STORE_1ADD + _2DROP. Pripadne se nektera pravidla daji pouzit bez toho _2DROP. Nebo jeste jinak jak se to zrovna hodi.

Napriklad: OVER_SWAP + STORE
ted mam prekvapive jako
OVER_SWAP + _2DUP_STORE_1ADD + _2DROP --> _2DUP_STORE_1ADD + DROP
Prvni token dela kopii NOS, ktera prezije STORE co nici prvni dve polozky na zasobniku, takze je to shodne s delanim kopie NOS a TOS a pak TOS odstranit.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'OVER SWAP STORE'
                        ;[5:34]     over swap ! over_swap_store   ( x addr -- x )
    ld  (HL),E          ; 1:7       over swap ! over_swap_store
    inc  HL             ; 1:6       over swap ! over_swap_store
    ld  (HL),D          ; 1:7       over swap ! over_swap_store
    ex   DE, HL         ; 1:4       over swap ! over_swap_store
    pop  DE             ; 1:10      over swap ! over_swap_store
; seconds: 0           ;[ 5:34]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'OVER SWAP _2DUP STORE _1ADD _2DROP'
                        ;[3:20]     over swap 2dup ! 1+ 2drop   ( x addr -- x addr+1 )
    ld  (HL),E          ; 1:7       over swap 2dup ! 1+ 2drop
    inc  HL             ; 1:6       over swap 2dup ! 1+ 2drop
    ld  (HL),D          ; 1:7       over swap 2dup ! 1+ 2drop
    ex   DE, HL         ; 1:4       2drop
    pop  DE             ; 1:10      2drop   ( a -- )
; seconds: 0           ;[ 5:34]

Nenechte se zmast tim popiskem 2drop, ty dva radky delaji obycejny drop.

PS: Zatim pomalu menim ty pravidla se STORE (a s CSTORE a HSTORE). Jeste nemam nastavene ze STORE vytvori dva tokeny.
Prvni __TOKEN_2DUP_STORE_1ADD a druhy __TOKEN_2DROP, stale to dela jen token __TOKEN_STORE, protoze by se pak nic z pravidel kde se hleda __TOKEN_STORE neaktivovalo.
Takze to v testech pisi rucne a az ty pravidla budou hotovy, tak to "prepnu".

_________________
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 ... 23, 24, 25, 26, 27, 28, 29 ... 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