OldComp.cz

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


Právě je 28.03.2024, 12:13

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 ... 9, 10, 11, 12, 13, 14, 15 ... 39  Další
Autor Zpráva
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 09.03.2022, 21:54 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Kód:
S_STK_LST   274C   PUSH DE   Stack the 'last' values briefly.
274D   CALL SYNTAX_Z   Do not perform the actual operation if syntax is being checked.
2750   JR Z,S_SYNTEST
2752   LD A,E   The 'last' operation code.
2753   AND $3F   Strip off bits 6 and 7 to convert the operation code to a calculator offset.
2755   LD B,A
2756   RST $28   Now use the calculator.
2757   DEFB $3B   fp_calc_2: (perform the actual operation)
2758   DEFB $38   end_calc
2759   JR S_RUNTEST   Jump forward.

Urcite #2755? Protoze to pak pokracuje S_RUNTEST a pak to udela S_LOOP na 0x2734.
Nemyslel jsi taky https://skoolkid.github.io/rom/asm/353B.html?

_________________
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: 09.03.2022, 22:12 
Offline
Óm Nejvyšší

Registrován: 22.05.2013, 21:14
Příspěvky: 3642
Bydliště: Bratislava
Has thanked: 371 times
Been thanked: 788 times
_dworkin píše:
Kód:
...
2755   LD B,A
2756   RST $28   Now use the calculator.
2757   DEFB $3B   fp_calc_2: (perform the actual operation)
2758   DEFB $38   end_calc
...
Urcite #2755? Protoze to pak pokracuje S_RUNTEST a pak to udela S_LOOP na 0x2734.
Ano, urcite, ved si sam v tom vypise uviedol - na #2755 sa pomocou LD B,A presunie kod operacie do B a potom od #2756 je sekvencia pre kalkulacku pozostavajuca z kodu #3B.

Uvadzal som to len ako priklad kde v romke a preco sa to pouziva. Ze kod za tym pokracuje dalsimi cinnostami, nie je podstatne.


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 09.03.2022, 22:38 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Busy píše:
_dworkin píše:
Kód:
...
2755   LD B,A
2756   RST $28   Now use the calculator.
2757   DEFB $3B   fp_calc_2: (perform the actual operation)
2758   DEFB $38   end_calc
...
Urcite #2755? Protoze to pak pokracuje S_RUNTEST a pak to udela S_LOOP na 0x2734.
Ano, urcite, ved si sam v tom vypise uviedol - na #2755 sa pomocou LD B,A presunie kod operacie do B a potom od #2756 je sekvencia pre kalkulacku pozostavajuca z kodu #3B.

Uvadzal som to len ako priklad kde v romke a preco sa to pouziva. Ze kod za tym pokracuje dalsimi cinnostami, nie je podstatne.


Aha uz me doslo jak to myslis. Protoze ja narazel na to ze kdyz budu volat call #2755 tak se mi program nikdy nevrati do meho kodu a ty jsi to myslel jen jako ukazku kterou mam zkopirovat do me rutiny.

Edit profiler me ukazuje ze pokud je po RST 0x28 byte s 0x3B tak to trva 2033356 taktu a pokud je tam 0x0D tak o trosku mene 2029202 taktu.
Oboje vraci spravne vysledky.
Kód:
Pouze rozdilne pruchody
0x0D    t-clock         0x3B   t-clock          diff t-clock
0x0a4f   475         0x0a4f   483               8
0x0adc   7984         0x0adc   8046               62
0x0ae2   7667         0x0ae2   7700               33
0x0ae8   7839         0x0ae8   7905               66
0x0aec   6445         0x0aec   6471               26
0x0b03   7309         0x0b03   7291               -18
0x0b09   7488         0x0b09   7506               18
0x0b0d   6199         0x0b0d   6220               21
0x0b10   7756         0x0b10   7820               64
0x0b66   6417         0x0b66   6335               -82
0x0b6e   4814         0x0b6e   4841               27
0x0b74   1375         0x0b74   1366               -9
0x0b9b   4214         0x0b9b   4195               -19
0x0bab   6643         0x0bab   6615               -28
0x0bb8   17088         0x0bb8   17074               -14
0x0bbc   18254         0x0bbc   18276               22
0x0be4   6496         0x0be4   6531               35
0x0be8   2157         0x0be8   2153               -4
0x0bec   6369         0x0bec   6392               23
0x0bfa   6792         0x0bfa   6823               31
0x0c08   2186         0x0c08   2183               -3
0x0c55   917         0x0c55   913               -4
0x0c5f   893         0x0c5f   879               -14
0x0c66   834         0x0c66   824               -10
0x0ddc   1381         0x0ddc   1369               -12
0x0de3   1436         0x0de3   1452               16
0x15f4   5971         0x15f4   6055               84
0x15f7   2315         0x15f7   2301               -14
0x15f9   2489         0x15f9   2483               -6
0x1f05   11237         0x1f05   11177               -60
0x2abb   39         0x2abb   42               3
0x2e8a   15631         0x2e8a   15666               35
0x2e8d   14461         0x2e8d   14442               -19
0x2e9d   1311         0x2e9d   1365               54
0x2ea1   10265         0x2ea1   9887               -378
0x2ea9   751         0x2ea9   791               40
0x2eab   2271         0x2eab   2250               -21
0x2eae   2339         0x2eae   2338               -1
0x2eba   691         0x2eba   675               -16
0x2edf   6394         0x2edf   6386               -8
0x2f02   5703         0x2f02   5684               -19
0x2f06   2521         0x2f06   2473               -48
0x2f07   7414         0x2f07   7428               14
0x2f10   964         0x2f10   973               9
0x2f19   2521         0x2f19   2523               2
0x2f1c   2246         0x2f1c   2255               9
0x2f2d   950         0x2f2d   959               9
0x2f36   997         0x2f36   989               -8
0x2f56   982         0x2f56   999               17
0x335f   4060         0x335f   4033               -27
0x3365   36180         0x3365   36415               235
0x336c   17743         0x336c   17941               198
0x336d   6452         0x336d   6524               72
0x336e   16130         0x336e   16310               180
0x3380   8659         0x3380   8785               126
0x3382   12484         0x3382   12700               216
0x338c   4948         0x338c   5020               72
0x338d   4948         0x338d   5020               72
0x338e   16130         0x338e   16310               180
0x3391   11291         0x3391   11417               126
0x3393   17743         0x3393   17941               198
0x3394   11291         0x3394   11417               126
0x3395   9678         0x3395   9786               108
0x3396   11291         0x3396   11417               126
0x3397   16130         0x3397   16310               180
0x339a   30647         0x339a   30989               342
0x339b   17743         0x339b   17941               198
0x339c   6452         0x339c   6524               72
0x339d   37617         0x339d   38340               723
0x33a1   18130         0x33a1   18310               180
            0x33a2   180               180
            0x33a3   236               236
            0x33a6   72               72
            0x33a7   216               216
0x33c3   61606         0x33c3   61677               71
0x3410   1642         0x3410   1594               -48
0x342f   4543         0x342f   4487               -56
0x35bf   6472         0x35bf   6335               -137
0x8148   1024         0x8148   1039               15
0x817f   1020         0x817f   987               -33
0x818c   1175         0x818c   1197               22
                              
   2029202            2033356               

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

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Jen pro zajimavost jak muze byt programovani matouci. Overoval jsem si jak vlastne presne uklada ROM cela cisla dovnitr floating-point. Na netu toho moc neni a neco je dokonce spatne. Slo mi hlavne o zaporna cisla, kvuli testu zda je cislo mensi nez nula. Zda mi staci overovat pouze nevyssi bit druheho bajtu. Zmatlo me ze mi nedoslo ze treti bajt je NIZSI a ctvrty VYSSI cisla, ne jak to ma mantisa. Tak jsem si napsal slovo pro vypis cisel v hex forme, abych rychle videl co je fyzicky v pameti a co se tiskne za cislo.
No a tohle me vylezlo, prvne jsem si toho nevsiml a pak jen ziral:
Příloha:
negate.png
negate.png [ 3.31 KiB | Zobrazeno 3740 krát ]

Vidite to taky? :D Co to ma byt?
Problem psani kompilatoru je ze chyba muze byt uplne kdekoliv. I v casti kterou uz pouzivate a zatim se chyba neprojevila. Takze jsem tam pridal jiny zpusob ukladani cisel na float zasobnik. Kopirovani z pameti z konstanty. Problem stejny. Prohlizim ZX48FHEXDOT a nechapu, vzdyt tam jen ctu a nic neukladam! Prohlizim jiny program kde nepouzivam ZX48FHEXDOT a ten funguje. Divam se do asm zdrojaku a nic nevidim.
Tisknu cislo pred ZX48FHEXDOT a je to spravne a po nem spatne.
Tisknu pomoci ZX48FHEXDOT 2x a uz je to spavne! Ale druhy hex vypis tiskne jine cislo. Nektere bity otoci, nektere ne. Presne tak aby ten float byl zaporny. Jak je to sakra mozny, az takhle komplexne.

