OldComp.cz

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

Vstava historickch poctacu

Právě je 05.12.2022, 22:29

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




Odeslat nové téma Odpovědět na téma  [ Příspěvků: 375 ]  Přejít na stránku Předchozí  1 ... 21, 22, 23, 24, 25
Autor Zpráva
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 07.11.2022, 17:25 
Offline
Profík

Registrován: 23.06.2013, 23:49
Příspěvky: 870
Has thanked: 71 times
Been thanked: 133 times
Takze to je univerzalni TO(name), ktere nacita bud jen z TOS nebo i z NOS.
Pripadne optimalizovane PUSH_TO(name) nebo PUSHDOT_TO(name).
Kód:
                       ;[ 0:0]
dworkin@dw-A15:~/Programovani/ZX/Forth/Nova_testovaci$ ../check_word.sh 'VALUE(_a) TO(_a)'
 
    ld  (_a), HL        ; 3:16      value _a
    ex   DE, HL         ; 1:4       value _a
    pop  DE             ; 1:10      value _a
    ld  (_a), HL        ; 3:16      to _a
    pop  HL             ; 1:10      to _a
    ex   DE, HL         ; 1:4       to _a

VARIABLE_SECTION:

_a: dw 0x0000
                       ;[10:60]
dworkin@dw-A15:~/Programovani/ZX/Forth/Nova_testovaci$ ../check_word.sh 'DVALUE(_a) TO(_a)'
 
    ld  (_a), HL        ; 3:16      dvalue _a   lo
    ld  (_a+2), DE      ; 4:20      dvalue _a   hi
    pop  HL             ; 1:10      dvalue _a
    pop  DE             ; 1:10      dvalue _a
    ld  (_a), HL        ; 3:16      to _a   lo
    ex   DE, HL         ; 1:4       to _a
    ld  (_a+2), HL      ; 3:16      to _a   hi
    pop  HL             ; 1:10      to _a
    pop  DE             ; 1:10      to _a

VARIABLE_SECTION:

_a:                     ;
    dw 0x0000
    dw 0x0000
                       ;[18:112]

PS: Premyslim nad tim zda neomezit velikost tech cisel v pameti na nasobky dvou. Jako 2,4,6,...256. To ze to bude sudy umozni i drobne optimalizace v operacich PADD, PSUB atd. I nepatrne zrychleni. Odstrani mi to problem jak to udelat v tech promennych, kdy lichy pocet podporuje v podstate jen PCONSTANT. Pokud se to ma nastavovat tak to proste zabere o bajt vice... Nebo udelat dve verze, zkontrolovat si zda se licha pouziva a podle toho tam dat tu spravnou... nevim. Jak moc to bude nekomu vadit ,ze nemuze nema podporu pro jedno bajtova, nebo tribajtova, petibajtova cisla?


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 12.11.2022, 05:09 
Offline
Profík

Registrován: 23.06.2013, 23:49
Příspěvky: 870
Has thanked: 71 times
Been thanked: 133 times
Pridal jsem do tokenu moznost zjistit pocet parametru. Normalne na to existuje symbol $#. Takze kdyz napisete neco jako
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'define({NUM},{$#}) NUM(10,20,30)'
 3
                       ;[ 0:0]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'define({NUM},{$#}) NUM(10,20)'
 2
                       ;[ 0:0]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'define({NUM},{$#}) NUM(10)'
 1
                       ;[ 0:0]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'define({NUM},{$#}) NUM()'
 1
                       ;[ 0:0]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'define({NUM},{$#}) NUM'
 0
                       ;[ 0:0]

