OldComp.cz

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


Právě je 28.03.2024, 20:34

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

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Sesmolil jsem prvni a nejkratsi verzi usecky, kde jsem jeste prevadel neustale X,Y na adresu tak test trval 1.05 vteriny.

Pak jsem to predelal, ze prevod na X,Y na adresu se provadi jen na pocatku a na zbytek se volaji funkce na relativni posun adresy. Test trval polovicni dobu 0.5 vteriny. Pak jsem se kouknul jak to dela basic a trosku me prekvapilo, ze jsem zase zapomnel syntaxi... :D Ze se to zadava relativne. Tedy se to vykresluje obousmerne, ne jednosmerne jak jsem to mel ja. Aby pri xorovani se to pokazde vykreslilo stejne, bez ohledu na smer. Problem ale byl, ze kdyz jsem udelal ten test tak nebyl na pixel soumerny jako v basicu.

Takze jsem to znovu prepsal a pribylo dvojnasobek relativnich posunu a zpomalilo se to na 0.52 vteriny. Delka se prodlouzila od prvni verze o 134 bajtu na 330 bajtu. Coz je dost velke, ale je v tom i prevod X,Y na adresu a vsechny relativni posuny. Slo by to jeste trosku zrychlit a zkratit. Ale uz by relativni posuny nebyly univerzalni. Pak by to jeste slo krapet zrychlit osefovanim, ze funkce budou lezet na stejnem "segmentu".

Reseni je stale osmibitove, nikde se nepocita s 16 bitovymi hodnotami. V originale se resi hodnota 0.5, protoze se jedno cislo deli dvema (a nebo se ostani nasobi dvema). Na to jsem se trosku vybodl.. protoze ta polovina je jen a pouze na vstupni hodnote a pak uz se jen pocita s celymi cisly.

Takze se tam neustale resi neco

if (X > 0)
X -= cele cislo;
else
X += cele cislo;

Moje prvni napad byl, ze staci pokud je X kladne cislo pricist pred delenim dvema jednicku a az pak vydelit. Takze se z 0.5 stane 1 a (1 > 0) stejne jako (0.5 > 0). Pak jsem to chvilku testoval a nevidel zadnou viditelnou zmenu a kdyz se snazim do dusledku premyslet jak se to chova tak me hlava zacne vypinat a radsi zacnu delat neco jineho. Takze tohle je jeste otevrene tema...

No na ukazkach mam krome jedne zabavne chyby co me vyskocila pred par minutama i original basic a to co to kresli me. A je tam videt ze u nekterych sikych car basic kresli 2 odskok 2 odskok atd. A me to kresli 3 odskok 1 odskok atd. Zeby to byl problem te pulky? Ale v testu mam rozdily vsechny liche... hmm... budu muset zas debugovat.


Přílohy:
new.png
new.png [ 7.92 KiB | Zobrazeno 5040 krát ]
basic.png
basic.png [ 7.96 KiB | Zobrazeno 5040 krát ]
error.png
error.png [ 8.58 KiB | Zobrazeno 5040 krát ]

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

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Odesla me klavesnice od notebooku. Vcera zacala sama od sebe psat nepretrzite jjjjjjj. A dnes rano nektere klavesy nereagovaly. Nedokazal jsem napsat heslo. Tak jsem se prosrouboval az k ni a pokusil procistit. Nasadil zpet kabliky a nejak se me to podarilo zasroubovat.

Nejede vubec. Ale nastesti jsem si vzpomel ze tamje nekde virtualni klavesnice a prihlasil se. Xfce maji zase onboard virtualni klavesnici. Ale je to utrpeni. Koupim nejakou externi a za tyden az bude volno zkusim znovu zapojit kabliky. Chce to asi novy notebook. Ale tenhle mel jen 6 let asi... ale pouzival jsem ho denne.

PS: Tohle je stopka pro nejake tvoreni. Sam v cizi zemi. Bez jazyka. Koronavirus. Jedina ceska ve stejnem meste fetacka. Jedina slovenka me dluzi. Moc se mi nechce utracet.

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


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 24.07.2020, 18:38 
Offline
Pan Generální
Uživatelský avatar

Registrován: 13.05.2013, 09:15
Příspěvky: 2278
Bydliště: Brno
Has thanked: 842 times
Been thanked: 302 times
Si vybiras zajimavou spolecnost :)

_________________
Amiga - PMD 85


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 24.07.2020, 19:51 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Dnes rano jsem sel po 8 jak jsem skoncil v praci do Wilka koupit nejakou klavesnici. Venku me zadrzela prodavacka, a nejak jsme se domluvili ze po me chce rousku (mask) a ze ji chteji uz v kazdem obchode a jedna mila pani me rovnou jednu darovala kdyz poznala ze u sebe zadnou nemam. Neuveritelne.
Ve Wilku meli vyprodano. Drahy Tecso melo zavreny zadni vchod a tak jsem si udelal hodinovou prochazku do Home&Bargains, tam meli dve. Jednu kablikovou nejakou game za 12 liber a druhou bezdrat i s mysi za 10 liber. Jak vidite funguje i v linuxu, hned co jsem teda dodal jednu AAA baterii. Ma teda uzky enter a spousta znaku v popisku jinde, takze pisi zpameti.

