OldComp.cz

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


Právě je 28.03.2024, 16:05

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 ... 19, 20, 21, 22, 23, 24, 25 ... 39  Další
Autor Zpráva
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 27.09.2022, 17:20 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Snazil jsem se zkompilovat ukazkovy program LIFE co jsem mel napsany pro M4 FORTH.
Idea byla ze promazu ruzne DUP_PUSH(num) na DUP PUSH(num) a pekne se me ukaze, kde me jeste chybi pravidla v tokenech na spojovani slov. Neocekavan zadny velky problem.
Promazu podtrzitka, presunu parametry vzdy k PUSH a kompuluji...
Kód:
m4:life.m4:111: invalid operator in eval: ( -- )
m4:life.m4:111: invalid operator in eval: ( -- )
m4:life.m4:111: invalid operator in eval: ( -- )
m4:life.m4:111: invalid operator in eval: ( -- )
m4:life.m4:111: invalid operator in eval: ( -- )
m4:life.m4:111: invalid operator in eval: ( -- )
Tohle je tam asi 100x a pokracuje to
Kód:
m4:../M4/FIRST.M4:34: bad expression in eval (bad input): (((buff) & 0xFF00) == ((buff + 32*24) & 0xFF00)) && ((32*24) % 3 == 0)
m4:../M4/FIRST.M4:34: bad expression in eval (bad input): (buff+1) & 0x03
m4:../M4/FIRST.M4:34: bad expression in eval (bad input): (buff+2) & 0x03
m4:../M4/FIRST.M4:34: bad expression in eval (bad input): (buff+3) & 0x03
m4:../M4/FIRST.M4:34: bad expression in eval (bad input): (buff+0) & 0x03
m4:../M4/FIRST.M4:34: bad expression in eval (bad input): (((buff) & 0xFF00) == ((buff + 32*24) & 0xFF00)) && ((32*24) % 3 == 0)
m4:../M4/FIRST.M4:34: bad expression in eval (bad input): (buff+1) & 0x03
m4:../M4/FIRST.M4:34: bad expression in eval (bad input): (buff+2) & 0x03
m4:../M4/FIRST.M4:34: bad expression in eval (bad input): (buff+3) & 0x03
m4:../M4/FIRST.M4:34: bad expression in eval (bad input): (buff+0) & 0x03
m4:../M4/runtime.m4:1725: ERROR: end of file in argument list
old: ls: nelze přistoupit k 'life.bin': Adresář nebo soubor neexistuje
ERROR: Symbol 'buff' is undefined  on line 201 of file life.asm
new: ls: nelze přistoupit k 'life.bin': Adresář nebo soubor neexistuje

Po nejakem case pridavam pravidlo do makra __IS_NUM, ze pokud neobsahuje ZADNY znak 0 az 9 tak to neni cislo. Hex hodnota se zapisuje pres 0x... takze je tam nula. Neni to 100% kontrola, protoze "( abc_0 -- )" by to zmatlo.
Tim odstranuji tech cca 100 vypisu s ( -- ). Generovalo me to slovo SCOLON pro zacatek definice vlastniho slova, kde jako druhy parametr je popis co to dela se zasobnikem.

U tech dalsich pravidel jsem bezradny, koukam na program a nikde to tam nemam, podeziram CSTORE a ani tam to nemam.
Divam se na ty vzroce a vypadaji logicky, snazi se zjistit zda nepretikam segment. Tu delitelnost ctyrma nechapu. Ale nepomaha to.
Nakonec to vzdavam a delam kopii programu a postupne odmazavam radky az zjistim ze to dela PUSH3_FILL.