Prazdny retezec je ale bran taky jako parametr...
Takze:
Kód:
define({__DIM},{ifelse({$#},1,{ifelse({$1},{},0,1)},{$#})}){}dnl

Jenze tokeny maji parametry obaleny do zavorky, takze cele pole je jen jedna polozka. Takze se prvne vola makro co spojuje nazev makra s parametry. Neco jako __SPOJ(__ALL,(10,20,30)) co vytvori __ALL(10,20,30). A makro _ALL jen tiskne vsechny parametry.
Kód:
define({__GET_TOKEN_ITEMS}, {__DIM(__SPOJ({__ALL},defn(__TOKEN[}$1{].PARAM)))}){}dnl

Tenhle zpusob nejak funguje. Ale staci nekde pridat {} a uz se to rozbali pozde atd.

Pro zkratku je vytvoreno i makro __LAST_TOKEN_ITEMS, ktere je temer totozne z predchozim jen nema parametr, ale implicitni __TOKEN_COUNT, ktery ukazuje na posledni existujici token ve fronte.
Kód:
define({__LAST_TOKEN_ITEMS},  {__DIM(__SPOJ({__ALL},defn(__TOKEN[}__TOKEN_COUNT{].PARAM)))}){}dnl


Proc jsem to potreboval? Protoze jsem si hral s temi dlouhymi cisly... Predelal jsem zpusob jak si ukladam informaci jak je dlouha ta promenna v pameti. Predtim jsem mel jen single a double. Ted se automaticky vytvori k promenne xxx makro __PSIZE_xxx ktere se nahrazuje za pocet bajtu. Potrebuje to slovo TO, ktere nahraje ze zasobniku data do dane promenne v pameti.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PCONSTANT(10,0,xxx) TO(xxx)'
 
                        ;           no_segment(10)
    ld  (xxx), HL       ; 3:16      to xxx
    ex   DE, HL         ; 1:4       to xxx
    ld  (xxx+2), HL     ; 3:16      to xxx
    pop  HL             ; 1:10      to xxx
    ld  (xxx+4), HL     ; 3:16      to xxx
    pop  HL             ; 1:10      to xxx
    ld  (xxx+6), HL     ; 3:16      to xxx
    pop  HL             ; 1:10      to xxx
    ld  (xxx+8), HL     ; 3:16      to xxx
    pop  HL             ; 1:10      to xxx
    pop  DE             ; 1:10      to xxx

VARIABLE_SECTION:

; The padding will fill if the following X bytes overflow the 256 byte segment.
; Any use of Allot with a negative value exceeding this address will result in undefined behavior.
if  ((($ + 10 - 1) / 256) != ($/256))
  DEFS    (($/256)+1)*256 - $
endif
xxx:                    ; = 0
    dw 0x0000
    dw 0x0000
    dw 0x0000
    dw 0x0000
    dw 0x0000
                       ;[21:134]

Tady je to jeste v pohode. Ale nez to tahame ze zasobniku do promenne tak to tam musime nejak dostat. A ze budeme sypat do zasobniku tolik dat jsem nepocital... Z tokenu PUSH PUSH to dela PUSH2, dalsi PUSH vytvori PUSH3, dalsi PUSH4 a dalsi to uz rozsekne na PUSH2 a PUSH3. Protoze nemam slovo pro PUSH5. A ted si jeste vemte ze diky tomu ze mam token PUSH3 a PUSH4 tak mam "duplicitne" vsechny pravidla pro "PUSH3 AND" a "PUSH4 AND" atd.

Co se teda stane kdyz nasypu deset nul na zasobnik? Vytvori to PUSH2(0,0) PUSH2(0,0) PUSH2(0,0) PUSH4(0,0,0,0). A ani jeden netusi co lezi v registrech... takze vysledek je
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(0) PUSH(0) PUSH(0) PUSH(0) PUSH(0) PUSH(0) PUSH(0) PUSH(0) PUSH(0) PUSH(0)'
         
                        ;[7:40]     0 0 0 0 2drop   ( -- 0 0 )
    push DE             ; 1:11      0 0 0 0 2drop
    push HL             ; 1:11      0 0 0 0 2drop
    ld   DE, 0x0000     ; 3:10      0 0 0 0 2drop
    ld    L, D          ; 1:4       0 0 0 0 2drop   L = D = 0x00
    ld    H, L          ; 1:4       0 0 0 0 2drop   H = L = 0x00
                        ;[7:40]     0 0 0 0 2drop   ( -- 0 0 )
    push DE             ; 1:11      0 0 0 0 2drop
    push HL             ; 1:11      0 0 0 0 2drop
    ld   DE, 0x0000     ; 3:10      0 0 0 0 2drop
    ld    L, D          ; 1:4       0 0 0 0 2drop   L = D = 0x00
    ld    H, L          ; 1:4       0 0 0 0 2drop   H = L = 0x00
                        ;[7:40]     0 0 0 0 2drop   ( -- 0 0 )
    push DE             ; 1:11      0 0 0 0 2drop
    push HL             ; 1:11      0 0 0 0 2drop
    ld   DE, 0x0000     ; 3:10      0 0 0 0 2drop
    ld    L, D          ; 1:4       0 0 0 0 2drop   L = D = 0x00
    ld    H, L          ; 1:4       0 0 0 0 2drop   H = L = 0x00
    push DE             ; 1:11      0 0 0 0   ( -- 0 0 0 0 )
    push HL             ; 1:11      0 0 0 0
    ld   DE, 0x0000     ; 3:10      0 0 0 0
    ld    L, D          ; 1:4       0 0 0 0   L = D = 0x00
    ld    H, L          ; 1:4       0 0 0 0   H = L = 0x00
    push DE             ; 1:11      0 0 0 0
    push HL             ; 1:11      0 0 0 0
                       ;[30:182]

No a z toho se me delalo spatne.
Rikal jsem si ze proste pridam nejakou informaci jakou maji registry hodnotu po ukonceni makra, takze pristi to bude videt.
Tohle se musi ale udelat PRO KAZDE MAKRO BEZ VYJIMKY. Docela dost prace.
A ke vsemu jsem se dival jak mam udelany treba PUSH3 a nebylo by lehke tam na zacatek tohle pridat.

Tak jsem zkusil napsat PUSHS(). Obecne slovo pro N parametru. Ukazalo se to nakonec lehci i kdyz jsem zvolil ne uplne idealni reseni. Ale latka kterou jsem musel preskocit byla fakt nizko jak vidite vysse. PUSHS reseni zabira presne polovinu bajtu.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSHS(0,0,0,0,0,0,0,0,0,0)'

    push DE             ; 1:11       0 0 0 0 0 0 0 0 0 0
    push HL             ; 1:11       0 0 0 0 0 0 0 0 0 0
    ld   HL, 0x0000     ; 3:10       0 0 0 0 0 0 0 0 0 0
    push HL             ; 1:11       0 0 0 0 0 0 0 0 0 0
    push HL             ; 1:11       0 0 0 0 0 0 0 0 0 0
    push HL             ; 1:11       0 0 0 0 0 0 0 0 0 0
    push HL             ; 1:11       0 0 0 0 0 0 0 0 0 0
    push HL             ; 1:11       0 0 0 0 0 0 0 0 0 0
    push HL             ; 1:11       0 0 0 0 0 0 0 0 0 0
    push HL             ; 1:11       0 0 0 0 0 0 0 0 0 0
    push HL             ; 1:11       0 0 0 0 0 0 0 0 0 0
    ld    E, H          ; 1:4        0 0 0 0 0 0 0 0 0 0   E = H = 0x00
    ld    D, E          ; 1:4        0 0 0 0 0 0 0 0 0 0   D = E = 0x00
                       ;[15:128]

Udelal jsem to proste tak, ze pro kazde ukladane cislo zkoumam 3 reseni a volim to nejlepsi. Zda to ulozit do BC, DE a nebo HL.
Pritom k tomu jeste pridavam test kolik bude jeste stat udelat posledni 2 hodnoty u kterych vim ze posledni musi byt v HL(TOS) a predposledni v DE(NOS). Nic vic. Takze by to slo udelat obcas i efektivneji... Nejhorsi je se podivat na ten vysledek a hned vidite, kde by to slo jeste vylepsit... 8x push HL? Co smycka pres B kdyz vim ze neblo pouzito a rychlost bych i ozelel atd.

Zkousel jsem tomu hazet nejake data a i to BC se obcas pouzije.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSHS(0,0,0,0,0,0,0,0,0,10)'

    push DE             ; 1:11       0 0 0 0 0 0 0 0 0 10
    push HL             ; 1:11       0 0 0 0 0 0 0 0 0 10
    ld   DE, 0x0000     ; 3:10       0 0 0 0 0 0 0 0 0 10
    push DE             ; 1:11       0 0 0 0 0 0 0 0 0 10
    push DE             ; 1:11       0 0 0 0 0 0 0 0 0 10
    push DE             ; 1:11       0 0 0 0 0 0 0 0 0 10
    push DE             ; 1:11       0 0 0 0 0 0 0 0 0 10
    push DE             ; 1:11       0 0 0 0 0 0 0 0 0 10
    push DE             ; 1:11       0 0 0 0 0 0 0 0 0 10
    push DE             ; 1:11       0 0 0 0 0 0 0 0 0 10
    push DE             ; 1:11       0 0 0 0 0 0 0 0 0 10
    ld   HL, 0x000A     ; 3:10       0 0 0 0 0 0 0 0 0 10
                       ;[16:130]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSHS(0,0,0,10,0,0,0,0,0,10)'

    push DE             ; 1:11       0 0 0 10 0 0 0 0 0 10
    push HL             ; 1:11       0 0 0 10 0 0 0 0 0 10
    ld   DE, 0x0000     ; 3:10       0 0 0 10 0 0 0 0 0 10
    push DE             ; 1:11       0 0 0 10 0 0 0 0 0 10
    push DE             ; 1:11       0 0 0 10 0 0 0 0 0 10
    push DE             ; 1:11       0 0 0 10 0 0 0 0 0 10
    ld   HL, 0x000A     ; 3:10       0 0 0 10 0 0 0 0 0 10
    push HL             ; 1:11       0 0 0 10 0 0 0 0 0 10
    push DE             ; 1:11       0 0 0 10 0 0 0 0 0 10
    push DE             ; 1:11       0 0 0 10 0 0 0 0 0 10
    push DE             ; 1:11       0 0 0 10 0 0 0 0 0 10
    push DE             ; 1:11       0 0 0 10 0 0 0 0 0 10
                       ;[16:130]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSHS(0,0,0,10,0,0,10,0,0,(10))'

    push DE             ; 1:11       0 0 0 10 0 0 10 0 0 (10)
    push HL             ; 1:11       0 0 0 10 0 0 10 0 0 (10)
    ld   DE, 0x0000     ; 3:10       0 0 0 10 0 0 10 0 0 (10)
    push DE             ; 1:11       0 0 0 10 0 0 10 0 0 (10)
    push DE             ; 1:11       0 0 0 10 0 0 10 0 0 (10)
    push DE             ; 1:11       0 0 0 10 0 0 10 0 0 (10)
    ld   HL, 0x000A     ; 3:10       0 0 0 10 0 0 10 0 0 (10)
    push HL             ; 1:11       0 0 0 10 0 0 10 0 0 (10)
    push DE             ; 1:11       0 0 0 10 0 0 10 0 0 (10)
    push DE             ; 1:11       0 0 0 10 0 0 10 0 0 (10)
    push HL             ; 1:11       0 0 0 10 0 0 10 0 0 (10)
    push DE             ; 1:11       0 0 0 10 0 0 10 0 0 (10)
    ld   HL, (10)       ; 3:16       0 0 0 10 0 0 10 0 0 (10)
                       ;[19:146]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSHS(0,0,0,(10),0,0,10,0,0,(10))'

    push DE             ; 1:11       0 0 0 (10) 0 0 10 0 0 (10)
    push HL             ; 1:11       0 0 0 (10) 0 0 10 0 0 (10)
    ld   DE, 0x0000     ; 3:10       0 0 0 (10) 0 0 10 0 0 (10)
    push DE             ; 1:11       0 0 0 (10) 0 0 10 0 0 (10)
    push DE             ; 1:11       0 0 0 (10) 0 0 10 0 0 (10)
    push DE             ; 1:11       0 0 0 (10) 0 0 10 0 0 (10)
    ld   HL, (10)       ; 3:16       0 0 0 (10) 0 0 10 0 0 (10)
    push HL             ; 1:11       0 0 0 (10) 0 0 10 0 0 (10)
    push DE             ; 1:11       0 0 0 (10) 0 0 10 0 0 (10)
    push DE             ; 1:11       0 0 0 (10) 0 0 10 0 0 (10)
    ld   BC, 0x000A     ; 3:10       0 0 0 (10) 0 0 10 0 0 (10)
    push BC             ; 1:11       0 0 0 (10) 0 0 10 0 0 (10)
    push DE             ; 1:11       0 0 0 (10) 0 0 10 0 0 (10)
                       ;[19:146]

Fajn... ale to taky znamena ze musim upravit i ty tokenove pravidla.
Nakonec jsem se rozhodl tak ze vsechna slova jako PUSH2 nebo PUSH3 budou rovnou volat PUSHS a pravidla budou jen pro PUSHS. A prave proto potrebuji znat pocet polozek. Protoze "PUSHS(15) AND" nedela nic, zato "PUSHS(15,3) AND" by melo vytvorit PUSHS(3).
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSHS(15) AND'
 
    push DE             ; 1:11       15
    ex   DE, HL         ; 1:4        15
    ld   HL, 15         ; 3:10       15
    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
                       ;[12:59]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSHS(15,3) AND'
 
    push DE             ; 1:11       15 3 and
    ex   DE, HL         ; 1:4        15 3 and
    ld   HL, 3          ; 3:10       15 3 and
                       ;[ 5:25]


Jedno pravidlo pro PUSH4 a AND vypadalo takto
Kód:
            __LAST_TOKEN_NAME:$1:__LAST_TOKEN_IS_PTR_REVERSE_2_1,
__TOKEN_PUSH4:__TOKEN_AND:0,   
 {__SET_TOKEN({__TOKEN_PUSH3}, __LAST_TOKEN_INFO{ }$2,__DROP_2_PAR(__LAST_TOKEN_ARRAY),__EVAL_S16(&,__LAST_TOKEN_LAST_2_PAR))},

Pro PUSHS a AND to vypada takto
Kód:
__LAST_TOKEN_NAME:eval(__LAST_TOKEN_ITEMS>1):$1:__LAST_TOKEN_IS_PTR_REVERSE_2_1,
 __TOKEN_PUSHS:1:__TOKEN_AND:0,   
{__SET_TOKEN(__TOKEN_PUSHS, __LAST_TOKEN_INFO{ }$2,ifelse(__LAST_TOKEN_ITEMS,2,,__DROP_2_PAR(__LAST_TOKEN_ARRAY){,})__EVAL_S16(&,__LAST_TOKEN_LAST_2_PAR))},

Zalomil jsem to tady tak ze prvni radek nacita aktualni data, druhy radek je co musi odpovidat aby se volal treti radek. V kodu to mam jen oddelene carkama.
Je to zatim jen jedine testovaci pravidlo po PUSHS co mam...

PS: To predavani informaci o hodnotach v registrech by se ale stejne melo jednou udelat. Jen to nechci uplne rozdrbavat kdyz nemam uplne ani otestovano, kde mam jeste chyby diky tokenizaci.
V hlave mam reseni ze se pro kazdy __ASM_TOKEN_name musi na zacatek udelat nejaky BEGIN a na konci nejaky END. BEGIN by slo udelat skriptem automaticky vsude. END uz ne, ale dobra zprava je ze by slo udelat tak, aby sam BEGIN zjistil zda v predchozim slove byl nejaky END nebo ne. Reseni je spousta, staci treba aby BEGIN nastavil nejakou vlajku a END ji rusi.

Makra BEGIN a END by byla udelana tak, ze v END by se nastavoval vystup. A BEGIN by registry vyprazdnilo na prazdny retezec a nebo nacetlo predchozi hodnoty co byly v makru END.

No nic, 3 rano..., cas jit spat. Zitra je rusna sobota v praci, nastesti uz ve dvou.


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 13.11.2022, 17:53 
Offline
Profík

Registrován: 23.06.2013, 23:49
Příspěvky: 870
Has thanked: 71 times
Been thanked: 133 times
Pridana tokenova pravidla pro PUSHS + ...

FILL (tady mam u PUSH4+FILL chybu kdy to generuje PUSH4_FILL token, ale existuje jen PUSH3_FILL)
UMDIVMOD
SMDIVREM
FMDIVMOD
MADD
AND dvou cisel
AND jedno cislo je 0 (druhe muze byt i pointer)
AND jedno cislo je -1 (druhe muze byt i pointer)
OR dvou cisel
OR jedno cislo je 0 (druhe muze byt i pointer)
OR jedno cislo je -1 (druhe muze byt i pointer)
XOR dvou cisel
XOR jedno cislo je 0 (druhe muze byt i pointer), tohle jsem predtim zapomnel udelat s PUSH4 a mozna i PUSH3, atd.
ADD dvou cisel
ADD jedno cislo je 0 (druhe muze byt i pointer)
SUB dvou cisel
SUB druhe cislo je 0 (prvni muze byt i pointer)
MUL dvou cisel
MUL jedno cislo je 0 (druhe muze byt i pointer)
MUL jedno cislo je 1 (druhe muze byt i pointer)
MUL jedno cislo je -1 (druhe muze byt i pointer)
DIV dvou cisel
DIV prvni cislo je 0 (druhe muze byt i pointer)
DIV druhe cislo je 1 (prvni muze byt i pointer)
MOD dvou cisel
UMOD dvou cisel
DIVMOD dvou cisel
UDIVMOD dvou cisel
MMUL dvou cisel
UMMUL dvou cisel
MAX dvou cisel
MIN dvou cisel
EQ dvou cisel
NE dvou cisel
LT dvou cisel
GT dvou cisel
LE dvou cisel
GE dvou cisel
UEQ dvou cisel
UNE dvou cisel
ULT dvou cisel
UGT dvou cisel
ULE dvou cisel
UGE dvou cisel

U tech porovnani jsem opravil vystup kdy se me TRUE generovalo jako 1 jak to dela M4, misto -1 jak to chce FORTH.
<irony>Prekvapive si toho nikdo za celou dobu nevsimnul... :shock: </irony> Vsechny vetveni jsou delane pro 0 a nebo nenulovou hodnotu, takze rozdil by byl jen pokud vystup pouzije nejaky AND.

PS: Asi pred tydnem me na githubu pribyl treti lajk! .)


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 14.11.2022, 02:50 
Offline
Profík

Registrován: 23.06.2013, 23:49
Příspěvky: 870
Has thanked: 71 times
Been thanked: 133 times
Vytvoreno slovo PVALUE (takze uz neni jen PPUSH_VALUE), pouziva uvnitr slovo TO, ktere nacita polozky ze zasobniku na adresu v pameti.

Pridany kombinace PUSHS+...

CMOVE
MOVE
SWAP
WITHIN
PUSH
PUSHS
STORE
_2STORE
FETCH
_2FETCH
VALUE
DVALUE
a konecne i PVALUE.

Posledni kombinace slov nebyla jen o pravidlech tokenu, ale dala hodne zabrat. Musel jsem vytvorit pomocna makra

__IS_ARRAY_NUM ... overuje zda vsechny polozky pole jsou cisla (a ne pointery nebo nezname promenne)
__FIRST_X_PAR ... vypise oddelene carkama prvnich X polozek pole
__LAST_X_PAR ...vypise oddelene carkama poslednich X polozek pole
__ARRAY2HEXSTRING ...udela z pole hex retezec

a s nema jsem to uz nejak dal dohromady. Po overeni, ze je vse ok se pak uvnitr tokenovych pravidel vola PPUSH_VALUE(bytes,hex_string,val_name). Protoze ani ten nema token a jen vytvari nekolik tokenu pro NO_SEGMENT,CREATE a PHEXPUSH_COMMA_REC. A ten pak postupne teprve tvori tokeny PUSHS_COMMA.

Pokud mate radi barvicky: https://github.com/DW0RKiN/M4_FORTH/commit/e7e6b5464a6215a44efad30e8c2324b28509e1b7

Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSHS((0x6655),0x1122,0x1122,0x2244) PVALUE(8,_a)   __SHOW_TOKEN(1)'
   
; name: __TOKEN_PUSHS
; info: (0x6655) 0x1122 0x1122 0x2244
;items: 4
;param: ((0x6655),0x1122,0x1122,0x2244)
;array1: >(0x6655)<
;array2: >0x1122<
;array3: >0x1122<
;array: (0x6655),0x1122,0x1122,0x2244
    push DE             ; 1:11      (0x6655) 0x1122 0x1122 0x2244   ( -- (0x6655) 0x1122 0x1122 0x2244 )
    push HL             ; 1:11      (0x6655) 0x1122 0x1122 0x2244
    ld   DE, 0x1122     ; 3:10      (0x6655) 0x1122 0x1122 0x2244
    ld   HL, (0x6655)   ; 3:16      (0x6655) 0x1122 0x1122 0x2244
    push HL             ; 1:11      (0x6655) 0x1122 0x1122 0x2244
    push DE             ; 1:11      (0x6655) 0x1122 0x1122 0x2244
    ld   HL, 0x2244     ; 3:10      (0x6655) 0x1122 0x1122 0x2244
                        ;           p8value _a
    ld  (_a), HL        ; 3:16      p8value _a
    ex   DE, HL         ; 1:4       p8value _a
    ld  (_a+2), HL      ; 3:16      p8value _a
    pop  HL             ; 1:10      p8value _a
    ld  (_a+4), HL      ; 3:16      p8value _a
    pop  HL             ; 1:10      p8value _a
    ld  (_a+6), HL      ; 3:16      p8value _a
    pop  HL             ; 1:10      p8value _a
    pop  DE             ; 1:10      p8value _a

VARIABLE_SECTION:

; The padding will fill if the following X bytes overflow the 256 byte segment.
; Any use of Allot with a negative value exceeding this address will result in undefined behavior.
if  ((($ + 8 - 1) / 256) != ($/256))
  DEFS    (($/256)+1)*256 - $
endif
_a:                     ;
    dw 0x0000
    dw 0x0000
    dw 0x0000
    dw 0x0000
                       ;[30:188]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSHS((0x6655),0x1122,0x1122,0x2244) PVALUE(6,_a)   __SHOW_TOKEN(1)'
 
_a                   EQU __create__a
   
; name: __TOKEN_PUSHS
; info: (0x6655)
;items: 1
;param: ((0x6655))
;array1: >(0x6655)<
;array2: ><
;array3: ><
;array: (0x6655)
    push DE             ; 1:11      (0x6655)
    ex   DE, HL         ; 1:4       (0x6655)
    ld   HL, (0x6655)   ; 3:16      (0x6655)
                        ;           no_segment(6)
    push HL             ; 1:11      0x2244 , 0x1122 , ... 0x1122 ,   default version
    ld   HL, 0x1122     ; 3:10      0x1122 ,
    ld  (__create__a+2),HL; 3:16      0x1122 ,
    ld  (__create__a+4),HL; 3:16      0x1122 ,
    add  HL, HL         ; 1:11      0x2244 ,   0x2244 = 0x1122+0x1122
    ld  (__create__a),HL; 3:16      0x2244 ,
    pop  HL             ; 1:10      0x2244 , 0x1122 , ... 0x1122 ,
                        ;[15:90]    0x2244 , 0x1122 , ... 0x1122 ,

VARIABLE_SECTION:

; The padding will fill if the following X bytes overflow the 256 byte segment.
; Any use of Allot with a negative value exceeding this address will result in undefined behavior.
if  ((($ + 6 - 1) / 256) != ($/256))
  DEFS    (($/256)+1)*256 - $
endif
__create__a:            ;
    dw 0x2244
    dw 0x1122
    dw 0x1122
                       ;[20:121]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSHS(0x1122,0x2244) PVALUE(6,_a)   __SHOW_TOKEN(1)'
   
; name: __TOKEN_PUSHS
; info: 0x1122 0x2244
;items: 2
;param: (0x1122,0x2244)
;array1: >0x1122<
;array2: >0x2244<
;array3: ><
;array: 0x1122,0x2244
                        ;[8:42]     0x1122 0x2244   ( -- 0x1122 0x2244 )
    push DE             ; 1:11      0x1122 0x2244
    push HL             ; 1:11      0x1122 0x2244
    ld   DE, 0x1122     ; 3:10      0x1122 0x2244
    ld   HL, 0x2244     ; 3:10      0x1122 0x2244
                        ;           p6value _a
    ld  (_a), HL        ; 3:16      p6value _a
    ex   DE, HL         ; 1:4       p6value _a
    ld  (_a+2), HL      ; 3:16      p6value _a
    pop  HL             ; 1:10      p6value _a
    ld  (_a+4), HL      ; 3:16      p6value _a
    pop  HL             ; 1:10      p6value _a
    pop  DE             ; 1:10      p6value _a

VARIABLE_SECTION:

; The padding will fill if the following X bytes overflow the 256 byte segment.
; Any use of Allot with a negative value exceeding this address will result in undefined behavior.
if  ((($ + 6 - 1) / 256) != ($/256))
  DEFS    (($/256)+1)*256 - $
endif
_a:                     ;
    dw 0x0000
    dw 0x0000
    dw 0x0000
                       ;[21:124]


PS: Mam pocit jako bych stavel sam pyramidu, ale z dlazebnich kostek (protoze ty unesu). A uz si vubec nepamatuji, kde ktera kostka je.


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

Registrován: 23.06.2013, 23:49
Příspěvky: 870
Has thanked: 71 times
Been thanked: 133 times
Zkousel jsem napsat jinou metodu pro ukladani dat na zasobnik. Dela to slovo PUSHS. Ta puvodni je jak jsem uz rikal ze to porovna tri hodnoty a vybere tu s nejmensi cenou. Prioritu ma pri shodne hodnote HL, pak DE a nakonec BC.

Cena se pocita z ceny kolik stoji to ulozit do toho registru + cena za ulozeni predposledni hodnoty do DE a posledni hodnoty do HL (v tomhle poradi, ani jsem to nezkousel prohazovat coz muze byt nekdy vyhodnejsi).

Problem ktery jsem tu neukazoval je, ze me to obcas nacetlo dost nestastne nejakou hodnotu do HL, kdyz by BC bylo vyhodnejsi. Takze se muze stat, ze to nacte do HL, potom do HL nacte neco bliz koncove a pak klidne do nevyuziteho BC nacte co bylo prvne v HL...
Reseni co me napadlo bylo, udelat stinove makro co ma stejne pravdila a jen zjisti zda do BC neco nacitame a pokud ano tak to tam nacte a opusti stinovou funkci. Pak se vola normalni, ale uz s tim ze v BC mame nastavenou hodnotu.

Ukazka BEZ a pak SE stinovou funkci.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSHS(0x3333,10,(10),0x3333,0,(10))'

    push DE             ; 1:11      0x3333 10 (10) 0x3333 0 (10)
    push HL             ; 1:11      0x3333 10 (10) 0x3333 0 (10)
    ld   HL, 0x3333     ; 3:10      0x3333 10 (10) 0x3333 0 (10)
    push HL             ; 1:11      0x3333 10 (10) 0x3333 0 (10)
    ld   DE, 0x000A     ; 3:10      0x3333 10 (10) 0x3333 0 (10)
    push DE             ; 1:11      0x3333 10 (10) 0x3333 0 (10)
    ld   HL, (10)       ; 3:16      0x3333 10 (10) 0x3333 0 (10)
    push HL             ; 1:11      0x3333 10 (10) 0x3333 0 (10)
    ld   BC, 0x3333     ; 3:10      0x3333 10 (10) 0x3333 0 (10)
    push BC             ; 1:11      0x3333 10 (10) 0x3333 0 (10)
    ld    E, D          ; 1:4       0x3333 10 (10) 0x3333 0 (10)   E = D = 0x00
                       ;[19:116]
0 seconds
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSHS(0x3333,10,(10),0x3333,0,(10))'

    push DE             ; 1:11      0x3333 10 (10) 0x3333 0 (10)
    push HL             ; 1:11      0x3333 10 (10) 0x3333 0 (10)
    ld   BC, 0x3333     ; 3:10      0x3333 10 (10) 0x3333 0 (10)
    push BC             ; 1:11      0x3333 10 (10) 0x3333 0 (10)
    ld   DE, 0x000A     ; 3:10      0x3333 10 (10) 0x3333 0 (10)
    push DE             ; 1:11      0x3333 10 (10) 0x3333 0 (10)
    ld   HL, (10)       ; 3:16      0x3333 10 (10) 0x3333 0 (10)
    push HL             ; 1:11      0x3333 10 (10) 0x3333 0 (10)
    push BC             ; 1:11      0x3333 10 (10) 0x3333 0 (10)
    ld    E, D          ; 1:4       0x3333 10 (10) 0x3333 0 (10)   E = D = 0x00
                       ;[16:106]
0 seconds


Pak jsem premyslel jak udelat v M4 bruteforce prohledavani... ale narazel jsem na problem s tim ze potrebuji lokalni promenne u rekurzivniho makra a nechtelo se mi delat jmena typu "hodnota_COUNTER". Pouzit zasobnik pushdef a popdef me nenapadlo hm... muzu zkusit zda to nebude rychlejsi...
Vyresil jsem to tak ze jsou lokalni promenne ulozene jako vstupni parametry. Omezeni je ze jdou menit jen pri volani dalsi rekurze. Mam to jako FUNKCE(CENA,HL,DE,BC,pole_hodnot_co_se_uklada). Takze prvni polozka pole je az $5. Na konci se zjisti zda CENA je mensi nez __CHECK_PUSH_BEST a pokud ano, tak se __CHECK_PUSH_BEST aktualizuje.

Ale vysledek byl fakt POMALY. Protoze se to exponencionalne zpomaluje. A navic vysledky byly stejne jako ma prvni funkce. A pokud oddelam predvypocet BC tak i horsi... Zkusil jsem to drobne upravit aby nepokracoval ve vypoctu kdyz $1 je vetsi nez __CHECK_PUSH_BEST a bylo to skoro 3x rychlejsi, ale stale to neni moc pouzitelne. Jen pro jiny zpusob jak resit vypocet pro mensi hloubku pro prvni metodu.

Prvni je prvni metoda s BC a druhe je Bruteforce bez BC a treti to same s orezavanim.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSHS(0,(10),0,10,10,0,10,0,(10))'

    push DE             ; 1:11      0 (10) 0 10 10 0 10 0 (10)
    push HL             ; 1:11      0 (10) 0 10 10 0 10 0 (10)
    ld   BC, 0x000A     ; 3:10      0 (10) 0 10 10 0 10 0 (10)
    ld    E, B          ; 1:4       0 (10) 0 10 10 0 10 0 (10)   E = B = 0x00
    ld    D, E          ; 1:4       0 (10) 0 10 10 0 10 0 (10)   D = E = 0x00
    push DE             ; 1:11      0 (10) 0 10 10 0 10 0 (10)
    ld   HL, (10)       ; 3:16      0 (10) 0 10 10 0 10 0 (10)
    push HL             ; 1:11      0 (10) 0 10 10 0 10 0 (10)
    push DE             ; 1:11      0 (10) 0 10 10 0 10 0 (10)
    push BC             ; 1:11      0 (10) 0 10 10 0 10 0 (10)
    push BC             ; 1:11      0 (10) 0 10 10 0 10 0 (10)
    push DE             ; 1:11      0 (10) 0 10 10 0 10 0 (10)
    push BC             ; 1:11      0 (10) 0 10 10 0 10 0 (10)
                       ;[17:133]
1 seconds
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSHS(0,(10),0,10,10,0,10,0,(10))'

    push DE             ; 1:11      0 (10) 0 10 10 0 10 0 (10)
    push HL             ; 1:11      0 (10) 0 10 10 0 10 0 (10)
    ld   DE, 0x0000     ; 3:10      0 (10) 0 10 10 0 10 0 (10)
    push DE             ; 1:11      0 (10) 0 10 10 0 10 0 (10)
    ld   HL, (10)       ; 3:16      0 (10) 0 10 10 0 10 0 (10)
    push HL             ; 1:11      0 (10) 0 10 10 0 10 0 (10)
    push DE             ; 1:11      0 (10) 0 10 10 0 10 0 (10)
    ld   BC, 0x000A     ; 3:10      0 (10) 0 10 10 0 10 0 (10)
    push BC             ; 1:11      0 (10) 0 10 10 0 10 0 (10)
    push BC             ; 1:11      0 (10) 0 10 10 0 10 0 (10)
    push DE             ; 1:11      0 (10) 0 10 10 0 10 0 (10)
    push BC             ; 1:11      0 (10) 0 10 10 0 10 0 (10)
                       ;[18:135]
259 seconds
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSHS(0,(10),0,10,10,0,10,0,(10))'

    push DE             ; 1:11      0 (10) 0 10 10 0 10 0 (10)
    push HL             ; 1:11      0 (10) 0 10 10 0 10 0 (10)
    ld   DE, 0x0000     ; 3:10      0 (10) 0 10 10 0 10 0 (10)
    push DE             ; 1:11      0 (10) 0 10 10 0 10 0 (10)
    ld   HL, (10)       ; 3:16      0 (10) 0 10 10 0 10 0 (10)
    push HL             ; 1:11      0 (10) 0 10 10 0 10 0 (10)
    push DE             ; 1:11      0 (10) 0 10 10 0 10 0 (10)
    ld   BC, 0x000A     ; 3:10      0 (10) 0 10 10 0 10 0 (10)
    push BC             ; 1:11      0 (10) 0 10 10 0 10 0 (10)
    push BC             ; 1:11      0 (10) 0 10 10 0 10 0 (10)
    push DE             ; 1:11      0 (10) 0 10 10 0 10 0 (10)
    push BC             ; 1:11      0 (10) 0 10 10 0 10 0 (10)
                       ;[18:135]
90 seconds


Zvonil me budik tak to dnes nedopisi...

PS: Tak aspon jen poznamku ze i to BF s BC neumi byt optimalni, protoze zalezi i zda na zacatku to udela

ld BC, neco
ld DE, neco

a nebo

ld DE, neco
ld BC, neco

protoze to nekdy jde zapsat jako

ld DE, 0x0010
ld B,E
ld C,E

nebo naopak.

Pak neumi uprostred si vyhmatnout nejakou hodnotu co zrovna nepotrebuje, ale bude pozdeji a ted je nejlepsi cas ji odnekud vzit...

jako napr.

ld H,C

PPS: Jsem fakt prekvapeny ze ta prvni metoda s dodatkem v BC je tak efektivni.

Kód:
define({__BRUTEFORCE_CHECK_PUSH_REC},{dnl
__{}ifelse(dnl
__{}eval($1>=__CHECK_PUSH_BEST),1,{},
__{}$#,5,{dnl
__{}__{}__LD_REG16({HL},$5,{HL},$2,{DE},$3,{BC},$4){}dnl
__{}__{}ifelse(eval(__CHECK_PUSH_BEST>($1+__PRICE_16BIT)),1,{define({__CHECK_PUSH_BEST},eval($1+__PRICE_16BIT))}){}dnl
__{}},
__{}$#,6,{dnl
__{}__{}__RESET_ADD_LD_REG16{}dnl
__{}__{}__ADD_LD_REG16({DE},$5,{HL},$2,{DE},$3,{BC},$4){}dnl
__{}__{}__ADD_LD_REG16({HL},$6,{HL},$2,{DE},$5,{BC},$4){}dnl
__{}__{}ifelse(eval(__CHECK_PUSH_BEST>($1+__SUM_PRICE_16BIT)),1,{define({__CHECK_PUSH_BEST},eval($1+__SUM_PRICE_16BIT))}){}dnl
__{}},
__{}{dnl
__{}__{}__LD_REG16({HL},$5,{HL},$2,{DE},$3,{BC},$4){}dnl
__{}__{}$0(eval($1+__PRICE_16BIT),$5,$3,$4,shift(shift(shift(shift(shift($@)))))){}dnl
__{}__{}__LD_REG16({DE},$5,{HL},$2,{DE},$3,{BC},$4){}dnl
__{}__{}$0(eval($1+__PRICE_16BIT),$2,$5,$4,shift(shift(shift(shift(shift($@)))))){}dnl
__{}__{}__LD_REG16({BC},$5,{HL},$2,{DE},$3,{BC},$4){}dnl
__{}__{}$0(eval($1+__PRICE_16BIT),$2,$3,$5,shift(shift(shift(shift(shift($@)))))){}dnl
__{}}){}dnl
}){}dnl
dnl
dnl
dnl
define({__BRUTEFORCE_PUSHS_REC},{dnl
__{}ifelse(dnl
__{}$#,1,{dnl
__{}__{}__LD_REG16({HL},$1,{HL},__REG_HL,{DE},__REG_DE,{BC},__REG_BC){}__CODE_16BIT},
__{}$#,2,{dnl
__{}__{}__LD_REG16({DE},$1,{HL},__REG_HL,{DE},__REG_DE,{BC},__REG_BC){}__CODE_16BIT{}dnl
__{}__{}__LD_REG16({HL},$2,{HL},__REG_HL,{DE},      $1,{BC},__REG_BC){}__CODE_16BIT},
__{}{dnl
__{}__{}define({__CHECK_PUSH_BEST},0x7FFFFFFF){}dnl
__{}__{}__LD_REG16({HL},$1,{HL},__REG_HL,{DE},__REG_DE,{BC},__REG_BC){}dnl
__{}__{}__BRUTEFORCE_CHECK_PUSH_REC(__PRICE_16BIT,      $1,__REG_DE,__REG_BC,shift($@)){}dnl
__{}__{}define({__CHECK_PUSH_HL_BEST},__CHECK_PUSH_BEST){}dnl
__{}__{}dnl
__{}__{}define({__CHECK_PUSH_BEST},0x7FFFFFFF){}dnl
__{}__{}__LD_REG16({DE},$1,{HL},__REG_HL,{DE},__REG_DE,{BC},__REG_BC){}dnl
__{}__{}__BRUTEFORCE_CHECK_PUSH_REC(__PRICE_16BIT,__REG_HL,      $1,__REG_BC,shift($@)){}dnl
__{}__{}define({__CHECK_PUSH_DE_BEST},__CHECK_PUSH_BEST){}dnl
__{}__{}dnl
__{}__{}define({__CHECK_PUSH_BEST},0x7FFFFFFF){}dnl
__{}__{}__LD_REG16({BC},$1,{HL},__REG_HL,{DE},__REG_DE,{BC},__REG_BC){}dnl
__{}__{}__BRUTEFORCE_CHECK_PUSH_REC(__PRICE_16BIT,__REG_HL,__REG_DE,      $1,shift($@)){}dnl
__{}__{}define({__CHECK_PUSH_BC_BEST},__CHECK_PUSH_BEST){}dnl
__{}__{}dnl
__{}__{}ifelse(eval((__CHECK_PUSH_BC_BEST<__CHECK_PUSH_DE_BEST)&&(__CHECK_PUSH_BC_BEST<__CHECK_PUSH_HL_BEST)),1,{dnl
__{}__{}__{}__LD_REG16({BC},$1,{HL},__REG_HL,{DE},__REG_DE,{BC},__REG_BC){}dnl
__{}__{}__{}__CODE_16BIT{}dnl
__{}__{}__{}define({__REG_BC},$1)
__{}__{}__{}    push BC             ; 1:11      __INFO},
__{}__{}eval(__CHECK_PUSH_DE_BEST<__CHECK_PUSH_HL_BEST),1,{dnl
__{}__{}__{}__LD_REG16({DE},$1,{HL},__REG_HL,{DE},__REG_DE,{BC},__REG_BC){}dnl
__{}__{}__{}__CODE_16BIT{}dnl
__{}__{}__{}define({__REG_DE},$1)
__{}__{}__{}    push DE             ; 1:11      __INFO},
__{}__{}{dnl
__{}__{}__{}__LD_REG16({HL},$1,{HL},__REG_HL,{DE},__REG_DE,{BC},__REG_BC){}dnl
__{}__{}__{}__CODE_16BIT{}dnl
__{}__{}__{}define({__REG_HL},$1)
__{}__{}__{}    push HL             ; 1:11      __INFO{}dnl
__{}__{}}){}dnl
__{}__{}$0(shift($@)){}dnl
__{}}){}dnl
}){}dnl


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 15.11.2022, 18:26 
Offline
Profík