Vrtal jsem se pred chvili v te draw line rutine, prepsane do basicu a podarilo se me chybu reprodukovat, takze i odhalit. Nedoslo me ze v zaporne vetvi, kterou mam otocenou na kladnou se zmeni < na <=.
Kód:
3500 REM === DRAW a LINE.
3510 LET X1=128: LET Y1=80: LET X2=X1+X: LET Y2=Y1+Y
3520 LET AX=X:LET SX = +1:IF AX < 0 THEN LET SX = -1: LET AX=-X
3530 LET AY=Y:LET SY = +1:IF AY < 0 THEN LET SY = -1: LET AY=-Y
3540 LET D = INT((2*AY-AX)/2): IF D < 0 THEN GOTO 5700
3560 GOTO 4610

4600 LET D=-D
4610 PLOT X1, Y1
4620 LET Y1 = Y1 + SY: LET X1=X1+SX: LET D = D - AX + AY:
4630 IF X1 = X2 THEN RETURN
4640 IF D < 0 THEN GOTO 5700
4650 GOTO 4610

5700 LET D=-D
5710 PLOT X1, Y1
5720 LET X1 = X1 + SX: LET D = D - AY
5730 IF X1 = X2 THEN RETURN
5740 IF D =< 0 THEN GOTO 4600
5750 GOTO 5710
Chyba byla na radku 5740. Prekvapeni bylo, ze tohle vytvari uplne identicky cary jak ZX ROM. V asm jsem to vyresil dalsim skokem "jr z". I kdyz bych to mohl jeste resit LET D = D - AY - 1 a pak udelat "inc A", ktere nezmeni carry flag. A samozrejme z "AY-1" udelat konstantu.

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


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 24.07.2020, 20:04 
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:
20 FOR x=-80 TO +76 STEP +4: LET y= 80: GOSUB 1500: NEXT x
30 FOR y=+80 TO -76 STEP -4: LET x= 80: GOSUB 1500: NEXT y
40 FOR x=+80 TO -76 STEP -4: LET y=-80: GOSUB 1500: NEXT x
50 FOR y=-80 TO +76 STEP +4: LET x=-80: GOSUB 1500: NEXT y
60 STOP

1500 REM === DRAW a LINE.
1510 LET x1=128: LET y1=80: LET x2=x1+x: LET y2=y1+y: LET ax=abs(x): LET ay=abs(y)
1520 LET SX = -1:IF X1 < X2 THEN LET SX = 1
1530 LET SY = -1:IF Y1 < Y2 THEN LET SY = 1
1540 LET ER = -AY:IF AX > AY THEN LET ER = AX
1550 LET ER = INT(ER / 2)
1560 PLOT X1,Y1
1570 IF X1 = X2 AND Y1 = Y2 THEN RETURN
1580 LET E2 = ER
1590 IF E2 > -AX THEN LET ER = ER - AY:LET X1 = X1 + SX
1600 IF E2 <  AY THEN LET ER = ER + AX:LET Y1 = Y1 + SY
1610 GOTO 1560
Tahle varianta z rossettacode vytvari pekny obrazec, ale nepujde pocitat osmibitove protoze hodnota je minimalne v rozsahu -255 do 192. I kdyz jak na to koukam tak snad by to melo jit rozdelit... hmm.. nic jdu zkusit usnout.


Přílohy:
rossetta.png
rossetta.png [ 6.18 KiB | Zobrazeno 5001 krát ]

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

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Lisiak4 píše:
Si vybiras zajimavou spolecnost :)
Ja si nic nevybral. Zivot prinesl. Zacala chodit kourit travu k spolubydlicimu do sousedniho pokoje. A slysel jsem ji mluvit do telefonu cesky. Tak jsem mel radost, ze muzu s nekym mluvit. Ale je problematicka. Zbozi vylozene na pokladnim pase: "oh zapomnela jsem si penezenku"... (dluzi me taky, ale nic velkeho). Pri vecerni prochazce se to zmenilo v loudeni travy od ruznych lidi. Kdy se jedna skupinka ji uz neco chtela dat a pak otocila a zacala se smat, kdyz zjistila ze nosim dreveny krizek. Nastesti nevim co vsechno rikali. Dost trapny okamzik. Citil jsem se jako houmlesak z nadrazi. Druhy pokus skocil, protoze byla od rana uz napita a sli jsme smerem k dealerovi takze se trasa zmenila.. snazil jsem se ji ukecat, ale neslo to... Nakonec ze si koupi dalsi vino. Ale hned pote se slo stejne koupit travu, jak mu napsala ze chce travu a ne kokain. Takze pak z vyletu seslo a slo se zpet. Tam se sesypala a brecela, protoze jeji ex ji napsal ze je blba krava a skoncila u souseda. To jsem jeste dostal jen tak ten den z niceho nic facku a kdyz jsem se snazil neco vyfotit s odrazem pres kaluz vody tak se rozbehla a skocila predemnou do louze, ze me to celeho ohodilo. Oboji vyvolalo vybuch smichu. Dalsi den si me blokla, kdyz me napsala jestli me bude vadit kdyz me nevrati tech 60 liber. Ja ji napsal, ze me to teda vadit bude, protoze utrati tydne vic za chlast a huleni. Proste clovek na ktereho se muzete spolehnout ze vas dostane tak jedine do problemu. Takze uz zase chodim jen do prace a do obchodu.