Oh! Je zapomel ukoncit fci pomoci RET...

A pod tim je ZX48FNEGATE...

lol

_________________
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: 10.03.2022, 19:12 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Zmenil jsem nacitani celych cisel z Forth zasobniku do floating zasobniku.
Kód:
_ZX48U_TO_F:
    push DE             ; 1:11      _zx48u>f   ( c ret . b a -- ret . c b )
    ld    B, H          ; 1:4       _zx48u>f
    ld    C, L          ; 1:4       _zx48u>f
    call 0x2D2B         ; 3:17      _zx48u>f   call ZX ROM stack BC routine
    pop  HL             ; 1:10      _zx48u>f
    pop  BC             ; 1:10      _zx48u>f   ret
    pop  DE             ; 1:10      _zx48u>f
    push BC             ; 1:11      _zx48u>f   ret
    ret                 ; 1:10      _zx48u>f
                       ;[11:87]
_ZX48BC_TO_F:
    push DE             ; 1:11      _zx48bc_to_f
    push HL             ; 1:11      _zx48bc_to_f
    call 0x2D2B         ; 3:17      _zx48bc_to_f   call ZX ROM stack BC routine
    pop  HL             ; 1:10      _zx48bc_to_f
    pop  DE             ; 1:10      _zx48bc_to_f
    ret                 ; 1:10      _zx48bc_to_f
                       ;[ 8:69]
_ZX48FNEGATE:
    push DE             ; 1:11      _zx48fnegate
    push HL             ; 1:11      _zx48fnegate
    rst 0x28            ; 1:11      Use the calculator
    db  0x1B            ; 1:        calc-negate
    db  0x38            ; 1:        calc-end    Pollutes: AF, BC, BC', DE'(=DE)
    pop  HL             ; 1:10      _zx48fnegate
    pop  DE             ; 1:10      _zx48fnegate
    ret                 ; 1:10      _zx48fnegate
                       ;[ 8:63+?]

Mam na mysli variantu kdy vlozite konstantu do Forthu a tu hned presouvate do float zasobniku.
Predtim jsem pouzival ZX ROM fci "BC_TO_F".
Ta byla super kratoucka.
Ale nacita cisla jakou unsigned.
Takze zaporna jsem nacital tak, ze jsem je po prevedeni na kladna nacetl a zavolal fci FNEGATE.
To fungovalo pekne, jen to u vsech zapornych hodnot bylo o 3 bajty delsi a kod celkem pomaly.

Ted kdyz jsem pochopil jak ma ZX ulozeny ty celociselne konstanty jsem udelal fce:
Kód:
_ZX48S_TO_F:            ;           _zx48s>f   ( num ret . de hl -- ret . num de )
    ld    B, H          ; 1:4       _zx48s>f
    ld    C, L          ; 1:4       _zx48s>f
    pop  HL             ; 1:10      _zx48s>f   ( num . de ret )
    ex  (SP),HL         ; 1:19      _zx48s>f   ( ret . de num )
    ex   DE, HL         ; 1:4       _zx48s>f   ( ret . num de )
    ; fall to _zx48bbc_to_f

_ZX48BBC_TO_F:          ;[3:12]     _zx48bbc_to_f
    ld    A, B          ; 1:4       _zx48bbc_to_f
    add   A, A          ; 1:4       _zx48bbc_to_f
    sbc   A, A          ; 1:4       _zx48bbc_to_f
    ; fall to _zx48abc_to_f

_ZX48ABC_TO_F:         ;[21:134]    _zx48abc_to_f
    push HL             ; 1:11      _zx48abc_to_f
    ld   HL,(0x5C65)    ; 3:16      _zx48abc_to_f   load STKEND
    ld  (HL),0x00       ; 2:10      _zx48abc_to_f
    inc  HL             ; 1:6       _zx48abc_to_f
    ld  (HL), A         ; 1:7       _zx48abc_to_f
    inc  HL             ; 1:6       _zx48abc_to_f
    ld  (HL), C         ; 1:7       _zx48abc_to_f
    inc  HL             ; 1:6       _zx48abc_to_f
    ld  (HL), B         ; 1:7       _zx48abc_to_f
    inc  HL             ; 1:6       _zx48abc_to_f
    ld  (HL),0x00       ; 2:10      _zx48abc_to_f
    inc  HL             ; 1:6       _zx48abc_to_f
    ld  (0x5C65),HL     ; 3:16      _zx48abc_to_f   save STKEND+5
    pop  HL             ; 1:10      _zx48abc_to_f
    ret                 ; 1:10      _zx48abc_to_f
Ktera jsou o dost vetsi nez puvodni osmibajtova BC_TO_F. Ale vypadla dalsi osmibajtova fce FNEGATE, protoze ji nemusim pouzivat pro zaporne konstanty.
A pokud volam cislo v rozsahu 16 bitoveho integeru staci me volat vzdy BBC_TO_F. Protoze znamenko do druheho bajtu si najde.
Pokud bych volal kladne cislo vetsi nez 0x7FFF tak mi to vygeneruje
xor A
call ABC_TO_F
Coz je o jeden bajt delsi nez puvodni varianta.
Pokud bych volal zaporne cislo, ktere je zaporne pouze jako 17 bitove. Teda ma nejvyssi bajt nulovy tak mi to vygeneruje
ld A, 0xFF
call ABC_TO_F
Na kazdem volani bych tak usetril 1 bajt oproti puvodni variante.

Zda je to lepsi zalezi hodne na konkretnim programu, ale prijde mi, ze to stoji za zmenu.
Puvodni slovo jsem radsi ponechal s novym jmenem ZX48U_TO_S ( == u>s) a PUSH_ZX48U_S(123) ( == 123 s>f )

PS: Hmm, mohl jsem vtvorit rutinu pro zaporna cisla s volanim BC_TO_HL a pak negate. Takze by pak volani bylo vzdy 3 bajty. Ale to je mi stale proti srsti, delat to tak zbytecne pomalu a slozite.

_________________
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: 11.03.2022, 03:48 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Ukazalo se vyhodnejsi pouzit misto parametru "reg A + reg BC" pouze "carry + reg BC".
Mezi rutinami jsem jen presunul instrukci "sbc A,A" a ted usetrim pokazde jeden bajt kdyz misto "ld A, 0xFF" pouziji "scf".

Dalsich 8 bajtu se usetrilo kdyz volam 0x2ABB. Viz
Kód:
_ZX48S_TO_F:            ;           _zx48s>f   ( num ret . de hl -- ret . num de )
    ld    B, H          ; 1:4       _zx48s>f
    ld    C, L          ; 1:4       _zx48s>f
    pop  HL             ; 1:10      _zx48s>f   ( num . de ret )
    ex  (SP),HL         ; 1:19      _zx48s>f   ( ret . de num )
    ex   DE, HL         ; 1:4       _zx48s>f   ( ret . num de )
    ; fall to _zx48bbc_to_f

_ZX48BBC_TO_F:          ;[2:8]      _zx48bbc_to_f
    ld    A, B          ; 1:4       _zx48bbc_to_f
    add   A, A          ; 1:4       _zx48bbc_to_f
    ; fall to _zx48cfbc_to_f

if 1
_ZX48CFBC_TO_F:        ;[14:200]    _zx48cfbc_to_f
    sbc   A, A          ; 1:4       _zx48cfbc_to_f   0x00 or 0xff
    push HL             ; 1:11      _zx48cfbc_to_f
    push DE             ; 1:11      _zx48cfbc_to_f
    ld    E, A          ; 1:4       _zx48cfbc_to_f
    ld    D, C          ; 1:4       _zx48cfbc_to_f
    ld    C, B          ; 1:4       _zx48cfbc_to_f
    xor   A             ; 1:4       _zx48cfbc_to_f
    ld    B, A          ; 1:4       _zx48cfbc_to_f
    call 0x2ABB         ; 3:124     _zx48cfbc_to_f   new float = a,e,d,c,b = 0,0-sign,lo,hi,0
    pop  DE             ; 1:10      _zx48cfbc_to_f
else
_ZX48CFBC_TO_F:        ;[22:138]    _zx48cfbc_to_f
    sbc   A, A          ; 1:4       _zx48cfbc_to_f   0x00 or 0xff
    push HL             ; 1:11      _zx48cfbc_to_f
    ld   HL,(0x5C65)    ; 3:16      _zx48cfbc_to_f   load STKEND
    ld  (HL),0x00       ; 2:10      _zx48cfbc_to_f
    inc  HL             ; 1:6       _zx48cfbc_to_f
    ld  (HL), A         ; 1:7       _zx48cfbc_to_f
    inc  HL             ; 1:6       _zx48cfbc_to_f
    ld  (HL), C         ; 1:7       _zx48cfbc_to_f
    inc  HL             ; 1:6       _zx48cfbc_to_f
    ld  (HL), B         ; 1:7       _zx48cfbc_to_f
    inc  HL             ; 1:6       _zx48cfbc_to_f
    ld  (HL),0x00       ; 2:10      _zx48cfbc_to_f
    inc  HL             ; 1:6       _zx48cfbc_to_f
    ld  (0x5C65),HL     ; 3:16      _zx48cfbc_to_f   save STKEND+5