Registrován: 23.06.2013, 23:49
Příspěvky: 870
Has thanked: 71 times
Been thanked: 133 times
Vyzkousel jsem prepsat tu BF rekurzi, abych mel v poli jen jednu polozku navic a registry si drzel ve vlastnich zasobnicich pomoci pushdef a popdef a na cas to nemelo zadny vliv.
Predhodil jsem tomu trolovaci data kdy nalakam DE a HL na koncove hodnoty a pak prohazuji dve konstanty. Tohle odrovna ten jednoduchy algoritmus, protoze se nepokusi uvolnit DE a nebo HL a vytrvale bude znovu a znovu nacitat hodnoty do BC.
BF to odhali, ale nevim proc uvolni HL misto DE, coz by melo byt o 6 taktu kratsi!!!
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH4(0,(10),0x1431,0x3333,0x1431,0x3333,0,(10)) __SHOW_TOKEN(1)'
 
; name: __TOKEN_PUSHS
; info: 0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
;items: 8
;param: (0,(10),0x1431,0x3333,0x1431,0x3333,0,(10))
;array1: >0<
;array2: >(10)<
;array3: >0x1431<
;array: 0,(10),0x1431,0x3333,0x1431,0x3333,0,(10)
    push DE             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    push HL             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    ld   DE, 0x0000     ; 3:10      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    push DE             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    ld   HL, (10)       ; 3:16      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    push HL             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    ld   HL, 0x1431     ; 3:10      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    push HL             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    ld   BC, 0x3333     ; 3:10      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    push BC             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    push HL             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    push BC             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    ld   HL, (10)       ; 3:16      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
                       ;[23:150]