Slovenka je v pohode i kdyz ceska o ni tvrdi ze je zavisla na kokainu a ze to na ni nejde poznat, ale ted uz vim ze je lharka. Slovenka je na tom financne taky blede, protoze sekla s praci tesne pred tim, nez se vse zavrelo. Byla tedy bez podpory, tak jsem ji pujcil 600 liber na jidlo.

Ja jsem hrozny hlupak. Na nocni me v lednu tvrdil jeden rumun, ze jeho matka je v nemocnici a ze potrebuje do rana 1000 liber a ze jsem posledni nadeje a ze me to do 2 tydnu vrati. Ja mu rikal ze mu neverim. Dopadlo to tak, ze me dluzi doted. Jeho byvalka co z prace pak odesla rikala, ze mamce nikdy neposlal ani penny a ze hraje hry na mobilu... a nechcete slyset vsechny vymluvy a lzi co jsem od neho slysel. Nemuze me to poslat protoze, nevi zda mam na uctu pred jmenem Mr. nebo ne treba... Mimochodem ted mi sefuje... a delam v praci s jeho bratrem, jeho manzelkou a jeste jednim blaznivym rumunem co u nich bydli a mam smeje se mi zda mam uz penize zpatky.

O dalsich psat nebudu, ty aspon rekli pravdu jak slovenka a povazuji je za pratele.

Proste se clovek musi spolehnout jen sam na sebe a programovani je jedina svetla chvilka dne.

PS: Doufam ze ta programovaci sekce zustane stale neverejna, tohle bylo az moc osobni. :D

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


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 24.07.2020, 21:37 
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:
No na ukazkach mam krome jedne zabavne chyby co me vyskocila pred par minutama i original basic a to co to kresli me. A je tam videt ze u nekterych sikych car basic kresli 2 odskok 2 odskok atd. A me to kresli 3 odskok 1 odskok atd. Zeby to byl problem te pulky?
Ano, je to presne tak, prisiel si na to :)
To delenie dvomi je tam len na to, aby boli ciary pekne symetricke, t.j. aby mali na oboch stranach cca rovnake odskoky. Aby sa nestalo, ze zacina odskokom 3 a konci odskokom 1, lebo potom to vyzera blbo, hlavne pri ciarach ktore su nie prilis daleko od vodorovneho alebo zvisleho smeru. To delenie dvomi nastavi zaciatocnu hodnotu bresenhamovho iteratora tak, aby prvy odskok bol cca polovica odskoku, ktory sa potom pouziva pocas kreslenia zvysku ciary.


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 25.07.2020, 06:55 
Offline
Pan Generální
Uživatelský avatar

Registrován: 13.05.2013, 09:15
Příspěvky: 2278
Bydliště: Brno
Has thanked: 842 times
Been thanked: 302 times
V ramci toho rozsahu -255 až 192. Nestacilo by jen v dalsim byte jedním bitem urcit, jestli je hodnotá kladna, nebo zaporna?

_________________
Amiga - PMD 85


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

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Lisiak4 píše:
V ramci toho rozsahu -255 až 192. Nestacilo by jen v dalsim byte jedním bitem urcit, jestli je hodnotá kladna, nebo zaporna?

To ale uz pracujes s dvema bajty. Takze si uz nijak nepomuzes.

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


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

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Pokud nekoho zajima jak to vypada, tak tady je kod. Nejvic prace je v nastaveni ktera z osmi rutin pro smer se bude vykonavat. To je ta cast jak jsem rikal, ze to jde zjednodusit pokud budou lezet na jednom "segmentu". Druhy napad byl, ze ted mam volny HL i DE a existuje rychla zamena pres ex DE,HL. Takze se nemusi kod prepisovat ale volat rychly jp (HL). Ale ty rutiny relativniho posunu adresy pixelu by misto ret museli mit pevny skok nazpet, takze by uz nesly jinde vyuzit.

Rychlost jsem stahl z 0.52 na 0.5 vteriny, protoze jsem si dnes pohral s kodem a uz nemam u zaporne varianty absolutni hodnotu, ale stale zapornou a misto odcitani relativniho rozdilu ho pricitam. Vypadne me pak to porovnani na nulu a jeste jsem usetril nejake misto jinde na skocich. Takze je to rychlejsi a o 19 bajtu kratsi.
Kód:
line:
    call  Pixel_addr    ; 3:17      DE'= pixel addr, C'=pixel mask

    ld    A, H          ; 1:4   
    sub   D             ; 1:4
    jr   nc, $+4        ; 2:8
    neg                 ; 1:4
    ld    C, A          ; 1:4       C = abs(dy)
   
    ld    A, L          ; 1:4
    sub   E             ; 1:4
    jr   nc, $+4        ; 2:8
    neg                 ; 1:4
    ld    B, A          ; 1:4       B = abs(dx)
   
    cp    C             ; 1:4       abs(dx) - abs(dy)
    jr   nc, line_hor   ; 2:7/12