endif
    pop  HL             ; 1:10      _zx48cfbc_to_f
    ret                 ; 1:10      _zx48cfbc_to_f

Kód:
2ABB   LD HL,($5C65)   Fetch the address of the first location above the present stack (STKEND).
2ABE   LD (HL),A   Transfer the first byte.
2ABF   INC HL   Step on.
2AC0   LD (HL),E   Transfer the second and third bytes; for a string these will be the 'start'.
2AC1   INC HL
2AC2   LD (HL),D
2AC3   INC HL   Step on.
2AC4   LD (HL),C   Transfer the fourth and fifth bytes; for a string these will be the 'length'.
2AC5   INC HL
2AC6   LD (HL),B
2AC7   INC HL   Step on so as to point to the location above the stack.
2AC8   LD ($5C65),HL   Save this address in STKEND and return.
2ACB   RET

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

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Mensi odbocka od floating point. Dodelal jsem si optimalizaci pro bitove posuny. Mel jsem univerzalni funkce co ctou parametry ze zasobniku (RSHIFT & LSHIFT) a pak pro pripad posunu o jeden bit (_1RSHIFT & _1LSHIFT). Pridal jsem zbytek, kdyz je znamo v dobe prekladu o kolik bitu se to ma posouvat.

V podstate je to skoro stejne jako na strance https://www.chilliant.com/z80shift.html, jen tam chybi v posunu >> 6 optimalni varianta.