43 seconds
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH4(0,(10),0x1431,0x3333,0x1431,0x3333,0,(10)) __SHOW_TOKEN(1)'
 
; name: __TOKEN_PUSHS
; info: 0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
;items: 8
;param: (0,(10),0x1431,0x3333,0x1431,0x3333,0,(10))
;array1: >0<
;array2: >(10)<
;array3: >0x1431<
;array: 0,(10),0x1431,0x3333,0x1431,0x3333,0,(10)
    push DE             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    push HL             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    ld   HL, 0x0000     ; 3:10      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    push HL             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    ld   HL, (10)       ; 3:16      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    push HL             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    ld   DE, 0x1431     ; 3:10      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    push DE             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    ld   BC, 0x3333     ; 3:10      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    push BC             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    push DE             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    push BC             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    ld   DE, 0x0000     ; 3:10      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
                       ;[23:144]
43 seconds

Oh, ted vidim ze druha (nova) varianta to prece udelala spravne, nekde mam teda chybu v puvodnim kodu... Cas jit do prace.


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 16.11.2022, 03:20 
Offline
Profík

Registrován: 23.06.2013, 23:49
Příspěvky: 870
Has thanked: 71 times
Been thanked: 133 times
Hmm... zitra mam celodenni takze nemam cas se v tom moc vrtat. Dival jsem se na ten kod a nenasel jsem chybu. Tak jsem se dival na ten novy, zda to nedela lepsi kod protoze je blbe ten a ani tam jsem nenasel chybu. Vzhledem k tomu ze jsem to psal skoro cely copy+paste tak tomu fakt nerozumim. Puvodni ma vetsi sanci byt spatne (mohou byt oba), protoze ten algoritmus by to mel najit...

Napsal jsem jeste kratsi verzi testu a zase si to prohodi i kdyz maji stejny vysledek. Mimochodem treti verze je psana rucne s jednim trikem co me napadl v pondeli v praci.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH4(0,(10),0x1431,0x3333,0x1431,0,(10)) __SHOW_TOKEN(1)'
 
; name: __TOKEN_PUSHS
; info: 0 (10) 0x1431 0x3333 0x1431 0 (10)
;items: 7
;param: (0,(10),0x1431,0x3333,0x1431,0,(10))
;array1: >0<
;array2: >(10)<
;array3: >0x1431<
;array: 0,(10),0x1431,0x3333,0x1431,0,(10)
    push DE             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0 (10)
    push HL             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0 (10)
    ld   DE, 0x0000     ; 3:10      0 (10) 0x1431 0x3333 0x1431 0 (10)
    push DE             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0 (10)
    ld   HL, (10)       ; 3:16      0 (10) 0x1431 0x3333 0x1431 0 (10)
    push HL             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0 (10)
    ld   BC, 0x1431     ; 3:10      0 (10) 0x1431 0x3333 0x1431 0 (10)
    push BC             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0 (10)
    ld   BC, 0x3333     ; 3:10      0 (10) 0x1431 0x3333 0x1431 0 (10)
    push BC             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0 (10)
    ld   BC, 0x1431     ; 3:10      0 (10) 0x1431 0x3333 0x1431 0 (10)
    push BC             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0 (10)
                       ;[22:133]
14 seconds
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH4(0,(10),0x1431,0x3333,0x1431,0,(10)) __SHOW_TOKEN(1)'
 
; name: __TOKEN_PUSHS
; info: 0 (10) 0x1431 0x3333 0x1431 0 (10)
;items: 7
;param: (0,(10),0x1431,0x3333,0x1431,0,(10))
;array1: >0<
;array2: >(10)<
;array3: >0x1431<
;array: 0,(10),0x1431,0x3333,0x1431,0,(10)
    push DE             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0 (10)
    push HL             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0 (10)
    ld   HL, 0x0000     ; 3:10      0 (10) 0x1431 0x3333 0x1431 0 (10)
    push HL             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0 (10)
    ld   HL, (10)       ; 3:16      0 (10) 0x1431 0x3333 0x1431 0 (10)
    push HL             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0 (10)
    ld   DE, 0x1431     ; 3:10      0 (10) 0x1431 0x3333 0x1431 0 (10)
    push DE             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0 (10)
    ld   BC, 0x3333     ; 3:10      0 (10) 0x1431 0x3333 0x1431 0 (10)
    push BC             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0 (10)
    push DE             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0 (10)
    ld   DE, 0x0000     ; 3:10      0 (10) 0x1431 0x3333 0x1431 0 (10)
                       ;[22:133]
53 seconds
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ cat smaz.txt | ../count.sh
    push DE             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0 (10)
    push HL             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0 (10)
    ld   DE, 0x0000     ; 3:10      0 (10) 0x1431 0x3333 0x1431 0 (10)
    push DE             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0 (10)
    ld   HL, (10)       ; 3:16      0 (10) 0x1431 0x3333 0x1431 0 (10)
    push HL             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0 (10)
    ld   BC, 0x1431     ; 3:10      0 (10) 0x1431 0x3333 0x1431 0 (10)
    push BC             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0 (10)
    push HL             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0 (10)
    ld   HL, 0x3333     ; 3:10      0 (10) 0x1431 0x3333 0x1431 0 (10)
    ex  (SP),HL         ; 1:19      0 (10) 0x1431 0x3333 0x1431 0 (10)
    push BC             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0 (10)
                       ;[20:142]

Je o 2 bajty krasti, ale o 9 taktu pomalejsi.

Novy kod vypada takto, muzete porovnat s tim co jsem ukazal predtim.
Kód:
define({__BRUTEFORCE_CHECK_PUSH_REC2},{dnl
__{}ifelse(dnl
__{}eval($1>=__CHECK_PUSH_BEST),1,{},
__{}$#,2,{dnl
__{}__{}__LD_REG16({HL},$2,{HL},__REG_HL,{DE},__REG_DE,{BC},__REG_BC){}dnl
__{}__{}ifelse(eval(__CHECK_PUSH_BEST>($1+__PRICE_16BIT)),1,{define({__CHECK_PUSH_BEST},eval($1+__PRICE_16BIT))}){}dnl
__{}},
__{}$#,3,{dnl
__{}__{}__RESET_ADD_LD_REG16{}dnl
__{}__{}__ADD_LD_REG16({DE},$2,{HL},__REG_HL,{DE},__REG_DE,{BC},__REG_BC){}dnl
__{}__{}__ADD_LD_REG16({HL},$3,{HL},__REG_HL,{DE},      $2,{BC},__REG_BC){}dnl
__{}__{}ifelse(eval(__CHECK_PUSH_BEST>($1+__SUM_PRICE_16BIT)),1,{define({__CHECK_PUSH_BEST},eval($1+__SUM_PRICE_16BIT))}){}dnl
__{}},
__{}{dnl
__{}__{}__LD_REG16({HL},$2,{HL},__REG_HL,{DE},__REG_DE,{BC},__REG_BC){}dnl
__{}__{}pushdef({__REG_HL}){}dnl
__{}__{}define({__REG_HL},$2){}dnl
__{}__{}$0(eval($1+__PRICE_16BIT),shift(shift($@))){}dnl
__{}__{}popdef({__REG_HL}){}dnl
__{}__{}dnl
__{}__{}__LD_REG16({DE},$2,{HL},__REG_HL,{DE},__REG_DE,{BC},__REG_BC){}dnl
__{}__{}pushdef({__REG_DE}){}dnl
__{}__{}define({__REG_DE},$2){}dnl
__{}__{}$0(eval($1+__PRICE_16BIT),shift(shift($@))){}dnl
__{}__{}popdef({__REG_DE}){}dnl
__{}__{}dnl
__{}__{}__LD_REG16({BC},$2,{HL},__REG_HL,{DE},__REG_DE,{BC},__REG_BC){}dnl
__{}__{}pushdef({__REG_BC}){}dnl
__{}__{}define({__REG_BC},$2){}dnl
__{}__{}$0(eval($1+__PRICE_16BIT),shift(shift($@))){}dnl
__{}__{}popdef({__REG_BC}){}dnl
__{}}){}dnl
}){}dnl
dnl
dnl
dnl
define({__BRUTEFORCE_PUSHS_REC2},{dnl
__{}ifelse(dnl
__{}$#,1,{dnl
__{}__{}__LD_REG16({HL},$1,{HL},__REG_HL,{DE},__REG_DE,{BC},__REG_BC){}__CODE_16BIT},
__{}$#,2,{dnl
__{}__{}__LD_REG16({DE},$1,{HL},__REG_HL,{DE},__REG_DE,{BC},__REG_BC){}__CODE_16BIT{}dnl
__{}__{}__LD_REG16({HL},$2,{HL},__REG_HL,{DE},      $1,{BC},__REG_BC){}__CODE_16BIT},
__{}{dnl
__{}__{}define({__CHECK_PUSH_BEST},0x7FFFFFFF){}dnl
__{}__{}__LD_REG16({HL},$1,{HL},__REG_HL,{DE},__REG_DE,{BC},__REG_BC){}dnl
__{}__{}pushdef({__REG_HL}){}dnl
__{}__{}define({_REG_HL},$1){}dnl
__{}__{}__BRUTEFORCE_CHECK_PUSH_REC2(__PRICE_16BIT,shift($@)){}dnl
__{}__{}popdef({__REG_HL}){}dnl
__{}__{}define({__CHECK_PUSH_HL_BEST},__CHECK_PUSH_BEST){}dnl
__{}__{}dnl
__{}__{}define({__CHECK_PUSH_BEST},0x7FFFFFFF){}dnl
__{}__{}__LD_REG16({DE},$1,{HL},__REG_HL,{DE},__REG_DE,{BC},__REG_BC){}dnl
__{}__{}pushdef({__REG_DE}){}dnl
__{}__{}define({_REG_DE},$1){}dnl
__{}__{}__BRUTEFORCE_CHECK_PUSH_REC2(__PRICE_16BIT,shift($@)){}dnl
__{}__{}popdef({__REG_DE}){}dnl
__{}__{}define({__CHECK_PUSH_DE_BEST},__CHECK_PUSH_BEST){}dnl
__{}__{}dnl
__{}__{}define({__CHECK_PUSH_BEST},0x7FFFFFFF){}dnl
__{}__{}__LD_REG16({BC},$1,{HL},__REG_HL,{DE},__REG_DE,{BC},__REG_BC){}dnl
__{}__{}pushdef({__REG_BC}){}dnl
__{}__{}define({_REG_BC},$1){}dnl
__{}__{}__BRUTEFORCE_CHECK_PUSH_REC2(__PRICE_16BIT,shift($@)){}dnl
__{}__{}popdef({__REG_BC}){}dnl
__{}__{}define({__CHECK_PUSH_BC_BEST},__CHECK_PUSH_BEST){}dnl
__{}__{}dnl
__{}__{}ifelse(eval((__CHECK_PUSH_BC_BEST<__CHECK_PUSH_DE_BEST)&&(__CHECK_PUSH_BC_BEST<__CHECK_PUSH_HL_BEST)),1,{dnl
__{}__{}__{}__LD_REG16({BC},$1,{HL},__REG_HL,{DE},__REG_DE,{BC},__REG_BC){}dnl
__{}__{}__{}__CODE_16BIT{}dnl
__{}__{}__{}define({__REG_BC},$1)
__{}__{}__{}    push BC             ; 1:11      __INFO},
__{}__{}eval(__CHECK_PUSH_DE_BEST<__CHECK_PUSH_HL_BEST),1,{dnl
__{}__{}__{}__LD_REG16({DE},$1,{HL},__REG_HL,{DE},__REG_DE,{BC},__REG_BC){}dnl
__{}__{}__{}__CODE_16BIT{}dnl
__{}__{}__{}define({__REG_DE},$1)
__{}__{}__{}    push DE             ; 1:11      __INFO},
__{}__{}{dnl
__{}__{}__{}__LD_REG16({HL},$1,{HL},__REG_HL,{DE},__REG_DE,{BC},__REG_BC){}dnl
__{}__{}__{}__CODE_16BIT{}dnl
__{}__{}__{}define({__REG_HL},$1)
__{}__{}__{}    push HL             ; 1:11      __INFO{}dnl
__{}__{}}){}dnl
__{}__{}$0(shift($@)){}dnl
__{}}){}dnl
}){}dnl


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