;------ vertical line ------

    ld    A, H          ; 1:4
    sub   D             ; 1:4       y1-y0
    ld    A, L          ; 1:4   
    jr   nc, line_ver_d ; 2:8

line_ver_u:
    ld   HL, Pixel_U    ; 3:10
    ld  (line_n_adr), HL; 3:16

    sub   E             ; 1:4       x1-x0
    ld   HL, Pixel_RU   ; 3:10
    jr   nc, line_ver_c ; 2:8
    ld   HL, Pixel_LU   ; 3:10
    jp   line_ver_c     ; 3:10

line_ver_d:
    ld   HL, Pixel_D    ; 3:10
    ld  (line_n_adr), HL; 3:16

    sub   E             ; 1:4       x1-x0
    ld   HL, Pixel_RD   ; 3:10
    jr   nc, line_ver_c ; 2:8
    ld   HL, Pixel_LD   ; 3:10

line_ver_c:
    ld  (line_p_adr), HL; 3:16

    ld    A, C          ; 1:4       abs(dy)
    ld    C, B          ; 1:4
    ld    B, A          ; 1:4       B <-> C
    sub   C             ; 1:4       abs(dy)-abs(dx)
    ld    E, A          ; 1:4
   
    ld    A, B          ; 1:4       abs(dy)
    rra                 ; 1:4       dy/2
    ld    D, A          ; 1:4
    ld    A, C          ; 1:4       abs(dx)
    sub   D             ; 1:4       abs(dx)-abs(dy)/2

    inc   B             ; 1:4

    ccf                 ; 1:4
;-----------

line_n_loop:
    jr    c, line_p_in  ; 2:7/12
line_n_in:
    exx                 ; 1:4
    ex   AF, AF'        ; 1:4
    ld    A,(DE)        ; 1:7
    or    C             ; 1:4
    ld  (DE),A          ; 1:7
line_n_adr EQU $+1
    call 0x0000         ; 3:17
    ex   AF, AF'        ; 1:4
    exx                 ; 1:4
   
    add   A, C          ; 1:4       +d_short
   
    djnz line_n_loop    ; 2:8/13
    ret                 ; 1:10

;------ horizontal line ------

line_hor:

    ld    A, L          ; 1:4
    sub   E             ; 1:4       x1-x0
    ld    A, H          ; 1:4   
    jr   nc, line_hor_r ; 2:8

line_hor_l:
    ld   HL, Pixel_L    ; 3:10
    ld  (line_n_adr), HL; 3:16

    sub   D             ; 1:4       y1-y0
    ld   HL, Pixel_LD   ; 3:10
    jr   nc, line_hor_c ; 2:8
    ld   HL, Pixel_LU   ; 3:10
    jp   line_hor_c     ; 3:10

line_hor_r:
    ld   HL, Pixel_R    ; 3:10
    ld  (line_n_adr), HL; 3:16

    sub   D             ; 1:4       y1-y0
    ld   HL, Pixel_RD   ; 3:10
    jr   nc, line_hor_c ; 2:8
    ld   HL, Pixel_RU   ; 3:10

line_hor_c:
    ld  (line_p_adr), HL; 3:16

    ld    A, B          ; 1:4       abs(dx)
    sub   C             ; 1:4       abs(dx)-abs(dy)
    ld    E, A          ; 1:4

    ld    A, B          ; 1:4       abs(dx)
    rra                 ; 1:4       dx/2
    ld    D, A          ; 1:4
    ld    A, C          ; 1:4       abs(dy)
    sub   D             ; 1:4       abs(dy)-abs(dx)/2
       
    inc   B             ; 1:4

;-----------
   
line_p_loop:
    jr    c, line_n_in  ; 2:7/12
line_p_in:
    exx                 ; 1:4
    ex   AF, AF'        ; 1:4
    ld    A,(DE)        ; 1:7
    or    C             ; 1:4
    ld  (DE),A          ; 1:7
line_p_adr EQU $+1
    call 0x0000         ; 3:17
    ex   AF, AF'        ; 1:4
    exx                 ; 1:4

    sub   E             ; 1:4       error-dxy
   
    djnz line_p_loop    ; 2:8/13
    ret                 ; 1:10

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


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

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Podstatna cast je tady pokud to nechcete lustit.
Kód:
line_n_loop:
    jr    c, line_p_in  ; 2:7/12
line_n_in:
    exx                 ; 1:4
    ex   AF, AF'        ; 1:4
tiskni a posun pixel sikmo po diagonale
    ex   AF, AF'        ; 1:4
    exx                 ; 1:4
   
    add   A, C          ; 1:4       +d_short
   
    djnz line_n_loop    ; 2:8/13
    ret                 ; 1:10