Takhle to vypada v testech pro LSHIFT
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ echo "10 lshift" | ../forth2m4.sh
include(`../M4/FIRST.M4')dnl
ORG 0x8000
INIT(60000)
...
STOP
PUSH_LSHIFT(10)

include({../M4/LAST.M4})dnl
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ echo "+10 lshift" | ../forth2m4.sh
include(`../M4/FIRST.M4')dnl
ORG 0x8000
INIT(60000)
...
STOP
PUSH_LSHIFT(+10)

include({../M4/LAST.M4})dnl
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ echo "-10 lshift" | ../forth2m4.sh
include(`../M4/FIRST.M4')dnl
ORG 0x8000
INIT(60000)
...
STOP
PUSH_RSHIFT(10)

include({../M4/LAST.M4})dnl
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_LSHIFT()"
; vvv
; ^^^
    .error PUSH_LSHIFT(): Missing address parameter!
                       ;[ 0:0]
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_LSHIFT(1,2)"
; vvv
; ^^^
    .error PUSH_LSHIFT(1,2): 2 parameters found in macro!
                       ;[ 0:0]
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_LSHIFT(xxx)"
m4:stdin:3: bad expression in eval: xxx
; vvv
; ^^^
    .error PUSH_LSHIFT(xxx): M4 does not know the "xxx" value and therefore cannot create the code!
                       ;[ 0:0]
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_LSHIFT((0x8080))"
; vvv
; ^^^
    .error PUSH_LSHIFT((0x8080)): Pointer as parameter is not supported!
                       ;[ 0:0]
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_LSHIFT(0)"
; vvv
; ^^^
                        ;           0 lshift
                       ;[ 0:0]
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_LSHIFT(17)"
; vvv
; ^^^
                        ;           17 lshift --> 16 lshift
    ld   HL, 0x0000     ; 3:10      16 lshift   ( u -- u<<16 )
                       ;[ 3:10]
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_LSHIFT(1)"
; vvv
; ^^^
    add  HL, HL         ; 1:11      1 lshift   ( u -- u<<1 )
                       ;[ 1:11]
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_LSHIFT(2)"
; vvv
; ^^^
    add  HL, HL         ; 1:11      2 lshift   ( u -- u<<2 )
    add  HL, HL         ; 1:11      2 lshift
                       ;[ 2:22]
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_LSHIFT(3)"
; vvv
; ^^^
    add  HL, HL         ; 1:11      3 lshift   ( u -- u<<3 )
    add  HL, HL         ; 1:11      3 lshift
    add  HL, HL         ; 1:11      3 lshift
                       ;[ 3:33]
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_LSHIFT(4)"
; vvv
; ^^^
    add  HL, HL         ; 1:11      4 lshift   ( u -- u<<4 )
    add  HL, HL         ; 1:11      4 lshift
    add  HL, HL         ; 1:11      4 lshift
    add  HL, HL         ; 1:11      4 lshift
                       ;[ 4:44]
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_LSHIFT(5)"
; vvv
; ^^^
    add  HL, HL         ; 1:11      5 lshift   ( u -- u<<5 )
    add  HL, HL         ; 1:11      5 lshift
    add  HL, HL         ; 1:11      5 lshift
    add  HL, HL         ; 1:11      5 lshift
    add  HL, HL         ; 1:11      5 lshift
                       ;[ 5:55]
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_LSHIFT(6)"
; vvv
; ^^^
                       ;[12:47]     6 lshift   ( u -- u<<6 )
    ld    A, H          ; 1:4       6 lshift
    and   0x03          ; 2:7       6 lshift   .... ..98   7654 3210
    rra                 ; 1:4       6 lshift   .... ...9 8 7654 3210
    rr    L             ; 2:8       6 lshift   .... ...9   8765 4321 0
    rra                 ; 1:4       6 lshift   0... .... 9 8765 4321
    rr    L             ; 2:8       6 lshift   0... ....   9876 5432 1
    rra                 ; 1:4       6 lshift   10.. .... . 9876 5432
    ld    H, L          ; 1:4       6 lshift
    ld    L, A          ; 1:4       6 lshift
                       ;[12:47]
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_LSHIFT(7)"
; vvv
; ^^^
    xor   A             ; 1:4       7 lshift   ( u -- u<<7 )
    srl   H             ; 2:8       7 lshift
    rr    L             ; 2:8       7 lshift
    ld    H, L          ; 1:4       7 lshift
    rra                 ; 1:4       7 lshift
    ld    L, A          ; 1:4       7 lshift
                       ;[ 8:32]
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_LSHIFT(8)"
; vvv
; ^^^
    ld    H, L          ; 1:4       8 lshift   ( u -- u<<8 )
    ld    L, 0x00       ; 2:7       8 lshift
                       ;[ 3:11]
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_LSHIFT(9)"
; vvv
; ^^^
    sla   L             ; 2:8       9 lshift   ( u -- u<<9 )
    ld    H, L          ; 1:4       9 lshift
    ld    L, 0x00       ; 2:7       9 lshift
                       ;[ 5:19]
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_LSHIFT(10)"
; vvv
; ^^^
    ld    A, L          ; 1:4       10 lshift   ( u -- u<<10 )
    add   A, A          ; 1:4       10 lshift
    add   A, A          ; 1:4       10 lshift
    ld    H, A          ; 1:4       10 lshift
    ld    L, 0x00       ; 2:7       10 lshift
                       ;[ 6:23]
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_LSHIFT(11)"
; vvv
; ^^^
    ld    A, L          ; 1:4       11 lshift   ( u -- u<<11 )
    add   A, A          ; 1:4       11 lshift
    add   A, A          ; 1:4       11 lshift
    add   A, A          ; 1:4       11 lshift
    ld    H, A          ; 1:4       11 lshift
    ld    L, 0x00       ; 2:7       11 lshift
                       ;[ 7:27]
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_LSHIFT(12)"
; vvv
; ^^^
    ld    A, L          ; 1:4       12 lshift   ( u -- u<<12 )
    add   A, A          ; 1:4       12 lshift
    add   A, A          ; 1:4       12 lshift
    add   A, A          ; 1:4       12 lshift
    add   A, A          ; 1:4       12 lshift
    ld    H, A          ; 1:4       12 lshift
    ld    L, 0x00       ; 2:7       12 lshift
                       ;[ 8:31]
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_LSHIFT(13)"
; vvv
; ^^^
    ld    A, L          ; 1:4       13 lshift   ( u -- u<<13 )
    rrca                ; 1:4       13 lshift
    rrca                ; 1:4       13 lshift
    rrca                ; 1:4       13 lshift
    and  0xE0           ; 2:7       13 lshift
    ld    H, A          ; 1:4       13 lshift
    ld    L, 0x00       ; 2:7       13 lshift
                       ;[ 9:34]
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_LSHIFT(14)"
; vvv
; ^^^
    ld    A, L          ; 1:4       14 lshift   ( u -- u<<14 )
    rrca                ; 1:4       14 lshift
    rrca                ; 1:4       14 lshift
    and  0xC0           ; 2:7       14 lshift
    ld    H, A          ; 1:4       14 lshift
    ld    L, 0x00       ; 2:7       14 lshift
                       ;[ 8:30]
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_LSHIFT(15)"
; vvv
; ^^^
    xor   A             ; 1:4       15 lshift   ( u -- u<<15 )
    rr    L             ; 2:8       15 lshift
    ld    L, A          ; 1:4       15 lshift
    rra                 ; 1:4       15 lshift
    ld    H, A          ; 1:4       15 lshift
                       ;[ 6:24]

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

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
A tohle ukazi testy pro RSHIFT
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ echo "10 rshift" | ../forth2m4.sh
include(`../M4/FIRST.M4')dnl
ORG 0x8000
INIT(60000)
...
STOP
PUSH_RSHIFT(10)

include({../M4/LAST.M4})dnl
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ echo "+11 rshift" | ../forth2m4.sh
include(`../M4/FIRST.M4')dnl
ORG 0x8000
INIT(60000)
...
STOP
PUSH_RSHIFT(+11)

include({../M4/LAST.M4})dnl
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ echo "-11 rshift" | ../forth2m4.sh
include(`../M4/FIRST.M4')dnl
ORG 0x8000
INIT(60000)
...
STOP
PUSH_LSHIFT(11)

include({../M4/LAST.M4})dnl
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_RSHIFT(xxx)"
m4:stdin:3: bad expression in eval: xxx
; vvv
; ^^^
    .error PUSH_RSHIFT(xxx): M4 does not know the "xxx" value and therefore cannot create the code!
                       ;[ 0:0]
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "CONSTANT(xxx,8)PUSH_RSHIFT(xxx)"
; vvv
; ^^^
xxx                  EQU 8
    ld    L, H          ; 1:4       8 rshift   ( u -- u>>8 )
    ld    H, 0x00       ; 2:7       8 rshift
                       ;[ 3:11]
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_RSHIFT((0x8000))"
; vvv
; ^^^
    .error PUSH_RSHIFT((0x8000)): Pointer as parameter is not supported!
                       ;[ 0:0]
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_RSHIFT()"
; vvv
; ^^^
    .error PUSH_RSHIFT(): Missing address parameter!
                       ;[ 0:0]
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_RSHIFT(1,2)"
; vvv
; ^^^
    .error PUSH_RSHIFT(1,2): 2 parameters found in macro!
                       ;[ 0:0]
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_RSHIFT(0)"
; vvv
; ^^^
                        ;           0 rshift
                       ;[ 0:0]
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_RSHIFT(1)"
; vvv
; ^^^
    srl   H             ; 2:8       1 rshift   ( u -- u>>1 )
    rr    L             ; 2:8       1 rshift
                       ;[ 4:16]
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_RSHIFT(2)"
; vvv
; ^^^
    srl   H             ; 2:8       2 rshift   ( u -- u>>2 )
    rr    L             ; 2:8       2 rshift
    srl   H             ; 2:8       2 rshift
    rr    L             ; 2:8       2 rshift
                       ;[ 8:32]
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_RSHIFT(3)"
; vvv
; ^^^
    ld    A, L          ; 1:4       3 rshift   ( u -- u>>3 )
    srl   H             ; 2:8       3 rshift
    rra                 ; 1:4       3 rshift
    srl   H             ; 2:8       3 rshift
    rra                 ; 1:4       3 rshift
    srl   H             ; 2:8       3 rshift
    rra                 ; 1:4       3 rshift
    ld    L, A          ; 1:4       3 rshift
                       ;[11:44]
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_RSHIFT(4)"
; vvv
; ^^^
    ld    A, L          ; 1:4       4 rshift   ( u -- u>>4 )
    srl   H             ; 2:8       4 rshift
    rra                 ; 1:4       4 rshift
    srl   H             ; 2:8       4 rshift
    rra                 ; 1:4       4 rshift
    srl   H             ; 2:8       4 rshift
    rra                 ; 1:4       4 rshift
    srl   H             ; 2:8       4 rshift
    rra                 ; 1:4       4 rshift
    ld    L, A          ; 1:4       4 rshift
                       ;[14:56]
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_RSHIFT(5)"
; vvv
; ^^^
    xor   A             ; 1:4       5 rshift   ( u -- u>>5 )
    add  HL, HL         ; 1:11      5 rshift
    adc   A, A          ; 1:4       5 rshift
    add  HL, HL         ; 1:11      5 rshift
    adc   A, A          ; 1:4       5 rshift
    add  HL, HL         ; 1:11      5 rshift
    adc   A, A          ; 1:4       5 rshift
    ld    L, H          ; 1:4       5 rshift
    ld    H, A          ; 1:4       5 rshift
                       ;[ 9:57]
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_RSHIFT(6)"
; vvv
; ^^^
    xor   A             ; 1:4       6 rshift   ( u -- u>>6 )
    add  HL, HL         ; 1:11      6 rshift
    adc   A, A          ; 1:4       6 rshift
    add  HL, HL         ; 1:11      6 rshift
    adc   A, A          ; 1:4       6 rshift
    ld    L, H          ; 1:4       6 rshift
    ld    H, A          ; 1:4       6 rshift
                       ;[ 7:42]
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_RSHIFT(7)"
; vvv
; ^^^
    xor   A             ; 1:4       7 rshift   ( u -- u>>7 )
    add  HL, HL         ; 1:11      7 rshift
    adc   A, A          ; 1:4       7 rshift
    ld    L, H          ; 1:4       7 rshift
    ld    H, A          ; 1:4       7 rshift
                       ;[ 5:27]
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_RSHIFT(8)"
; vvv
; ^^^
    ld    L, H          ; 1:4       8 rshift   ( u -- u>>8 )
    ld    H, 0x00       ; 2:7       8 rshift
                       ;[ 3:11]
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_RSHIFT(9)"
; vvv
; ^^^
    srl   H             ; 2:8       9 rshift   ( u -- u>>9 )
    ld    L, H          ; 1:4       9 rshift
    ld    H, 0x00       ; 2:7       9 rshift
                       ;[ 5:19]
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_RSHIFT(10)"
; vvv
; ^^^
    srl   H             ; 2:8       10 rshift   ( u -- u>>10 )
    srl   H             ; 2:8       10 rshift
    ld    L, H          ; 1:4       10 rshift
    ld    H, 0x00       ; 2:7       10 rshift
                       ;[ 7:27]
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_RSHIFT(11)"
; vvv
; ^^^
    ld    A, H          ; 1:4       11 rshift   ( u -- u>>11 )
    and  0xF8           ; 2:7       11 rshift
    rrca                ; 1:4       11 rshift
    rrca                ; 1:4       11 rshift
    rrca                ; 1:4       11 rshift
    ld    L, A          ; 1:4       11 rshift
    ld    H, 0x00       ; 2:7       11 rshift
                       ;[ 9:34]
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_RSHIFT(12)"
; vvv
; ^^^
    ld    A, H          ; 1:4       12 rshift   ( u -- u>>12 )
    and  0xF0           ; 2:7       12 rshift
    rrca                ; 1:4       12 rshift
    rrca                ; 1:4       12 rshift
    rrca                ; 1:4       12 rshift
    rrca                ; 1:4       12 rshift
    ld    L, A          ; 1:4       12 rshift
    ld    H, 0x00       ; 2:7       12 rshift
                       ;[10:38]
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_RSHIFT(13)"
; vvv
; ^^^
    ld    A, H          ; 1:4       13 rshift   ( u -- u>>13 )
    and  0xE0           ; 2:7       13 rshift
    rlca                ; 1:4       13 rshift
    rlca                ; 1:4       13 rshift
    rlca                ; 1:4       13 rshift
    ld    L, A          ; 1:4       13 rshift
    ld    H, 0x00       ; 2:7       13 rshift
                       ;[ 9:34]
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_RSHIFT(14)"
; vvv
; ^^^
    ld    A, H          ; 1:4       14 rshift   ( u -- u>>14 )
    and  0xC0           ; 2:7       14 rshift
    rlca                ; 1:4       14 rshift
    rlca                ; 1:4       14 rshift
    ld    L, A          ; 1:4       14 rshift
    ld    H, 0x00       ; 2:7       14 rshift
                       ;[ 8:30]
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_RSHIFT(15)"
; vvv
; ^^^
    xor   A             ; 1:4       15 rshift   ( u -- u>>15 )
    rl    H             ; 2:8       15 rshift
    ld    H, A          ; 1:4       15 rshift
    rra                 ; 1:4       15 rshift
    ld    L, A          ; 1:4       15 rshift
                       ;[ 6:24]
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_RSHIFT(16)"
; vvv
; ^^^
    ld   HL, 0x0000     ; 3:10      16 rshift   ( u -- u>>16 )
                       ;[ 3:10]
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_RSHIFT(17)"
; vvv
; ^^^
                        ;           17 rshift --> 16 rshift
    ld   HL, 0x0000     ; 3:10      16 rshift   ( u -- u>>16 )
                       ;[ 3:10]
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_RSHIFT(-1)"
; vvv
; ^^^
    .error PUSH_RSHIFT(-1): negative parameters found in macro! Use PUSH_LSHIFT(1).
                       ;[ 0:0]

V emulatoru jsem to jeste netestoval.

Mimochodem mel jsem celou dobu pocit, ze jsem to prece uz jednou delal... a taky ano, resil jsem to v nasobeni, jen jsem na to jako sklerotik uz zapomnel.

Jinak uplne mimo tema jsem sehnal novou praci, nebo mi spis uplne spadla do klina, protoze jsem byl bez anglictiny uplne bezradny, ale napsal me po mesici byvaly sef zda neshanim praci. A taky jsem zoufale shanel a i zaroven neshanel, podle toho jak se na to podivate. Takze budu mit mene casu a budu mene spamovat. "Delam" s jednou symptatickou brazilkou (co byla v Brazilii profesorkou hry na akustickou kytaru, ale neumi poradne anglicky, takze dela tuhle hroznou praci) a jeste rumunem. Ta restaurace je celkem mala, je to prace jen pro jednoho, takze se vidime jen pri stridani smen.

_________________
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.03.2022, 20:19 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Tak uz by to melo byt spravne, nasel jsem jen chybu v ">> 15" kdy jsem 15. bit presouval do 7. bitu a ne do nulteho.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_RSHIFT(15)"
; vvv
; ^^^
    xor   A             ; 1:4       15 rshift   ( u -- u>>15 )
    rl    H             ; 2:8       15 rshift
    ld    H, A          ; 1:4       15 rshift
    rra                 ; 1:4       15 rshift
    ld    L, A          ; 1:4       15 rshift
                       ;[ 6:24]
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../compile.sh shift
old: -rw-rw-r-- 1 dworkin dworkin 1865 Mar 17 18:14 shift.bin
new: -rw-rw-r-- 1 dworkin dworkin 1865 Mar 17 18:17 shift.bin
dworkin@dw-A15:~/Programovani/ZX/Forth/new2$ ../check_word.sh "PUSH_RSHIFT(15)"
; vvv
; ^^^
    xor   A             ; 1:4       15 rshift   ( u -- u>>15 )
    rl    H             ; 2:8       15 rshift
    ld    H, A          ; 1:4       15 rshift
    adc   A, A          ; 1:4       15 rshift
    ld    L, A          ; 1:4       15 rshift
                       ;[ 6:24]

_________________
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: 22.06.2022, 22:10 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Po delsi dobe sem zase neco napisi. Pridaval jsem podporu 32 bitovych cisel a dostal se do casti kdy pracuji s konstantama. Proste kdyz vlozim cislo a s nim a dalsim pro prekladac uz neznamym cislem v zasobniku provedu matematickou operaci. Kupodivu nejnarocnejsi je operace zjisteni zda jsou cisla shodne nebo ruzne, protoze u vseho ostatniho to bud spocteme a nebo nam pomuze priznak carry. Tady ale ne, musime se spolehnout na priznak nuly a ten se neda prakticky prenaset mezi bajty. S tim jak neni Z80 ortgonalni byla tohle docela velka vyzva a zaroven zabava.

Protoze u techto operaci se mnohokrat opakuje kod u ruznych slov, nebo kombinaci slov, jako je:
123456789 =
123456789 = if
123456789 = while
2dup 123456789 =
2dup 123456789 = if
2dup 123456789 = while
123456789 <>
123456789 <> if
123456789 <> while
2dup 123456789 <>
2dup 123456789 <> if
2dup 123456789 <> while
jsem se rozhodl ze se pokusim udelat nejakou makro funkci, ktera by zakladni shodny kod sama vygenerova, a zbytek co se lisi se obalil pak zvlast.

M4 Forth uklada 32 bitove cislo v zasobniku tak, ze HL obsahuje nizsich 16 bajtu a DE obsahuje vyssich 16 bajtu. Coz je mimochodem presne naopak nez je v standartu, ale pro nektere funkce to bylo vyhodnejsi tak jsem to tak zvolil. A Z80 nema podporu pro 32 bitove cisla takze endianitu si stejne musite resit softwarove.

A protoze podporuji operace typu "2dup constant = if" tak si v te makro funkci nesmim znicit hodnoty v registru. Vcetne HL. Takze jsem v podstate odkazany na akumulator A, protoze to skoro vzdy vychazi rychleji nez schovavat HL na zasobnik.

Zakladni kod vypada nejak takto
Kód:
../check_word.sh '_2DUP_PUSHDOT_DNE_IF(0x45352515)'
 
               ;[21:75/23,41,59,75] 2dup 0x45352515 D<> if   ( d1 -- d1 )   0x45352515 <> DEHL
    ld    A, 0x15       ; 2:7       2dup 0x45352515 D<> if
    cp    L             ; 1:4       2dup 0x45352515 D<> if   x[1] = 0x15
    jr   nz, $+18       ; 2:7/12    2dup 0x45352515 D<> if
    ld    A, 0x25       ; 2:7       2dup 0x45352515 D<> if
    cp    H             ; 1:4       2dup 0x45352515 D<> if   x[2] = 0x25
    jr   nz, $+13       ; 2:7/12    2dup 0x45352515 D<> if
    ld    A, 0x35       ; 2:7       2dup 0x45352515 D<> if
    cp    E             ; 1:4       2dup 0x45352515 D<> if   x[3] = 0x35
    jr   nz, $+8        ; 2:7/12    2dup 0x45352515 D<> if
    ld    A, 0x45       ; 2:7       2dup 0x45352515 D<> if
    xor   D             ; 1:4       2dup 0x45352515 D<> if   x[4] = 0x45
    jp    z, else101    ; 3:10      2dup 0x45352515 D<> if
                       ;[21:75]

Pokud jsou bajty shodne tak kod vypada nejak takto
Kód:
../check_word.sh '_2DUP_PUSHDOT_DNE_IF(0x33333333)'
 
               ;[15:54/20,31,42,54] 2dup 0x33333333 D<> if   ( d1 -- d1 )   0x33333333 <> DEHL
    ld    A, L          ; 1:4       2dup 0x33333333 D<> if   the beginning of identical values
    cp    H             ; 1:4       2dup 0x33333333 D<> if   x[1] = x[2]
    jr   nz, $+13       ; 2:7/12    2dup 0x33333333 D<> if
    cp    D             ; 1:4       2dup 0x33333333 D<> if   x[2] = x[3]  continuation of identical values
    jr   nz, $+10       ; 2:7/12    2dup 0x33333333 D<> if
    cp    E             ; 1:4       2dup 0x33333333 D<> if   x[3] = x[4]  continuation of identical values
    jr   nz, $+7        ; 2:7/12    2dup 0x33333333 D<> if
    xor   0x33          ; 2:7       2dup 0x33333333 D<> if   x[4] = 0x33  termination of identical values
    jp    z, else101    ; 3:10      2dup 0x33333333 D<> if
                       ;[15:54]

Pokud cislo obsahuje nejake nulove bajty tak je to stale snadne, proste se jen daji nakonec, a predchozi testovani musi vynulovat akumulator.
Kód:
../check_word.sh '_2DUP_PUSHDOT_DNE_IF(0x45002500)'
 
               ;[13:47/23,47,47,47] 2dup 0x45002500 D<> if   ( d1 -- d1 )   0x45002500 <> DEHL
    ld    A, 0x25       ; 2:7       2dup 0x45002500 D<> if
    cp    H             ; 1:4       2dup 0x45002500 D<> if   x[1] = 0x25
    jr   nz, $+10       ; 2:7/12    2dup 0x45002500 D<> if
    ld    A, 0x45       ; 2:7       2dup 0x45002500 D<> if
    xor   D             ; 1:4       2dup 0x45002500 D<> if   x[2] = 0x45
    or    E             ; 1:4       2dup 0x45002500 D<> if   x[3] = 0
    or    L             ; 1:4       2dup 0x45002500 D<> if   x[4] = 0
    jp    z, else101    ; 3:10      2dup 0x45002500 D<> if
                       ;[13:47]

Vylepseni oproti 16 bitove verzi co jsem uz resil je v tom, ze me doslo ze ty jednotlive bajty mohu chapat jako nejakou posloupnost, kdy mezi nema mohou existovat i nejake vztahy.
Napriklad kazde dalsi cislo je dvounasobkem predchoziho, zde konkretne vidite zradnost preteceni, kdy polovina cisla 0x2A muze byt jak 0x15 tak 0x95. V tomto kodu pouzivam jednoduse pro overeni uz overene hodnoty.
Kód:
../check_word.sh '_2DUP_PUSHDOT_DNE_IF(0xA8542A95)'
 
               ;[18:66/23,38,53,66] 2dup 0xA8542A95 D<> if   ( d1 -- d1 )   0xA8542A95 <> DEHL
    ld    A, 0x95       ; 2:7       2dup 0xA8542A95 D<> if
    cp    L             ; 1:4       2dup 0xA8542A95 D<> if   x[1] = 0x95
    jr   nz, $+15       ; 2:7/12    2dup 0xA8542A95 D<> if
    add   A, L          ; 1:4       2dup 0xA8542A95 D<> if
    cp    H             ; 1:4       2dup 0xA8542A95 D<> if   x[2] = x[1] + x[1]
    jr   nz, $+11       ; 2:7/12    2dup 0xA8542A95 D<> if
    add   A, H          ; 1:4       2dup 0xA8542A95 D<> if
    cp    E             ; 1:4       2dup 0xA8542A95 D<> if   x[3] = x[2] + x[2]
    jr   nz, $+7        ; 2:7/12    2dup 0xA8542A95 D<> if
    add   A, E          ; 1:4       2dup 0xA8542A95 D<> if
    xor   D             ; 1:4       2dup 0xA8542A95 D<> if   x[4] = x[3] + x[3]
    jp    z, else101    ; 3:10      2dup 0xA8542A95 D<> if
                       ;[18:66]

Nebo jiny matematicky vztah, nebo jejich kombinace
Kód:
../check_word.sh '_2DUP_PUSHDOT_DNE_IF(0x3f1f2010)'
 
               ;[18:66/23,38,53,66] 2dup 0x3f1f2010 D<> if   ( d1 -- d1 )   0x3F1F2010 <> DEHL
    ld    A, 0x10       ; 2:7       2dup 0x3f1f2010 D<> if
    cp    L             ; 1:4       2dup 0x3f1f2010 D<> if   x[1] = 0x10
    jr   nz, $+15       ; 2:7/12    2dup 0x3f1f2010 D<> if
    add   A, L          ; 1:4       2dup 0x3f1f2010 D<> if
    cp    H             ; 1:4       2dup 0x3f1f2010 D<> if   x[2] = x[1] + x[1]
    jr   nz, $+11       ; 2:7/12    2dup 0x3f1f2010 D<> if
    dec   A             ; 1:4       2dup 0x3f1f2010 D<> if
    cp    E             ; 1:4       2dup 0x3f1f2010 D<> if   x[3] = x[2] - 1
    jr   nz, $+7        ; 2:7/12    2dup 0x3f1f2010 D<> if
    add   A, H          ; 1:4       2dup 0x3f1f2010 D<> if
    xor   D             ; 1:4       2dup 0x3f1f2010 D<> if   x[4] = x[3] + x[2]
    jp    z, else101    ; 3:10      2dup 0x3f1f2010 D<> if
                       ;[18:66]

U bajtu s hodnotu 0xFF jsem prisel na to, ze ten vztah nemusim prevadet na nulu, ale na hodnotu 0xFF a misto OR pouzivat instrukci AND. Tohle je jedna z mala veci, kdy mohu spojit test bajtu bezpecne dohromady. Dalsim trikem ktery jsem objevil je, ze predchozi vztah, ktery jsem nuloval a pak pomoci "dec A" nastavoval na 0xFF mohu udelat jeste efektivnejsi kdyz misto
Kód:
ld A, 0x45
xor D
dec A
pouziji
Kód:
ld A, (0x45 ^ 0xFF)
xor D
Vysledny kod vypada podobne jak s nulama takto, jen o jeden bajt delsi pro ukoncujici instrukci "inc A". 0xFF bajty jsou vzdy na konci, popripade hned pred nulovymi bajty.
Kód:
../check_word.sh '_2DUP_PUSHDOT_DNE_IF(0x45FF25FF)'
 
               ;[14:51/23,51,51,51] 2dup 0x45FF25FF D<> if   ( d1 -- d1 )   0x45FF25FF <> DEHL
    ld    A, 0x25       ; 2:7       2dup 0x45FF25FF D<> if
    cp    H             ; 1:4       2dup 0x45FF25FF D<> if   x[1] = 0x25
    jr   nz, $+11       ; 2:7/12    2dup 0x45FF25FF D<> if
    ld    A, D          ; 1:4       2dup 0x45FF25FF D<> if
    xor   0xBA          ; 2:7       2dup 0x45FF25FF D<> if   x[2] = 0x45 = 0xFF ^ 0xBA
    and   E             ; 1:4       2dup 0x45FF25FF D<> if   x[3] = 0xFF
    and   L             ; 1:4       2dup 0x45FF25FF D<> if   x[4] = 0xFF
    inc   A             ; 1:4       2dup 0x45FF25FF D<> if
    jp    z, else101    ; 3:10      2dup 0x45FF25FF D<> if
                       ;[14:51]

Drobne optimalizace jsou pokud pred 0xFF je 0xFE
Kód:
./check_word.sh '_2DUP_PUSHDOT_DNE_IF(0xFEFF25FF)'
 
               ;[13:48/23,48,48,48] 2dup 0xFEFF25FF D<> if   ( d1 -- d1 )   0xFEFF25FF <> DEHL
    ld    A, 0x25       ; 2:7       2dup 0xFEFF25FF D<> if
    cp    H             ; 1:4       2dup 0xFEFF25FF D<> if   x[1] = 0x25
    jr   nz, $+10       ; 2:7/12    2dup 0xFEFF25FF D<> if
    ld    A, D          ; 1:4       2dup 0xFEFF25FF D<> if
    inc   A             ; 1:4       2dup 0xFEFF25FF D<> if   x[2] + 1 = 0xFF
    and   E             ; 1:4       2dup 0xFEFF25FF D<> if   x[3] = 0xFF
    and   L             ; 1:4       2dup 0xFEFF25FF D<> if   x[4] = 0xFF
    inc   A             ; 1:4       2dup 0xFEFF25FF D<> if
    jp    z, else101    ; 3:10      2dup 0xFEFF25FF D<> if
                       ;[13:48]

Posledni odlisnou cislici jsou jednicky, ty mohou byt obcas rychlejsi kdyz se s nema zachazi odlisne. Zde jen podobne vylepseni jako u 254
Kód:
../check_word.sh '_2DUP_PUSHDOT_DNE_IF(0xFEFF01FF)'
 
               ;[12:45/20,45,45,45] 2dup 0xFEFF01FF D<> if   ( d1 -- d1 )   0xFEFF01FF <> DEHL
    ld    A, H          ; 1:4       2dup 0xFEFF01FF D<> if
    dec   A             ; 1:4       2dup 0xFEFF01FF D<> if   x[1] = 1
    jr   nz, $+10       ; 2:7/12    2dup 0xFEFF01FF D<> if
    ld    A, D          ; 1:4       2dup 0xFEFF01FF D<> if
    inc   A             ; 1:4       2dup 0xFEFF01FF D<> if   x[2] + 1 = 0xFF
    and   E             ; 1:4       2dup 0xFEFF01FF D<> if   x[3] = 0xFF
    and   L             ; 1:4       2dup 0xFEFF01FF D<> if   x[4] = 0xFF
    inc   A             ; 1:4       2dup 0xFEFF01FF D<> if
    jp    z, else101    ; 3:10      2dup 0xFEFF01FF D<> if
                       ;[12:45]

A tady je uz videt ze pomoci pouziti volneho registru C, dokazi spojit bajty v jeden test
Kód:
../check_word.sh '_2DUP_PUSHDOT_DNE_IF(0x00443333)'
 
               ;[15:54/20,34,54,54] 2dup 0x00443333 D<> if   ( d1 -- d1 )   0x00443333 <> DEHL
    ld    A, L          ; 1:4       2dup 0x00443333 D<> if   the beginning of identical values
    cp    H             ; 1:4       2dup 0x00443333 D<> if   x[1] = x[2]
    jr   nz, $+13       ; 2:7/12    2dup 0x00443333 D<> if
    cp    0x33          ; 2:7       2dup 0x00443333 D<> if   x[2] = 0x33  termination of identical values
    jr   nz, $+9        ; 2:7/12    2dup 0x00443333 D<> if
    ld    A, 0x44       ; 2:7       2dup 0x00443333 D<> if
    xor   E             ; 1:4       2dup 0x00443333 D<> if   x[3] = 0x44
    or    D             ; 1:4       2dup 0x00443333 D<> if   x[4] = 0
    jp    z, else101    ; 3:10      2dup 0x00443333 D<> if
                       ;[15:54]
../check_word.sh '_2DUP_PUSHDOT_DNE_IF(0x00013333)'
 
               ;[13:48/20,48,48,48] 2dup 0x00013333 D<> if   ( d1 -- d1 )   0x00013333 <> DEHL
    ld    A, L          ; 1:4       2dup 0x00013333 D<> if   the beginning of identical values
    cp    H             ; 1:4       2dup 0x00013333 D<> if   x[1] = x[2]
    jr   nz, $+11       ; 2:7/12    2dup 0x00013333 D<> if
    xor   0x33          ; 2:7       2dup 0x00013333 D<> if   x[2] = 0x33  termination of identical values
    ld    C, E          ; 1:4       2dup 0x00013333 D<> if
    dec   C             ; 1:4       2dup 0x00013333 D<> if
    or    C             ; 1:4       2dup 0x00013333 D<> if   x[3] = 1
    or    D             ; 1:4       2dup 0x00013333 D<> if   x[4] = 0
    jp    z, else101    ; 3:10      2dup 0x00013333 D<> if
                       ;[13:48]



U tech testu jsem dospel k zaveru, ze pokud jsou v nich vic jak jeden xor na test, tak je ten kod vadny. Musel jsem si to overit v excelu, kde jsem si zkratil cislo na 3 bity a dival se co to udela. Problem je ze kobinaci chyb u vice cisel bude test ukazovat obcas spatne vysledky.

Proste pokud mam v cisle jednicku a pokusim se to spojit tak ze
Kód:
...
inc A
xor A
dec A
...

Tak to pri soubehu chyb selze.

Zpetne pouzivani jeste neoverenych hodnot funguje jen u pripadu kdy mame cisla 4,3,2,1
a budou se testovat jako
Kód:
ld A,D
dec A
cp E        x[3] = x[4]-1
jr nz,...
dec A
cp H        x[2] = x[3]-1
jr nz,...
dec A
cp L        x[1] = x[2]-1
jr nz,...
dec A       x[4] = 4

Protoze tady nakonec opravdu tu x[4] nezavisle overime na nulu. Ale tento kod neni rychlejsi nez generovany
Kód:
../check_word.sh '_2DUP_PUSHDOT_DNE_IF(0x04030201)'
 
               ;[17:63/23,38,63,63] 2dup 0x04030201 D<> if   ( d1 -- d1 )   0x04030201 <> DEHL
    ld    A, 0x03       ; 2:7       2dup 0x04030201 D<> if
    cp    E             ; 1:4       2dup 0x04030201 D<> if   x[1] = 0x03
    jr   nz, $+14       ; 2:7/12    2dup 0x04030201 D<> if
    dec   A             ; 1:4       2dup 0x04030201 D<> if
    cp    H             ; 1:4       2dup 0x04030201 D<> if   x[2] = x[1] - 1
    jr   nz, $+10       ; 2:7/12    2dup 0x04030201 D<> if
    add   A, H          ; 1:4       2dup 0x04030201 D<> if
    xor   D             ; 1:4       2dup 0x04030201 D<> if   x[3] = x[2] + x[2]
    ld    C, L          ; 1:4       2dup 0x04030201 D<> if
    dec   C             ; 1:4       2dup 0x04030201 D<> if
    or    C             ; 1:4       2dup 0x04030201 D<> if   x[4] = 1
    jp    z, else101    ; 3:10      2dup 0x04030201 D<> if
                       ;[17:63]


Puvodne jsem ten kod psal tak, ze jsem si tu posloupnost 4 cisel seradil a nepouzival odcitani, ale pak mi doslo ze cislo 0x3F201F10 ma kratsi zapis jako x, 2*x, 2*x-1, 2*x-1+2*x. Po case jsem dospel k reseni kdy delam variace te rady, jen ignoruji bajty 255 a 0 (nuly mam vnitrne jako 256, kvuli razeni).

Jak napsat v makru variace? :shock:

No rozepsal jsem si to na "papir" a je to snadne. Udelame vic maker. Mame cisla 1,2,3,4. Posledni jen vola generovani kodu (pokud je lepsi co mame tak ho nahradi) a pokud je cislo na pozici 3 mensi jak 255 tak ho prohodi s cislem na pozici 4 (a s nema prohodi i jmena registru). Pokud prohazoval tak znovu vola generovani kodu (pokud je lepsi co mame tak ho nahradi).

Dalsi makro vola posledni makro, pak pokud je cislo na pozici 3 mensi jak 255 tak to zameni s cislem na pozici 2 a pokud prohazoval tak znovu vola posledni makro a udela opet prohozeni 3 a 2 pozice a znovu vola posleni makro. Posledni makro totiz vzdy vymeni cislo na 2 pozici tak to pekne navazuje.

Prvni (main) makro nastavi pocatecni hodnoty kodu na nejhorsi a pak vola prostredni makro. Pokud je cislo na 4 pozici mensi nez 255 tak prohodi hodnotu na 4 pozici s hodnotou na 3 pozici a znovu vola prostredni makro, tohle jednou zopakuje a nakonec prohazuje cislo na pozici 4 s cislem na pozici 1 (takove preteceni misto cisla na 5. pozici) a vola naposledy prostredni makro.

Posledni makro generuje 2 kody.
Prostredni generuje az 6 kodu.
Prvni generuje az 24 kodu, coz je variace 4 hodnot kdy zalezi na poradi. Vlastne je to podobne nejakemu kodovani kdy nasledujici cislice se vzdy lisi jen jednim bitem. Zapomel jsem nazev, protoze jsem sklerotik. Takze jsem vedel ze to nejak pujde kdyz se do toho opru.

Vaše zpráva obsahuje 18813 znaků. Maximální povolený počet znaků je 17000.

_________________
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: 22.06.2022, 22:10 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Mozna snazi bude ukazat kod
Kód:
dnl
define({____DEQ_VARIATION_21},{dnl
__{}dnl debug:
__{}dnl format({0x%02X},_TMP_N4)-format({0x%02X},_TMP_N3)-format({0x%02X},_TMP_N2)-format({0x%02X},_TMP_N1)
__{}dnl
__{}____DEQ_MAKE_CODE($1,$2,$3,$4,$5){}dnl
__{}__{}ifelse(____CHEAPER,{1},{dnl
__{}__{}__{}define({_TMP_BEST_P},____DEQ_PRICE){}dnl
__{}__{}__{}define({_TMP_BEST_B},____DEQ_BYTES){}dnl
__{}__{}__{}define({_TMP_BEST_C},____DEQ_CLOCKS){}dnl
__{}__{}__{}define({_TMP_BEST_CODE},____DEQ_CODE)}){}dnl
__{}ifelse(eval(_TMP_N2<255),{1},{dnl
__{}____SWAP2DEF({_TMP_N2},{_TMP_N1}){}dnl
__{}____SWAP2DEF({_TMP_R2},{_TMP_R1}){}dnl
__{}dnl debug:
__{}dnl format({0x%02X},_TMP_N4)-format({0x%02X},_TMP_N3)-format({0x%02X},_TMP_N2)-format({0x%02X},_TMP_N1)
__{}dnl
__{}____DEQ_MAKE_CODE($1,$2,$3,$4,$5){}dnl
__{}__{}ifelse(____CHEAPER,{1},{dnl
__{}__{}__{}define({_TMP_BEST_P},____DEQ_PRICE){}dnl
__{}__{}__{}define({_TMP_BEST_B},____DEQ_BYTES){}dnl
__{}__{}__{}define({_TMP_BEST_C},____DEQ_CLOCKS){}dnl
__{}__{}__{}define({_TMP_BEST_CODE},____DEQ_CODE)})})}){}dnl
dnl
dnl
dnl
define({____DEQ_VARIATION_32},{dnl
__{}____DEQ_VARIATION_21($1,$2,$3,$4,$5){}dnl
__{}ifelse(eval(_TMP_N3<255),{1},{dnl
__{}____SWAP2DEF({_TMP_N3},{_TMP_N2}){}dnl
__{}____SWAP2DEF({_TMP_R3},{_TMP_R2}){}dnl
__{}____DEQ_VARIATION_21($1,$2,$3,$4,$5){}dnl
__{}____SWAP2DEF({_TMP_N3},{_TMP_N2}){}dnl
__{}____SWAP2DEF({_TMP_R3},{_TMP_R2}){}dnl
__{}____DEQ_VARIATION_21($1,$2,$3,$4,$5)})}){}dnl
dnl
dnl
dnl
define({____DEQ_MAKE_BEST_CODE},{dnl
____DEQ_INIT_CODE($1){}dnl
__{}define({_TMP_BEST_P},10000000){}dnl
__{}define({_TMP_BEST_B},10000000){}dnl
__{}define({_TMP_BEST_C},10000000){}dnl
__{}____DEQ_VARIATION_32($1,$2,$3,$4,$5){}dnl
__{}ifelse(eval(_TMP_N4<255),{1},{dnl
__{}____SWAP2DEF({_TMP_N4},{_TMP_N3}){}dnl
__{}____SWAP2DEF({_TMP_R4},{_TMP_R3}){}dnl
__{}____DEQ_VARIATION_32($1,$2,$3,$4,$5){}dnl
__{}____SWAP2DEF({_TMP_N4},{_TMP_N3}){}dnl
__{}____SWAP2DEF({_TMP_R4},{_TMP_R3}){}dnl
__{}____DEQ_VARIATION_32($1,$2,$3,$4,$5){}dnl
__{}____SWAP2DEF({_TMP_N4},{_TMP_N1}){}dnl
__{}____SWAP2DEF({_TMP_R4},{_TMP_R1}){}dnl
__{}____DEQ_VARIATION_32($1,$2,$3,$4,$5)})}){}dnl
dnl
dnl

To poradi vypada takto:

0x44-0x33-0x22-0x11
0x44-0x33-0x11-0x22
0x44-0x11-0x33-0x22
0x44-0x11-0x22-0x33
0x44-0x22-0x11-0x33
0x44-0x22-0x33-0x11
0x22-0x44-0x33-0x11
0x22-0x44-0x11-0x33
0x22-0x11-0x44-0x33
0x22-0x11-0x33-0x44
0x22-0x33-0x11-0x44
0x22-0x33-0x44-0x11
0x33-0x22-0x44-0x11
0x33-0x22-0x11-0x44
0x33-0x11-0x22-0x44
0x33-0x11-0x44-0x22
0x33-0x44-0x11-0x22
0x33-0x44-0x22-0x11
0x11-0x44-0x22-0x33
0x11-0x44-0x33-0x22
0x11-0x33-0x44-0x22
0x11-0x33-0x22-0x44
0x11-0x22-0x33-0x44
0x11-0x22-0x44-0x33

nebo takto:

0xFF-0x33-0x22-0x11
0xFF-0x33-0x11-0x22
0xFF-0x11-0x33-0x22
0xFF-0x11-0x22-0x33
0xFF-0x22-0x11-0x33
0xFF-0x22-0x33-0x11

nebo takto:

0xFF-0xFF-0x22-0x11
0xFF-0xFF-0x11-0x22

popripade:

0xFF-0xFF-0xFF-0x11

PS: Nemůžete vytvořit příspěvek tak brzo po předešlém.

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

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Ohledne toho generovani kodu, vyvstava jeden problem ze neexistuje a nebo ho neznam zadne kriterium jak porovnat dva kody. Na prvni pohled se to muze zdat jednoduche a vetsinou i je pokud vime co ten kod dela a jak je pouzit. Proste dame urcite vahy na velikost a na rychlost kodu.
Ja to ted mam tak ze spocitam CENU kodu a levnejsi vitezi. CENA = 8*(takty+4*bajty). Vynasobene osmi je to kvuli tomu ze makra pocitaji jen s celymi cisly a vy mate kod ktery vapada takto
Kód:
../check_word.sh '_2DUP_PUSHDOT_DEQ_IF(0x45352515)'
 
               ;[21:75/33,51,69,75] 2dup 0x45352515 D= if   ( d1 -- d1 )   0x45352515 == DEHL
    ld    A, 0x15       ; 2:7       2dup 0x45352515 D= if
    cp    L             ; 1:4       2dup 0x45352515 D= if   x[1] = 0x15
    jr   nz, $+15       ; 2:7/12    2dup 0x45352515 D= if
    ld    A, 0x25       ; 2:7       2dup 0x45352515 D= if
    cp    H             ; 1:4       2dup 0x45352515 D= if   x[2] = 0x25
    jr   nz, $+10       ; 2:7/12    2dup 0x45352515 D= if
    ld    A, 0x35       ; 2:7       2dup 0x45352515 D= if
    cp    E             ; 1:4       2dup 0x45352515 D= if   x[3] = 0x35
    jr   nz, $+5        ; 2:7/12    2dup 0x45352515 D= if
    ld    A, 0x45       ; 2:7       2dup 0x45352515 D= if
    xor   D             ; 1:4       2dup 0x45352515 D= if   x[4] = 0x45
    jp   nz, else101    ; 3:10      2dup 0x45352515 D= if
                       ;[21:75]

Tady narazim na to ze proste nemam "dynamickou analyzu kodu", nebo jak se tomu nadava, a zpusoby jak naslepo pocitat takty muze byt vice. Ja jsem nakonec zvolil ze jedna vetev je TRUE a ty dalsi 4 jsou FALSE. A obema jsem dal stejnou vahu takze muj prumer byl (75+(33+51+69+75)/4)/2 = (75+57)/2 = 66. Ale ne vzdy to vychazi celociselne tak proto to nasobim osmi. Teda vlastne je to spis: 4*75 + (33+51+69+75). A bajtu jsem zvolil vahu 4 taktu. Pocet bajtu jsou jedine absolutni kriterium, u tech na nic dalsim nezalezi. Jen na jejich vaze oproti rychlosti.

Ale to muze byt cele uplne spatne! Co kdyz to cislo pouzivam ve smycce pro ukonceni a ty cisla postupuji kontinualne! Pak je nejefektivnejsi prvni testovat registr "L", protoze kazdy dalsi test se provede 256x mene. Takze kdyz pak spojim test "HL" do jednoho testu a kod vypada kratsi a celkove rychlejsi tak je leda tak kratsi a 256x pomalejsi o kazdy takt navic, kdy srovnam jen takty za "L" test oproti "HL" testu...

Proto jsem taky pridal do ceny jeden jediny bod navic pokud neni "L" jako prvni testovany registr. Bez ohledu zda je teda ten test spojeny a ma to nejaky vyznam. To me aspon kdy je to mozny uprednostni kod, ktery ma "L" v testech vepredu.

U tech stejnych vah pro TRUE a FALSE jsem to bral tak ze nevim jak ten kod vypada (i kdyz ho budu mit cely k dispozici, ale to chce proste uz nejake AI a ne makro) a co dela. A i kdyz by se mohlo zdat ze tady napriklad u TRUE bude pravdepodobnost 1/(256*256*256*256-1) oproti FALSE kde bude temer rovna jedne, tak to tak proste v kodu normalne nebyva.

Jestli na to existuje nejake kriterium (nebo metrika? To by melo byt neco jineho) fakt netusim. Nevite to nekdo?

Kod me ted generuje obcas vice variant a vypada to pak nejak takto:
Kód:
if 0
; price: 1038
               ;[15:71/60,71,71,71] 2dup 0x66330000 D<>   ( d1 -- d1 flag )   0x66330000 <> DEHL
    ld    A, 0x33       ; 2:7       2dup 0x66330000 D<>
    cp    E             ; 1:4       2dup 0x66330000 D<>   x[1] = 0x33
    jr   nz, $+6        ; 2:7/12    2dup 0x66330000 D<>
    add   A, E          ; 1:4       2dup 0x66330000 D<>
    xor   D             ; 1:4       2dup 0x66330000 D<>   x[2] = x[1] + x[1]
    or    H             ; 1:4       2dup 0x66330000 D<>   x[3] = 0
    or    L             ; 1:4       2dup 0x66330000 D<>   x[4] = 0
    add   A, 0xFF       ; 2:7       2dup 0x66330000 D<>
    ex   DE, HL         ; 1:4       2dup 0x66330000 D<>
    push HL             ; 1:11      2dup 0x66330000 D<>
    sbc  HL, HL         ; 2:15      2dup 0x66330000 D<>   set flag d1==0x66330000
else
; price: 1014
                     ;[16:45,72/67] 2dup 0x66330000 D<>   ( d1 -- d1 flag )   # default version with 0x????0000
    ex   DE, HL         ; 1:4       2dup 0x66330000 D<>
    push HL             ; 1:11      2dup 0x66330000 D<>
    ld    A, E          ; 1:4       2dup 0x66330000 D<>
    or    D             ; 1:4       2dup 0x66330000 D<>
    jr   nz, $+9        ; 2:7/12    2dup 0x66330000 D<>
    ld   BC, 0x6633     ; 3:10      2dup 0x66330000 D<>   hi16(0x66330000)
    sbc  HL, BC         ; 2:15      2dup 0x66330000 D<>   HL-hi16(d1)
    jr    z, $+5        ; 2:7/12    2dup 0x66330000 D<>
    ld   HL, 0xFFFF     ; 3:10      2dup 0x66330000 D<>   set flag d1<>0x66330000
endif

Kdy kratsi kod je jen ukazan, ale nepouzit, protoze si makro mysli ze ten defaultni kod je lepsi. A vy si to muzete prohodit, kdyz prepisete nulu na nenulove cislo.

_________________
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: 23.06.2022, 12:09 
Offline
Óm Nejvyšší

Registrován: 22.05.2013, 21:14
Příspěvky: 3642
Bydliště: Bratislava
Has thanked: 371 times
Been thanked: 788 times
_dworkin píše:
Kód:
    jr   nz, $+18       ; 2:7/12    2dup 0x45352515 D<> if
Kam skoci to $+18 ? 18 je uz dost velka hodnota, uz to zacina byt neintuitivne a nachylne na chyby (clovek medzi tym nieco doplni a zabudne zmenit tu 18-ku). Podla mna, preto pouzivame asembler, aby sme taketo skoky nemuseli prepocitavat rucne. Navrhujem pozivat labely...
(vnutri makra samozrejme lokalne labely, ktore dnes uz vie kazdy poriadny asembler)


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

Registrován: 22.05.2013, 21:14
Příspěvky: 3642
Bydliště: Bratislava
Has thanked: 371 times
Been thanked: 788 times
_dworkin píše:
Proste pokud mam v cisle jednicku a pokusim se to spojit tak ze
Kód:
...
inc A
xor A
dec A
...
Tak to pri soubehu chyb selze.
Obavam sa ze toto zlyha vzdy, pretoze je uplne jedno ci v A je predtym jednicka alebo nie, instrukcia XOR A totalne zvalcuje cele AF...


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 23.06.2022, 12:45 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Busy píše:
_dworkin píše:
Proste pokud mam v cisle jednicku a pokusim se to spojit tak ze
Kód:
...
inc A
xor A
dec A
...
Tak to pri soubehu chyb selze.
Obavam sa ze toto zlyha vzdy, pretoze je uplne jedno ci v A je predtym jednicka alebo nie, instrukcia XOR A totalne zvalcuje cele AF...


Dobry postreh, melo tam byt jakykoliv registr z DEHL, napr. "xor L".

_________________
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 ... 9, 10, 11, 12, 13, 14, 15 ... 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 1 návštěvní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