Registrován: 23.06.2013, 23:49
Příspěvky: 870
Has thanked: 71 times
Been thanked: 133 times
Napsal jsem jeste v noci treti verzi, kde jsem pouzil myslenku, ze nema cenu zjistovat (volat fci) pro kazdou hodnotu pole ktery ze tri registru HL,DE,BC se ma na tu hodnotu nastavit, kdyz uz u prvni hodnoty se to cele spocita az do konce. Takze pokud si nekam ulozim optimalni "cestu", tak usetrim cca 25% casu.
Cestu ukladam jako retezec cisel kde "1" znaci HL, "2" znaci DE a "3" BC. Musel jsem pro to napsat rekurzivni makro co to prevede na kod, to jsem pozdeji upravil tak ze to tiskne jen do zarazky "-".

Pomoci tisku toho retezce cesty jsem zjistil ze me v prubehu vypoctu najde nejlepsi reseni a pote ho zahodi a "cena" toho reseni je jina nez by mela byt. Takze jsem to postupne rucne krokoval, az nasel chybu mimo muj kod. Byla schovana v __LD_REG16(). Pokud je totiz pozadovano nacteni dat z pointeru tak to resi jina vetev kodu a tam jsem zapomel vynulovat __BYTES_16BIT a __CLOCKS_16BIT. Takze i kdyz to spravne generovalo kod tak pokud byl kod prazdny retezec, protoze registr uz drzel hodnotu tak cena byla stejna jako z predchoziho vypoctu... To me spravilo prvni funkci, uz generuje spravny kod, ale duvod proc se to lisilo od druhe stale nechapu. Mely byt chybne oba nebo ani jeden.

Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH4(0,(10),0x1431,0x3333,0x1431,0x3333,0,(10)) __SHOW_TOKEN(1)'
 
; name: __TOKEN_PUSHS
; info: 0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
;items: 8
;param: (0,(10),0x1431,0x3333,0x1431,0x3333,0,(10))
;array1: >0<
;array2: >(10)<
;array3: >0x1431<
;array: 0,(10),0x1431,0x3333,0x1431,0x3333,0,(10)
    push DE             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    push HL             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    ld   HL, 0x0000     ; 3:10      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    push HL             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    ld   HL, (10)       ; 3:16      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    push HL             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    ld   DE, 0x1431     ; 3:10      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    push DE             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    ld   BC, 0x3333     ; 3:10      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    push BC             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    push DE             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    push BC             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    ld   DE, 0x0000     ; 3:10      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
                       ;[23:144]
14 seconds
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH4(0,(10),0x1431,0x3333,0x1431,0,(10)) __SHOW_TOKEN(1)'
 
; name: __TOKEN_PUSHS
; info: 0 (10) 0x1431 0x3333 0x1431 0 (10)
;items: 7
;param: (0,(10),0x1431,0x3333,0x1431,0,(10))
;array1: >0<
;array2: >(10)<
;array3: >0x1431<
;array: 0,(10),0x1431,0x3333,0x1431,0,(10)
    push DE             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0 (10)
    push HL             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0 (10)
    ld   HL, 0x0000     ; 3:10      0 (10) 0x1431 0x3333 0x1431 0 (10)
    push HL             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0 (10)
    ld   HL, (10)       ; 3:16      0 (10) 0x1431 0x3333 0x1431 0 (10)
    push HL             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0 (10)
    ld   DE, 0x1431     ; 3:10      0 (10) 0x1431 0x3333 0x1431 0 (10)
    push DE             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0 (10)
    ld   BC, 0x3333     ; 3:10      0 (10) 0x1431 0x3333 0x1431 0 (10)
    push BC             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0 (10)
    push DE             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0 (10)
    ld   DE, 0x0000     ; 3:10      0 (10) 0x1431 0x3333 0x1431 0 (10)
                       ;[22:133]
7 seconds
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$


Protoze i pres zrychleni ten vypocet zpomaluje exponencialne tak jsem napsal ctvrtou variantu, kde pouzivam kombinaci BruteForce rekurze a puvodniho algoritmu kde se testuje jak to pak sedi na konci.

Pro kazdou hodnotu se to vola se ctyrmi nasledujicimi parametry ke kterym se pridaji 2 koncove parametry a to co bylo mezitim se vynecha. Takove opakovane BF nad 6 hodnotama. Tim to dokaze odhalit to 0x1431, 0x3333, 0x1431, 0x3333, posledni_DE, posledni_HL. Proto jsem potreboval aby ta tisknouci funkce umela "-".

Problem byl stale vstup typu 0,0,0,0,0,0,0, ... 0,0,0,0x8765,0x4321. Generovalo se to prilis dlouho. Nakonec jsem pridal do BruteForce kodu pred zjistovanim ktery ze tri registru je nejlepsi varianta test na kazdy registr, zda uz nedrzi vyslednou hodnotu.
Kód:
__{}__{}__REG_HL,$3,{$0($1,$2{}1,shift(shift(shift($@))))},
__{}__{}__REG_DE,$3,{$0($1,$2{}2,shift(shift(shift($@))))},
__{}__{}__REG_BC,$3,{$0($1,$2{}3,shift(shift(shift($@))))},
Pokud drzi nema cenu zjistovat rekurzivne ktery je nejlepsi a rovnou vybrat ten co uz tu hodnotu ma. (Ma to drobnou chybku ze to delam pres porovnani retezcu a ne hodnot, takze pokud je to cislo zapsane jinak tak to nepozna, a kdyz bych pridal zase ze porovnavam hodnoty tak se to zase spomali, ale mozna ne o tolik, musim vyzkouset. Hmm.. ale zase nemusim resit zda neporovnavam jablka s hruskama, hodnotu a odkaz nebo jmeno promenne)

Tohle vylepseni me v podstate vygeneruje kod pro to cislo se spousty nul na zacatku okamzite a zrychli to i ten testovaci vypocet. Takze tam kde jsem mel cca 43 sekund puvodne, pak 14 sekund, to jsou ted 4 sekundy. (Je to shodne s verzi bez posledniho 0x3333)
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH4(0,(10),0x1431,0x3333,0x1431,0x3333,0,(10)) __SHOW_TOKEN(1)'
 
; name: __TOKEN_PUSHS
; info: 0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
;items: 8
;param: (0,(10),0x1431,0x3333,0x1431,0x3333,0,(10))
;array1: >0<
;array2: >(10)<
;array3: >0x1431<
;array: 0,(10),0x1431,0x3333,0x1431,0x3333,0,(10)
    push DE             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    push HL             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    ld   DE, 0x0000     ; 3:10      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    push DE             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    ld   HL, (10)       ; 3:16      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    push HL             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    ld   DE, 0x1431     ; 3:10      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    push DE             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    ld   BC, 0x3333     ; 3:10      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    push BC             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    push DE             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    push BC             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
    ld   DE, 0x0000     ; 3:10      0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
                       ;[23:144]
4 seconds
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH4(0,(10),0x1431,0x3333,0x1431,0,(10)) __SHOW_TOKEN(1)'
 
; name: __TOKEN_PUSHS
; info: 0 (10) 0x1431 0x3333 0x1431 0 (10)
;items: 7
;param: (0,(10),0x1431,0x3333,0x1431,0,(10))
;array1: >0<
;array2: >(10)<
;array3: >0x1431<
;array: 0,(10),0x1431,0x3333,0x1431,0,(10)
    push DE             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0 (10)
    push HL             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0 (10)
    ld   DE, 0x0000     ; 3:10      0 (10) 0x1431 0x3333 0x1431 0 (10)
    push DE             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0 (10)
    ld   HL, (10)       ; 3:16      0 (10) 0x1431 0x3333 0x1431 0 (10)
    push HL             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0 (10)
    ld   DE, 0x1431     ; 3:10      0 (10) 0x1431 0x3333 0x1431 0 (10)
    push DE             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0 (10)
    ld   BC, 0x3333     ; 3:10      0 (10) 0x1431 0x3333 0x1431 0 (10)
    push BC             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0 (10)
    push DE             ; 1:11      0 (10) 0x1431 0x3333 0x1431 0 (10)
    ld   DE, 0x0000     ; 3:10      0 (10) 0x1431 0x3333 0x1431 0 (10)
                       ;[22:133]
4 seconds