;-----------
   
line_p_loop:
    jr    c, line_n_in  ; 2:7/12
line_p_in:
    exx                 ; 1:4
    ex   AF, AF'        ; 1:4
tiskni a posun pixel rovne po horizontale nebo vertikale
    ex   AF, AF'        ; 1:4
    exx                 ; 1:4

    sub   E             ; 1:4       error-dxy
   
    djnz line_p_loop    ; 2:8/13
    ret                 ; 1:10

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


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 30.11.2021, 10:28 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Koupil jsem novy laptop a zacal zase pracovat na M4 FORTHu. Delam na tom uz nejaky mesic, takze zmen je tolik, ze nevim kde zacit.

Prvne jsem pridal podporu pro argumenty lezici v pameti pro hodne slov. Tzn. misto konstanty je parametr adresa v pameti s danou hodnotou. Jako napriklad PUSH(10) --> PUSH((0x8000)).

--------

Zapracoval jsem znovu na nasobeni konstantou. Pro konstanty vetsi jak 255 to bylo hodne neefektivni. Delal jsem to zpusobem, ze jsem se kouknul co me leze z compileru a porovnal to s tim co bych napsal ja v assembleru a snazil se z toho vytvorit dalsi pravidlo. Skoro vzdy to slo udelat nejak lepe. Vytvoril jsem tak hodne algoritmu/pravidel a vysledky mi makro uklada do promenne. Takze mohu porovnat, podle mych kriterii ktera varianta je "nejlepsi" a tu zvolit. Pak jsem se jednou kouknul co leze z sdcc a neveril svym ocim. Prvne mi prislo ze to maji chybne a pak mi to docvaklo. Moc pekny. Ja to vetsinou resil zpusobem
Kód:
vysledek = 0
x
x *= 2
x *= 2
vysledek += x
x *= 2
vysledek += x
x *= 2
x *= 2
x *= 2
vysledek += x
atd.

Algoritmus vytvari vysledek od nejnizsich jednickovych bitu. To znamena ze jsem pricital k "vysledek" pokazde kdyz bit byl 1. Ale tenhle algoritmus ma nevyhodu od vic jak 2 jednickovych bitu, ze potrebujete mit v HL jak "vysledek" tak "x". Takze hledate pro danou konstantu nejlepsi reseni "ex DE,HL" nebo neco jineho.

sdcc to resi uplne naopak, vytvari vysledek od nejvyssich bitu. Ma "x" v BC a vysledek v "HL"
Kód:
HL = x
HL *= 2
HL *= 2
HL *= 2
HL += x
HL *= 2
HL += x


vysledek = 10011 * x. Algoritmus prvne pricte x a pak ji teprve nasobi dvema. Chytre, ale stale to neni optimalni algoritmus, porad dokazi napsat nejake konstanty vetsi 255 lepe.

Protoze se ve FORTHu jedna o nasobeni 16 bit = 16 bit * 16 bit. Tak pokud nasobime konstantou vetsi jak 8 bit tak lze udelat, pokud to hodne zjednodusim pro vysvetleni neco jako:

vysledek = 110 0001 0011 * x
Kód:
HL = x
HL *= 2
A = L
HL *= 2
A += L
HL *= 2
HL += x
HL *= 2
HL += x
H += A.

Takze ted to mam lepe udelane jak sdcc. .))
-----------

Zapracoval jsem na deleni konstantou. To je ale tak komplikovana zalezitost, ze jsem udelal jen par konstant. NEJDE* udelat udelat univerzalni algoritmus. Je to spis magie, proste zkousite nejake vzorce a triky dokud neudelate neco lepsiho nez mate. To je na dlouhe psani... Na netu se da neco najit, ale skoro vzdy se jedna o neco jako X / 9, kde X < 1440.

*Zatimco ja musim mit platnost v celem oboru 0..65535.

----

Doplnil jsem CASE OF ENDOF ENDCASE. Musel jsem se celkem drzet jak to maji ve FORTHu definovane, ale jedna varianta implementace je celkem pekna. Jedna se o ideu ze testovane hodnoty jdou vetsinou pekne za sebou. Jako 1,2,3,8,9,10.

Takze implementace jde udelat jako
Kód:
HL = x
dec HL
jr nz, next_of
...1
jr end_case
dec HL
jr nz, next_of
...2
jr end_case
dec HL
jr nz, next_of
...3
jr end_case
ld BC,3-8
or A
sbc HL,BC
jr nz, next_of
...8
jr end_case
dec HL
jr nz, next_of
...9
jr end_case
dec HL
jr nz, next_of
...10
jr end_case

---------