Koukam na PUSH3_FILL a nikde netestuji ze vstup neni cislo, takze pridavam vsude misto eval __SAVE_EVAL.
To pak musim opravit protoze kdyz parametr zacina ( tak je to pointer, takze opravuji vsude na +(.
Slava! Generuje to kod uz bez chyb.

Zjistuji ze ten kod je ale vadny...

Resim tam totiz tu delitelnost ctyrma, kvuli tomu ze je tam bud

inc HL nebo jen inc L

Divam se na svuj stary life.asm a mam tam taky vsude jen inc L a pritom je ten buffer 24*32=768, takze pretika segment. Divne. Protoze program bezi normalne. Tak kompiluji ten stary life.asm a uz to nejede. Aha takze jsem menil PUSH3_FILL nekdy potom, jeste kdyz jsem netokenizoval a udelal jsem chybu.

Hm... resim to teda ze testuji zda je adresa cislo a pokud ne pouzivam makra pasma.

Zkompiluji a pasmo me zarve ze nezna "buff"!

Pritom ze ho vklada do registru predtim mu nevadi... Vypada to nejak takto:
Kód:
 ld HL, buff
...
  ld (HL),C
  if 0x03 & (buff+1)
    inc L
  else
    inc HL
  ld (HL),C
  if 0x03 & (buff+2)
    inc L
  else
    inc HL
  ld (HL),C
  if 0x03 & (buff+3)
    inc L
  else
    inc HL
  ld (HL),C
  if 0x03 & (buff+0)
    inc L
  else
    inc HL
 djnz $-8
...
buff:

Sakra, takze Pasmo nezvladne kdyz ma v podmince adresu ktera je az za nim.
Chapu ze to uz chce asi vic pruchodu, ale zrovna tento pripad co mam nemeni adresu, obe varianty jsou vzdy jednobitove.
Hmm... Po case me napadne vyzkouset

buff equ adr_buff
...
...
...
adr_buf:

A on to zkompiluje!
Zarve na me chyby, ktere drive nevypisoval. Asi vicepruchod aktivuje analyzu kodu.
Binarka ale bezi normalne, zadne chyby jsem nezjistil.
Trosku jsem se na ne dival a vypada to vetsinou ze je to ok.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/Game$ pasmo life.asm life.bin
WARNING: Switching to 3 pass mode on line 2 of file life.asm
WARNING: Var STRING_SECTION is never used on line 945 of file life.asm
WARNING: Var _alive_end is never used on line 716 of file life.asm
WARNING: Var _copy_end is never used on line 238 of file life.asm
WARNING: Var _cursor is never used on line 33 of file life.asm
WARNING: Var _down_end is never used on line 189 of file life.asm
WARNING: Var _generation_end is never used on line 652 of file life.asm
WARNING: Var _h is never used on line 27 of file life.asm
WARNING: Var _init_end is never used on line 612 of file life.asm
WARNING: Var _invert_all_end is never used on line 556 of file life.asm
WARNING: Var _left_end is never used on line 99 of file life.asm
WARNING: Var _random_all_end is never used on line 515 of file life.asm
WARNING: Var _readkey_end is never used on line 477 of file life.asm
WARNING: Var _right_end is never used on line 159 of file life.asm
WARNING: Var _screen is never used on line 31 of file life.asm
WARNING: Var _stop is never used on line 35 of file life.asm
WARNING: Var _up_end is never used on line 219 of file life.asm
WARNING: Var _w is never used on line 25 of file life.asm
WARNING: Var _wh is never used on line 29 of file life.asm
WARNING: Var break101 is never used on line 22 of file life.asm
WARNING: Var break103 is never used on line 276 of file life.asm
WARNING: Var endif101 is never used on line 475 of file life.asm
WARNING: Var endif102 is never used on line 298 of file life.asm
WARNING: Var endif103 is never used on line 307 of file life.asm
WARNING: Var endif104 is never used on line 316 of file life.asm
WARNING: Var endif105 is never used on line 325 of file life.asm
WARNING: Var endif106 is never used on line 334 of file life.asm
WARNING: Var endif107 is never used on line 343 of file life.asm
WARNING: Var endif108 is never used on line 381 of file life.asm
WARNING: Var endif109 is never used on line 419 of file life.asm
WARNING: Var endif110 is never used on line 444 of file life.asm
WARNING: Var endif111 is never used on line 459 of file life.asm
WARNING: Var endif112 is never used on line 470 of file life.asm
WARNING: Var endif114 is never used on line 686 of file life.asm
WARNING: Var endif115 is never used on line 708 of file life.asm
WARNING: Var endif116 is never used on line 766 of file life.asm
WARNING: Var endif117 is never used on line 808 of file life.asm
WARNING: Var last_key is never used on line 37 of file life.asm
WARNING: Var sleave101 is never used on line 94 of file life.asm
WARNING: Var sleave102 is never used on line 154 of file life.asm
WARNING: Var sleave103 is never used on line 510 of file life.asm
WARNING: Var sleave104 is never used on line 551 of file life.asm
WARNING: Var snext105 is never used on line 581 of file life.asm
WARNING: Var snext106 is never used on line 648 of file life.asm
WARNING: Var sum_neighbors_end is never used on line 898 of file life.asm

break ani endif nemusi byt pouzite pokud neni ve smycce BREAK. Ostatni nevim, nemam cas, uz musim zase bezet do prace.

PS: Tu hlavni chybu kdy me M4 prestane generovat kod v casti runtime.m4 jsem jeste nedoresil. Naprosto nechapu. Diky tomu se nevygeneruje sekce s promennyma, vcetne buff.

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


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

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Tak jsem to uspesne doresil.

Chyba ktera koncila tim, ze me M4 nedokoncil makra byla, ze jsem mel ve slove DUP_PUSH_ADD() dvakrat ifelse. Copy paste chyba.

Predtim:

ifelse(podminka1,vysledek_podminky1,varianta1,
ifelse(podminka2,vysledek_podminky2,varianta2,
podminke3,vysledek_podminky3,varianta3,
podminka4,vysledek_podminky4,variatna4,
varianta_jinak)

Spravne:

ifelse(podminka1,vysledek_podminky1,varianta1,
podminka2,vysledek_podminky2,varianta2,
podminke3,vysledek_podminky3,varianta3,
podminka4,vysledek_podminky4,variatna4,
varianta_jinak)

Proc to koncilo az v runtime u konkretni funkci netusim.

Dalsi vtipna chyba byla ve stejne funkci, ale problem byl u tokenu ve vstupu.

Protoze v kodu je

I PUSH() ADD

kde je I index u smycky ktera ma index ulozeny na zasobniku takze I dela jen DUP.

Ale protoze to neni primo DUP tak to neaktivovalo optimalizace pro DUP_PUSH_ADD.

Mel a mam jeste jedno pravidlo, ktere me zatim vic skodi nez je k uzitku, ze jsem misto PUSH+NECO mam NECO+PUSH (to me pak rozbiji navazujici pravidla co by tim PUSH mohlo zacinat pote).

Takze mam I a PUSH, ktere vytvori I_PUSH.

Pridal jsem kontrolu zda nahodou nejsme ve smycce typu S a pokud ano tak jsem zmenil jmeno tokenu na DUP_PUSH misto I_PUSH.

A to byla chyba, protoze jsem zapomnel ze I vklada do parametru cislo smycky. Takze ten token ma 2 parametry a ne jeden.

Takze jsem pak vsude misto parametru z PUSH vkladal cislo smycky a ja nechapal proc mi to tam vklada 0x006A misto 0x5800.

Vysledny kod life ma ted 901 bajtu oproti puvodnim 910 bajtum.

Musel jsem pridat nejake pravidla pro tokeny s PODMINKA + IF co me chybely, tam toho bude jeste vic na dodelani.

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


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

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Hral jsem si jen tak pro zabavu s variantou, kdy misto double hodnot mame na zasobniku ukazatele na double hodnoty. Neni to prilis dobry napad, ale na druhou stranu, pokud se potrebujeme dostat ke treti double hodnote na zasobniku, tak uz mame strasnou rezii taky. To se snazime dostat k treti a ctvrte polozce na zasobniku.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_2OVER DOR'
 
                        ;[9:91]     2over ( d c b a -- d c b a d c )
    pop  AF             ; 1:10      2over d       . b a     AF = c
    pop  BC             ; 1:10      2over         . b a     BC = d
    push BC             ; 1:11      2over d       . b a
    push AF             ; 1:11      2over d c     . b a
    push DE             ; 1:11      2over d c b   . b a
    push AF             ; 1:11      2over d c b c . b a
    ex  (SP),HL         ; 1:19      2over d c b a . b c
    ld    D, B          ; 1:4       2over
    ld    E, C          ; 1:4       2over d c b a . d c
    pop  BC             ; 1:10      dor   ( d2 d1 -- d )  d = d2 | d1
    ld    A, C          ; 1:4       dor
    or    L             ; 1:4       dor
    ld    L, A          ; 1:4       dor
    ld    A, B          ; 1:4       dor
    or    H             ; 1:4       dor
    ld    H, A          ; 1:4       dor
    pop  BC             ; 1:10      dor
    ld    A, C          ; 1:4       dor
    or    E             ; 1:4       dor
    ld    E, A          ; 1:4       dor
    ld    A, B          ; 1:4       dor
    or    D             ; 1:4       dor
    ld    D, A          ; 1:4       dor
                       ;[23:159]

Nenasel jsem pro Forth nejake peknou kombinaci standardnich slov tak jsem vytvoril nove, proste jsem pridal P ke slovum na zacatek. Vsechna slova jsou nedestruktivni, nic nemeni na zasobniku.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PDOR'

    ld    A,(DE)        ; 1:7       pdor   ( pd2 pd1 -- pd2 pd1 )  [pd1] |= [pd2] with align 4
    or   (HL)           ; 1:7       pdor
    ld   (HL), A        ; 1:7       pdor
    ld     C, L         ; 1:4       pdor
    ld     B, E         ; 1:4       pdor
    inc    L            ; 1:4       pdor
    inc    E            ; 1:4       pdor
    ld    A,(DE)        ; 1:7       pdor
    or   (HL)           ; 1:7       pdor
    ld   (HL), A        ; 1:7       pdor
    inc    L            ; 1:4       pdor
    inc    E            ; 1:4       pdor
    ld    A,(DE)        ; 1:7       pdor
    or   (HL)           ; 1:7       pdor
    ld   (HL), A        ; 1:7       pdor
    inc    L            ; 1:4       pdor
    inc    E            ; 1:4       pdor
    ld    A,(DE)        ; 1:7       pdor
    or   (HL)           ; 1:7       pdor
    ld   (HL), A        ; 1:7       pdor
    ld     L, C         ; 1:4       pdor
    ld     E, B         ; 1:4       pdor
                       ;[22:124]

Tohle bylo nejlepsi co me napadlo. Obdobne PDXOR a PDAND jako pres sablonu.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PDXOR'

    ld    A,(DE)        ; 1:7       pdxor   ( pd2 pd1 -- pd2 pd1 )  [pd1] ^= [pd2] with align 4
    xor  (HL)           ; 1:7       pdxor
    ld   (HL), A        ; 1:7       pdxor
    ld     C, L         ; 1:4       pdxor
    ld     B, E         ; 1:4       pdxor
    inc    L            ; 1:4       pdxor
    inc    E            ; 1:4       pdxor
    ld    A,(DE)        ; 1:7       pdxor
    xor  (HL)           ; 1:7       pdxor
    ld   (HL), A        ; 1:7       pdxor
    inc    L            ; 1:4       pdxor
    inc    E            ; 1:4       pdxor
    ld    A,(DE)        ; 1:7       pdxor
    xor  (HL)           ; 1:7       pdxor
    ld   (HL), A        ; 1:7       pdxor
    inc    L            ; 1:4       pdxor
    inc    E            ; 1:4       pdxor
    ld    A,(DE)        ; 1:7       pdxor
    xor  (HL)           ; 1:7       pdxor
    ld   (HL), A        ; 1:7       pdxor
    ld     L, C         ; 1:4       pdxor
    ld     E, B         ; 1:4       pdxor
                       ;[22:124]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PDAND'

    ld    A,(DE)        ; 1:7       pdand   ( pd2 pd1 -- pd2 pd1 )  [pd1] &= [pd2] with align 4
    and  (HL)           ; 1:7       pdand
    ld   (HL), A        ; 1:7       pdand
    ld     C, L         ; 1:4       pdand
    ld     B, E         ; 1:4       pdand
    inc    L            ; 1:4       pdand
    inc    E            ; 1:4       pdand
    ld    A,(DE)        ; 1:7       pdand
    and  (HL)           ; 1:7       pdand
    ld   (HL), A        ; 1:7       pdand
    inc    L            ; 1:4       pdand
    inc    E            ; 1:4       pdand
    ld    A,(DE)        ; 1:7       pdand
    and  (HL)           ; 1:7       pdand
    ld   (HL), A        ; 1:7       pdand
    inc    L            ; 1:4       pdand
    inc    E            ; 1:4       pdand
    ld    A,(DE)        ; 1:7       pdand
    and  (HL)           ; 1:7       pdand
    ld   (HL), A        ; 1:7       pdand
    ld     L, C         ; 1:4       pdand
    ld     E, B         ; 1:4       pdand
                       ;[22:124]

Pridal jsem k logickym i aritmeticke operatory. Tam uz se efektivita ztraci, protoze Z80 umi i 16bitovou aritmetiku.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_2OVER DADD'
 
                        ;[9:93]     2over D+   ( hi2 lo2 hi1 lo1 -- hi2 lo2 hi1+hi2+carry lo1+lo2 )
    pop  BC             ; 1:10      2over D+   lo2
    add  HL, BC         ; 1:11      2over D+
    ex  (SP),HL         ; 1:19      2over D+   hi2
    ex   DE, HL         ; 1:4       2over D+
    adc  HL, DE         ; 2:15      2over D+
    ex   DE, HL         ; 1:4       2over D+
    ex  (SP),HL         ; 1:19      2over D+
    push BC             ; 1:11      2over D+
                       ;[ 9:93]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PDADD'

    ld    A,(DE)        ; 1:7       pd+   ( pd2 pd1 -- pd2 pd1 )  [pd1] += [pd2] with align 4
    add  (HL)           ; 1:7       pd+
    ld   (HL), A        ; 1:7       pd+
    ld     C, L         ; 1:4       pd+
    ld     B, E         ; 1:4       pd+
    inc    L            ; 1:4       pd+
    inc    E            ; 1:4       pd+
    ld    A,(DE)        ; 1:7       pd+
    adc   A,(HL)        ; 1:7       pd+
    ld   (HL), A        ; 1:7       pd+
    inc    L            ; 1:4       pd+
    inc    E            ; 1:4       pd+
    ld    A,(DE)        ; 1:7       pd+
    adc   A,(HL)        ; 1:7       pd+
    ld   (HL), A        ; 1:7       pd+
    inc    L            ; 1:4       pd+
    inc    E            ; 1:4       pd+
    ld    A,(DE)        ; 1:7       pd+
    adc   A,(HL)        ; 1:7       pd+
    ld   (HL), A        ; 1:7       pd+
    ld     L, C         ; 1:4       pd+
    ld     E, B         ; 1:4       pd+
                       ;[22:124]

Obdobne pro odcitani
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_2OVER DSUB'
 
                        ;[11:101]   2over D-   ( hi2 lo2 hi1 lo1 -- hi2 lo2 hi1-hi2-carry lo2-lo1 )
    pop  BC             ; 1:10      2over D-   lo2
    or    A             ; 1:4       2over D-
    sbc  HL, BC         ; 2:15      2over D-
    ex  (SP),HL         ; 1:19      2over D-   hi2
    ex   DE, HL         ; 1:4       2over D-
    sbc  HL, DE         ; 2:15      2over D-
    ex   DE, HL         ; 1:4       2over D-
    ex  (SP),HL         ; 1:19      2over D-
    push BC             ; 1:11      2over D-
                       ;[11:101]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PDSUB'

    ld    A,(DE)        ; 1:7       pd-   ( pd2 pd1 -- pd2 pd1 )  [pd1] -= [pd2] with align 4
    sub  (HL)           ; 1:7       pd-
    ld   (HL), A        ; 1:7       pd-
    ld     C, L         ; 1:4       pd-
    ld     B, E         ; 1:4       pd-
    inc    L            ; 1:4       pd-
    inc    E            ; 1:4       pd-
    ld    A,(DE)        ; 1:7       pd-
    sbc   A,(HL)        ; 1:7       pd-
    ld   (HL), A        ; 1:7       pd-
    inc    L            ; 1:4       pd-
    inc    E            ; 1:4       pd-
    ld    A,(DE)        ; 1:7       pd-
    sbc   A,(HL)        ; 1:7       pd-
    ld   (HL), A        ; 1:7       pd-
    inc    L            ; 1:4       pd-
    inc    E            ; 1:4       pd-
    ld    A,(DE)        ; 1:7       pd-
    sbc   A,(HL)        ; 1:7       pd-
    ld   (HL), A        ; 1:7       pd-
    ld     L, C         ; 1:4       pd-
    ld     E, B         ; 1:4       pd-
                       ;[22:124]

Posledni co jsem zkousel je pricteni/odecteni jednicky. Kdy pricteni jeste jakztakz jde.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'D1ADD'

    inc  HL             ; 1:6       D1+   lo word
    ld    A, L          ; 1:4       D1+
    or    H             ; 1:4       D1+
    jr   nz, $+3        ; 2:7/12    D1+
    inc  DE             ; 1:6       D1+   hi word
                       ;[ 6:27]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PD1ADD'

    inc  (HL)           ; 1:11      pd1+   ( pd -- pd )  [pd] += 1 with align 4
    jr     z, $+14      ; 2:7/12    pd1+
    ld     C, L         ; 1:4       pd1+
    inc    L            ; 1:4       pd1+
    inc  (HL)           ; 1:11      pd1+
    jr     z, $+8       ; 2:7/12    pd1+
    inc    L            ; 1:4       pd1+
    inc  (HL)           ; 1:11      pd1+
    jr     z, $+4       ; 2:7/12    pd1+
    inc    L            ; 1:4       pd1+
    inc  (HL)           ; 1:11      pd1+
    ld     L, C         ; 1:4       pd1+
                       ;[15:85]

Ale odecteni je uz orisek, nakonec po vice variantach jsem dospel k tomuto reseni. A to jsem se celkem zapotil. Zase pro ukazku prvne jak to vypada kdyz je cislo primo na zasobniku.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'D1SUB'

    ld    A, L          ; 1:4       D1-   ( d -- d-1 )
    or    H             ; 1:4       D1-
    dec  HL             ; 1:6       D1-   lo word
    jr   nz, $+3        ; 2:7/12    D1-
    dec  DE             ; 1:6       D1-   hi word
                       ;[ 6:27]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PD1SUB'

                ;[19:34,71,100,110] pd1-   ( pd -- pd )  [pd] -= 1 with align 4
    xor    A            ; 1:4       pd1-
    or     A,(HL)       ; 1:7       pd1-
    jr    nz, $+16      ; 2:7/12    pd1-
    ld     C, L         ; 1:4       pd1-
    inc    L            ; 1:4       pd1-
    or   (HL)           ; 1:7       pd1-
    jr    nz, $+9       ; 2:7/12    pd1-
    dec  (HL)           ; 1:11      pd1-
    inc    L            ; 1:4       pd1-
    or   (HL)           ; 1:7       pd1-
    jr    nz, $+4       ; 2:7/12    pd1-
    dec  (HL)           ; 1:11      pd1-
    inc    L            ; 1:4       pd1-
    dec  (HL)           ; 1:11      pd1-
    ld     L, C         ; 1:4       pd1-
    dec  (HL)           ; 1:11      pd1-
                       ;[19:110]

Pokud buteme trvat na pointerech a nepouzivat tyhle slova je vse samozrejme mnohem horsi. Napriklad to "pd1-" co ma 19 bajtu a trva az 110 taktu (realne je to ve 255 pripadech z 256 jen 34 taktu).
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'DUP DUP _2FETCH D1SUB _2ROT _2STORE'
     
    push DE             ; 1:11      dup dup   ( a -- a a a )
    push HL             ; 1:11      dup dup
    ld    D, H          ; 1:4       dup dup
    ld    E, L          ; 1:4       dup dup
                        ;[10:65]    2@ _2fetch
    push DE             ; 1:11      2@ _2fetch
    ld    E, (HL)       ; 1:7       2@ _2fetch
    inc  HL             ; 1:6       2@ _2fetch
    ld    D, (HL)       ; 1:7       2@ _2fetch
    inc  HL             ; 1:6       2@ _2fetch
    ld    A, (HL)       ; 1:7       2@ _2fetch
    inc  HL             ; 1:6       2@ _2fetch
    ld    H, (HL)       ; 1:7       2@ _2fetch
    ld    L, A          ; 1:4       2@ _2fetch
    ex   DE, HL         ; 1:4       2@ _2fetch ( adr -- lo hi )
    ld    A, L          ; 1:4       D1-   ( d -- d-1 )
    or    H             ; 1:4       D1-
    dec  HL             ; 1:6       D1-   lo word
    jr   nz, $+3        ; 2:7/12    D1-
    dec  DE             ; 1:6       D1-   hi word
                       ;[15:127]    2rot ( f e d c b a -- d c b a f e ) # default version can be changed with "define({TYP_2ROT},{fast})"
    exx                 ; 1:4       2rot f e d c .
    pop  DE             ; 1:10      2rot f e d   .      DE' = c
    pop  BC             ; 1:10      2rot f e     .      BC' = d
    exx                 ; 1:4       2rot f e     . b a
    ex  (SP),HL         ; 1:19      2rot f a     . b e
    pop  AF             ; 1:10      2rot f       . b e  AF = a
    pop  BC             ; 1:10      2rot         . b e  BC = f
    exx                 ; 1:4       2rot
    push BC             ; 1:11      2rot d       .
    push DE             ; 1:11      2rot d c     .
    exx                 ; 1:4       2rot d c     . b e
    push DE             ; 1:11      2rot d c b   . b e
    ld    D, B          ; 1:4       2rot
    ld    E, C          ; 1:4       2rot d c b   . f e
    push AF             ; 1:11      2rot d c b a . f e
                        ;[10:76]    2!  _2store   ( hi lo addr -- )
    ld  (HL),E          ; 1:7       2!  _2store
    inc  HL             ; 1:6       2!  _2store
    ld  (HL),D          ; 1:7       2!  _2store
    inc  HL             ; 1:6       2!  _2store
    pop  DE             ; 1:10      2!  _2store
    ld  (HL),E          ; 1:7       2!  _2store
    inc  HL             ; 1:6       2!  _2store
    ld  (HL),D          ; 1:7       2!  _2store
    pop  HL             ; 1:10      2!  _2store
    pop  DE             ; 1:10      2!  _2store
                       ;[45:325]

PS: Musel jsem jeste zvlolit ze ty pointery nesmi lezet pres segment, jinak je ten kod jeste pomalejsi a delsi, takze obetovat nekdy az 3 bajty pro zarovnani se vyplati.
PPS: Tech slov je hodne malo, takze se stejne nevyplati pouzivat algoritmy, kde chceme pracovat s hodnotama v pameti, protoze skoncime u toho budeme kombinovat P-slova s neefektivni kombinaci zakladnich slov.

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

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Premyslel jsem jake zakladni slova jsou asi nejvic potreba pro ty pointery na 32 bitove hodnoty a nasel jsem si v sekci Benchmark program na hledani nejvetsiho spolecneho delitele. Prevedl jsem ho na 32bitovou verzi a u toho postupne doplnoval co to chtelo. Vcetne doplneni pravidel v tokenech i pro "nepointerova" slova a opravy nekterych slov jako treba pushdot_push_2store.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ grep -R 'define({PD'
logic.m4:define({PDAND},{dnl
logic.m4:define({PDOR},{dnl
logic.m4:define({PDXOR},{dnl
logic.m4:define({PD0EQ},{dnl
logic.m4:define({PD0NE},{dnl
logic.m4:define({PDEQ},{dnl
logic.m4:define({PDNE},{dnl
logic.m4:define({PDLT},{dnl
logic.m4:define({PDGE},{dnl
logic.m4:define({PDLE},{dnl
logic.m4:define({PDGT},{dnl
arithmetic.m4:define({PDADD},{dnl
arithmetic.m4:define({PDSUB},{dnl
arithmetic.m4:define({PDSUB_NEGATE},{dnl
arithmetic.m4:define({PD1ADD},{dnl
arithmetic.m4:define({PD1SUB},{dnl

Chybi tam nejmene jedno slovo pro "swap pdsub", ale to neni dulezite (navic ma stejny kod jako kdyz to nespojite).
Kód:
include(`../M4/FIRST.M4')dnl
    ORG 32768
    INIT(60000)
    CALL(d_gcd_bench)
    STOP   
    COLON(d_gcd,( d2 d1 -- gcd ))                                                               
        _2OVER D0NE IF                                                                         
            BEGIN                                                                         
            _2DUP D0NE WHILE                                                                   
                _4DUP DUGT IF _2SWAP THEN _2OVER DSUB                                               
            REPEAT _2DROP
        ELSE                                                               
            _2DUP D0NE IF _2NIP ELSE _2DROP PUSHDOT(1) THEN                                                   
        THEN
    SEMICOLON
    COLON(d_gcd_bench,( -- ))
        DO(M,100,0)
            DO(M,100,0)
               J S_TO_D
               I S_TO_D
               CALL(d_gcd)
;#J SPACE UDOT
;#I SPACE UDOT
;#SPACE UDDOT
;#CR
               _2DROP
            LOOP
        LOOP
    SEMICOLON

191 bajtu program trva 11.7 sekund.
Nejvnitrnejsi smycka je
Kód:
BEGIN                                                                         
            _2DUP D0NE WHILE                                                                   
                _4DUP DUGT IF _2SWAP THEN _2OVER DSUB                                               
            REPEAT

Pro predstavu jak moc je tahle cast zasadni tak nez jsem pridal pravidlo pro spojeni slov _2DUP D0NE WHILE do _2DUP_D0NE_WHILE a mel jsem spojeno _2DUP_D0NE, ktere ukladalo do TOS(=HL) TRUE nebo FALSE a teprve pak to WHILE cetlo, tak program mel 201 bajtu a trval 14.29 sekund. To je fakt velky rozdil.
Kod nejvnitrnejsi smycky vypada takto
Kód:
begin101:               ;           begin 101
                       ;[10:53]     2dup d0<>   ( d -- d flag )
    push DE             ; 1:11      2dup d0<>
    ex   DE, HL         ; 1:4       2dup d0<>
    ld    A, D          ; 1:4       2dup d0<>
    or    E             ; 1:4       2dup d0<>
    or    H             ; 1:4       2dup d0<>
    or    L             ; 1:4       2dup d0<>
    add   A, 0xFF       ; 2:7       2dup d0<>
    sbc  HL, HL         ; 2:15      2dup d0<>   set flag D <> 0

    ld    A, H          ; 1:4       while 101
    or    L             ; 1:4       while 101
    ex   DE, HL         ; 1:4       while 101
    pop  DE             ; 1:10      while 101
    jp    z, break101   ; 3:10      while 101
                       ;[15:101]    4dup Du> if   ( ud2 ud1 -- ud2 ud1 )   # default version can be changed with "define({_TYP_DOUBLE},{function})"
    pop  BC             ; 1:10      4dup Du> if   ud2 > ud1 --> 0>ud1-ud2 --> 0>DEHL-(SP)BC --> carry if true
    ld    A, L          ; 1:4       4dup Du> if
    sub   C             ; 1:4       4dup Du> if   0>L-C --> carry if true
    ld    A, H          ; 1:4       4dup Du> if
    sbc   A, B          ; 1:4       4dup Du> if   0>H-B --> carry if true
    ex  (SP),HL         ; 1:19      4dup Du> if   HL = hi2
    ld    A, E          ; 1:4       4dup Du> if   0>DE(SP)-HLBC -- carry if true
    sbc   A, L          ; 1:4       4dup Du> if   0>E-L --> carry if true
    ld    A, D          ; 1:4       4dup Du> if
    sbc   A, H          ; 1:4       4dup Du> if   0>D-H --> carry if true
    ex  (SP),HL         ; 1:19      4dup Du> if
    push BC             ; 1:11      4dup Du> if
    jp   nc, else102    ; 3:10      4dup Du> if
                        ;[6:67]     2swap   ( d c b a -- b a d c ) # default version can be changed with "define({TYP_2SWAP},{name})", name=fast
    ex  (SP),HL         ; 1:19      2swap   d a . b c
    ex   DE, HL         ; 1:4       2swap   d a . c b
    pop  AF             ; 1:10      2swap   d   . c b     AF = a
    ex  (SP),HL         ; 1:19      2swap   b   . c d
    ex   DE, HL         ; 1:4       2swap   b   . d c
    push AF             ; 1:11      2swap   b a . d c
else102  EQU $          ;           = endif
endif102:
                        ;[11:101]   2over D-   ( hi2 lo2 hi1 lo1 -- d2 d1-d2 )
    pop  BC             ; 1:10      2over D-   lo2
    or    A             ; 1:4       2over D-
    sbc  HL, BC         ; 2:15      2over D-
    ex  (SP),HL         ; 1:19      2over D-   hi2
    ex   DE, HL         ; 1:4       2over D-
    sbc  HL, DE         ; 2:15      2over D-
    ex   DE, HL         ; 1:4       2over D-
    ex  (SP),HL         ; 1:19      2over D-
    push BC             ; 1:11      2over D-
    jp   begin101       ; 3:10      repeat 101
break101:               ;           repeat 101
Popripade takto
Kód:
begin101:               ;           begin 101
    ld    A, H          ; 1:4       2dup D0<> while 101  ( d -- d )
    or    L             ; 1:4       2dup D0<> while 101
    or    D             ; 1:4       2dup D0<> while 101
    or    E             ; 1:4       2dup D0<> while 101
    jp    z, break101   ; 3:10      2dup D0<> while 101
...

Pointerova verze vypada takto
Kód:
include(`../M4/FIRST.M4')dnl
    ORG 32768
    INIT(60000)
    DVARIABLE(_a)
    DVARIABLE(_b)
    CALL(pd_gcd_bench)
    STOP   
    COLON(pd_gcd,( [a] [b] -- gcd ))                                                               
        OVER PD0NE NIP IF                                                                         
            BEGIN                                                                         
            PD0NE WHILE   
                PDGT IF SWAP THEN
                PDSUB_NEGATE                                               
            REPEAT
            DROP _2FETCH
        ELSE                                                               
            PD0NE IF NIP _2FETCH ELSE _2DROP PUSH(0) PUSH(1) THEN                                                   
        THEN
    SEMICOLON
    COLON(pd_gcd_bench,( -- ))
        DO(M,100,0)
            DO(M,100,0)
               J S_TO_D PUSH(_a) _2STORE
               I S_TO_D PUSH(_b) _2STORE
               PUSH(_a) PUSH(_b) CALL(pd_gcd)
;               #SPACE DDOT CR
               _2DROP
            LOOP
        LOOP
    SEMICOLON

297 bajtu a program trva 19.96 sekund.
S tim ale, ze nemam zadnou podporu pro spojeni s IF nebo WHILE, je tam jen co jsem vypsal predtim a OVER_PD0NE_NIP coz dela to, ze zjisti zda hodnota na kterou odkazuje pointer v NOS neobsahuje nulu.
Trochu matouci nazev.

OVER ( dp2 dp1 -- dp2 dp1 dp2 )
PD0NE ( dp2 dp1 dp2 -- dp2 dp1 dp2 flag )
NIP ( dp2 dp1 dp2 flag -- dp2 dp1 flag )

Nejvnitrnejsi smycka je
Kód:
            BEGIN                                                                         
            PD0NE WHILE   
                PDGT IF SWAP THEN
                PDSUB_NEGATE                                               
            REPEAT
a ta vypada takhle
Kód:
begin101:               ;           begin 101
    push DE             ; 1:11      pd0<>   ( pd1 -- pd1 flag )  flag == [pd1] <> 0  with align 4
    ld    A,(HL)        ; 1:7       pd0<>
    ld    C, L          ; 1:4       pd0<>
    inc   L             ; 1:4       pd0<>
    or  (HL)            ; 1:7       pd0<>
    inc   L             ; 1:4       pd0<>
    or  (HL)            ; 1:7       pd0<>
    inc   L             ; 1:4       pd0<>
    or  (HL)            ; 1:7       pd0<>
    add   A, 0xFF       ; 2:7       pd0<>
    ld    L, C          ; 1:4       pd0<>
    ex   DE, HL         ; 1:4       pd0<>
    sbc  HL, HL         ; 2:15      pd0<>
    ld    A, H          ; 1:4       while 101
    or    L             ; 1:4       while 101
    ex   DE, HL         ; 1:4       while 101
    pop  DE             ; 1:10      while 101
    jp    z, break101   ; 3:10      while 101
    push DE             ; 1:11      pdgt   ( pd2 pd1 -- pd2 pd1 flag )  flag == [pd2] > [pd1]  with align 4
    ex   DE, HL         ; 1:4       pdgt
    ld    A,(DE)        ; 1:7       pdgt
    sub (HL)            ; 1:7       pdgt
    ld    C, E          ; 1:4       pdgt
    inc   L             ; 1:4       pdgt
    inc   E             ; 1:4       pdgt
    ld    A,(DE)        ; 1:7       pdgt
    sbc   A,(HL)        ; 1:7       pdgt
    inc   L             ; 1:4       pdgt
    inc   E             ; 1:4       pdgt
    ld    A,(DE)        ; 1:7       pdgt
    sbc   A,(HL)        ; 1:7       pdgt
    inc   L             ; 1:4       pdgt
    inc   E             ; 1:4       pdgt
    ld    A,(DE)        ; 1:7       pdgt
    ld    B, A          ; 1:4       pdgt
    sbc   A,(HL)        ; 1:7       pdgt
    rra                 ; 1:4       pdgt   sign if true
    xor (HL)            ; 1:7       pdgt
    ld    E, C          ; 1:4       pdgt
    xor   B             ; 1:4       pdgt
    add   A, A          ; 1:4       pdgt   carry if true
    sbc  HL, HL         ; 2:15      pdgt   set flag [pd2]>[pd1]
    ld    A, H          ; 1:4       if
    or    L             ; 1:4       if
    ex   DE, HL         ; 1:4       if
    pop  DE             ; 1:10      if
    jp    z, else102    ; 3:10      if
    ex   DE, HL         ; 1:4       swap   ( b a -- a b )
else102  EQU $          ;           = endif
endif102:
    ex   DE, HL         ; 1:4       pd- negate   ( pd2 pd1 -- pd2 pd1 )  [pd1] = -[pd2]  with align 4
    ld    A,(DE)        ; 1:7       pd- negate
    sub  (HL)           ; 1:7       pd- negate
    ld   (DE), A        ; 1:7       pd- negate
    ld     C, L         ; 1:4       pd- negate
    ld     B, E         ; 1:4       pd- negate
    inc    L            ; 1:4       pd- negate
    inc    E            ; 1:4       pd- negate
    ld    A,(DE)        ; 1:7       pd- negate
    sbc   A,(HL)        ; 1:7       pd- negate
    ld   (DE), A        ; 1:7       pd- negate
    inc    L            ; 1:4       pd- negate
    inc    E            ; 1:4       pd- negate
    ld    A,(DE)        ; 1:7       pd- negate
    sbc   A,(HL)        ; 1:7       pd- negate
    ld   (DE), A        ; 1:7       pd- negate
    inc    L            ; 1:4       pd- negate
    inc    E            ; 1:4       pd- negate
    ld    A,(DE)        ; 1:7       pd- negate
    sbc   A,(HL)        ; 1:7       pd- negate
    ld   (DE), A        ; 1:7       pd- negate
    ld     L, C         ; 1:4       pd- negate
    ld     E, B         ; 1:4       pd- negate
    ex   DE, HL         ; 1:4       pd- negate
    jp   begin101       ; 3:10      repeat 101
break101:               ;           repeat 101

Takze mozna se to da jeste dost zrychlit. A to jeste je "PD>" se znamenkem.

PS: Ted me napada, ze jsem neresil to align 4, nastesti to pri 297 bajtech a umisteni na 0x8000 je v poradku.

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

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Pridal jsem dalsi slova.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ grep -R "define({PD"
loop/begin.m4:define({PD0EQ_WHILE},{dnl
loop/begin.m4:define({PD0NE_WHILE},{dnl
logic.m4:define({PDAND},{dnl
logic.m4:define({PDOR},{dnl
logic.m4:define({PDXOR},{dnl
logic.m4:define({PD0EQ},{dnl
logic.m4:define({PD0NE},{dnl
logic.m4:define({PDEQ},{dnl
logic.m4:define({PDNE},{dnl
logic.m4:define({PDLT},{dnl
logic.m4:define({PDULT},{dnl
logic.m4:define({PDGE},{dnl
logic.m4:define({PDUGE},{dnl
logic.m4:define({PDLE},{dnl
logic.m4:define({PDULE},{dnl
logic.m4:define({PDGT},{dnl
logic.m4:define({PDUGT},{dnl
arithmetic.m4:define({PDADD},{dnl
arithmetic.m4:define({PDSUB},{dnl
arithmetic.m4:define({PDSUB_NEGATE},{dnl
arithmetic.m4:define({PD1ADD},{dnl
arithmetic.m4:define({PD1SUB},{dnl
if.m4:define({PD0EQ_IF},{dnl
if.m4:define({PD0NE_IF},{dnl
if.m4:define({PDEQ_IF},{dnl
if.m4:define({PDNE_IF},{dnl
if.m4:define({PDULT_IF},{dnl
if.m4:define({PDUGE_IF},{dnl
if.m4:define({PDUGT_IF},{dnl
if.m4:define({PDULE_IF},{dnl

A tim zrychlil pointerovou verzi z 19.96 sekund na 14.76 sekund.
Velikostne se to zmensilo z 297 bajtu na 267 bajtu.
Nejvnitrnejsi smycka ted vypada takto
Kód:
begin101:               ;           begin 101
    ld    A,(HL)        ; 1:7       pd0<> while 101  ( pd -- pd )
    ld    C, L          ; 1:4       pd0<> while 101
    inc   L             ; 1:4       pd0<> while 101
    or  (HL)            ; 1:7       pd0<> while 101
    inc   L             ; 1:4       pd0<> while 101
    or  (HL)            ; 1:7       pd0<> while 101
    inc   L             ; 1:4       pd0<> while 101
    or  (HL)            ; 1:7       pd0<> while 101
    ld    L, C          ; 1:4       pd0<> while 101
    jp    z, break101   ; 3:10      pd0<> while 101
    scf                 ; 1:4       pdugt if   ( pd2 pd1 -- pd2 pd1 )  with align 4
    ld    A,(DE)        ; 1:7       pdugt if
    sbc   A,(HL)        ; 1:7       pdugt if
    ld    B, E          ; 1:4       pdugt if
    ld    C, L          ; 1:4       pdugt if
    inc   L             ; 1:4       pdugt if
    inc   E             ; 1:4       pdugt if
    ld    A,(DE)        ; 1:7       pdugt if
    sbc   A,(HL)        ; 1:7       pdugt if
    inc   L             ; 1:4       pdugt if
    inc   E             ; 1:4       pdugt if
    ld    A,(DE)        ; 1:7       pdugt if
    sbc   A,(HL)        ; 1:7       pdugt if
    inc   L             ; 1:4       pdugt if
    inc   E             ; 1:4       pdugt if
    ld    A,(DE)        ; 1:7       pdugt if
    sbc   A,(HL)        ; 1:7       pdugt if   carry if false
    ld    E, B          ; 1:4       pdugt if
    ld    L, C          ; 1:4       pdugt if
    jp    c, else102    ; 3:10      pdugt if
    ex   DE, HL         ; 1:4       swap   ( b a -- a b )
else102  EQU $          ;           = endif
endif102:
    ex   DE, HL         ; 1:4       pd- negate   ( pd2 pd1 -- pd2 pd1 )  [pd1] = -[pd2]  with align 4
    ld    A,(DE)        ; 1:7       pd- negate
    sub  (HL)           ; 1:7       pd- negate
    ld   (DE), A        ; 1:7       pd- negate
    ld     C, L         ; 1:4       pd- negate
    ld     B, E         ; 1:4       pd- negate
    inc    L            ; 1:4       pd- negate
    inc    E            ; 1:4       pd- negate
    ld    A,(DE)        ; 1:7       pd- negate
    sbc   A,(HL)        ; 1:7       pd- negate
    ld   (DE), A        ; 1:7       pd- negate
    inc    L            ; 1:4       pd- negate
    inc    E            ; 1:4       pd- negate
    ld    A,(DE)        ; 1:7       pd- negate
    sbc   A,(HL)        ; 1:7       pd- negate
    ld   (DE), A        ; 1:7       pd- negate
    inc    L            ; 1:4       pd- negate
    inc    E            ; 1:4       pd- negate
    ld    A,(DE)        ; 1:7       pd- negate
    sbc   A,(HL)        ; 1:7       pd- negate
    ld   (DE), A        ; 1:7       pd- negate
    ld     L, C         ; 1:4       pd- negate
    ld     E, B         ; 1:4       pd- negate
    ex   DE, HL         ; 1:4       pd- negate
    jp   begin101       ; 3:10      repeat 101
break101:               ;           repeat 101


Zajimave je na tom mozna to, ze vetsinou se u kontrol typu >,<,>=,<= da obejit od pouzivani carry pri odcitani tim, ze spravne zvolite co budete odcitat od ceho.
Pri pouziti dvou pointeru ale mohu efektivne odcitat jen [DE]-[HL]. Takze je to jedno carry navic kratsi, nez 2x pouzit ex DE,HL.

[DE] > [HL]
[DE]-[HL] > 0 --> ???
[DE]-1-[HL] >= 0 --> carry == false

Viz pdugt (Pointer Double Unsigned Great Than)

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

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Pridal jsem 2 slova, PDINVERT a PDNEGATE.
U psani slova PDINVERT me napadlo jiny zpusob jak resit PD1SUB.
Ze bych to mohl zkusit udelat pres pricitani 0xFF.
Pokud to vygeneruje preteceni tak je hotovo. Pokud ne tak tam byla nula a musi se pokracovat, ale s tim, ze mame v akumulatoru stale 0xFF.
Vysledny kod byl o 2 bajty delsi a prvni bajt byl kvuli tomu ze potrebujeme mit na zacatku misto nuly v akumulatoru 0xFF.
Takze misto "xor A" tam je "ld A,0xFF" a druhy bajt jsem nemohl porad nalezt. To si vzdy pripadam, ze na to nemam. A pak me to docvaklo, ze pokud nizzsi 3 bajty jsou nulove tak u nejvyssiho bajtu mam
Kód:
add A,(HL)
ld (HL),A
a pritom me tam staci uz jen
Kód:
dec (HL)

Dal jsem ten kod jako aktivni, protoze je fakt rychlejsi. Da se rici ze jen o jeden takt z 255 pripadu z 256 ale i tak...
Puvodni vs novy:
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PD1SUB'

                ;[19:34,71,100,110] pd1-   ( pd -- pd )  [pd] -= 1 with align 4
    xor   A             ; 1:4       pd1-
    or    A,(HL)        ; 1:7       pd1-
    jr   nz, $+16       ; 2:7/12    pd1-
    ld    C, L          ; 1:4       pd1-
    inc   L             ; 1:4       pd1-
    or  (HL)            ; 1:7       pd1-
    jr   nz, $+9        ; 2:7/12    pd1-
    dec (HL)            ; 1:11      pd1-
    inc   L             ; 1:4       pd1-
    or  (HL)            ; 1:7       pd1-
    jr   nz, $+4        ; 2:7/12    pd1-
    dec (HL)            ; 1:11      pd1-
    inc   L             ; 1:4       pd1-
    dec (HL)            ; 1:11      pd1-
    ld    L, C          ; 1:4       pd1-
    dec (HL)            ; 1:11      pd1-
                       ;[19:110]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PD1SUB'

                 ;[20:33,66,91,101] pd1-   ( pd -- pd )  [pd] -= 1 with align 4
    ld    A, 0xFF       ; 2:7       pd1-
    add   A,(HL)        ; 1:7       pd1-
    ld  (HL),A          ; 1:7       pd1-
    jr    c, $+16       ; 2:7/12    pd1-
    ld    C, L          ; 1:4       pd1-
    inc   L             ; 1:4       pd1-
    add   A,(HL)        ; 1:7       pd1-
    ld  (HL),A          ; 1:7       pd1-
    jr    c, $+9        ; 2:7/12    pd1-
    inc   L             ; 1:4       pd1-
    add   A,(HL)        ; 1:7       pd1-
    ld  (HL),A          ; 1:7       pd1-
    jr    c, $+4        ; 2:7/12    pd1-
    inc   L             ; 1:4       pd1-
    dec (HL)            ; 1:11      pd1-
    ld    L, C          ; 1:4       pd1-
                       ;[20:101]

Vypada to trosku nezvykle ze je tam vsude ADD a ne i ADC, ale je to dobre. Doufam. .)
A pro uplnost jeste uvedu ty dve nova slova
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PDINVERT'

    ld    A,(HL)        ; 1:7       pdinvert   ( pd -- pd )  [pd] = ~[pd]  with align 4
    cpl                 ; 1:4       pdinvert
    ld  (HL),A          ; 1:7       pdinvert
    ld    C, L          ; 1:4       pdinvert
    inc   L             ; 1:4       pdinvert
    ld    A,(HL)        ; 1:7       pdinvert
    cpl                 ; 1:4       pdinvert
    ld  (HL),A          ; 1:7       pdinvert
    inc   L             ; 1:4       pdinvert
    ld    A,(HL)        ; 1:7       pdinvert
    cpl                 ; 1:4       pdinvert
    ld  (HL),A          ; 1:7       pdinvert
    inc   L             ; 1:4       pdinvert
    ld    A,(HL)        ; 1:7       pdinvert
    cpl                 ; 1:4       pdinvert
    ld  (HL),A          ; 1:7       pdinvert
    ld    L, C          ; 1:4       pdinvert
                       ;[17:92]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PDNEGATE'

    xor   A             ; 1:4       pdnegate   ( pd -- pd )  [pd] = -[pd]  with align 4
    ld    B, A          ; 1:4       pdnegate
    sub (HL)            ; 1:7       pdnegate
    ld  (HL),A          ; 1:7       pdnegate
    ld    C, L          ; 1:4       pdnegate
    inc   L             ; 1:4       pdnegate
    ld    A, B          ; 1:4       pdnegate
    sbc   A,(HL)        ; 1:7       pdnegate
    ld  (HL),A          ; 1:7       pdnegate
    inc   L             ; 1:4       pdnegate
    ld    A, B          ; 1:4       pdnegate
    sbc   A,(HL)        ; 1:7       pdnegate
    ld  (HL),A          ; 1:7       pdnegate
    inc   L             ; 1:4       pdnegate
    ld    A, B          ; 1:4       pdnegate
    sbc   A,(HL)        ; 1:7       pdnegate
    ld  (HL),A          ; 1:7       pdnegate
    ld    L, C          ; 1:4       pdnegate
                       ;[18:96]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$

PS: Docela se tesim az udelam bitove posuny, konecne budu moc asi pouzit poprve v zivote pro posun o 4 bity RLD nebo RRD.
PPS: Tak jsem si grepnul rld, RLD, rrd a RRD. RLD jsem uz "pouzil" v ZX Dungeonu jako zpomalovac a myslim ze jsem se o tom bavil i s Bussym. Nebyl jsem si jisty jak jsem psal pro ZX Spectrum dekoder GIF obrazku, kde se pouziva Huffmanovo kodovani. Ale kdyz si uz nic nepamatuji, tak je to stejne zase poprve. .))

_________________
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.10.2022, 02:26 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Dalsi varka pravidelneho a podle pravidel fora legalniho spamu... .)

Hral jsem si dnes s temi bitovymi posuny. Mel jsem pro double hodnotu funkci, ale jak jsem delal pro pointery posun o konstantni pocet bitu, tak jsem to pridal pro obycene double.
Nedelal jsem vsech 32 posunu a pro obe strany, ale jen o 1,4,8,16,24 bitu. Prinejhorsim se zbytek da z toho neprilis efektivne nakombinovat.

Chtel jsem to porovnat s ZCC kompilerem, ale po "mensim" boji, kdy se mi to podarilo zprovoznit na https://godbolt.org/ kompiler exploreru. (Funguje to kdyz pridate parametr -zx) Prislo zklamani, ze umi rotace jen u 16 bitovych integeru...

Urcite se uz strasne tesite na kod, takze tady je. Nic jsem par dnu netestoval, takze pokud se na to nekdo fakt koukne a najde chybu nebo lepsi reseni tak se nebojte ozvat.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_1_DLSHIFT'

    add  HL, HL         ; 1:11      1 dlshift  ( d1 1 -- d )  d = d1 << 1
    rl    E             ; 2:8       1 dlshift
    rl    D             ; 2:8       1 dlshift
                       ;[ 5:27]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_1_DRSHIFT'

    srl   D             ; 2:8       1 drshift  ( d1 1 -- d )  d = d1 >> 1
    rr    E             ; 2:8       1 drshift
    rr    H             ; 2:8       1 drshift
    rr    L             ; 2:8       1 drshift
                       ;[ 8:32]

Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_1_PDLSHIFT'

    ld    C, L          ; 1:4       1 pdlshift  ( pd 1 -- pd )  [pd] <<= 1  with align 4
    ld    A,(HL)        ; 1:7       1 pdlshift
    add   A, A          ; 1:4       1 pdlshift
    ld  (HL),A          ; 1:7       1 pdlshift
    inc   L             ; 1:4       1 pdlshift
    rl  (HL)            ; 2:15      1 pdlshift
    inc   L             ; 1:4       1 pdlshift
    rl  (HL)            ; 2:15      1 pdlshift
    inc   L             ; 1:4       1 pdlshift
    rl  (HL)            ; 2:15      1 pdlshift
    ld    L, C          ; 1:4       1 pdlshift
                       ;[14:83]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_1_PDRSHIFT'

    inc   L             ; 1:4       1 pdrshift  ( pd 1 -- pd )  [pd] >>= 1  with align 4
    inc   L             ; 1:4       1 pdrshift
    inc   L             ; 1:4       1 pdrshift
    xor   A             ; 1:4       1 pdrshift
    rr  (HL)            ; 2:15      1 pdrshift
    dec   L             ; 1:4       1 pdrshift
    rr  (HL)            ; 2:15      1 pdrshift
    dec   L             ; 1:4       1 pdrshift
    rr  (HL)            ; 2:15      1 pdrshift
    dec   L             ; 1:4       1 pdrshift
    rr  (HL)            ; 2:15      1 pdrshift
                       ;[15:88]

Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_4_DLSHIFT'

    ld    A, E          ; 1:4       4 dlshift  ( d1 4 -- d )  d = d1 << 4
    add  HL, HL         ; 1:11      4 dlshift
    adc   A, A          ; 1:4       4 dlshift
    rl    D             ; 2:8       4 dlshift
    add  HL, HL         ; 1:11      4 dlshift
    adc   A, A          ; 1:4       4 dlshift
    rl    D             ; 2:8       4 dlshift
    add  HL, HL         ; 1:11      4 dlshift
    adc   A, A          ; 1:4       4 dlshift
    rl    D             ; 2:8       4 dlshift
    add  HL, HL         ; 1:11      4 dlshift
    adc   A, A          ; 1:4       4 dlshift
    rl    D             ; 2:8       4 dlshift
    ld    E, A          ; 1:4       4 dlshift
                       ;[18:100]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_4_DRSHIFT'

                       ;[25:128]    4 drshift  ( d1 4 -- d )  d = d1 >> 4
    ld    A, E          ; 1:4       4 drshift
    add  HL, HL         ; 1:11      4 drshift  654321->5432.10
    adc   A, A          ; 1:4       4 drshift
    add  HL, HL         ; 1:11      4 drshift  654321->5432.10
    adc   A, A          ; 1:4       4 drshift
    add  HL, HL         ; 1:11      4 drshift  654321->5432.10
    adc   A, A          ; 1:4       4 drshift
    add  HL, HL         ; 1:11      4 drshift  654321->5432.10
    adc   A, A          ; 1:4       4 drshift
    ld    L, H          ; 1:4       4 drshift
    ld    H, A          ; 1:4       4 drshift
    ld    A, E          ; 1:4       4 drshift
    srl   D             ; 2:8       4 drshift  8765->0876
    rra                 ; 1:4       4 drshift
    srl   D             ; 2:8       4 drshift  8765->0876
    rra                 ; 1:4       4 drshift
    srl   D             ; 2:8       4 drshift  8765->0876
    rra                 ; 1:4       4 drshift
    srl   D             ; 2:8       4 drshift  8765->0876
    rra                 ; 1:4       4 drshift
    ld    E, A          ; 1:4       4 drshift
                       ;[25:128]

Tady ta rotace vpravo je celkem orisek jak to resit. Radsi ukazi jeste jak vypada kod, mam tam radsi vsechno co jsem psal, vcetne prvniho nejmene efektivniho reseni.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'dumpdef({__ASM_TOKEN_4_DRSHIFT})'
__ASM_TOKEN_4_DRSHIFT:   dnl
__{}define({__INFO},__COMPILE_INFO){}dnl
__{}ifelse(1,1,{
                       ;[25:128]    __INFO  ( d1 4 -- d )  d = d1 >> 4
    ld    A, E          ; 1:4       __INFO
    add  HL, HL         ; 1:11      __INFO  654321->5432.10
    adc   A, A          ; 1:4       __INFO
    add  HL, HL         ; 1:11      __INFO  654321->5432.10
    adc   A, A          ; 1:4       __INFO
    add  HL, HL         ; 1:11      __INFO  654321->5432.10
    adc   A, A          ; 1:4       __INFO
    add  HL, HL         ; 1:11      __INFO  654321->5432.10
    adc   A, A          ; 1:4       __INFO
    ld    L, H          ; 1:4       __INFO
    ld    H, A          ; 1:4       __INFO
    ld    A, E          ; 1:4       __INFO
    srl   D             ; 2:8       __INFO  8765->0876
    rra                 ; 1:4       __INFO
    srl   D             ; 2:8       __INFO  8765->0876
    rra                 ; 1:4       __INFO
    srl   D             ; 2:8       __INFO  8765->0876
    rra                 ; 1:4       __INFO
    srl   D             ; 2:8       __INFO  8765->0876
    rra                 ; 1:4       __INFO
    ld    E, A          ; 1:4       __INFO},
1,1,{
                       ;[30:120]    __INFO  ( d1 4 -- d )  d = d1 >> 4
    ld    A, E          ; 1:4       __INFO
    srl   D             ; 2:8       __INFO  87654321->08765432
    rra                 ; 1:4       __INFO
    rr    H             ; 2:8       __INFO
    rr    L             ; 2:8       __INFO
    srl   D             ; 2:8       __INFO  87654321->08765432
    rra                 ; 1:4       __INFO
    rr    H             ; 2:8       __INFO
    rr    L             ; 2:8       __INFO
    srl   D             ; 2:8       __INFO  87654321->08765432
    rra                 ; 1:4       __INFO
    rr    H             ; 2:8       __INFO
    rr    L             ; 2:8       __INFO
    srl   D             ; 2:8       __INFO  87654321->08765432
    rra                 ; 1:4       __INFO
    rr    H             ; 2:8       __INFO
    rr    L             ; 2:8       __INFO
    ld    E, A          ; 1:4       __INFO},
{
                       ;[24:152]    __INFO  ( d1 4 -- d )  d = d1 >> 4
    ld    A, E          ; 1:4       __INFO
    add  HL, HL         ; 1:11      __INFO  654321->5432.10
    adc   A, A          ; 1:4       __INFO
    add  HL, HL         ; 1:11      __INFO  654321->5432.10
    adc   A, A          ; 1:4       __INFO
    add  HL, HL         ; 1:11      __INFO  654321->5432.10
    adc   A, A          ; 1:4       __INFO
    add  HL, HL         ; 1:11      __INFO  654321->5432.10
    adc   A, A          ; 1:4       __INFO
    ld    L, H          ; 1:4       __INFO
    ld    H, A          ; 1:4       __INFO
    xor   A             ; 1:4       __INFO
    ex   DE, HL         ; 1:4       __INFO
    add  HL, HL         ; 1:11      __INFO  008765->0876.50
    adc   A, A          ; 1:4       __INFO
    add  HL, HL         ; 1:11      __INFO  008765->0876.50
    adc   A, A          ; 1:4       __INFO
    add  HL, HL         ; 1:11      __INFO  008765->0876.50
    adc   A, A          ; 1:4       __INFO
    add  HL, HL         ; 1:11      __INFO  008765->0876.50
    adc   A, A          ; 1:4       __INFO
    ex   DE, HL         ; 1:4       __INFO
    ld    E, D          ; 1:4       __INFO
    ld    D, A          ; 1:4       __INFO}){}dnl

                       ;[ 0:0]

Ted prijde zlaty hreb vecera (1:09 Greenwitch time, tak asi noci)
Snazil jsem se to smysluplne okomentovat. Mam na mysli RLD, RRD instrukce.
To ze mam v informaci jak vypada zasobnik vsude i tu ciselnou konstantu je mozna trosku matouci, protoze tam jeste neni a po konci uz nebude. Mluvim o tom ( pd 4 -- pd ), kde "pd" ma (podle me) znamenat "pointer to double". Mozna to tam fakt nepatri... hmm...
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_4_PDLSHIFT'

    xor   A             ; 1:4       4 pdlshift  ( pd 4 -- pd )  [pd] <<= 4  with align 4
    rld                 ; 2:18      4 pdlshift  A(HL)=0xA021-->0xA210
    ld    C, L          ; 1:4       4 pdlshift
    inc   L             ; 1:4       4 pdlshift
    rld                 ; 2:18      4 pdlshift  A(HL)=0xA243-->0xA432
    inc   L             ; 1:4       4 pdlshift
    rld                 ; 2:18      4 pdlshift  A(HL)=0xA465-->0xA654
    inc   L             ; 1:4       4 pdlshift
    rld                 ; 2:18      4 pdlshift  A(HL)=0xA687-->0xA876
    ld    L, C          ; 1:4       4 pdlshift
                       ;[14:96]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_4_PDRSHIFT'

    inc   L             ; 1:4       4 pdrshift  ( pd 4 -- pd )  [pd] >>= 4  with align 4
    inc   L             ; 1:4       4 pdrshift
    inc   L             ; 1:4       4 pdrshift
    xor   A             ; 1:4       4 pdrshift
    rrd                 ; 2:18      4 pdrshift  A(HL)=0xA087-->0xA708
    dec   L             ; 1:4       4 pdrshift
    rrd                 ; 2:18      4 pdrshift  A(HL)=0xA765-->0xA576
    dec   L             ; 1:4       4 pdrshift
    rrd                 ; 2:18      4 pdrshift  A(HL)=0xA543-->0xA354
    dec   L             ; 1:4       4 pdrshift
    rrd                 ; 2:18      4 pdrshift  A(HL)=0xA321-->0xA132
                       ;[15:100]

Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_8_DLSHIFT'

    ld    D, E          ; 1:4       8 dlshift  ( d1 8 -- d )  d = d1 << 8
    ld    E, H          ; 1:4       8 dlshift
    ld    H, L          ; 1:4       8 dlshift
    ld    L, 0x00       ; 2:7       8 dlshift
                       ;[ 5:19]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_8_DRSHIFT'

    ld    L, H          ; 1:4       8 drshift  ( d1 8 -- d )  d = d1 >> 8
    ld    H, E          ; 1:4       8 drshift
    ld    E, D          ; 1:4       8 drshift
    ld    D, 0x00       ; 2:7       8 drshift
                       ;[ 5:19]

Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_8_PDLSHIFT'

    ld    C, L          ; 1:4       8 pdlshift  ( pd 8 -- pd )  [pd] <<= 8  with align 4
    ld    A,(HL)        ; 1:7       8 pdlshift
    ld  (HL),0x00       ; 2:10      8 pdlshift
    inc   L             ; 1:4       8 pdlshift
    ld    B,(HL)        ; 1:7       8 pdlshift
    ld  (HL),A          ; 1:7       8 pdlshift
    inc   L             ; 1:4       8 pdlshift
    ld    A,(HL)        ; 1:7       8 pdlshift
    ld  (HL),B          ; 1:7       8 pdlshift
    inc   L             ; 1:4       8 pdlshift
    ld  (HL),A          ; 1:7       8 pdlshift
    ld    L, C          ; 1:4       8 pdlshift
                       ;[13:72]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_8_PDRSHIFT'

    inc   L             ; 1:4       8 pdrshift  ( pd 8 -- pd )  [pd] >>= 8  with align 4
    inc   L             ; 1:4       8 pdrshift
    inc   L             ; 1:4       8 pdrshift
    ld    A,(HL)        ; 1:7       8 pdrshift
    ld  (HL),0x00       ; 2:10      8 pdrshift
    dec   L             ; 1:4       8 pdrshift
    ld    B,(HL)        ; 1:7       8 pdrshift
    ld  (HL),A          ; 1:7       8 pdrshift
    dec   L             ; 1:4       8 pdrshift
    ld    A,(HL)        ; 1:7       8 pdrshift
    ld  (HL),B          ; 1:7       8 pdrshift
    dec   L             ; 1:4       8 pdrshift
    ld  (HL),A          ; 1:7       8 pdrshift
                       ;[14:76]

Nebudete tomu mozna verit, ale u posunu o 16 bitu jsem mel puvodne kod obdobny jako u posunu o 8 bitu a vubec me nedoslo, ze to jde udelat mnohem lepe.
Kód:
-    ld    D, H          ; 1:4       __INFO  ( d1 16 -- d )  d = d1 << 16
-    ld    E, L          ; 1:4       __INFO
-    ld    H, 0x00       ; 2:7       __INFO
-    ld    L, H          ; 1:4       __INFO}){}dnl
+    ex   DE, HL         ; 1:4       __INFO  ( d1 16 -- d )  d = d1 << 16
+    ld   HL, 0x0000     ; 3:10      __INFO}){}dnl

Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_16_DLSHIFT'

    ex   DE, HL         ; 1:4       16 dlshift  ( d1 16 -- d )  d = d1 << 16
    ld   HL, 0x0000     ; 3:10      16 dlshift
                       ;[ 4:14]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_16_DRSHIFT'

    ld   DE, HL         ; 1:4       16 drshift  ( d1 16 -- d )  d = d1 >> 16
    ld   DE, 0x0000     ; 3:10      16 drshift
                       ;[ 4:14]

U "16 pdlshift" me chybi jeden volny osmibitovy registr, abych se zbavil dvou "ld (HL),0x00" instrukci a nahradil je "xor A" a dvema "ld (HL),A" instrukcema. Proto je ten posun vlevo stejne velky jak vpravo a jen o 2 takty rychlejsi.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_16_PDLSHIFT'

    ld    C, L          ; 1:4       16 pdlshift  ( pd 16 -- pd )  [pd] <<= 16  with align 4
    ld    A,(HL)        ; 1:7       16 pdlshift
    ld  (HL),0x00       ; 2:10      16 pdlshift
    inc   L             ; 1:4       16 pdlshift
    ld    B,(HL)        ; 1:7       16 pdlshift
    ld  (HL),0x00       ; 2:10      16 pdlshift
    inc   L             ; 1:4       16 pdlshift
    ld  (HL),A          ; 1:7       16 pdlshift
    inc   L             ; 1:4       16 pdlshift
    ld  (HL),B          ; 1:7       16 pdlshift
    ld    L, C          ; 1:4       16 pdlshift
                       ;[13:68]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_16_PDRSHIFT'

    inc   L             ; 1:4       16 pdrshift  ( pd 16 -- pd )  [pd] >>= 16  with align 4
    inc   L             ; 1:4       16 pdrshift
    inc   L             ; 1:4       16 pdrshift
    xor   A             ; 1:4       16 pdrshift
    ld    B,(HL)        ; 1:7       16 pdrshift
    ld  (HL),A          ; 1:7       16 pdrshift
    dec   L             ; 1:4       16 pdrshift
    ld    C,(HL)        ; 1:7       16 pdrshift
    ld  (HL),A          ; 1:7       16 pdrshift
    dec   L             ; 1:4       16 pdrshift
    ld  (HL),B          ; 1:7       16 pdrshift
    dec   L             ; 1:4       16 pdrshift
    ld  (HL),C          ; 1:7       16 pdrshift
                       ;[13:70]

A posledni hodnota o 24 byla puvodne o takt pomalejsi, ale jak jsem spravoval tu o 16 bitu tak uz to bylo snadne, i kdyz prekvapive nahradit za "ld reg16,0"
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_24_DLSHIFT'

    ld    D, L          ; 1:4       24 dlshift  ( d1 24 -- d )  d = d1 << 24
    ld   HL, 0x0000     ; 3:10      24 dlshift
    ld    E, L          ; 1:4       24 dlshift
                       ;[ 5:18]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_24_DRSHIFT'

    ld    L, D          ; 1:4       24 drshift  ( d1 24 -- d )  d = d1 >> 24
    ld   DE, 0x0000     ; 3:10      24 drshift
    ld    H, D          ; 1:4       24 drshift
                       ;[ 5:18]

Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_24_PDLSHIFT'

    ld    C, L          ; 1:4       24 pdlshift  ( pd 24 -- pd )  [pd] <<= 24  with align 4
    xor   A             ; 1:4       24 pdlshift
    ld    B,(HL)        ; 1:7       24 pdlshift
    ld  (HL),A          ; 1:7       24 pdlshift
    inc   L             ; 1:4       24 pdlshift
    ld  (HL),A          ; 1:7       24 pdlshift
    inc   L             ; 1:4       24 pdlshift
    ld  (HL),A          ; 1:7       24 pdlshift
    inc   L             ; 1:4       24 pdlshift
    ld  (HL),B          ; 1:7       24 pdlshift
    ld    L, C          ; 1:4       24 pdlshift
                       ;[11:59]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_24_PDRSHIFT'

    ld    C, L          ; 1:4       24 pdrshift  ( pd 24 -- pd )  [pd] >>= 24  with align 4
    xor   A             ; 1:4       24 pdrshift
    inc   L             ; 1:4       24 pdrshift
    ld  (HL),A          ; 1:7       24 pdrshift
    inc   L             ; 1:4       24 pdrshift
    ld  (HL),A          ; 1:7       24 pdrshift
    inc   L             ; 1:4       24 pdrshift
    ld    B,(HL)        ; 1:7       24 pdrshift   
    ld  (HL),A          ; 1:7       24 pdrshift
    ld    L, C          ; 1:4       24 pdrshift
    ld  (HL),B          ; 1:7       24 pdrshift
                       ;[11:59]

To je asi pro dnesek vse. Mozna nekdy dodelam posun o 12, protoze tam me vypadne u varinaty kdy to neni pointer jeden registr, takze to jde krasne resit jen pomoci "add HL,HL" a "rla/adc A,A".

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

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Příloha:
shift.png
shift.png [ 1.85 KiB | Zobrazeno 2207 krát ]

Testovani pro posuny 1,4,8,12,16 a 24. Pro obe strany.
Mel jsem smulu a vyslo me to zrovna na predel segmentu. To jsem ohakoval ze jsem pridal nejaky dalsi data.
Stale to bylo spatne, tak jsem pridaval informace. Prvne cislo co se bude menit (vstup) a az pak vystup.
Na konci me doslo, ze jsem udelal
VARIABLE(_a)
VARIABLE(_b)
a ne
DVARIABLE(_a)
DVARIABLE(_b)

Pridam kod pro 12 bitove posuny. U pointeru to bylo trosku tezsi nez jsem cekal, takze jsem to udelal hlavne aby to bylo a nezdrzoval jsem se s tim. To same pravy posun i u registru. Proto jsem uz delal testovani.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/Nova_testovaci$ ../check_word.sh '_12_DLSHIFT'

    ld    A, E          ; 1:4       12 dlshift  ( d1 12 -- d )  d = d1 << 12
    add  HL, HL         ; 1:11      12 dlshift
    adc   A, A          ; 1:4       12 dlshift
    add  HL, HL         ; 1:11      12 dlshift
    adc   A, A          ; 1:4       12 dlshift
    add  HL, HL         ; 1:11      12 dlshift
    adc   A, A          ; 1:4       12 dlshift
    add  HL, HL         ; 1:11      12 dlshift
    adc   A, A          ; 1:4       12 dlshift
    ld    D, A          ; 1:4       12 dlshift
    ld    E, H          ; 1:4       12 dlshift
    ld    H, L          ; 1:4       12 dlshift
    ld    L, 0x00       ; 2:7       12 dlshift
                       ;[14:83]
dworkin@dw-A15:~/Programovani/ZX/Forth/Nova_testovaci$ ../check_word.sh '_12_DRSHIFT'

    ld    A, H          ; 1:4       12 drshift  ( d1 12 -- d )  d = d1 >> 12
    srl   D             ; 2:8       12 drshift  876543..->087654..
    rr    E             ; 2:8       12 drshift
    rra                 ; 1:4       12 drshift
    srl   D             ; 2:8       12 drshift  876543..->087654..
    rr    E             ; 2:8       12 drshift
    rra                 ; 1:4       12 drshift
    srl   D             ; 2:8       12 drshift  876543..->087654..
    rr    E             ; 2:8       12 drshift
    rra                 ; 1:4       12 drshift
    srl   D             ; 2:8       12 drshift  876543..->087654..
    rr    E             ; 2:8       12 drshift
    rra                 ; 1:4       12 drshift
    ld    L, A          ; 1:4       12 drshift
    ld    H, E          ; 1:4       12 drshift
    ld    E, D          ; 1:4       12 drshift
    ld    D, 0x00       ; 2:7       12 drshift
                       ;[26:103]

Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/Nova_testovaci$ ../check_word.sh '_12_PDLSHIFT'

    xor   A             ; 1:4       12 pdlshift  ( pd 12 -- pd )  [pd] <<= 12  with align 4
    ld    C,(HL)        ; 1:7       12 pdlshift
    ld  (HL),A          ; 1:7       12 pdlshift  0x00
    inc   L             ; 1:4       12 pdlshift
    ld    B,(HL)        ; 1:7       12 pdlshift
    ld  (HL),C          ; 1:7       12 pdlshift
    rld                 ; 2:18      12 pdlshift  A(HL)=0xA021-->0xA210
    inc   L             ; 1:4       12 pdlshift
    ld    C,(HL)        ; 1:7       12 pdlshift
    ld  (HL),B          ; 1:7       12 pdlshift
    rld                 ; 2:18      12 pdlshift  A(HL)=0xA243-->0xA432
    inc   L             ; 1:4       12 pdlshift
    ld  (HL),C          ; 1:7       12 pdlshift
    rld                 ; 2:18      12 pdlshift  A(HL)=0xA465-->0xA654
    dec   L             ; 1:4       12 pdlshift
    dec   L             ; 1:4       12 pdlshift
    dec   L             ; 1:4       12 pdlshift
                       ;[20:131]
dworkin@dw-A15:~/Programovani/ZX/Forth/Nova_testovaci$ ../check_word.sh '_12_PDRSHIFT'

    xor   A             ; 1:4       12 pdrshift  ( pd 12 -- pd )  [pd] >>= 12  with align 4
    inc   L             ; 1:4       12 pdrshift
    inc   L             ; 1:4       12 pdrshift
    inc   L             ; 1:4       12 pdrshift
    ld    B,(HL)        ; 1:7       12 pdrshift
    ld  (HL),A          ; 1:7       12 pdrshift  0x00
    dec   L             ; 1:4       12 pdrshift
    ld    C,(HL)        ; 1:7       12 pdrshift
    ld  (HL),B          ; 1:7       12 pdrshift
    rrd                 ; 2:18      12 pdrshift  A(HL)=0xA087-->0xA708
    dec   L             ; 1:4       12 pdrshift
    ld    B,(HL)        ; 1:7       12 pdrshift
    ld  (HL),C          ; 1:7       12 pdrshift
    rrd                 ; 2:18      12 pdrshift  A(HL)=0xA765-->0xA576
    dec   L             ; 1:4       12 pdrshift
    ld  (HL),B          ; 1:7       12 pdrshift
    rrd                 ; 2:18      12 pdrshift  A(HL)=0xA543-->0xA354
                       ;[20:131]


PS: Jeste by to chtelo dodelat testovani kdyz to lezi v registrech a asi ty posledni 2 nibble posuny co nemam 20 a 28.

_________________
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.10.2022, 21:44 
Offline
Óm Nejvyšší

Registrován: 22.05.2013, 21:14
Příspěvky: 3642
Bydliště: Bratislava
Has thanked: 371 times
Been thanked: 788 times
Kód:
xor   A             ; 1:4       1 pdrshift
rr  (HL)            ; 2:15      1 pdrshift
Pokial nepotrebujes nulovat A, tak mozes XOR A vynechat a ako rotaciu pouzit SRL (HL).


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 10.10.2022, 21:48 
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
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_16_DRSHIFT'

    ld   DE, HL         ; 1:4       16 drshift  ( d1 16 -- d )  d = d1 >> 16
    ld   DE, 0x0000     ; 3:10      16 drshift
Tu si prvu instrukciu asi myslel ex de,hl ;)


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 10.10.2022, 22:11 
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
Kód:
    ld    A,(HL)        ; 1:7       1 pdlshift
    add   A, A          ; 1:4       1 pdlshift
    ld  (HL),A          ; 1:7       1 pdlshift
A tu by som pouzil SLA (HL)


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

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Puvodne jsem jen chtel ve strucnosti umistit tento prispevek, ze jsem dodelal posuny o 20 a 28 bit a ze jsem otestoval i verzi kde to je v registrech a byla tam jen jedna chyba s "ld DE,HL". (vlastne dve, protoze jsem ji zkopiroval i do posunu o 20).
V praci jsem si trosku poranil palec na prave ruce tesne pred koncem, kdy jsem vytahoval kontejnery na odpad a dalsi na papir. Musi se s nema jit az pred hlavni vchod, protoze u zadniho je tak uzka ulicka jen pro pesi, ze by se tam popelari nedostali.
https://www.google.com/maps/@53.1911745,-2.8905599,3a,75y,165.76h,74.62t/data=!3m6!1e1!3m4!1sFCXtRnE7oaib0NUz4t0slw!2e0!7i13312!8i6656
A fakt blbe se s ovazanym palcem pise, a jeste to otravuje jak to pulzuje.

Příloha:
shift.png
shift.png [ 2.45 KiB | Zobrazeno 2120 krát ]


Ale Busy me udelal opravdu radost. :)

Busy píše:
Kód:
    ld    A,(HL)        ; 1:7       1 pdlshift
    add   A, A          ; 1:4       1 pdlshift
    ld  (HL),A          ; 1:7       1 pdlshift
A tu by som pouzil SLA (HL)

Mas pravdu, SLA(HL) jsem zazdil. Priznam se, ze i tu RR(HL) a RL(HL) jsem musel hledat zda to Z80 umi, jak pouzivam vetsinou jen instrukce bez prefixu pokud to jde.
Busy píše:
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_16_DRSHIFT'

    ld   DE, HL         ; 1:4       16 drshift  ( d1 16 -- d )  d = d1 >> 16
    ld   DE, 0x0000     ; 3:10      16 drshift
Tu si prvu instrukciu asi myslel ex de,hl ;)

Jo zase mas pravdu, skoda ze jsem si tohle precetl, az kdyz jsem to nasel. Nebo spis Pasmo naslo. V te chvili me hlavou proletlo, ze kdyby Pasmo melo rozsirene instrukce tak mam problem a druha vec byla jak jsem psal jestli ten zdrojak nekdo cte, tak tim aspon otestuji ze to fakt nikdo necte... a ty jsi to nasel. Wow. Navic celkem neprijemna chyba na pozornost pro odhaleni. Respekt.
Busy píše:
Kód:
xor   A             ; 1:4       1 pdrshift
rr  (HL)            ; 2:15      1 pdrshift
Pokial nepotrebujes nulovat A, tak mozes XOR A vynechat a ako rotaciu pouzit SRL (HL).

Potreti musim rici ze mas pravdu. .)
Ke vsemu je to krasne videt jak je ten kod stejny s verzi s daty v registrech. Zazdil jsem to.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_1_DRSHIFT'

    srl   D             ; 2:8       1 drshift  ( d1 1 -- d )  d = d1 >> 1
    rr    E             ; 2:8       1 drshift
    rr    H             ; 2:8       1 drshift
    rr    L             ; 2:8       1 drshift
                       ;[ 8:32]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_1_PDRSHIFT'

    inc   L             ; 1:4       1 pdrshift  ( pd 1 -- pd )  [pd] >>= 1  with align 4
    inc   L             ; 1:4       1 pdrshift
    inc   L             ; 1:4       1 pdrshift
    srl (HL)            ; 2:15      1 pdrshift  Thnx Busy!
    dec   L             ; 1:4       1 pdrshift
    rr  (HL)            ; 2:15      1 pdrshift
    dec   L             ; 1:4       1 pdrshift
    rr  (HL)            ; 2:15      1 pdrshift
    dec   L             ; 1:4       1 pdrshift
    rr  (HL)            ; 2:15      1 pdrshift
                       ;[14:84]

Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_1_PDLSHIFT'

    ld    C, L          ; 1:4       1 pdlshift  ( pd 1 -- pd )  [pd] <<= 1  with align 4
    sla (HL)            ; 2:15      1 pdlshift  Thnx Busy!
    inc   L             ; 1:4       1 pdlshift
    rl  (HL)            ; 2:15      1 pdlshift
    inc   L             ; 1:4       1 pdlshift
    rl  (HL)            ; 2:15      1 pdlshift
    inc   L             ; 1:4       1 pdlshift
    rl  (HL)            ; 2:15      1 pdlshift
    ld    L, C          ; 1:4       1 pdlshift
                       ;[13:80]

Diky, diky a diky.
Pridal jsem ti aspon matouci komentar s podekovanim. .)
Znovu jsem si overil, ze pri zmene jsem nezavedl dalsi chybu a kod byl o 2 bajty kratsi.
Fakt mam radost. .)

_________________
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.10.2022, 06:34 
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
Tvoja radost je aj mojou radostou :thumbup:

Este k tomuto:
_dworkin píše:
Busy píše:
Kód:
ld   DE, HL
Tu si prvu instrukciu asi myslel ex de,hl ;)
Jo zase mas pravdu, skoda ze jsem si tohle precetl, az kdyz jsem to nasel. Nebo spis Pasmo naslo.
Sjasmplus ma prepinac --syntax=F a vtedy warninguje/erroruje taketo fake instrukcie. Pokial ich nepouzivas, je dobre mat tento prepinac a sjasmplus to najde tiez.


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

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Par dnu se uz vyhybam resit to zarovnani adres.
Staci se na to jen letmo podivat a problemy vidim vsude.
Mozna bych si jen mel dat pauzu, nebo delat neco lehciho jako jsou ty shifty.
Boli me hlava. V noci jsem nespal a dnes jsem mel mit celodenni smenu, ale spatne jsem se dival na rozpis sluzeb a mam to prohozeny ze zitrkem, takze ze me stejne dnes nic rozumneho nevypadne.

Pro osvezeni pameti: Pro alokaci, ale i dealokaci pameti je ve forthu slovo https://forth-standard.org/standard/core/ALLOT

Mel jsem to implementovane tak, ze pokud pouzivate pamet, tak se do vysledneho souboru vygeneruje:

VARIABLE_SECTION:

a pod tim se budou vypisovat ruzne promenne atd. M4 si bude pres zasobnik pamatovat jak se ty labely jmenuji a kolik bajtu zabiraji.
A kdyz provedete zapornou alokaci pres ten ALLOT tak napise

ORG $ + -alokace

A ze zasobniku vyhodi tolik labelu kolik je potreba a najde si jaky je aktualni. To potrebuje napriklad slovo HERE, ktere uklada do TOS tu adresu.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'VARIABLE(_a) HERE PUSH(10) ALLOT HERE DVARIABLE(_b) HERE PUSH(-5) ALLOT HERE'
         
    push DE             ; 1:11      here
    ex   DE, HL         ; 1:4       here
    ld   HL, _a+2       ; 3:10      here
    push DE             ; 1:11      here
    ex   DE, HL         ; 1:4       here
    ld   HL, _a+12      ; 3:10      here
    push DE             ; 1:11      here
    ex   DE, HL         ; 1:4       here
    ld   HL, _b+4       ; 3:10      here
    push DE             ; 1:11      here
    ex   DE, HL         ; 1:4       here
    ld   HL, _a+11      ; 3:10      here

VARIABLE_SECTION:

_a:
    dw 0x0000
ds 10
_b:
    dw 0x0000
    dw 0x0000
    ORG $-4             ;           -5 allot   (deallocation 4 bytes from _b)
    ORG $-1             ;           -1 allot   ( allocation -1 bytes from _a)
                       ;[20:100]

Mimochodem jsem fixnul chybu, kde jsem volal znovu fci ALLOT uvnitr __ASM_TOKEN_ALLOT a nove se musi volat __ASM_TOKEN_ALLOT, protoze jsem vse tokenizoval.

Kdyz ale provedu zarovnani tak se mi do tech dat prida neznama hodnota a HERE zacne ukazovat na spatne adresy.

Hlavni problem je v tom ze M4 nezna ani pocatecni adresu, protoze ignoruje "ORG 0x8000". A ani nepocita jak je ten kod velky. I kdyz by to slo, ale bylo by to fakt pracne a dalsi zdroj chyb. Vysledkem je, ze M4 nezna fyzickou adresu VARIABLE_SECTION.

To zarovnani potrebuji jen pro ty pointery na 32 bitove hodnoty. Pokud nepocitam floating point aritmetiku, kde mam data zarovnana na 256 bajtu, ale to si resi ty tabulky zvlast. Vsude jinde jsem psal kod, ze je ocekavan nejhorsi scenar, ze deli "segment". Jeste teda mam zasobnik navratovych adres zarovnany na sude adresy.

Podival jsem se jak resi Forth standart to zarovnani.

https://forth-standard.org/standard/core/ALIGNED
ALIGNED
CORE
( addr -- a-addr )
a-addr is the first aligned address greater than or equal to addr.

To vypada celkem pouzitelne, nez si uvedomite, ze je to delane pro interpretovany kod a pro binarku neprakticke. Neco jako
Kód:
HERE ALIGNED HERE SUB ALLOT

Ja potrebuji ALLOT s konstatnim parametrem. Z tohoto kodu by se to dalo jeste vycist ze programator chce zarovnat adresu, ale nemusi to byt vzdy zrejme.

https://forth-standard.org/standard/core/ALIGN
ALIGN
( -- )
If the data-space pointer is not aligned, reserve enough space to align it.

Tohle (asi) dela presne to co ten kod vysse s ALIGNED. Ale ani u jednoho nejak nevidim na kolik bajtu je to zarovnany.

Vzdal jsem Forth standart a udelal jsem slovo ALIGN4, ktere vlozi tento kod
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'ALIGN4'

                        ;           align4

VARIABLE_SECTION:

; Align to 4-byte page boundary. Any use of Allot with a negative value exceeding this address will result in undefined behavior.
DEFS    (($ + 3) / 4) * 4 - $
                       ;[ 0:0]

Myslenka je ta, ze pokud tohle provedu pred vytvorenim 32bitove promenne tak me NIKDY NEBUDE DELENA "SEGMENTEM". To je vlastne to co chci. Nic vic nepotrebuji.
Mimochodem v standartu se pise ze promenne by meli byt zarovnane automaticky.

Reseni jak toho dosahnout je nekolik. Vsechny me prijdou spatne.

Kód:
DEFS    (($ + 255) / 256) * 256 - $
VARIABLE_SECTION:

Tohle by zajistilo ze VARIBALE_SECTION bude zacinat presne na predelu "segmentu" (adresa ma spodnich 8 bitu nulove).
Pak by si to M4 uz mohl spocitat sam(ze nekdy nechci aby me date delil segment). Mohl by si to zapnout i jen kdyz by byly pouzity ty pointery.


Kód:
DEFS    (($ + 3) / 4) * 4 - $
VARIABLE_SECTION:

Tohle by zajistilo ze VARIBALE_SECTION bude adresa nasobku 4 (adresa ma spodni 2 bity nulove).
Pak by si to M4 uz mohl spocitat sam. Mohl by si to zapnout i jen kdyz by byly pouzity ty pointery.
Jen by musel pred kazdou 32bitovou hodnotu ktera nelezi na nasobku 4 a zaroven na ni odkazuje nejake pointerove slovo pridavat vypln.

Pri kombinaci VARIABLE DVARIABLE VARIABLE DVARIABLE by po kazdem VARIABLE pridaval 2 bajty jen proto, aby mel jistotu ze DVARIABLE lezi na nasobku 4 a neni delena segmentem.
Tady by se mozna mohla vyplatit analyza typu dat a zarovnat VARIABLE_SECTION na 8 bajtu. Ma to i sve nevyhody, ze by zacatek te sekce V DV V DV V... musel taky zarovnat na 8 bajtu. Hmmm... to zni jako opravneny duvod udelat i slovo ALIGN8, mozna rovnou ALIGN(x).

Po kazde dealokaci vytvaret novy label. Takze HERE by ukazovalo na ten novy label a na ukladani predchozich labelu na zasobnik se vykaslat. Mozna nejschudnejsi reseni.


Zrusit optimalizaci v pointerech a mit vsude DEC HL a INC HL. Zarovnani tak vubec neresit. To ale fakt boli.


Pocitat tu delku kodu, to by umoznilo i jine optimalizace jako volit vhodnou instrukci skoku. Ale ta narocnost je desiva, asi bych to nikdy nedotahl ani do faze vhodne pro hrani jako je to ted.


PS: A jeste bych se mohl zminit, ze kdyz jsem prepisoval ukazkove hry tak jsem narazil u LIFE na problem, ze kdyz alokuji misto pro buffer tak se mi zacal v Pasmu generovat kod 2x a dokonce do vysledne binarky pridal i ty ten neinicializovany buffer. Takze jsem to napsal jen pres CREATE(buff) co udela na konci jen ukazatel a zatim Pasmo neresil.

PPS: Mozna by to chtelo i jine slovo co misto zarovnani bude delat neco jako

if (($+3)/256)!=($/256)
DS (($ + 3) / 4) * 4 - $
endif

Jak to nazvat? IF_ALIGN4, nebo to spojit s DVARIABLE a mit ALIGN_DVARIABLE? Stejne se to musi psat pred kazdou promennou.
Pro ty co to nedokazi precist, tak by se jednalo o test zda ctyri po sobe jdouci adresy nedeli segment a pokud ano tak to zarovnat na dalsi segment. Jinak setrit mistem.

_________________
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: 12.10.2022, 20:23 
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:
include(`../M4/FIRST.M4')dnl
    ORG 0x8000
    INIT(60000)
    STOP
    CREATE(buff)

Kód:
      ORG 8000
buff      EQU 8015
8000:ED730E80   LD(800E), SP
8004:2E1A   LD L, 1A
8006:CD0516   CALL 1605
8009:2160EA   LD HL, EA60
800C:D9      EXX
800D:      label Stop
800D:310000   LD SP, 0000
8010:215827   LD HL, 2758
8013:D9      EXX
8014:C9      RET
8015:      label VARIABLE_SECTION
8015:      label __create_buff
      ORG 8000
buff      EQU 8015
8000:ED730E80   LD(800E), SP
8004:2E1A   LD L, 1A
8006:CD0516   CALL 1605
8009:2160EA   LD HL, EA60
800C:D9      EXX
800D:      label Stop
800D:310000   LD SP, 0000
8010:215827   LD HL, 2758
8013:D9      EXX
8014:C9      RET
8015:      label VARIABLE_SECTION
8015:      label __create_buff
Emiting raw binary from 8000 to 8014

Kód:
include(`../M4/FIRST.M4')dnl
    ORG 0x8000
    INIT(60000)
    STOP
    CREATE(buff)
    PUSH(32) ALLOT

Kód:
      ORG 8000
buff      EQU 8015
8000:ED730E80   LD(800E), SP
8004:2E1A   LD L, 1A
8006:CD0516   CALL 1605
8009:2160EA   LD HL, EA60
800C:D9      EXX
800D:      label Stop
800D:310000   LD SP, 0000
8010:215827   LD HL, 2758
8013:D9      EXX
8014:C9      RET
8015:      label VARIABLE_SECTION
8015:      label __create_buff
8015:00000000   DEFS of 32 bytes with value 00
8019:00000000
801D:00000000
8021:00000000
8025:00000000
8029:00000000
802D:00000000
8031:00000000
      ORG 8000
buff      EQU 8015
8000:ED730E80   LD(800E), SP
8004:2E1A   LD L, 1A
8006:CD0516   CALL 1605
8009:2160EA   LD HL, EA60
800C:D9      EXX
800D:      label Stop
800D:310000   LD SP, 0000
8010:215827   LD HL, 2758
8013:D9      EXX
8014:C9      RET
8015:      label VARIABLE_SECTION
8015:      label __create_buff
8015:00000000   DEFS of 32 bytes with value 00
8019:00000000
801D:00000000
8021:00000000
8025:00000000
8029:00000000
802D:00000000
8031:00000000
Emiting raw binary from 8000 to 8034

Kód:
include(`../M4/FIRST.M4')dnl
    ORG 0x8000
    INIT(60000)
    STOP
    CREATE(buff)
__ASM({
DEFS 32})

Kód:
      ORG 8000
buff      EQU 8035
8000:ED730E80   LD(800E), SP
8004:2E1A   LD L, 1A
8006:CD0516   CALL 1605
8009:2160EA   LD HL, EA60
800C:D9      EXX
800D:      label Stop
800D:310000   LD SP, 0000
8010:215827   LD HL, 2758
8013:D9      EXX
8014:C9      RET
8015:00000000   DEFS of 32 bytes with value 00
8019:00000000
801D:00000000
8021:00000000
8025:00000000
8029:00000000
802D:00000000
8031:00000000
8035:      label VARIABLE_SECTION
8035:      label __create_buff
      ORG 8000
buff      EQU 8035
8000:ED730E80   LD(800E), SP
8004:2E1A   LD L, 1A
8006:CD0516   CALL 1605
8009:2160EA   LD HL, EA60
800C:D9      EXX
800D:      label Stop
800D:310000   LD SP, 0000
8010:215827   LD HL, 2758
8013:D9      EXX
8014:C9      RET
8015:00000000   DEFS of 32 bytes with value 00
8019:00000000
801D:00000000
8021:00000000
8025:00000000
8029:00000000
802D:00000000
8031:00000000
8035:      label VARIABLE_SECTION
8035:      label __create_buff
Emiting raw binary from 8000 to 8034

To je jeste horsi nez jsem cekal... nastesti to vypada, ze to nemelo vliv na binarku, jen na testovaci vypis. Asi to tam bylo celou dobu a nevsiml jsem si toho dokud nebyly soucasti vypisu data, kde je to dost vyrazny predel.
Kód:
include(`../M4/FIRST.M4')dnl
    ORG 0x8000
    INIT(60000)
    STOP

Kód:
      ORG 8000
8000:ED730E80   LD(800E), SP
8004:2E1A   LD L, 1A
8006:CD0516   CALL 1605
8009:2160EA   LD HL, EA60
800C:D9      EXX
800D:      label Stop
800D:310000   LD SP, 0000
8010:215827   LD HL, 2758
8013:D9      EXX
8014:C9      RET
Emiting raw binary from 8000 to 8014


PS: Myslim, ze uz chapu proc ten kod ukazuje duplicitne. Jedna se podle me o to, ze jsem si pomohl tou obezlickou ze Pasmo nezna hodnotu adresy pouzite nize. Ze umi sice

ld hl,adresa
adresa:

ale uz neumi

if adresa>0x9000
ld hl,5
endif
adresa:

a proto jsem nasel reseni pres

adresa equ _adresa
ld hl,adresa
_adresa:

a nebo

adresa equ _adresa
if adresa>0x9000
ld hl,5
endif
_adresa:

A Pasmo na to asi potrebuje dva pruchody a pri kazdem ukazuje kod..

_________________
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 ... 19, 20, 21, 22, 23, 24, 25 ... 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 3 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