PS: Kdyz uz mam tu cestu tak by stalo za uvahu tam nejak implementovat ten trik s tim BC co se predpocita dopredu a pak umisti na zacatek. Tady to mohu vytahnout z te cesty. A nejen BC.
Kód:
define({__BRUTEFORCE_CHECK_PUSH_REC3},{dnl
__{}ifelse(dnl
__{}eval($1>=__CHECK_PUSH_BEST),1,{},
dnl __{}$#,3,{dnl
dnl __{}__{}__LD_REG16({HL},$3,{HL},__REG_HL,{DE},__REG_DE,{BC},__REG_BC){}dnl
dnl __{}__{}ifelse(eval(__CHECK_PUSH_BEST>($1+__PRICE_16BIT)),1,{dnl
dnl __{}__{}__{}define({__CHECK_PUSH_BEST},eval($1+__PRICE_16BIT)){}dnl
dnl __{}__{}__{}define({__CHECK_PUSH_BEST_PATH},$2){}dnl
dnl errprint({
dnl },__CHECK_PUSH_BEST:__CHECK_PUSH_BEST_PATH{}){}dnl
dnl __{}__{}}){}dnl
dnl __{}},
__{}$#,4,{dnl
__{}__{}__RESET_ADD_LD_REG16{}dnl
__{}__{}__ADD_LD_REG16({DE},$3,{HL},__REG_HL,{DE},__REG_DE,{BC},__REG_BC){}dnl
__{}__{}__ADD_LD_REG16({HL},$4,{HL},__REG_HL,{DE},      $3,{BC},__REG_BC){}dnl
__{}__{}ifelse(eval(__CHECK_PUSH_BEST>($1+__SUM_PRICE_16BIT)),1,{dnl
__{}__{}__{}define({__CHECK_PUSH_BEST},eval($1+__SUM_PRICE_16BIT)){}dnl
__{}__{}__{}define({__CHECK_PUSH_BEST_PATH},$2){}dnl
__{}__{}}){}dnl
__{}},
__{}{dnl
__{}__{}ifelse(dnl
__{}__{}__REG_HL,$3,{$0($1,$2{}1,shift(shift(shift($@))))},
__{}__{}__REG_DE,$3,{$0($1,$2{}2,shift(shift(shift($@))))},
__{}__{}__REG_BC,$3,{$0($1,$2{}3,shift(shift(shift($@))))},
__{}__{}{dnl
__{}__{}__{}__LD_REG16({HL},$3,{HL},__REG_HL,{DE},__REG_DE,{BC},__REG_BC){}dnl
__{}__{}__{}pushdef({__REG_HL}){}dnl
__{}__{}__{}define({__REG_HL},$3){}dnl
__{}__{}__{}$0(eval($1+__PRICE_16BIT),$2{}1,shift(shift(shift($@)))){}dnl
__{}__{}__{}popdef({__REG_HL}){}dnl
__{}__{}__{}dnl
__{}__{}__{}__LD_REG16({DE},$3,{HL},__REG_HL,{DE},__REG_DE,{BC},__REG_BC){}dnl
__{}__{}__{}pushdef({__REG_DE}){}dnl
__{}__{}__{}define({__REG_DE},$3){}dnl
__{}__{}__{}$0(eval($1+__PRICE_16BIT),$2{}2,shift(shift(shift($@)))){}dnl
__{}__{}__{}popdef({__REG_DE}){}dnl
__{}__{}__{}dnl
__{}__{}__{}__LD_REG16({BC},$3,{HL},__REG_HL,{DE},__REG_DE,{BC},__REG_BC){}dnl
__{}__{}__{}pushdef({__REG_BC}){}dnl
__{}__{}__{}define({__REG_BC},$3){}dnl
__{}__{}__{}$0(eval($1+__PRICE_16BIT),$2{}3,shift(shift(shift($@)))){}dnl
__{}__{}__{}popdef({__REG_BC}){}dnl
__{}__{}}){}dnl
__{}}){}dnl
}){}dnl
dnl
dnl
dnl
define({__PRINT_PUSH_REC3},{dnl
__{}ifelse(dnl
__{}$1,{},{dnl
__{}__{}__LD_REG16({DE},$2,{HL},__REG_HL,{DE},__REG_DE,{BC},__REG_BC){}dnl
__{}__{}__CODE_16BIT{}dnl
__{}__{}define({__REG_DE},$2){}dnl
__{}__{}__LD_REG16({HL},$3,{HL},__REG_HL,{DE},__REG_DE,{BC},__REG_BC){}dnl
__{}__{}__CODE_16BIT{}dnl
__{}__{}define({__REG_HL},$3){}dnl
__{}},
__{}substr($1,0,1),{-},{},
__{}substr($1,0,1),1,{dnl
__{}__{}__LD_REG16({HL},$2,{HL},__REG_HL,{DE},__REG_DE,{BC},__REG_BC){}dnl
__{}__{}__CODE_16BIT{}dnl
__{}__{}define({__REG_HL},$2)
__{}__{}    push HL             ; 1:11      __INFO{}dnl
__{}__{}$0(substr($1,1),shift(shift($@))){}dnl
__{}},
__{}substr($1,0,1),2,{dnl
__{}__{}__LD_REG16({DE},$2,{HL},__REG_HL,{DE},__REG_DE,{BC},__REG_BC){}dnl
__{}__{}__CODE_16BIT{}dnl
__{}__{}define({__REG_DE},$2)
__{}__{}    push DE             ; 1:11      __INFO{}dnl
__{}__{}$0(substr($1,1),shift(shift($@))){}dnl
__{}},
__{}substr($1,0,1),3,{dnl
__{}__{}__LD_REG16({BC},$2,{HL},__REG_HL,{DE},__REG_DE,{BC},__REG_BC){}dnl
__{}__{}__CODE_16BIT{}dnl
__{}__{}define({__REG_BC},$2)
__{}__{}    push BC             ; 1:11      __INFO{}dnl
__{}__{}$0(substr($1,1),shift(shift($@))){}dnl
__{}}){}dnl
}){}dnl
dnl
dnl
dnl
define({__BRUTEFORCE_PUSHS_REC3},{dnl
__{}define({__CHECK_PUSH_BEST},0x7FFFFFFF){}dnl
__{}__BRUTEFORCE_CHECK_PUSH_REC3(0,,$@){}dnl
__{}__PRINT_PUSH_REC3(__CHECK_PUSH_BEST_PATH,$@){}dnl
}){}dnl
dnl
dnl
dnl
define({__BRUTEFORCE_PUSHS_REC4},{dnl
__{}ifelse($#,0,{},
__{}$#,1,{
__{}__{}  .error {$0}($@)},
__{}$#,2,{__BRUTEFORCE_PUSHS_REC3($@)},
__{}$#,3,{__BRUTEFORCE_PUSHS_REC3($@)},
__{}$#,4,{__BRUTEFORCE_PUSHS_REC3($@)},
__{}$#,5,{__BRUTEFORCE_PUSHS_REC3($@)},
__{}$#,6,{__BRUTEFORCE_PUSHS_REC3($@)},
__{}{dnl
__{}__{}define({__CHECK_PUSH_BEST},0x7FFFFFFF){}dnl
__{}__{}__BRUTEFORCE_CHECK_PUSH_REC3(0,,$1,$2,$3,$4,__LAST_REG_DE,__LAST_REG_HL){}dnl
__{}__{}__PRINT_PUSH_REC3(substr(__CHECK_PUSH_BEST_PATH,0,1){-},$@){}dnl
__{}__{}$0(shift($@)){}dnl
__{}}){}dnl
}){}dnl


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 17.11.2022, 23:42 
Offline
Profík

Registrován: 23.06.2013, 23:49
Příspěvky: 870
Has thanked: 71 times
Been thanked: 133 times
Tak jsem to kompletne zase prepsal (musel jsem vytvorit promennou pro celou cestu a fci pro pocitani kolik stoji vypis te cesty) a promazal, aby byla jen jedna metoda. Ted to zkousi postupne pridat na zacatek nastaveni HL, pak DE a nakonec BC a pokud je to lepsi nez to bylo predtim tak to zapise.

Ukazka vzdy dvou "inverznich" vstupu, kdy se jednou to vyplati prohodit a podruhe ne.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH4(80,(10),80,0,0,80,0,80,(10)) __SHOW_TOKEN(1)'
 
; name: __TOKEN_PUSHS
; info: 80 (10) 80 0 0 80 0 80 (10)
;items: 9
;param: (80,(10),80,0,0,80,0,80,(10))
;array1: >80<
;array2: >(10)<
;array3: >80<
;array: 80,(10),80,0,0,80,0,80,(10)
    push DE             ; 1:11      80 (10) 80 0 0 80 0 80 (10)
    push HL             ; 1:11      80 (10) 80 0 0 80 0 80 (10)
    ld   DE, 0x0050     ; 3:10      80 (10) 80 0 0 80 0 80 (10)
    push DE             ; 1:11      80 (10) 80 0 0 80 0 80 (10)
    ld   HL, (10)       ; 3:16      80 (10) 80 0 0 80 0 80 (10)
    push HL             ; 1:11      80 (10) 80 0 0 80 0 80 (10)
    push DE             ; 1:11      80 (10) 80 0 0 80 0 80 (10)
    ld    C, D          ; 1:4       80 (10) 80 0 0 80 0 80 (10)   C = D = 0x00
    ld    B, C          ; 1:4       80 (10) 80 0 0 80 0 80 (10)   B = C = 0x00
    push BC             ; 1:11      80 (10) 80 0 0 80 0 80 (10)
    push BC             ; 1:11      80 (10) 80 0 0 80 0 80 (10)
    push DE             ; 1:11      80 (10) 80 0 0 80 0 80 (10)
    push BC             ; 1:11      80 (10) 80 0 0 80 0 80 (10)
                       ;[17:133]
1 seconds
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH4(0,(10),0,10,10,0,10,0,(10)) __SHOW_TOKEN(1)'
 
; name: __TOKEN_PUSHS
; info: 0 (10) 0 10 10 0 10 0 (10)
;items: 9
;param: (0,(10),0,10,10,0,10,0,(10))
;array1: >0<
;array2: >(10)<
;array3: >0<
;array: 0,(10),0,10,10,0,10,0,(10)
    push DE             ; 1:11      0 (10) 0 10 10 0 10 0 (10)
    push HL             ; 1:11      0 (10) 0 10 10 0 10 0 (10)
    ld   BC, 0x000A     ; 3:10      0 (10) 0 10 10 0 10 0 (10)
    ld    E, B          ; 1:4       0 (10) 0 10 10 0 10 0 (10)   E = B = 0x00
    ld    D, E          ; 1:4       0 (10) 0 10 10 0 10 0 (10)   D = E = 0x00
    push DE             ; 1:11      0 (10) 0 10 10 0 10 0 (10)
    ld   HL, (10)       ; 3:16      0 (10) 0 10 10 0 10 0 (10)
    push HL             ; 1:11      0 (10) 0 10 10 0 10 0 (10)
    push DE             ; 1:11      0 (10) 0 10 10 0 10 0 (10)
    push BC             ; 1:11      0 (10) 0 10 10 0 10 0 (10)
    push BC             ; 1:11      0 (10) 0 10 10 0 10 0 (10)
    push DE             ; 1:11      0 (10) 0 10 10 0 10 0 (10)
    push BC             ; 1:11      0 (10) 0 10 10 0 10 0 (10)
                       ;[17:133]
1 seconds
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH4(0,10,0,0,0,0,0,0,10) __SHOW_TOKEN(1)'
 
; name: __TOKEN_PUSHS
; info: 0 10 0 0 0 0 0 0 10
;items: 9
;param: (0,10,0,0,0,0,0,0,10)
;array1: >0<
;array2: >10<
;array3: >0<
;array: 0,10,0,0,0,0,0,0,10
    push DE             ; 1:11      0 10 0 0 0 0 0 0 10
    push HL             ; 1:11      0 10 0 0 0 0 0 0 10
    ld   HL, 0x000A     ; 3:10      0 10 0 0 0 0 0 0 10
    ld    E, H          ; 1:4       0 10 0 0 0 0 0 0 10   E = H = 0x00
    ld    D, E          ; 1:4       0 10 0 0 0 0 0 0 10   D = E = 0x00
    push DE             ; 1:11      0 10 0 0 0 0 0 0 10
    push HL             ; 1:11      0 10 0 0 0 0 0 0 10
    push DE             ; 1:11      0 10 0 0 0 0 0 0 10
    push DE             ; 1:11      0 10 0 0 0 0 0 0 10
    push DE             ; 1:11      0 10 0 0 0 0 0 0 10
    push DE             ; 1:11      0 10 0 0 0 0 0 0 10
    push DE             ; 1:11      0 10 0 0 0 0 0 0 10
                       ;[14:117]
1 seconds
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH4(10,0,10,10,10,10,10,10,0) __SHOW_TOKEN(1)'
 
; name: __TOKEN_PUSHS
; info: 10 0 10 10 10 10 10 10 0
;items: 9
;param: (10,0,10,10,10,10,10,10,0)
;array1: >10<
;array2: >0<
;array3: >10<
;array: 10,0,10,10,10,10,10,10,0
    push DE             ; 1:11      10 0 10 10 10 10 10 10 0
    push HL             ; 1:11      10 0 10 10 10 10 10 10 0
    ld   DE, 0x000A     ; 3:10      10 0 10 10 10 10 10 10 0
    push DE             ; 1:11      10 0 10 10 10 10 10 10 0
    ld    L, D          ; 1:4       10 0 10 10 10 10 10 10 0   L = D = 0x00
    ld    H, L          ; 1:4       10 0 10 10 10 10 10 10 0   H = L = 0x00
    push HL             ; 1:11      10 0 10 10 10 10 10 10 0
    push DE             ; 1:11      10 0 10 10 10 10 10 10 0
    push DE             ; 1:11      10 0 10 10 10 10 10 10 0
    push DE             ; 1:11      10 0 10 10 10 10 10 10 0
    push DE             ; 1:11      10 0 10 10 10 10 10 10 0
    push DE             ; 1:11      10 0 10 10 10 10 10 10 0
                       ;[14:117]
1 seconds
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$


Za me je tohle uz docela prijatelna fce a uz se me nechce v tom vice drbat, dokud nezjistim nejake chyby...

PS: Mozna tak jedine pridat tam ten trik s EX (SP),HL. Ale ten bude efektivni jen pokud budou vstupy same pointery.

PPS: A taky by to chtelo mozna trosku ocesat ten zivelny kod... .)


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 22.11.2022, 04:17 
Offline
Profík

Registrován: 23.06.2013, 23:49
Příspěvky: 870
Has thanked: 71 times
Been thanked: 133 times
Stale pracuji na tom prevodu PUSH,PUSH2,PUSH3,PUSH4 na PUSHS.

Samostatne tokeny __TOKEN_PUSH,__TOKEN_PUSH2, atd uz nemam. Pri volani PUSH2(10,30) se rovnou vytvari token __TOKEN_PUSHS(10,30).
Slova PUSH2, PUSH3 atd jsem nerusil, takze se nemusi menit zdrojaky, ale ciste reseni by bylo asi mit jen PUSH a PUSHS.
Na __ASM_TOKEN_PUSH2 atd, coz je primo zdrojak pro to slovo se nic nemeni, vola ho primo __ASM_TOKEN_PUSHS pokud zrovna obsahuje 2 parametry.

Problem co mam je spravit pravidla v tokenech, kde se to XXX+PUSH?+XXX jen hemzi.

Rozdelil jsem to na dve varianty. PUSHS+XXX a XXX+PUSHS.
Prvni varianta se zadava stejnym zpusobem jak dosud (proste se pridava do fronty jeden token za druhym, pripadne se edituje predposledni atd.), zato druha varianta kde se nejake slovo spojuje s PUSHS se musela udelat uplne nove.

Tesne pred pocatkem vytvarenim zdrojaku pro frotnu tokenu se jeste jednou projede od prvniho tokenu cela fronta a porovnavaji se predchozi a nasledujici token a pokud to pasuje na XXX+PUSHS tak se predchozi token jen zmeni na __TOKEN_NOPE, ktery vyvari prazdny zdrojak. Je to skoro jako smazani tokenu, jen nemenim cislovani ani nedelam mezery. Hledam cestu nejmensiho odporu. A nasledujici se prejmenuje na __TOKEN_XXX_PUSHS.

Proc to delam? Protoze prvne PUSHS+XXX slova maji mnohem lepsi optimalizace. Napriklad PUSHS(10,0) DO. Je mnohem vic dulezitejsi nez napriklad FETCH PUSHS(10,0). Obe kombinace se daji ale optimalizovat.

Pokud udelam token pro FETCH_PUSHS, tak najednou musim vytvorit nasobne vic tokenu.
Token pro FETCH_PUSHS_DO
pravidlo pro FETCH_PUSHS_ADD
pravidlo pro FETCH_PUSHS+PUSHS=FETCH_PUSHS
proste pro vsechny tokeny typu PUSHS+XXX.