Vytvoril jsem fajn bash skript, ktery me dokaze ukazat primo assembler pro dane slovo, nebo vice slov. Takze mohu hned koukat na vysledek, a ne na mnohem mene prehledne makro.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth$ ./check_word.sh '_3UDIV'
; vvv
; ^^^
                        ;[35:212]   3/   Variant HL/3 = (HL*257*85) >> 16 = (HL*(1+1/256)*b_0101_0101) >> 8
    ld    B, H          ; 1:4       3/
    ld    C, L          ; 1:4       3/   1     1x = base
    xor   A             ; 1:4       3/
    add  HL, HL         ; 1:11      3/   0
    adc   A, A          ; 1:4       3/      *2 AHL = 2x
    add  HL, HL         ; 1:11      3/   1
    adc   A, A          ; 1:4       3/      *2 AHL = 4x
    add  HL, BC         ; 1:11      3/
    adc   A, 0x00       ; 2:7       3/      +1 AHL = 5x
    add  HL, HL         ; 1:11      3/   0
    adc   A, A          ; 1:4       3/      *2 AHL = 10x
    add  HL, HL         ; 1:11      3/   1
    adc   A, A          ; 1:4       3/      *2 AHL = 20x
    add  HL, BC         ; 1:11      3/
    adc   A, 0x00       ; 2:7       3/      +1 AHL = 21x
    add  HL, HL         ; 1:11      3/   0
    adc   A, A          ; 1:4       3/      *2 AHL = 42x
    add  HL, HL         ; 1:11      3/   1
    adc   A, A          ; 1:4       3/      *2 AHL = 84x
    add  HL, BC         ; 1:11      3/
    ld   BC, 0x0055     ; 3:10      3/         rounding down constant
    adc   A, B          ; 1:4       3/      +1 AHL = 85x
    add  HL, BC         ; 1:11      3/
    adc   A, B          ; 1:4       3/      +0 AHL = 85x with rounding down constant
    ld    B, A          ; 1:4       3/        (AHL * 257) >> 16 = (AHL0 + 0AHL) >> 16 = AH.L0 + A.HL = A0 + H.L + A.H
    ld    C, H          ; 1:4       3/         BC = "A.H"
    add  HL, BC         ; 1:11      3/         HL = "H.L" + "A.H"
    ld    L, H          ; 1:4       3/
    adc   A, 0x00       ; 2:7       3/         + carry
    ld    H, A          ; 1:4       3/         HL = HL/3 = HL*(65536/65536)/3 = HL*21845/65536 = (HL*(1+256)*85) >> 16
                       ;[35:212]
Pocita me to i takty a bajty. Takty spravne jen pokud nema kod smycky, ale i tak to nemusim pocitat rucne a hned vidim co je efektivnejsi. Kdyz porovnavam 2 slova a spojenou variantu do jednoho souslovi.
------
FORTH ma vlastni zpusob jak testovat slova.
Kód:
T{ 1 2 SWAP -> 2 1 }T

Cte se to tak ze se neco testuje pred sipkou -> a pak se zasobnik porovna s tim co je za sipkou. Implementoval jsem to, jen trosku jinak nez pres pomaly zasobnik adres.
Kód:
TEST_START PUSH2(1,2) SWAP TEST_EQ PUSH2(2,1) TEST_END
. V podstate se uklada hodnota SP ve slovech TEST_START i TEST_EQ a pak se provadi porovnani hodnot i poctu.
------
Diky tomu jsem mohl provadet nejake klasicke testy a odhalil nejake chyby a narazil na tuhle silnost
BEGIN ... WHILE ... WHILE ... UNTIL ... ELSE ... THEN https://forth-standard.org/standard/core/WHILE
Coz neni nikde dokumentovany, ze WHILE se nekdy chova jako IF.
BEGIN ... IF ... WHILE ... UNTIL ... ELSE ... THEN (coz zase nesezere gforth, protoze se krizi BEGIN UNTIL s IF ELSE THEN)
Muselo by se to "korektne" zapsat jako
IF ... BEGIN ... WHILE ... UNTIL ... ELSE ... THEN. Pak tomu rozumi vsichni.
------
Pridal jsem podporu pro praci s cisly typu 16 * 16 = 32 bit nebo 32 / 16 = 16 bit. Takze jsem musel pridat i tisk pro 32 bitove cislo. Neni to uplne nejlepsi, jeste se musim kouknout na jeden algoritmus, zda to nebude v me implementaci rychlejsi/kratsi. https://my.eng.utah.edu/~nmcdonal/Tutorials/BCDTutorial/BCDConversion.html
-------
Narazil jsem u testovani na neprijemnou vec ze FORTH ma "floor" deleni. Ne to na co jste :D urcite zvykly z C. Jina receno, pokud je vysledek deleni zaporny. Tak nema zbytek vzdy znamenko cisla co se deli, ale je pokazde kladny a vysledek se stale zaokrouhluje dolu, ne k nule. -7/3 = -3 a zbytek je 2. Uf... Bohuzel jsem nezjistil jak to spocitat jinak nez pres "symetricke" deleni s dodatecnou opravou. Takze mi slova DIV, MOD a DIVMOD vrazi jine hodnoty nez standard.
https://www.nimblemachines.com/symmetric-division-considered-harmful/ S clankem a dalsimi nesouhlasim. Argumentuji tim ze pokud indexuji nejake pole tak nebudu indexovat od nuly, ale od zaporneho cisla a pak mi vysledky bude davat spravne pro indexy jen floor division. Ale proc bych to delal? Naopak me prijde spravne ze se vysledky zrcadli kolem osy Y.
------
No to je asi tak vse s cim jsem se chtel podelit... Pokud vas to jen trchou zajima tak urcite doporucuji to hrani s checkword.sh skriptem. Hodi se to i kdyz potrebujete jen neco pridat do vlastniho programu, jako to nasobeni nebo deleni konstantou.

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