Proto misto toho abych udelal sum(XXX+PUSHS)*sum(PUSHS+XXX) tokenu jsem to rozdelil.

Jak ale rikam tech pravidel bylo hodne a je tam hodne pravidel jen pro jeden PUSH+XXX a musel jsem to upravovat na univerzalni PUSHS+XXX.

Lepim to pomoci toho makra co jsem mel pro PUSHS, jen jsem zjistil ze obecny makro je vlastne "2DROP+PUSHS" a samotne PUSHS je uz specialni pripad kdy udelam

push DE
push HL
volam makro pro 2DROP+PUSHS ktere uz ignoruje co bylo v DE a HL.

Atd DUP+PUSHS je:

push DE
push HL
push HL (to je to DUP)
volam makro pro 2DROP+PUSHS...

PS: Prejmenoval jsem pocitadlo tokenu z __TOKEN_COUNT na __CONT_TOKEN, protozeto bylo hloupe, kdyz __TOKEN_xxx je vyhrazeno pro slova, takze bych si blokoval slovo COUNT. Doslo me to az kdyz jsem vytvarel slovo __TOKEN_SUM, protoze COUNT protrebuji pouzit znovu jako index pro to druhe prochazeni fronty (nemusim pak menit pomocna makra) a __SUM_TOKEN drzi celkovy pocet.


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 22.11.2022, 05:34 
Offline
Profík

Registrován: 23.06.2013, 23:49
Příspěvky: 870
Has thanked: 71 times
Been thanked: 133 times
Lol, narazil jsem na tento kod a vypada to jako pekna divocina. Nedokazi zjistit zda je to dobre...
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'DUP  PUSH(5,10) WITHIN IF __SHOW_TOKEN(1) __SHOW_TOKEN(2)'
     
; name: __TOKEN_DUP
; info: dup
;items: 0
;param: ()
;array1: ><
;array2: ><
;array3: ><
;array: 
; name: __TOKEN_PUSH2_WITHIN_IF
; info: 5 10 within if
;items: 2
;param: (5,10)
;array1: >5<
;array2: >10<
;array3: ><
;array: 5,10
                        ;[15:54]    dup 5 10 within if   ( x -- x )  true=(5<=x<10)
    ld    A, L          ; 1:4       dup 5 10 within if
    sub   0x05          ; 2:7       dup 5 10 within if
    ld    B, H          ; 1:4       dup 5 10 within if
    jr   nc, $+3        ; 2:7/12    dup 5 10 within if
    dec   B             ; 1:4       dup 5 10 within if   BA = TOS-(5)
    sub  0x05           ; 2:7       dup 5 10 within if
    ld    A, B          ; 1:4       dup 5 10 within if
    sbc   A, 0x00       ; 2:7       dup 5 10 within if   carry: BC - (10 - (5))
    jp   nc, else101    ; 3:10      dup 5 10 within if
                       ;[15:54]
0 seconds

Hmm... ale asi mozna je.
Vypada to ze to resim pres
(HL - 5) < (10-5)

Asi bych to resil spis pomoci
Kód:
    ld    A, H          ; 1:4       dup 5 10 within if
    or    A             ; 1:4       dup 5 10 within if
    jp   nz, else101    ; 3:10      dup 5 10 within if
    ld    A, L          ; 1:4       dup 5 10 within if
    sub   0x05          ; 2:7       dup 5 10 within if
    sub  0x05           ; 2:7       dup 5 10 within if
    jp   nc, else101    ; 3:10      dup 5 10 within if
                       ;[13:46]

Jen je to generovany pres ruzne vetveni a prvne se dela prvni polovina kodu, takze to nebude snadne to tam pridat...

Hmm... navic to vraci carry protoze to posledni jp uz neni soucast kodu... takze by to vypadalo spis
Kód:
    ld    A, H          ; 1:4       dup 5 10 within if
    or    A             ; 1:4       dup 5 10 within if
    jr   nz, $+7        ; 2:7/12    dup 5 10 within if
    ld    A, L          ; 1:4       dup 5 10 within if
    sub   0x05          ; 2:7       dup 5 10 within if
    sub  0x05           ; 2:7       dup 5 10 within if
    jp   nc, else101    ; 3:10      dup 5 10 within if
                       ;[12:43]


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 01.12.2022, 14:11 
Offline
Profík

Registrován: 23.06.2013, 23:49
Příspěvky: 870
Has thanked: 71 times
Been thanked: 133 times
Zjistil jsem ze nemam tokenova pravidla pro double + nejaka operace.

Opravoval jsem kod pro pushdot_dand a kdyz jsem zadal "pushdot dand" tak se to nespojilo.

Prvne jsem delal nova slova push2_dadd a push2_dsub, ktere jsem predelaval z pushdot_dadd a pushdot_dsub. Tohle me zjednodusilo dost pravidla. Protoze se snazim uplne zbavit tokenu pushdot a vse resit pres pushs.

Pushdot se prevadi automaticky na pushs s dvema hodnotami. Nefunguje to jen u neznameho jmena. 32 bitovou hodnotu prevede M4 hned, odkaz se rozsekne na ((ptr)+2) a (ptr).Pokud se to misto pushdot zadava primo pres push2 tak to umoznuje i ruzne kombinace ukazatele a hodnoty pro jedno 32 bitove cislo.

Udelal jsem proto i nova slova push2_dand, push2_dor a push2_dxor. Taky jednoduchym prevodem z pushdot_dand, ...

Napsal jsem tokenova pravidla a zjistil ze je nemam uplne dobre.

Prvne jsem treba zjistoval zda posledni 4 parametry v pushs jsou hodnoty a pokud ano volal funkci __EVAL_S32().

U and, or a xor jsem ale zjistil ze mi vlastne staci zjistit zda posledni 4 parametry v pushs nejsou ukazatele a volat dvakrat __EVAL_S16(), ktera to umi zpracovat i pro nezname 16 bitove hodnoty.

Pak jsem to jeste vic zkomplikoval ze rovnou prvne testuji zda to pro kazdy par ta __EVAL_S16() dokaze spocitat.

Napriklad "0 and (ukazatel)" je 0 a nebo "-1 and (ukazatel)" je (ukazatel). Opravil jsem __EVAL_S16() kdy neumel zpracovat "0 xor (ukazatel)" pripadne "(ukazatel) xor 0.

Pak jsem resil ostatni pripady a doiteroval k dalsim pravidlum. Kdyz to nedokaze odchytit predchozi pravidla tak se tam nekde vyskytuje "(ukazatel1) operace (ukazatel2)" a nebo "(ukazatel1) operace spatna_hodnota", pripadne s prohozenyma parametrama.

Takze prvne zjistim zda vyssi dvojslovo tu operaci zvladne a pokud ano tak mohu volat push_and, push_or nebo push_xor na nizsi 16 bitovou hodnotu. Tam to jeste upravuji tak ze do toho push_operace pokud to jde leze hodnota a ne ukazatel.

Takze to pak vypada uvnitr nejak takto pushs(...,...,...,...,hi1 operace hi2,(lo1)) push_operace(lo2).

Pokud je to naopak a mohu spocitat spodni 16 bitovou hodnotu, tak by me stacilo to prohodit parametry a nakonec volat jeden swap (ex DE,HL). Jenze to jde jeste lepe, takze jsem udelal slovo swap_push_operace_swap. A vysledek vypada jako kdyz jde spocitat hi.

Radsi ukazi nejaky kod.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH2(0x33,0x0000,(656),(abc)) DAND __SHOW_TOKEN(1) __SHOW_TOKEN(2)'

__eval_op_num_xxx_pasmo({&},{0x0000},{(abc)})
; name: __TOKEN_PUSHS
; info: 0x33 0x0000 (656) (abc) dand
;items: 2
;param: ((656),            0)
;array1: >(656)<
;array2: >0<
;array: (656),0
; name: __TOKEN_SWAP_PUSH_AND_SWAP
; info: 0x33 0x0000 (656) (abc) dand
;items: 1
;param: (0x33)
;array1: >0x33<
;array: 0x33
                        ;[9:52]     0x33 0x0000 (656) (abc) dand   ( -- (656) 0 )
    push DE             ; 1:11      0x33 0x0000 (656) (abc) dand
    push HL             ; 1:11      0x33 0x0000 (656) (abc) dand
    ld   DE, (656)      ; 4:20      0x33 0x0000 (656) (abc) dand
    ld   HL, 0x0000     ; 3:10      0x33 0x0000 (656) (abc) dand
    ld    A, 0x33       ; 2:7       0x33 0x0000 (656) (abc) dand
    and   E             ; 1:4       0x33 0x0000 (656) (abc) dand
    ld    E, A          ; 1:4       0x33 0x0000 (656) (abc) dand
    ld    D, 0x00       ; 2:7       0x33 0x0000 (656) (abc) dand
; seconds: 0           ;[15:74]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH2(0,0x33,(656),(abc)) DAND __SHOW_TOKEN(1) __SHOW_TOKEN(2)'

__eval_op_num_xxx_pasmo({&},{0},{(656)})
; name: __TOKEN_PUSHS
; info: 0 0x33 (656) (abc) dand
;items: 2
;param: (            0,(abc))
;array1: >0<
;array2: >(abc)<
;array: 0,(abc)
; name: __TOKEN_PUSH_AND
; info: 0 0x33 (656) (abc) dand
;items: 1
;param: (0x33)
;array1: >0x33<
;array: 0x33
                        ;[8:48]     0 0x33 (656) (abc) dand   ( -- 0 (abc) )
    push DE             ; 1:11      0 0x33 (656) (abc) dand
    push HL             ; 1:11      0 0x33 (656) (abc) dand
    ld   DE, 0x0000     ; 3:10      0 0x33 (656) (abc) dand
    ld   HL, (abc)      ; 3:16      0 0x33 (656) (abc) dand
    ld    A, 0x33       ; 2:7       0 0x33 (656) (abc) dand
    and   L             ; 1:4       0 0x33 (656) (abc) dand
    ld    L, A          ; 1:4       0 0x33 (656) (abc) dand
    ld    H, 0x00       ; 2:7       0 0x33 (656) (abc) dand
; seconds: 0           ;[14:70]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$

Je to asi nejlepsi reseni, i kdyz to muze stale trochu drhnout. Treba u prvni ukazky nepotrebuji nacitat z pameti vyssi bajt.
Kód:
    ld   DE, (656)      ; 4:20      0x33 0x0000 (656) (abc) dand

stacilo by neco jako
Kód:
    ld    A, (656)      ; 3:13      0x33 0x0000 (656) (abc) dand
    ld    E, A          ; 1:4       0x33 0x0000 (656) (abc) dand
Ale tohle by bylo uz fakt moc komplexni.

Posledni pripad je ze nedokazi spocitat ani jeden par. Pak zase nezavisle na vyssi a nizsi hodnote se do push2_operace snazim nacpat hodnotu, protoze je pak kod efektivnejsi.
V teto ukazce je to videt ze se to jakoby provede vnitrne prvne 2swap a az pak vola dand.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH2(0x1100,0x33,(656),(abc)) DAND __SHOW_TOKEN(1) __SHOW_TOKEN(2)'
; name: __TOKEN_PUSHS
; info: 0x1100 0x33 (656) (abc) dand
;items: 2
;param: ((656),(abc))
;array1: >(656)<
;array2: >(abc)<
;array: (656),(abc)
; name: __TOKEN_PUSH2_DAND
; info: 0x1100 0x33 (656) (abc) dand
;items: 2
;param: (0x1100,0x33)
;array1: >0x1100<
;array2: >0x33<
;array: 0x1100,0x33
                        ;[9:58]     0x1100 0x33 (656) (abc) dand   ( -- (656) (abc) )
    push DE             ; 1:11      0x1100 0x33 (656) (abc) dand
    push HL             ; 1:11      0x1100 0x33 (656) (abc) dand
    ld   DE, (656)      ; 4:20      0x1100 0x33 (656) (abc) dand
    ld   HL, (abc)      ; 3:16      0x1100 0x33 (656) (abc) dand
    ld    A, 0x33       ; 2:7       0x1100 0x33 (656) (abc) dand
    and   L             ; 1:4       0x1100 0x33 (656) (abc) dand
    ld    L, A          ; 1:4       0x1100 0x33 (656) (abc) dand
    ld    H, 0x00       ; 2:7       0x1100 0x33 (656) (abc) dand
    ld    E, 0x00       ; 2:7       0x1100 0x33 (656) (abc) dand
    ld    A, 0x11       ; 2:7       0x1100 0x33 (656) (abc) dand
    and   D             ; 1:4       0x1100 0x33 (656) (abc) dand
    ld    D, A          ; 1:4       0x1100 0x33 (656) (abc) dand
; seconds: 0           ;[21:102]

Tohle se vola i v pripade ze pred dand jsou v pushs jen dva parametry Pripad pro 3 parametry a pak doperace jsem neresil.

Docela zajimave hrani.


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 01.12.2022, 21:58 
Offline
Profík

Registrován: 23.06.2013, 23:49
Příspěvky: 870
Has thanked: 71 times
Been thanked: 133 times
Hmm... koukam v tom poslednim kodu je
Kód:
    ld    H, 0x00       ; 2:7       0x1100 0x33 (656) (abc) dand
    ld    E, 0x00       ; 2:7       0x1100 0x33 (656) (abc) dand

Protoze se HL a DE resi nezavisle pres __AND_REG16_16BIT()