Naposledy upravil _dworkin dne 30.11.2021, 11:20, celkově upraveno 1

Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 30.11.2021, 10:34 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
PS: Podarilo se mi pres temer hack dodelat testovani duplicitnich retezcu. Takze se uplne shodne ukladaji jen jednou.

Kdybych to rozvedl tak... stale je ten "FORTH kompiler" jen obycejny seznam maker. Nemate jedinou promennou. Nic. Jen M4 umi zmenit definici makra a zapamatovat si starou. Pomoci pushdef a popdef se vraci puvodni a uplne ztraci aktualni. Jenze, jenze... vy potrebujete mit cely text jako jednu hodnotu. Ne ze se vam zacne interpretovat carka jako soucast definice makra! Takze to musite cely necim obalit a (anglicke) uvozovky to byt nemohou. U tech ani nevite ktera je pocatecni a ktera ukoncujici. Takze kdyz uz to nejak obalite a ukladate si jednotlive vety do pushdef, tak pri prvni kontrole duplicity pres popdef VSE ztratite. A kopii neudelate, protoze pri kazde manipulaci ztracite jedno "obaleni", a pak se zacnou dit divy. Takze co s tim? Podarilo se mi pomoci predefinovani "obaleni" na jine znaky, kdy zaroven pri kazde manipulaci s retezcem to znovu obalim puvodnim obalenim, ktere ted chape makro jako obecejny znak a predefinovani zpet na puvodni znaky udelat kopii zasobniku retezcu a pak uz to jde samo.

Nejsem si jisty zda to lze z meho textu pochopit... :D

mam retezec v makru z nazvem treba XXX, oteviraci a ukoncujici znaky jsou definovany u me jako {}. Neco jako

XXX = {Hello, word!}

Pokud napisi XXX tak ze to zameni za retezec, pokud napisi {XXX}, bude vystup jen XXX, protoze to sezere jednu vrstvu {}. Takze kdybych udelal neco jako define({YYY},XXX). Tak

YYY = Hello, word!

define({YYY},{XXX})

YYY = XXX

A ja potrebuji aby

YYY = {Hello, word!}

Takze predefinuji {} na treba [] (pro nazornost, jinak jsou to nejake UTF8 znaky co ZX Ascii nezna) a pak udelam

define([YYY],{XXX})

vratim {} a je to...


PPS: Pridal jsem nestandardni podporu pro retezce ukoncene nulovym bajtem. Nekde jsem zase cetl jake je to zlo, ale... proste je to kratsi a rychlejsi pro obycejny vypis textu.

Tady by me hodne zajimalo kde ma ZX 48Kb rutinu na vypis textu ukonceny znakem + 128, nebo jak je to delany. Ze bych pak volal tu rutinu, editovat znaky retezce makro umi, takze pridat k poslednimu znaku konstantu bych mel zvladnout.

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


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 30.11.2021, 11:26 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
https://github.com/DW0RKiN/M4_FORTH
Aspon myslim, ze se mi podarilo na githubu povolit "issues". Kdyby to fakt nekdo nahodou zkousel a prisel na nejaky problem, nebo tak. Pokud to dobre chapu o co ma jit.

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


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

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Hodne jsem si jeste hral se smyckou XDO(konec,pocatek) XLOOP. Vcetne kompletni iterace vsech hodnot a zjistovani zda u koncove hodnoty neni vyssi nebo nizsi bajt jedinecny. Tim chci rici, ze ta hodnota nastane jen jednou, prave na konci. Takze pak lze testovat jen ji. A do vcetne PUSH_ADDXLOOP(krok). Kdy jsem predtim zjistoval zda se neotaci znamenko mezi (index-konec) a (index+krok-konec). A ted to zjistuje presne tu posledni (uz neplatnou) hodnotu indexu, kterou makro dopredu spocita. Atd.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth$ ./check_word.sh 'XDO(250,0) SWAP SWAP XLOOP'
; vvv
; ^^^
    ld   BC, 0          ; 3:10      xdo(250,0) 101
xdo101save:             ;           xdo(250,0) 101
    ld  (idx101),BC     ; 4:20      xdo(250,0) 101
xdo101:                 ;           xdo(250,0) 101
    ex   DE, HL         ; 1:4       swap ( b a -- a b )
    ex   DE, HL         ; 1:4       swap ( b a -- a b )
                        ;[12:45]    xloop 101   variant +1.B: 0 <= index < stop <= 256, run 250x