Kód:
dnl # ( d1 -- d )
dnl # d = d1 & n
define({PUSH2_DAND},{dnl
__{}__ADD_TOKEN({__TOKEN_PUSH2_DAND},{$1 $2 d&},$@){}dnl
}){}dnl
dnl
define({__ASM_TOKEN_PUSH2_DAND},{dnl
__{}define({__INFO},__COMPILE_INFO){}dnl
ifelse(eval($#<2),1,{
__{}  .error {$0}($@): Missing address parameter!},
eval($#>2),{1},{
__{}  .error {$0}($@): $# parameters found in macro!},
{dnl
__{}__{}define({_TMP_INFO},__COMPILE_INFO){}dnl
__{}__{}__AND_REG16_16BIT({HL},$2){}dnl
__{}__{}__AND_REG16_16BIT({DE},$1){}dnl
})}){}dnl


__AND_REG16_16BIT({HL},0x0000)
__AND_REG16_16BIT({DE},0x1234)

__AND_REG16_16BIT({DE},0x1234)
__AND_REG16_16BIT({HL},0x0000)

__AND_REG16_16BIT({DE},0x1200)
__AND_REG16_16BIT({HL},0x0000)

__AND_REG16_16BIT({DE},0x0000)
__AND_REG16_16BIT({HL},0x0034)

__AND_REG16_16BIT({HL},0x0000)
__AND_REG16_16BIT({DE},0x0000)

Tech kombinaci muze byt docela dost, to abych konecne vyresil predavani konstant(znamych hodnot) v registrech a nebo udelal __AND_REG32_32BIT().


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 01.12.2022, 23:31 
Offline
Profík

Registrován: 23.06.2013, 23:49
Příspěvky: 870
Has thanked: 71 times
Been thanked: 133 times
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH2(0x1100,0x33,(656),(abc)) DAND __SHOW_TOKEN(1) __SHOW_TOKEN(2)'
; name: __TOKEN_PUSHS
; info: 0x1100 0x33 (656) (abc) dand
;items: 2
;param: ((656),(abc))
;array1: >(656)<
;array2: >(abc)<
;array: (656),(abc)
; name: __TOKEN_PUSH2_DAND
; info: 0x1100 0x33 (656) (abc) dand
;items: 2
;param: (0x1100,0x33)
;array1: >0x1100<
;array2: >0x33<
;array: 0x1100,0x33
                        ;[9:58]     0x1100 0x33 (656) (abc) dand   ( -- (656) (abc) )
    push DE             ; 1:11      0x1100 0x33 (656) (abc) dand
    push HL             ; 1:11      0x1100 0x33 (656) (abc) dand
    ld   DE, (656)      ; 4:20      0x1100 0x33 (656) (abc) dand
    ld   HL, (abc)      ; 3:16      0x1100 0x33 (656) (abc) dand
    ld    A, 0x33       ; 2:7       0x1100 0x33 (656) (abc) dand
    and   L             ; 1:4       0x1100 0x33 (656) (abc) dand
    ld    L, A          ; 1:4       0x1100 0x33 (656) (abc) dand
    ld    H, 0x00       ; 2:7       0x1100 0x33 (656) (abc) dand
    ld    E, H          ; 1:4       0x1100 0x33 (656) (abc) dand
    ld    A, 0x11       ; 2:7       0x1100 0x33 (656) (abc) dand
    and   D             ; 1:4       0x1100 0x33 (656) (abc) dand
    ld    D, A          ; 1:4       0x1100 0x33 (656) (abc) dand
; seconds: 0           ;[20:99]


Pridal jsem dalsi parametry $3 a $4 do __AND_REG16_16BIT()

Kód:
define({__AND_REG16_16BIT},{dnl
dnl # Input
dnl #   $1 name reg pair
dnl #   $2 16bit value
dnl #   $3 name reg
dnl #   $4 8bit value with hex form 0xNN, $3 = $4
ifelse(dnl
__IS_MEM_REF($2),{1},{
__{}    ld    A,format({%-12s},$2); 3:13      _TMP_INFO
__{}    and   substr($1,1,1)             ; 1:4       _TMP_INFO
__{}    ld    substr($1,1,1), A          ; 1:4       _TMP_INFO
__{}    ld    A,format({%-12s},($2+1)); 3:13      _TMP_INFO
__{}    and   substr($1,0,1)             ; 1:4       _TMP_INFO
__{}    ld    substr($1,0,1), A          ; 1:4       _TMP_INFO},
__IS_NUM($2),{0},{
__{}  .warning {$0}($@): M4 does not know the "{$2}" value and therefore cannot optimize the code.
__{}  if (($2) = 0x0000)
__{}    ld   $1, 0x0000     ; 3:10      _TMP_INFO
__{}  else{}dnl
__{}__AND_REG8_8BIT(substr($1,1,1),0xFF & ($2)){}dnl
__{}__AND_REG8_8BIT(substr($1,0,1),+($2) >> 8)
__{}  endif},
{dnl
__{}ifelse(__HEX_HL($2),{0x0000},{
__{}    ld   $1, 0x0000     ; 3:10      _TMP_INFO},
__{}{dnl
__{}__{}__AND_REG8_8BIT(substr($1,1,1),__HEX_L($2),$3,$4){}dnl
__{}__{}__AND_REG8_8BIT(substr($1,0,1),__HEX_H($2),$3,$4){}dnl
})})}){}dnl


Takze jsem je musel pridat i do __AND_REG8_8BIT, a tam resi pripad kdy potrebujeme vlozit do registru nulu a tu nulu uz ma registr $3, pripadne to resi i pripad kdy potrebujeme Rx = Rx & const a Ry = const. Makro cast ktera je na zacatku jsem radsi nemenil...

Kód:
define({__AND_REG8_8BIT},{dnl
dnl # Input
dnl #   $1 name reg
dnl #   $2 8bit value with hex form 0xNN
dnl #   $3 name reg
dnl #   $4 8bit value with hex form 0xNN, $3 = $4
dnl # Output
dnl #   code $1 = $1 and $2
ifelse(__IS_NUM($2),{0},{
__{}   if (($2) = 0x00)
__{}     ld    $1, 0x00       ; 2:7       _TMP_INFO
__{}   else
__{}    if (($2) = 0xFE)
__{}      res   0, $1          ; 2:8       _TMP_INFO
__{}    else
__{}     if (($2) = 0xFD)
__{}       res   1, $1          ; 2:8       _TMP_INFO
__{}     else
__{}      if (($2) = 0xFB)
__{}        res   2, $1          ; 2:8       _TMP_INFO
__{}      else
__{}       if (($2) = 0xF7)
__{}         res   3, $1          ; 2:8       _TMP_INFO
__{}       else
__{}        if (($2) = 0xEF)
__{}          res   4, $1          ; 2:8       _TMP_INFO
__{}        else
__{}         if (($2) = 0xDF)
__{}           res   5, $1          ; 2:8       _TMP_INFO
__{}         else
__{}          if (($2) = 0xBF)
__{}            res   6, $1          ; 2:8       _TMP_INFO
__{}          else
__{}           if (($2) = 0x7F)
__{}             res   7, $1          ; 2:8       _TMP_INFO
__{}           else
__{}            if ((($2) > 0x00) && (($2) <= 0xFF))
__{}              ld    A,format({%-12s},$2); 2:7       _TMP_INFO
__{}              and   $1             ; 1:4       _TMP_INFO
__{}              ld    $1, A          ; 1:4       _TMP_INFO
__{}            endif
__{}           endif
__{}          endif
__{}         endif
__{}        endif
__{}       endif
__{}      endif
__{}     endif
__{}    endif
__{}   endif},
{dnl
__{}ifelse(__HEX_L($2),{0xFF},{},
__{}$1:$2,$3:$4,{
__{}__{}                        ;           _TMP_INFO   $1 = $2},
__{}$2:$4,{0x00:0x00},{
__{}__{}    ld    $1, $3          ; 1:4       _TMP_INFO},
__{}__HEX_L($2),{0x00},{
__{}__{}    ld    $1, 0x00       ; 2:7       _TMP_INFO},
__{}__HEX_L($2),{0xFE},{
__{}__{}    res   0, $1          ; 2:8       _TMP_INFO},
__{}__HEX_L($2),{0xFD},{
__{}__{}    res   1, $1          ; 2:8       _TMP_INFO},
__{}__HEX_L($2),{0xFB},{
__{}__{}    res   2, $1          ; 2:8       _TMP_INFO},
__{}__HEX_L($2),{0xF7},{
__{}__{}    res   3, $1          ; 2:8       _TMP_INFO},
__{}__HEX_L($2),{0xEF},{
__{}__{}    res   4, $1          ; 2:8       _TMP_INFO},
__{}__HEX_L($2),{0xDF},{
__{}__{}    res   5, $1          ; 2:8       _TMP_INFO},
__{}__HEX_L($2),{0xBF},{
__{}__{}    res   6, $1          ; 2:8       _TMP_INFO},
__{}__HEX_L($2),{0x7F},{
__{}__{}    res   7, $1          ; 2:8       _TMP_INFO},
__{}$2,$4,{
__{}__{}    ld    A, $3          ; 1:4       _TMP_INFO
__{}__{}    and   $1             ; 1:4       _TMP_INFO
__{}__{}    ld    $1, A          ; 1:4       _TMP_INFO},
__{}{
__{}__{}    ld    A, __HEX_L($2)       ; 2:7       _TMP_INFO
__{}__{}    and   $1             ; 1:4       _TMP_INFO
__{}__{}    ld    $1, A          ; 1:4       _TMP_INFO})})}){}dnl


A to samotne __PUSH2_DAND vypada ted takto
Kód:
dnl # ( d1 -- d )
dnl # d = d1 & n
define({PUSH2_DAND},{dnl
__{}__ADD_TOKEN({__TOKEN_PUSH2_DAND},{$1 $2 d&},$@){}dnl
}){}dnl
dnl
define({__ASM_TOKEN_PUSH2_DAND},{dnl
__{}define({__INFO},__COMPILE_INFO){}dnl
ifelse(eval($#<2),1,{
__{}  .error {$0}($@): Missing address parameter!},
eval($#>2),{1},{
__{}  .error {$0}($@): $# parameters found in macro!},
{dnl
__{}define({_TMP_INFO},__COMPILE_INFO){}dnl
__{}__AND_REG16_16BIT({HL},$2){}dnl
__{}ifelse(dnl
__{}__HEX_L($2),0x00,{__AND_REG16_16BIT({DE},$1,{L},0x00)},
__{}__HEX_H($2),0x00,{__AND_REG16_16BIT({DE},$1,{H},0x00)},
__{}{__AND_REG16_16BIT({DE},$1)}){}dnl
})}){}dnl

Vyuziva to triku, ze kdyz neni v kazdem 16bitovem slove 8 bitova nula tak se to stejne neda zlepsit, takze zadne prohozeni (nastesti) nepomaha.

PS: Uz mam najednou 7 hvezdicek na githubu! :o Dlouho byly tri nedavno 5 a ted 7. Nekde se o tom musel nekdo zminit. Nebo ze by ty samotne hvezdicky to posouvaly v githubu vic dopredu ve vyhledavani neceho kde je FORTH Z80 ZX? https://github.com/DW0RKiN/M4_FORTH/stargazers

PPS: Sakra mam tam chybu... pridal jsem do __AND_REG16_16BIT() atd podporu pro ukazatele a ty makra s tim nepocitaji. Ted me ukazuji ze se snazi zjistit zda
Kód:
   if ((0xFF & (abc)) = 0x00)
     ld    E, 0x00       ; 2:7       abc 0x33 (656) (abc) dand
chjo...

PPPS: Uf! Tak je to dobre. To abc v zavorce je prvni parametr...
Kód:
   if ((0xFF & (xxx)) = 0x00)
     ld    E, 0x00       ; 2:7       xxx 0x33 (656) (abc) dand


PPPPS: Vetsina tech co mi davaji hvezdicky maji zajimave repozitare. Napriklad tohle dokaze skladat kod Z80 jako puzzle. :shock:
https://github.com/haroldo-ok/blockly-z80
Příloha:
blockly-z80.png
blockly-z80.png [ 143.56 KiB | Zobrazeno 154 krát ]


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 02.12.2022, 03:27 
Offline
Profík

Registrován: 23.06.2013, 23:49
Příspěvky: 870
Has thanked: 71 times
Been thanked: 133 times
Opravena chyba v PUSH3.

Nejak me to menilo "656" na "+(656)".
Dival jsem se na kod a radsi jsem ho napsal cely znovu.
Uploadnu to ale az v sobotu rano.
U toho jsem zmenil poradi tokenovych pravidel pro XOR (AND,OR) takze to hned nevytvari PUSH_XOR pokud je jeden parametr pointer, kdyz je sance ze druhy bude nula.

Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(0,0,(656),0) XOR __SHOW_TOKEN(1)'
; name: __TOKEN_PUSHS
; info: 0 0 (656) 0 xor
;items: 3
;param: (0,0,(656))
;array1: >0<
;array2: >0<
;array3: >(656)<
;array: 0,0,(656)
    push DE             ; 1:11      0 0 (656) 0 xor   ( -- 0 0 (656) )
    push HL             ; 1:11      0 0 (656) 0 xor
    ld   DE, 0          ; 3:10      0 0 (656) 0 xor
    push DE             ; 1:11      0 0 (656) 0 xor
    ld   HL, +(656)     ; 3:10      0 0 (656) 0 xor
; seconds: 1           ;[ 9:53]

Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(0,0,(656),0) XOR __SHOW_TOKEN(1)'
; name: __TOKEN_PUSHS
; info: 0 0 (656) 0 xor
;items: 3
;param: (0,0,(656))
;array1: >0<
;array2: >0<
;array3: >(656)<
;array: 0,0,(656)
    push DE             ; 1:11      0 0 (656) 0 xor   ( -- 0 0 (656) ) push3.m3
    push HL             ; 1:11      0 0 (656) 0 xor
    ld   DE, 0x0000     ; 3:10      0 0 (656) 0 xor
    push DE             ; 1:11      0 0 (656) 0 xor
    ld   HL, (656)      ; 3:16      0 0 (656) 0 xor
; seconds: 0           ;[ 9:59]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$


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ů: 375 ]  Přejít na stránku Předchozí  1 ... 21, 22, 23, 24, 25

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