idx101 EQU $+1          ;           xloop 101   idx always points to a 16-bit index
    ld    A, 0          ; 2:7       xloop 101   0.. +1 ..(250), real_stop:0x00FA
    nop                 ; 1:4       xloop 101   hi(index) = 0 = nop -> idx always points to a 16-bit index.
    inc   A             ; 1:4       xloop 101   index++
    ld  (idx101),A      ; 3:13      xloop 101
    xor  0xFA           ; 2:7       xloop 101   lo(real_stop)
    jp   nz, xdo101     ; 3:10      xloop 101   index-stop
xleave101:              ;           xloop 101
xexit101:               ;           xloop 101
                       ;[21:83]
dworkin@dw-A15:~/Programovani/ZX/Forth$ ./check_word.sh 'XDO(0,250) SWAP SWAP XLOOP'
; vvv
; ^^^
    ld   BC, 250        ; 3:10      xdo(0,250) 101
xdo101save:             ;           xdo(0,250) 101
    ld  (idx101),BC     ; 4:20      xdo(0,250) 101
xdo101:                 ;           xdo(0,250) 101
    ex   DE, HL         ; 1:4       swap ( b a -- a b )
    ex   DE, HL         ; 1:4       swap ( b a -- a b )
                        ;[9:54/34]  xloop 101   variant +1.G: stop == 0, run 65286x
idx101 EQU $+1          ;           xloop 101   idx always points to a 16-bit index
    ld   BC, 0x0000     ; 3:10      xloop 101   250.. +1 ..(0), real_stop:0x0000
    inc  BC             ; 1:6       xloop 101   index++
    ld    A, B          ; 1:4       xloop 101
    or    C             ; 1:4       xloop 101
    jp   nz, xdo101save ; 3:10      xloop 101
xleave101:              ;           xloop 101
xexit101:               ;           xloop 101
                       ;[18:72]
dworkin@dw-A15:~/Programovani/ZX/Forth$ ./check_word.sh 'XDO(250,0) SWAP SWAP PUSH_ADDXLOOP(5)'
; vvv
; ^^^
    ld   BC, 0          ; 3:10      xdo(250,0) 101
xdo101save:             ;           xdo(250,0) 101
    ld  (idx101),BC     ; 4:20      xdo(250,0) 101
xdo101:                 ;           xdo(250,0) 101
    ex   DE, HL         ; 1:4       swap ( b a -- a b )
    ex   DE, HL         ; 1:4       swap ( b a -- a b )
                        ;[13:48]    5 +xloop 101   variant +X.A: positive step and 0 <= index < stop < 256, run 50x
idx101 EQU $+1          ;           5 +xloop 101   idx always points to a 16-bit index
    ld    A, 0x00       ; 2:7       5 +xloop 101   0.. +5 ..(250), real_stop:0x00FA
    nop                 ; 1:4       5 +xloop 101   Contains a zero value because idx always points to a 16-bit index.
    add   A, low 5      ; 2:7       5 +xloop 101   A = index+step
    ld  (idx101), A     ; 3:13      5 +xloop 101   save new index
    xor  0xFA           ; 2:7       5 +xloop 101   lo(real_stop)
    jp   nz, xdo101     ; 3:10      5 +xloop 101
xleave101:              ;           5 +xloop 101
xexit101:               ;           5 +xloop 101
                       ;[22:86]

Nekdy jsem pridal uz uplne silenosti jako...
Kód:
; vvv
; ^^^
    ld   BC, 0x3c20     ; 3:10      xdo(0x3c80,0x3c20) 101
xdo101save:             ;           xdo(0x3c80,0x3c20) 101
    ld  (idx101),BC     ; 4:20      xdo(0x3c80,0x3c20) 101
xdo101:                 ;           xdo(0x3c80,0x3c20) 101
    ex   DE, HL         ; 1:4       swap ( b a -- a b )
    ex   DE, HL         ; 1:4       swap ( b a -- a b )
                        ;[11:41]    xloop 101   variant +1.D: 0x3C00 <=index < stop <= 0x3D00, run 96x
idx101 EQU $+1          ;           xloop 101   idx always points to a 16-bit index
    ld    A, 0          ; 2:7       xloop 101   0x3c20.. +1 ..(0x3c80), real_stop:0x3C80
    inc   A             ; 1:4       xloop 101   = hi(index) = 0x3c = inc A -> idx always points to a 16-bit index
    ld  (idx101),A      ; 3:13      xloop 101   save index
    xor  0x80           ; 2:7       xloop 101   lo(real_stop)
    jp   nz, xdo101     ; 3:10      xloop 101
xleave101:              ;           xloop 101
xexit101:               ;           xloop 101
                       ;[20:79]
Kdy hex hodnota 3C je vyuzita primo jako "inc A".

Dost jsem pridal ulozeni noveho indexu pres label "xdo101save". Tam mam problem, ze ne vzdy je to nejvhodnejsi a ja dopredu nevim jaka varianta LOOP bude zvolena kdyz vytvarim kod pro DO. Takze tam mam nekde i nedoresenou chybu pri jedne optimalizaci pokud si vzpominam...

_________________
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 ... 7, 8, 9, 10, 11, 12, 13 ... 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