OldComp.cz

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


Právě je 28.03.2024, 17:25

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

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Jen ve strucnosti.
ALIGN nyni vyzaduje jeden parameter a to hodnotu na kolik bajtu se to ma zarovnat. Nesmi to byt ukazatel.
NO_SEGMENT je jako ALIGN, ale pouze pokud fakt nasledujicich X bajtu by prelezalo segment.
Vlastne to je spatne... lol. A to jsem to testoval.
Takze ted uz NO_SEGMENT dela to, ze si zjisti zda aktualni adresa a aktualni adresa + X - 1 lezi na stejnem segmentu. Pokud ne tak datovy prostor vyplni tak, aby novy label lezel na adrese (segment+1)*256.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/Pasmo_test$ ../check_word.sh 'ORG 0x8000 PUSH(201) ALLOT NO_SEGMENT(56) PUSH(56) ALLOT' > smaz.asm && cat -n smaz.asm && pasmo -d smaz.asm smaz.bin
     1   ORG 0x8000     
     2                           ;           no_segment(56)
     3   
     4   VARIABLE_SECTION:
     5   
     6   ds 201
     7   ; The padding will fill if the following X bytes overflow the 256 byte segment.
     8   ; Any use of Allot with a negative value exceeding this address will result in undefined behavior.
     9   if  ((($ + 56 - 1) / 256) != ($/256))
    10     DEFS    (($/256)+1)*256 - $
    11   endif
    12   ds 56
    13                          ;[ 0:0]
      ORG 8000
8000:      label VARIABLE_SECTION
8000:00000000   DEFS of 201 bytes with value 00
8004:00000000
...
80C0:00000000
80C4:00000000
80C8:00
      IF(true)
80C9:00000000   DEFS of 55 bytes with value 00
80CD:00000000
80D1:00000000
80D5:00000000
80D9:00000000
80DD:00000000
80E1:00000000
80E5:00000000
80E9:00000000
80ED:00000000
80F1:00000000
80F5:00000000
80F9:00000000
80FD:000000
      ENDIF
8100:00000000   DEFS of 56 bytes with value 00
8104:00000000
8108:00000000
810C:00000000
8110:00000000
8114:00000000
8118:00000000
811C:00000000
8120:00000000
8124:00000000
8128:00000000
812C:00000000
8130:00000000
8134:00000000
WARNING: Var VARIABLE_SECTION is never used on line 4 of file smaz.asm
Emiting raw binary from 8000 to 8137

Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/Pasmo_test$ ../check_word.sh 'ORG 0x8000 PUSH(200) ALLOT NO_SEGMENT(56) PUSH(56) ALLOT' > smaz.asm && cat -n smaz.asm && pasmo -d smaz.asm smaz.bin
     1   ORG 0x8000     
     2                           ;           no_segment(56)
     3   
     4   VARIABLE_SECTION:
     5   
     6   ds 200
     7   ; The padding will fill if the following X bytes overflow the 256 byte segment.
     8   ; Any use of Allot with a negative value exceeding this address will result in undefined behavior.
     9   if  ((($ + 56 - 1) / 256) != ($/256))
    10     DEFS    (($/256)+1)*256 - $
    11   endif
    12   ds 56
    13                          ;[ 0:0]
      ORG 8000
8000:      label VARIABLE_SECTION
8000:00000000   DEFS of 200 bytes with value 00
8004:00000000
...
80C0:00000000
80C4:00000000
      IF(false)
-   DEFS    (($/256)+1)*256 - $
      ENDIF
80C8:00000000   DEFS of 56 bytes with value 00
80CC:00000000
80D0:00000000
80D4:00000000
80D8:00000000
80DC:00000000
80E0:00000000
80E4:00000000
80E8:00000000
80EC:00000000
80F0:00000000
80F4:00000000
80F8:00000000
80FC:00000000
WARNING: Var VARIABLE_SECTION is never used on line 4 of file smaz.asm
Emiting raw binary from 8000 to 80FF

A jeste ukazka ALIGN(X) ze bude pridavat vypln i kdyz neni potreba, protoze ji to rikame aby to delala.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/Pasmo_test$ ../check_word.sh 'ORG 0x8000 PUSH(201) ALLOT ALIGN(4) PUSH(56) ALLOT' > smaz.asm && cat -n smaz.asm && pasmo -d smaz.asm smaz.bin
     1   ORG 0x8000     
     2                           ;           align(4)
     3   
     4   VARIABLE_SECTION:
     5   
     6   ds 201
     7   ; Align to 4-byte page boundary.
     8   ; Any use of Allot with a negative value exceeding this address will result in undefined behavior.
     9   DEFS    (($ + 4 - 1) / (4)) * (4) - $
    10   ds 56
    11                          ;[ 0:0]
      ORG 8000
8000:      label VARIABLE_SECTION
8000:00000000   DEFS of 201 bytes with value 00
8004:00000000
...
80C0:00000000
80C4:00000000
80C8:00
80C9:000000   DEFS of 3 bytes with value 00
80CC:00000000   DEFS of 56 bytes with value 00
80D0:00000000
80D4:00000000
80D8:00000000
80DC:00000000
80E0:00000000
80E4:00000000
80E8:00000000
80EC:00000000
80F0:00000000
80F4:00000000
80F8:00000000
80FC:00000000
8100:00000000
WARNING: Var VARIABLE_SECTION is never used on line 4 of file smaz.asm
Emiting raw binary from 8000 to 8103

Za me dobry. .)

PS: Stahujte! Kompilujte! Je to velmi rychle! Velmi male! Velmi nenarocne! Odladene! Bez bugu! Stabilni API! Vhodne pro kardiostimulatory a druzice! .) Zatim jeste nikdo na to nezemrel a zadna druzice nespadla. .)) Minimalne zadna stiznost od zemreleho nebo na me nic nespadlo z nebes. .)))
https://github.com/DW0RKiN/M4_FORTH

PPS: Kdy budete pravidelne refreshovat ten odkaz kazdou noc tak muzete videt zmeny skoro online! :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: 17.10.2022, 04:03 
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 jsem se odmlcel, protoze me napadla takova zajimava myslenka.
Kdyz uz si hraji s temi pointery a ani u tech 32 bitovych hodnot nejsou moc efektivni....
Co to trosku rozsirit...
Na neco vic univerzalniho.
Na neco cim by slo resit i https://projecteuler.net/
Na aritmetiku a logiku cisel s "neomezenou" delkou.
Co takhle misto 32 bitoveho PDADD mit PADD(X), kde X je velikost cisla v bajtech na kterou pointer ukazuje... Kde X si nastavi programator podle toho co potrebuje.
Omezil jsem "neomezenou" delku X na 256 bajtu, protoze ty cisla maji byt stale zarovnane.

Takze jsem zacal postupne psat
PADD()
PSUB()
PSUB_NEGATE()
POR()
PXOR()
PAND()

skoro vsude jsem resil zvlast pripad pro X = 1,2,3,4,5..255,256

a pak pridal i PADC() a PSBC(), pro snadne rozsireni na vetsi velikost. Pro ty co neznaji assembler Z80 tak se jedna o scitani a odcitani s pridanim hodnoty carry. Tyhle slova jsou uplny vlhky sen pokud pisete v C.

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

    ld    A,(DE)        ; 1:7       p8+c   ( p8_2 p8_1 -- p8_2 p8_1 )  [p8_1] += [p8_2] + carry  with align 1
    adc   A,(HL)        ; 1:7       p8+c
    ld  (HL),A          ; 1:7       p8+c
                       ;[ 3:21]
dworkin@dw-A15:~/Programovani/ZX/Forth/Nova_testovaci$ ../check_word.sh 'PADC(2)'

    ld    A,(DE)        ; 1:7       p16+c   ( p16_2 p16_1 -- p16_2 p16_1 )  [p16_1] += [p16_2] + carry  with align 2
    adc   A,(HL)        ; 1:7       p16+c
    ld  (HL),A          ; 1:7       p16+c
    inc   L             ; 1:4       p16+c
    inc   E             ; 1:4       p16+c
    ld    A,(DE)        ; 1:7       p16+c
    adc   A,(HL)        ; 1:7       p16+c
    ld  (HL),A          ; 1:7       p16+c
    dec   L             ; 1:4       p16+c
    dec   E             ; 1:4       p16+c
                       ;[10:58]
dworkin@dw-A15:~/Programovani/ZX/Forth/Nova_testovaci$ ../check_word.sh 'PADC(3)'

    ld    A,(DE)        ; 1:7       p24+c   ( p24_2 p24_1 -- p24_2 p24_1 )  [p24_1] += [p24_2] + carry  with align 3
    adc   A,(HL)        ; 1:7       p24+c
    ld  (HL),A          ; 1:7       p24+c
    inc   L             ; 1:4       p24+c
    inc   E             ; 1:4       p24+c
    ld    A,(DE)        ; 1:7       p24+c
    adc   A,(HL)        ; 1:7       p24+c
    ld  (HL),A          ; 1:7       p24+c
    inc   L             ; 1:4       p24+c
    inc   E             ; 1:4       p24+c
    ld    A,(DE)        ; 1:7       p24+c
    adc   A,(HL)        ; 1:7       p24+c
    ld  (HL),A          ; 1:7       p24+c
    dec   L             ; 1:4       p24+c
    dec   E             ; 1:4       p24+c
    dec   L             ; 1:4       p24+c
    dec   E             ; 1:4       p24+c
                       ;[17:95]
dworkin@dw-A15:~/Programovani/ZX/Forth/Nova_testovaci$ ../check_word.sh 'PADC(4)'

    ld    A,(DE)        ; 1:7       p32+c   ( p32_2 p32_1 -- p32_2 p32_1 )  [p32_1] += [p32_2] + carry  with align 4
    adc   A,(HL)        ; 1:7       p32+c
    ld  (HL),A          ; 1:7       p32+c
    ld    C, L          ; 1:4       p32+c
    ld    B, E          ; 1:4       p32+c
    inc   L             ; 1:4       p32+c
    inc   E             ; 1:4       p32+c
    ld    A,(DE)        ; 1:7       p32+c
    adc   A,(HL)        ; 1:7       p32+c
    ld  (HL),A          ; 1:7       p32+c
    inc   L             ; 1:4       p32+c
    inc   E             ; 1:4       p32+c
    ld    A,(DE)        ; 1:7       p32+c
    adc   A,(HL)        ; 1:7       p32+c
    ld  (HL),A          ; 1:7       p32+c
    inc   L             ; 1:4       p32+c
    inc   E             ; 1:4       p32+c
    ld    A,(DE)        ; 1:7       p32+c
    adc   A,(HL)        ; 1:7       p32+c
    ld  (HL),A          ; 1:7       p32+c
    ld    L, C          ; 1:4       p32+c
    ld    E, B          ; 1:4       p32+c
                       ;[22:124]
dworkin@dw-A15:~/Programovani/ZX/Forth/Nova_testovaci$ ../check_word.sh 'PADC(5)'

    ld    C, L          ; 1:4       p40+c   ( p40_2 p40_1 -- p40_2 p40_1 )  [p40_1] += [p40_2] + carry  with align 5
    push DE             ; 1:11      p40+c
    ld    B, 0x05       ; 2:7       p40+c
    ld    A,(DE)        ; 1:7       p40+c
    adc   A,(HL)        ; 1:7       p40+c
    ld  (HL),A          ; 1:7       p40+c
    inc   L             ; 1:4       p40+c
    inc   E             ; 1:4       p40+c
    djnz $-5            ; 2:8/13    p40+c
    ld    L, C          ; 1:4       p40+c
    pop  DE             ; 1:10      p40+c
                       ;[13:73]
dworkin@dw-A15:~/Programovani/ZX/Forth/Nova_testovaci$ ../check_word.sh 'PADC(256)'

    ld    A,(DE)        ; 1:7       p2048+c   ( p2048_2 p2048_1 -- p2048_2 p2048_1 )  [p2048_1] += [p2048_2] + carry  with align 256
    adc   A,(HL)        ; 1:7       p2048+c
    ld  (HL),A          ; 1:7       p2048+c
    inc   L             ; 1:4       p2048+c
    inc   E             ; 1:4       p2048+c
    jr   nz, $-5        ; 2:7/12    p2048+c
                       ;[ 7:36]


Pridal jsem shift/posun o jeden bit vlevo _1_PLSHIFT()

a zacal psat i bezznamenkove nasobeni. Prvne jsem teda jeste musel vyresit textovy vystup a udelal slovo HEX_PUDOT. To jeste slo snadno, udelal jsem jen malou zmenu v runtime knihovne.

U nasobeni uz to neslo tak snadno. Protoze potrebuji drzet 3 hodnoty v pameti.
Jednu pro vysledek. Druhou hodnotu co se bude pricitat k prvni pokud treti hodnota bude mit nastaveny bit na jedna.
To uz jsou 3 ukazatele a ja musim mit jeste dalsi promenne.
Protoze jen scitani chce B jako pocitadlo a meni se me dvakrat spodni hodnoty adres a ja je potrebuji uchovat pro navrat do puvodniho stavu a jeste ke vsemu pouziji pro scitani i akumulator.

Ale neco jsem ted narychlo dosmolil.
Ta "treti" hodnota pouziva neco jako _1_LSHIFT(), az na to ze prvne si ten ukazatel zvednu na nejvyssi hodnotu a postupne odcitam, takze nemusim ukladat puvodni hodnotu, protoze me sama vyleze. A za druhe se rotuje vzdy jen 1 bajt osmkrat. A pak se snizi ten ukazatel o jedna. A na konci zustane hodnota nezmenena. Aspon doufam, zapomnel jsem to otestovat... .)))

Příloha:
Snímek obrazovky_2022-10-17_02-32-03.png
Snímek obrazovky_2022-10-17_02-32-03.png [ 304.29 KiB | Zobrazeno 3031 krát ]


No neni to nadhera? Podle me je to uplna bomba. Dokazat snadno psat pro ZX software co pocita i s 2048 bitovymi cisly? Mel jsem problem otestovat bez specializovaneho softwaru 64 bit*64 bit a ZX to ve Forthu ted zvladne levou zadni. Trosku jsem musel ohackoval vystup z kalkulacky, aby me vubec ukazala spravny vysledek.

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


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

Registrován: 11.06.2013, 15:27
Příspěvky: 3025
Has thanked: 2192 times
Been thanked: 894 times
_dworkin píše:
No neni to nadhera? Podle me je to uplna bomba.

Je. :god2: :thumbup:

To tady hltam nadsene, jen obcas si musim k pochopeni doplnit zakladni vzdelani :-)

Komentar a dotaz:
1) Ted tyhle stranky sbalit do jednoho pdfka, dat svazat a prihlasit na nejakou malou vedeckou praci.
2) Bude PDF manual? (primo v TeXu sazeny nemusi byt)

_________________
// na co myslím, když sedím u oldkompů: Blood Products from Genetic Vaccine Recipients


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

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
SCjoe píše:
To tady hltam nadsene, jen obcas si musim k pochopeni doplnit zakladni vzdelani :-)


Nejsi prvni co tohle rika. Neco jako: rad to ctu, ale uplne to nechapu. Zajimalo by me co pisi slozite. Popis, kod nebo neco jineho?

SCjoe píše:
1) Ted tyhle stranky sbalit do jednoho pdfka, dat svazat a prihlasit na nejakou malou vedeckou praci.


Mam to tu jako verejny zapisnicek, kde si ventiluji co me zrovna napadne. Kdyz s nikym roky nemluvite, protoze nazivo tu nikdo cestine nerozumi a ja zase nerozumim jim... Takze nastavaji situace, kdy je nejvetsi frmol ja nestiham a jeste mi nekdo rekne, ze mam prinest z pripravne kuchyne hned "skočex" a muj mozek na to reaguje jen "dop*dele, co to po me chce", misto aby genialni zkratkou to spojil se scotish eggs. Nebo slysim ze chce "brauný" a misto toho rekl "prawns". Nastesti rekl i "blů box". "led bolt" jsem uz myslim tady zminoval, a s bleskem z ledek to fakt nema nic spolecneho (muj mozek mi vybavil jen moji oblibenou magic kartu Lightning bolt, kdy jsem hral pred 25 lety cervenou barvu), to spis s cervenym prknem na krajeni. Tohle je dost zajimave a hruzostracne tema. Je to jako kdybychom oba hrali na klavir, ale ja mel polovicni pocet klaves a v drtive vetsine v jinych frekvencich.
https://www.youtube.com/watch?v=U37hX8NPgjQ

Je to tady v podstate me jedine spojeni se svetem. Takovy zapisnik silenstvi. Zajimave spis tim popisem cesty, kam me to bloudeni za zrovna zajimavym tematem dostane.

SCjoe píše:
2) Bude PDF manual? (primo v TeXu sazeny nemusi byt)


Manual ceho? M4 FORTH? Na https://github.com/DW0RKiN/M4_FORTH je automaticky zobrazen README.md co je markdown soubor kde je spatne aktualizovany posledni stav. .)
Protoze i kdyz je casu dost, tak je mnoho zajimavych temat na prozkoumani, nez se snazit pouzivat automaticky prekladac.

Treba takova grafika. Co udelat podporu jako ma QBASIC pro kresleni multicar? Pridat FILL funcki a mit tak neco co by dokazalo zobrazovat obrazky jako ma hra Hobbit.

Ale kdyz neni hotovo posledni tema tak asi tezko. To nasobeni jsem delal cely volny den a vysledek nic moc v kodu. .)

Delat to seriozne tak dotahnu do konce tu tokenizaci prvne. Nachazim dost chyb v tom, ze obcas nejake slovo pouziva jine slovo. A kdyz uz se to nerozbaluje rovnou na kod, ale prvne meni na token a az ten pozdeji vola makro s kodem, tak se me to rozbali nekde jinde, nebo rovnou zacykli, kdyz vola samo sebe.

Jinak jsem skoncil v praci zase pozde, protoze zitra rano ma byt nejaka kontrola na cistotu tak jsem si jen hral s tim nasobenim ve variante ukazatele na dvoubajtove cislo. Prvne jsem, jen rozbalil smycky a vzniklo neco takoveho
Kód:
    ex  (SP),HL         ; 1:19      pu*16   ( p16_3 p16_2 p16_1 -- p16_3 p16_2 p16_1 )  [p16_1] = [p16_2] u* [p16_3] with align 2
    inc   L             ; 1:4       pu*16
    inc   L             ; 1:4       pu*16
    ex  (SP),HL         ; 1:19      pu*16   p3 += 2
    xor   A             ; 1:4       pu*16
    ld  (HL),A          ; 1:7       pu*16
    inc   L             ; 1:4       pu*16
    ld  (HL),A          ; 1:7       pu*16
    dec   L             ; 1:4       pu*16

    ld    C, 0x02       ; 2:7       pu*16

    ld    B, 0x08       ; 2:7       pu*16
    ex  (SP),HL         ; 1:19      pu*16
    dec   L             ; 1:4       pu*16
    ex  (SP),HL         ; 1:19      pu*16

    sla (HL)            ; 2:15      pu*16
    inc   L             ; 1:4       pu*16
    rl  (HL)            ; 2:15      pu*16
    dec   L             ; 1:4       pu*16

    ex  (SP),HL         ; 1:19      pu*16
    rlc (HL)            ; 2:15      pu*16
    ex  (SP),HL         ; 1:19      pu*16

    jr   nc, $+12       ; 2:7/12    pu*16

    ld    A,(DE)        ; 1:7       pu*16
    add   A,(HL)        ; 1:7       pu*16
    ld  (HL),A          ; 1:7       pu*16
    inc   L             ; 1:4       pu*16
    inc   E             ; 1:4       pu*16
    ld    A,(DE)        ; 1:7       pu*16
    adc   A,(HL)        ; 1:7       pu*16
    ld  (HL),A          ; 1:7       pu*16
    dec   L             ; 1:4       pu*16
    dec   E             ; 1:4       pu*16

    djnz $-37           ; 2:8/13    pu*16
    dec   C             ; 1:4       pu*16
    jr   nz, $-45       ; 2:7/12    pu*16

Kde jsou tam ty strasne veci jak se snazim dostat k p3 pointeru co uz lezi na zasobiku jako
Kód:
    ex  (SP),HL         ; 1:19      pu*16
    dec   L             ; 1:4       pu*16
    ex  (SP),HL         ; 1:19      pu*16

...
    ex  (SP),HL         ; 1:19      pu*16
    rlc (HL)            ; 2:15      pu*16
    ex  (SP),HL         ; 1:19      pu*16

Ten pointer se pouziva jen pro postupnou rotaci vlevo a kdyz vypadne carry tak se k vysledku ([p1] = [HL]) pricte hodnota [p2] (=[DE])
Ale slo by to i jinak, ze bych si z toho pointeru natahl to cislo a to hodil na zasobnik, a pak uz na nej nemusel vubec sahnout. To cislo ma jen 2 bajty takze to ani nezahlti zasobnik.
To se mi nakonec s pouzitim stinoveho A podarilo a vysledek byl o dost rychlejsi (stale desne pomale oproti verzi v registrech), ale mel stejnych 43 bajtu jako ex (SP),HL verze.
Pouzil jsem teda trik, kdy se me podarilo eliminovat jedno PUSH AF, protoze jsem zrusil v cyklu jedno nacteni POP AF.
Jedina zajimava vec v podstate pro dnesek.
Jde o to ze misto
Kód:
    pop  BC             ; 1:10      pu*16
    push BC             ; 1:11      pu*16
    ld    A,(BC)        ; 1:7       pu*16
    push AF             ; 1:11      pu*16
    inc   C             ; 1:4       pu*16
    ld    A,(BC)        ; 1:7       pu*16
    push AF             ; 1:11      pu*16
    ld    C, 0x02       ; 2:7       pu*16
... sem skaze C smycka...
    ld    B, 0x08       ; 2:7       pu*16
    pop  AF             ; 1:10      pu*16
mam
Kód:
    pop  BC             ; 1:10      pu*16
    push BC             ; 1:11      pu*16
    ld    A,(BC)        ; 1:7       pu*16
    push AF             ; 1:11      pu*16
    inc   C             ; 1:4       pu*16
    ld    A,(BC)        ; 1:7       pu*16
    ld   BC, 0xF101     ; 3:10      pu*16   ld C,1 && pop af
    ld    B, 0x08       ; 2:7       pu*16

Prohodil jsem "pop af" s "ld b,8" a v prvnim pruchodu skryl "pop af" tim ze pouziji ten trik s maskovanim instrukce za ld bc,xxxx, ale tentokrat tu hodnotu v C chci a jen B je falesna a hned ji prenastavuji, coz by melo kazdeho trknout ze se tam deje neco divneho.
Cely ten pomaly kod
Kód:
    xor   A             ; 1:4       pu*16   ( p16_3 p16_2 p16_1 -- p16_3 p16_2 p16_1 )  [p16_1] = [p16_2] u* [p16_3] with align 2
    ld  (HL),A          ; 1:7       pu*16
    inc   L             ; 1:4       pu*16
    ld  (HL),A          ; 1:7       pu*16
    dec   L             ; 1:4       pu*16
    pop  BC             ; 1:10      pu*16
    push BC             ; 1:11      pu*16
    ld    A,(BC)        ; 1:7       pu*16
    push AF             ; 1:11      pu*16
    inc   C             ; 1:4       pu*16
    ld    A,(BC)        ; 1:7       pu*16
    ld   BC, 0xF102     ; 3:10      pu*16   ld C,1 && pop af
    ld    B, 0x08       ; 2:7       pu*16
    sla (HL)            ; 2:15      pu*16
    inc   L             ; 1:4       pu*16
    rl  (HL)            ; 2:15      pu*16
    dec   L             ; 1:4       pu*16
    add   A, A          ; 1:4       pu*16
    jr   nc, $+14       ; 2:7/12    pu*16
    ex   AF, AF'        ; 1:4       pu*16
    ld    A,(DE)        ; 1:7       pu*16
    add   A,(HL)        ; 1:7       pu*16
    ld  (HL),A          ; 1:7       pu*16
    inc   L             ; 1:4       pu*16
    inc   E             ; 1:4       pu*16
    ld    A,(DE)        ; 1:7       pu*16
    adc   A,(HL)        ; 1:7       pu*16
    ld  (HL),A          ; 1:7       pu*16
    ex   AF, AF'        ; 1:4       pu*16
    dec   L             ; 1:4       pu*16
    dec   E             ; 1:4       pu*16
    djnz $-21           ; 2:8/13    pu*16
    dec   C             ; 1:4       pu*16
    jr   nz, $-27       ; 2:7/12    pu*16
                       ;[42:227]

Vlastne bude lepsi to ukazat spis takhle. Lepe uvidite skoky a F1 = pop AF
Kód:
8027:AF      XOR A
8028:77      LD (HL), A
8029:2C      INC L
802A:77      LD (HL), A
802B:2D      DEC L
802C:C1      POP BC
802D:C5      PUSH BC
802E:0A      LD A, (BC)
802F:F5      PUSH AF
8030:0C      INC C
8031:0A      LD A, (BC)
8032:0102F1   LD BC, F102
8035:0608   LD B, 08
8037:CB26   SLA (HL)
8039:2C      INC L
803A:CB16   RL (HL)
803C:2D      DEC L
803D:87      ADD A, A
803E:300C   JR NC, 804C
8040:08      EX AF, AF'
8041:1A      LD A, (DE)
8042:86      ADD A, (HL)
8043:77      LD (HL), A
8044:2C      INC L
8045:1C      INC E
8046:1A      LD A, (DE)
8047:8E      ADC A, (HL)
8048:77      LD (HL), A
8049:08      EX AF, AF'
804A:2D      DEC L
804B:1D      DEC E
804C:10E9   DJNZ 8037
804E:0D      DEC C
804F:20E3   JR NZ, 8034


PS: Asi bych mohl pro tu "neomezenou" delku pouzit nejake stinove instrukce, abych to trosku zrychlil.
PPS: Mozna jeste pseudokod nasobeni [P3] * [P2] = [P1]
Kód:
[P1] = 0
for x = 1 to pocet_bitu_cisla
  [P1] = [P1] * 2
  rotace [P3] (na konci ma mit [P3] stejnou hodnotu)
  if nastavila se vlajka preteceni? then
     [P1] = [P1] + [P2]
  end
next

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


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 19.10.2022, 02:35 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Kontrola cistoty nedopadla dobre (uz podruhe), ale ja nemusim na poradu. .)
Zitra mam celodenni smenu, takze dnes v noci to nebudu hrotit.
Pridal jsem variantu nasobeni pro delku 256 bajtu.
Tam se da ve vetsine smycek obejit bez pocitadla v B a ani ukladat puvodni offset se nemusi, protoze kvuli zarovnani vime ze vse konci nulou. Proto ani neni potreba to pocitadlo.

Drobne jsem upravil ten predchozi test, nechal jsem stejnou hodnotu jen jsem za ni pridal spoustu nul, aby delka byla tech 256 bajtu, vystupy jsem nechal 128 bitove a spustil test.
Vse probehlo v poradku, jen uz to nebylo okamzite a musel jsem cekat.
4.94 sekundy.
To neni az tak strasne, ale zrovna v tomto pripade je to nasobeni skoro samych nulovych bitu.
Tak jsem pridal parametr
"TYP_PUMUL" a pokud je "fast" tak si pri nacitani toho bajtu z P3 pointeru do A, ktery se postupne 8x testuje na carry, a pokud je priznak preteceni nastaven, tak se pricte k vysledku (P1) hodnota na kterou odkazuje P2...
Sakra uz to pisi jako slohovku.
Proste kdyz ten bajt je nulovy tak se jen zbytecne nasobi vysledek osmkrat hodnotou dvema. Dela se osmkrat shift vlevo o bajt aniz by se neco pricitalo.
Takze kdyz je nulovy tak vysledek posunu o bajt. Tzn shiftnu o 8 bitu. Tzn nasobim 256. A ta smycka kde se posouve vse o bit se preskoci.
Kód:
80C3:AF      XOR A
80C4:77      LD (HL), A
80C5:2C      INC L
80C6:20FC   JR NZ, 80C4
80C8:0E00   LD C, 00
80CA:E3      EX(SP), HL
80CB:2D      DEC L
80CC:7E      LD A, (HL)
80CD:E3      EX(SP), HL
------------vvvvvvvv------------
80CE:B7      OR A
80CF:200A   JR NZ, 80DB
80D1:46      LD B, (HL)
80D2:77      LD (HL), A
80D3:2C      INC L
80D4:7E      LD A, (HL)
80D5:70      LD (HL), B
80D6:2C      INC L
80D7:20F8   JR NZ, 80D1
80D9:1817   JR 80F2
-------------^^^^^^^------------
80DB:0608   LD B, 08
80DD:B7      OR A
80DE:CB16   RL (HL)
80E0:2C      INC L
80E1:20FB   JR NZ, 80DE
80E3:87      ADD A, A
80E4:300A   JR NC, 80F0
80E6:08      EX AF, AF'
80E7:B7      OR A
80E8:1A      LD A, (DE)
80E9:8E      ADC A, (HL)
80EA:77      LD (HL), A
80EB:2C      INC L
80EC:1C      INC E
80ED:20F9   JR NZ, 80E8
80EF:08      EX AF, AF'
80F0:10EB   DJNZ 80DD
80F2:0D      DEC C
80F3:20D5   JR NZ, 80CA    <----- a tady se musi zmenit adresa, aby stale odkazovala pod ld C,0


Mate to i s chybou, kde staci misto ld C,0 udelat ld C,E nebo ld C,L.

PS: Zapomel jsem napsat, ze po zmene je to o 13 bajtu delsi (na vysledku jsem to nepoznal kvuli tomu zarovnani) a trvalo to 0.81 sekundy.

_________________
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: 20.10.2022, 21:16 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Chtel jsem se uz venovat deleni, mam to v hlave uz nejak doresene co je treba.
Jedna z veci co deleni potrebuje je porovnani vetsi mensi atd.
Takze jsem udelal zatim jen = a <> pro delku cisel az 256 bajtu.
U testovani jsem ale zjistil, ze mam chybu ve vypisu cisel HEX UDOT, dekadicky UDOT zobrazoval vysledky v poradku jako 0 a 65535. Jenze jsem chtel videt 0000 a nebo FFFF, k memu prekvapeni se uz ukazovali jine hodnoty.
Zacal jsem teda zkouset jak vypada zasobnik a ten me ukazoval ze na konci programu je v nem 0 hodnot a to bylo taky spatne.
Nakonec jsem nasel chybu v HEX_UDOT, ktera vyplivla
Kód:
    call PRT_HEX_U16    ; 3:17      hex u.   ( u -- )
    pop  HL             ; 1:10      hex u.
    pop  DE             ; 1:10      hex u.

Po prozkoumani te rutiny na vypis, jsem si overil ze meni jen hodnotu A, takze spravne ma byt
Kód:
    call PRT_HEX_U16    ; 3:17      hex u.   ( u -- )
    ex   DE, HL         ; 1:4       hex u.
    pop  DE             ; 1:10      hex u.

To znamena ze odstranim jen tu vypsanou hodnotu.

Jeste predtim jsem mel nejakou nekonzistenci mezi PUSH_COMMA a PUSHS_COMMA. Prvni me nacetla hodnotu do BC a hned ulozila do pameti. A druha me ulozila TOS (HL) a pak to resila pres HL a uz nevratila to puvodni HL.
Forth me tvrdi ze COMMA (,) udela ( x -- ), tzn vyzvedne si hodnotu z TOS a ulozi do pameti.

Chyba se stala behem tokenizace, nektere pomocne rutiny jsem zase automaticky tokenizival, coz jsem nemel a jak je volam/pouzivam uz v casti co generuji kod tak to delalo psi kusy. Provedl jsem nejake automaticke zmeny a nahradil nejaky text za jiny. Doufam ze vsude spravne, ale je to jako hrabat do svycarskeho hodinoveho strojku, kde si uz uplne nepamatujete co vse dela, jen si myslite ze vite ze tohle by mohlo pomoct... ZMENIT VSE je trosku riskantni operace, kdyz to neprochazite a nekontrolujete.

Takze push_comma uz opet na konci nacte HL ze zasobniku.

Aby toho nebylo malo tak jsem nemel pravidlo v tokenech co me dokaze zmenit

PUSH(1) COMMA PUSH(2) COMMA PUSH(3) COMMA

na

PUSHS_COMMA(1,2,3)

ale jen

PUSH_COMMA(1) PUSH_COMMA(2) PUSH_COMMA(3)

Predtim to ani neslo. Protoze se uz musi sahat na 2 predchozi tokeny, protoze token pro PUSH_COMMA_PUSH neexistuje. Pri pridani jsem tam omylem zavlekl dalsi chybu, kdy se me vypisovala carka do vystupu a nez jsem to nasel... Udelal jsem omylem

__BEFORELAST_TOKEN_NAME:__LAST_TOKEN_NAME:$1, __TOKEN_PUSHS_COMMA:__TOKEN_PUSH:__TOKEN_COMMA,
{__SET_TOKEN_X(eval(__TOKEN_COUNT-1),{__TOKEN_PUSHS_COMMA},__BEFORELAST_TOKEN_INFO{ }__LAST_TOKEN_INFO,__BEFORELAST_TOKEN_ARRAY,__LAST_TOKEN_ARRAY),__DELETE_LAST_TOKEN},

misto

__BEFORELAST_TOKEN_NAME:__LAST_TOKEN_NAME:$1, __TOKEN_PUSHS_COMMA:__TOKEN_PUSH:__TOKEN_COMMA,
{__SET_TOKEN_X(eval(__TOKEN_COUNT-1),{__TOKEN_PUSHS_COMMA},__BEFORELAST_TOKEN_INFO{ }__LAST_TOKEN_INFO,__BEFORELAST_TOKEN_ARRAY,__LAST_TOKEN_ARRAY){}__DELETE_LAST_TOKEN},

Je to tesne pred __DELETE_LAST_TOKEN

Mimochodem __SET_TOKEN_X() ma parametry ID_TOKENU,JMENO_TOKENU,INFO_TOKENU(co se bude ukazovat pak na vystupu na kazdem radku toho slova) a pak uz jen data oddelena carkami

PS: A jeste potrebuji predelat to nasobeni a mozna i jine slova na rutiny to runtime knihovny. Je to tak pomale, ze jedno call a ret navic tomu uz neublizi.

PPS: U toho porovnani jsem to u 32 bitove hodnoty delal pomoci opakovaneho odcitani od nejnizsich hodnot. Ale existuje druhy pristup, ze to delam od nejvyssich a pokracuji k nizsim dokud se ty hodnoty nelisi. Az pokud se lisi tak provedu vyhodnoceni. Bohuzel stale musim kontrolovat zda uz nejsem na konci, protoze cisla mohou byt shodna. Oproti prvnimu pristupu je to slozitejsi o ten test rovnosti, ale zase se nemusi vetsinou testovat vsechny bajty. Rychlost bude zavisla na konkretnich hodnotach, tezko rici co je obecne vyhodnejsi. Ja mam jako clovek informaci navic, ze testuji sice 2048 bitove cislo, ale nenulovych je jen spodnich 64bitu, takze odcitat od sebe ty horni nuly je nesmysl. Ale druhy pristup je taky naprd, protoze 248 hornich bajtu je shodnych... a jeste ten test navic neco stoji...

PPPS: To deleni je takove neprijemne. Obecne reseni je takove ze budete delitele nasobit dvema tak dlouho dokud nebude vetsi nez delenec. Vynasobite vysledek dvema. A pak se ho budete snazit odecist od delence a pokud to pujde tak pridate k vysledku jednicku. A pak pokud je delitel stale vetsi nez byl na zacatku tak ho vydelite dvema a opakujete od kroku kdy nasobite vysledek dvema.

PPPPS: To nasobeni jde asi jeste zrychlit pokud obetujete nejake bajty navic. Trik by spocival v tom ze jak nasobite vysledek v jednom bajtu 8 krat postupne dvema a obcas prictete puvodni hodnotu tak by to melo jit zaridit tak ze vysledek budu sice nasobit dvema 8 krat, ale jen jednou a ne pro kazdy bajt prvniho nasobitele.

Proste bych kontroloval (X-ty bit mod 8) prvniho nasobitele a pokud by byl nastaven tak sice pricital puvodni hodnotu, ale posunutou od pocatku o spravny pocet bajtu.

Musel bych si jeste drzet u vysledne hodnoty nekde v nejakem registru jeden bajt navic aby to fungovalo. Nebo bajt navic u druheho cisla pokud bych posouval ten, protoze ma mit na konci stejnou hodnotu.

Lip to napsat neumim...

A * B = 0010 1001 0111 1111 * 0101 0101 1111 0000 = 0000 0000 0000 0000 +

A 0010 1001 0111 111(1) --> 1 --> + B
A 0010 100(1) 0111 1111 --> 1 --> + 256*B

budu menit v teto variante B

A 0010 1001 0111 11(1)1 --> 1 --> + 2*B
A 0010 10(0)1 0111 1111 --> 0

A 0010 1001 0111 1(1)11 --> 1 --> + 2*2*B
A 0010 1(0)01 0111 1111 --> 0

A 0010 1001 0111 (1)111 --> 1 --> + 2*2*2*B
A 0010 (1)001 0111 1111 --> 1 --> + 256*2*2*2*B

-- dtto --

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

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Tak pro dnes a dnesni noc vse (doufam)

Dodelano krome PEQ a PNE i PULT, PUGT, PULE, PUGE. Ctete to jako Pointer to Unsigned a LT je <, GT je > a LE je <= a GE je >=.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/Nova_testovaci$ ../check_word.sh 'PEQ(1) __ASM PNE(1) __ASM PULT(1) __ASM PUGT(1) __ASM PULE(1) __ASM PUGE(1)'
         
    push DE             ; 1:11      p8=   ( p8_2 p8_1 -- p8_2 p8_1 flag )  flag = [p8_1] == [p8_2]  with align 1
    ld    A,(DE)        ; 1:7       p8=
    xor (HL)            ; 1:7       p8=
    sub 0x01            ; 2:7       p8=
    ex   DE, HL         ; 1:4       p8=
    sbc  HL, HL         ; 2:15      p8=

    push DE             ; 1:11      p8<>   ( p8_2 p8_1 -- p8_2 p8_1 flag )  flag = [p8_1] != [p8_2]  with align 1
    ld    A,(DE)        ; 1:7       p8<>
    xor (HL)            ; 1:7       p8<>
    add   A, 0xFF       ; 2:7       p8<>   carry if not zero
    ex   DE, HL         ; 1:4       p8<>
    sbc  HL, HL         ; 2:15      p8<>

    push DE             ; 1:11      p8ult   ( pu8_2 pu8_1 -- pu8_2 pu8_1 flag )  flag == [pu8_2] u< [pu8_1]  with align 4
    ld    A,(DE)        ; 1:7       p8ult
    sub (HL)            ; 1:7       p8ult
    ex   DE, HL         ; 1:4       p8ult
    sbc  HL, HL         ; 2:15      p8ult   set flag [pu8_2]u<[pu8_1]

    push DE             ; 1:11      p8ugt   ( pu8_2 pu8_1 -- pu8_2 pu8_1 flag )  flag == [pu8_2] u> [pu8_1]  with align 4
    ex   DE, HL         ; 1:4       p8ugt
    ld    A,(DE)        ; 1:7       p8ugt
    sub (HL)            ; 1:7       p8ugt
    sbc  HL, HL         ; 2:15      p8ugt   set flag [pu8_2]u>[pu8_1]

    push DE             ; 1:11      p8ule   ( pu8_2 pu8_1 -- pu8_2 pu8_1 flag )  flag == [pu8_2] u<= [pu8_1]  with align 4
    ex   DE, HL         ; 1:4       p8ule
    ld    A,(DE)        ; 1:7       p8ule
    sub (HL)            ; 1:7       p8ule
    ccf                 ; 1:4       p8ule
    sbc  HL, HL         ; 2:15      p8ule   set flag [pu8_2]u<=[pu8_1]

    push DE             ; 1:11      p8uge   ( pu8_2 pu8_1 -- pu8_2 pu8_1 flag )  flag == [pu8_2] u>= [pu8_1]  with align 4
    ld    A,(DE)        ; 1:7       p8uge
    sub (HL)            ; 1:7       p8uge
    ex   DE, HL         ; 1:4       p8uge
    ccf                 ; 1:4       p8uge
    sbc  HL, HL         ; 2:15      p8uge   set flag [pu8_2]u>=[pu8_1]
                       ;[42:286]

Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/Nova_testovaci$ ../check_word.sh 'PEQ(2) __ASM PNE(2) __ASM PULT(2) __ASM PUGT(2) __ASM PULE(2) __ASM PUGE(2)'
         
    push DE             ; 1:11      p16=   ( p16_2 p16_1 -- p16_2 p16_1 flag )  flag = [p16_1] == [p16_2]  with align 2
    ld    A,(DE)        ; 1:7       p16=
    xor (HL)            ; 1:7       p16=
    jr   nz, $+9        ; 2:7/12    p16=
    inc   L             ; 1:4       p16=
    inc   E             ; 1:4       p16=
    ld    A,(DE)        ; 1:7       p16=
    xor (HL)            ; 1:7       p16=
    sub 0x01            ; 2:7       p16=
    dec   L             ; 1:4       p16=
    ex   DE, HL         ; 1:4       p16=
    sbc  HL, HL         ; 2:15      p16=

    push DE             ; 1:11      p16<>   ( p16_2 p16_1 -- p16_2 p16_1 flag )  flag = [p16_1] != [p16_2]  with align 2
    ld    A,(DE)        ; 1:7       p16<>
    xor (HL)            ; 1:7       p16<>
    jr   nz, $+7        ; 2:7/12    p16<>
    inc   L             ; 1:4       p16<>
    inc   E             ; 1:4       p16<>
    ld    A,(DE)        ; 1:7       p16<>
    xor (HL)            ; 1:7       p16<>
    dec   L             ; 1:4       p16<>
    add   A, 0xFF       ; 2:7       p16<>   carry if not zero
    ex   DE, HL         ; 1:4       p16<>
    sbc  HL, HL         ; 2:15      p16<>

    push DE             ; 1:11      p16ult   ( pu16_2 pu16_1 -- pu16_2 pu16_1 flag )  flag == [pu16_2] u< [pu16_1]  with align 4
    ld    A,(DE)        ; 1:7       p16ult
    sub (HL)            ; 1:7       p16ult
    inc   L             ; 1:4       p16ult
    inc   E             ; 1:4       p16ult
    ld    A,(DE)        ; 1:7       p16ult
    sbc   A,(HL)        ; 1:7       p16ult
    dec   L             ; 1:4       p16ult
    ex   DE, HL         ; 1:4       p16ult
    sbc  HL, HL         ; 2:15      p16ult   set flag [pu16_2]u<[pu16_1]

    push DE             ; 1:11      p16ugt   ( pu16_2 pu16_1 -- pu16_2 pu16_1 flag )  flag == [pu16_2] u> [pu16_1]  with align 4
    ex   DE, HL         ; 1:4       p16ugt
    ld    A,(DE)        ; 1:7       p16ugt
    sub (HL)            ; 1:7       p16ugt
    inc   L             ; 1:4       p16ugt
    inc   E             ; 1:4       p16ugt
    ld    A,(DE)        ; 1:7       p16ugt
    sbc   A,(HL)        ; 1:7       p16ugt
    dec   L             ; 1:4       p16ugt
    sbc  HL, HL         ; 2:15      p16ugt   set flag [pu16_2]u>[pu16_1]

    push DE             ; 1:11      p16ule   ( pu16_2 pu16_1 -- pu16_2 pu16_1 flag )  flag == [pu16_2] u<= [pu16_1]  with align 4
    ex   DE, HL         ; 1:4       p16ule
    ld    A,(DE)        ; 1:7       p16ule
    sub (HL)            ; 1:7       p16ule
    inc   L             ; 1:4       p16ule
    inc   E             ; 1:4       p16ule
    ld    A,(DE)        ; 1:7       p16ule
    sbc   A,(HL)        ; 1:7       p16ule
    dec   L             ; 1:4       p16ule
    ccf                 ; 1:4       p16ule
    sbc  HL, HL         ; 2:15      p16ule   set flag [pu16_2]u<=[pu16_1]

    push DE             ; 1:11      p16uge   ( pu16_2 pu16_1 -- pu16_2 pu16_1 flag )  flag == [pu16_2] u>= [pu16_1]  with align 4
    ld    A,(DE)        ; 1:7       p16uge
    sub (HL)            ; 1:7       p16uge
    inc   L             ; 1:4       p16uge
    inc   E             ; 1:4       p16uge
    ld    A,(DE)        ; 1:7       p16uge
    sbc   A,(HL)        ; 1:7       p16uge
    dec   L             ; 1:4       p16uge
    ex   DE, HL         ; 1:4       p16uge
    ccf                 ; 1:4       p16uge
    sbc  HL, HL         ; 2:15      p16uge   set flag [pu16_2]u>=[pu16_1]
                       ;[76:456]

Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/Nova_testovaci$ ../check_word.sh 'PEQ(3) __ASM PNE(3) __ASM PULT(3) __ASM PUGT(3) __ASM PULE(3) __ASM PUGE(3)'
         
    push DE             ; 1:11      p24=   ( p24_2 p24_1 -- p24_2 p24_1 flag )  flag = [p24_1] == [p24_2]  with align 3
    ld    A,(DE)        ; 1:7       p24=
    xor (HL)            ; 1:7       p24=
    jr   nz, $+16       ; 2:7/12    p24=
    inc   L             ; 1:4       p24=
    inc   E             ; 1:4       p24=
    ld    A,(DE)        ; 1:7       p24=
    xor (HL)            ; 1:7       p24=
    jr   nz, $+9        ; 2:7/12    p24=
    inc   L             ; 1:4       p24=
    inc   E             ; 1:4       p24=
    ld    A,(DE)        ; 1:7       p24=
    xor (HL)            ; 1:7       p24=
    sub 0x01            ; 2:7       p24=
    dec   L             ; 1:4       p24=
    dec   L             ; 1:4       p24=
    ex   DE, HL         ; 1:4       p24=
    sbc  HL, HL         ; 2:15      p24=

    push DE             ; 1:11      p24<>   ( p24_2 p24_1 -- p24_2 p24_1 flag )  flag = [p24_1] != [p24_2]  with align 3
    ld    A,(DE)        ; 1:7       p24<>
    xor (HL)            ; 1:7       p24<>
    jr   nz, $+14       ; 2:7/12    p24<>
    inc   L             ; 1:4       p24<>
    inc   E             ; 1:4       p24<>
    ld    A,(DE)        ; 1:7       p24<>
    xor (HL)            ; 1:7       p24<>
    jr   nz, $+7        ; 2:7/12    p24<>
    inc   L             ; 1:4       p24<>
    inc   E             ; 1:4       p24<>
    ld    A,(DE)        ; 1:7       p24<>
    xor (HL)            ; 1:7       p24<>
    dec   L             ; 1:4       p24<>
    dec   L             ; 1:4       p24<>
    add   A, 0xFF       ; 2:7       p24<>   carry if not zero
    ex   DE, HL         ; 1:4       p24<>
    sbc  HL, HL         ; 2:15      p24<>

    push DE             ; 1:11      p24ult   ( pu24_2 pu24_1 -- pu24_2 pu24_1 flag )  flag == [pu24_2] u< [pu24_1]  with align 4
    ld    A,(DE)        ; 1:7       p24ult
    sub (HL)            ; 1:7       p24ult
    inc   L             ; 1:4       p24ult
    inc   E             ; 1:4       p24ult
    ld    A,(DE)        ; 1:7       p24ult
    sbc   A,(HL)        ; 1:7       p24ult
    inc   L             ; 1:4       p24ult
    inc   E             ; 1:4       p24ult
    ld    A,(DE)        ; 1:7       p24ult
    sbc   A,(HL)        ; 1:7       p24ult
    dec   L             ; 1:4       p24ult
    dec   L             ; 1:4       p24ult
    ex   DE, HL         ; 1:4       p24ult
    sbc  HL, HL         ; 2:15      p24ult   set flag [pu24_2]u<[pu24_1]

    push DE             ; 1:11      p24ugt   ( pu24_2 pu24_1 -- pu24_2 pu24_1 flag )  flag == [pu24_2] u> [pu24_1]  with align 4
    ex   DE, HL         ; 1:4       p24ugt
    ld    A,(DE)        ; 1:7       p24ugt
    sub (HL)            ; 1:7       p24ugt
    inc   L             ; 1:4       p24ugt
    inc   E             ; 1:4       p24ugt
    ld    A,(DE)        ; 1:7       p24ugt
    sbc   A,(HL)        ; 1:7       p24ugt
    inc   L             ; 1:4       p24ugt
    inc   E             ; 1:4       p24ugt
    ld    A,(DE)        ; 1:7       p24ugt
    sbc   A,(HL)        ; 1:7       p24ugt
    dec   L             ; 1:4       p24ugt
    dec   L             ; 1:4       p24ugt
    sbc  HL, HL         ; 2:15      p24ugt   set flag [pu24_2]u>[pu24_1]

    push DE             ; 1:11      p24ule   ( pu24_2 pu24_1 -- pu24_2 pu24_1 flag )  flag == [pu24_2] u<= [pu24_1]  with align 4
    ex   DE, HL         ; 1:4       p24ule
    ld    A,(DE)        ; 1:7       p24ule
    sub (HL)            ; 1:7       p24ule
    inc   L             ; 1:4       p24ule
    inc   E             ; 1:4       p24ule
    ld    A,(DE)        ; 1:7       p24ule
    sbc   A,(HL)        ; 1:7       p24ule
    inc   L             ; 1:4       p24ule
    inc   E             ; 1:4       p24ule
    ld    A,(DE)        ; 1:7       p24ule
    sbc   A,(HL)        ; 1:7       p24ule
    dec   L             ; 1:4       p24ule
    dec   L             ; 1:4       p24ule
    ccf                 ; 1:4       p24ule
    sbc  HL, HL         ; 2:15      p24ule   set flag [pu24_2]u<=[pu24_1]

    push DE             ; 1:11      p24uge   ( pu24_2 pu24_1 -- pu24_2 pu24_1 flag )  flag == [pu24_2] u>= [pu24_1]  with align 4
    ld    A,(DE)        ; 1:7       p24uge
    sub (HL)            ; 1:7       p24uge
    inc   L             ; 1:4       p24uge
    inc   E             ; 1:4       p24uge
    ld    A,(DE)        ; 1:7       p24uge
    sbc   A,(HL)        ; 1:7       p24uge
    inc   L             ; 1:4       p24uge
    inc   E             ; 1:4       p24uge
    ld    A,(DE)        ; 1:7       p24uge
    sbc   A,(HL)        ; 1:7       p24uge
    dec   L             ; 1:4       p24uge
    dec   L             ; 1:4       p24uge
    ex   DE, HL         ; 1:4       p24uge
    ccf                 ; 1:4       p24uge
    sbc  HL, HL         ; 2:15      p24uge   set flag [pu24_2]u>=[pu24_1]
                       ;[110:626]

_________________
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: 20.10.2022, 23:34 
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:
dworkin@dw-A15:~/Programovani/ZX/Forth/Nova_testovaci$ ../check_word.sh 'PEQ(4) __ASM PNE(4) __ASM PULT(4) __ASM PUGT(4) __ASM PULE(4) __ASM PUGE(4)'
         
    push DE             ; 1:11      p32=   ( p32_2 p32_1 -- p32_2 p32_1 flag )  flag = [p32_1] == [p32_2]  with align 4
    ld    A,(DE)        ; 1:7       p32=
    xor (HL)            ; 1:7       p32=
    jr   nz, $+22       ; 2:7/12    p32=
    ld    C, L          ; 1:4       p32=
    inc   L             ; 1:4       p32=
    inc   E             ; 1:4       p32=
    ld    A,(DE)        ; 1:7       p32=
    xor (HL)            ; 1:7       p32=
    jr   nz, $+14       ; 2:7/12    p32=
    inc   L             ; 1:4       p32=
    inc   E             ; 1:4       p32=
    ld    A,(DE)        ; 1:7       p32=
    xor (HL)            ; 1:7       p32=
    jr   nz, $+8        ; 2:7/12    p32=
    inc   L             ; 1:4       p32=
    inc   E             ; 1:4       p32=
    ld    A,(DE)        ; 1:7       p32=
    xor (HL)            ; 1:7       p32=
    sub 0x01            ; 2:7       p32=
    ld    L, C          ; 1:4       p32=
    ex   DE, HL         ; 1:4       p32=
    sbc  HL, HL         ; 2:15      p32=

    push DE             ; 1:11      p32<>   ( p32_2 p32_1 -- p32_2 p32_1 flag )  flag = [p32_1] != [p32_2]  with align 4
    ld    C, L          ; 1:4       p32<>
    ld    A,(DE)        ; 1:7       p32<>
    xor (HL)            ; 1:7       p32<>
    jr   nz, $+18       ; 2:7/12    p32<>
    inc   L             ; 1:4       p32<>
    inc   E             ; 1:4       p32<>
    ld    A,(DE)        ; 1:7       p32<>
    xor (HL)            ; 1:7       p32<>
    jr   nz, $+12       ; 2:7/12    p32<>
    inc   L             ; 1:4       p32<>
    inc   E             ; 1:4       p32<>
    ld    A,(DE)        ; 1:7       p32<>
    xor (HL)            ; 1:7       p32<>
    jr   nz, $+6        ; 2:7/12    p32<>
    inc   L             ; 1:4       p32<>
    inc   E             ; 1:4       p32<>
    ld    A,(DE)        ; 1:7       p32<>
    xor (HL)            ; 1:7       p32<>
    add   A, 0xFF       ; 2:7       p32<>   carry if not zero
    ld     L, C         ; 1:4       p32<>
    ex    DE, HL        ; 1:4       p32<>
    sbc   HL, HL        ; 2:15      p32<>

    push DE             ; 1:11      p32ult   ( pu32_2 pu32_1 -- pu32_2 pu32_1 flag )  flag == [pu32_2] u< [pu32_1]  with align 4
    ld    A,(DE)        ; 1:7       p32ult
    sub (HL)            ; 1:7       p32ult
    ld    C, L          ; 1:4       p32ult
    inc   L             ; 1:4       p32ult
    inc   E             ; 1:4       p32ult
    ld    A,(DE)        ; 1:7       p32ult
    sbc   A,(HL)        ; 1:7       p32ult
    inc   L             ; 1:4       p32ult
    inc   E             ; 1:4       p32ult
    ld    A,(DE)        ; 1:7       p32ult
    sbc   A,(HL)        ; 1:7       p32ult
    inc   L             ; 1:4       p32ult
    inc   E             ; 1:4       p32ult
    ld    A,(DE)        ; 1:7       p32ult
    sbc   A,(HL)        ; 1:7       p32ult
    ld    L, C          ; 1:4       p32ult
    ex   DE, HL         ; 1:4       p32ult
    sbc  HL, HL         ; 2:15      p32ult   set flag [pu32_2]u<[pu32_1]

    push DE             ; 1:11      p32ugt   ( pu32_2 pu32_1 -- pu32_2 pu32_1 flag )  flag == [pu32_2] u> [pu32_1]  with align 4
    ex   DE, HL         ; 1:4       p32ugt
    ld    A,(DE)        ; 1:7       p32ugt
    sub (HL)            ; 1:7       p32ugt
    ld    C, L          ; 1:4       p32ugt
    inc   L             ; 1:4       p32ugt
    inc   E             ; 1:4       p32ugt
    ld    A,(DE)        ; 1:7       p32ugt
    sbc   A,(HL)        ; 1:7       p32ugt
    inc   L             ; 1:4       p32ugt
    inc   E             ; 1:4       p32ugt
    ld    A,(DE)        ; 1:7       p32ugt
    sbc   A,(HL)        ; 1:7       p32ugt
    inc   L             ; 1:4       p32ugt
    inc   E             ; 1:4       p32ugt
    ld    A,(DE)        ; 1:7       p32ugt
    sbc   A,(HL)        ; 1:7       p32ugt
    ld    L, C          ; 1:4       p32ugt
    sbc  HL, HL         ; 2:15      p32ugt   set flag [pu32_2]u>[pu32_1]

    push DE             ; 1:11      p32ule   ( pu32_2 pu32_1 -- pu32_2 pu32_1 flag )  flag == [pu32_2] u<= [pu32_1]  with align 4
    ex   DE, HL         ; 1:4       p32ule
    ld    A,(DE)        ; 1:7       p32ule
    sub (HL)            ; 1:7       p32ule
    ld    C, L          ; 1:4       p32ule
    inc   L             ; 1:4       p32ule
    inc   E             ; 1:4       p32ule
    ld    A,(DE)        ; 1:7       p32ule
    sbc   A,(HL)        ; 1:7       p32ule
    inc   L             ; 1:4       p32ule
    inc   E             ; 1:4       p32ule
    ld    A,(DE)        ; 1:7       p32ule
    sbc   A,(HL)        ; 1:7       p32ule
    inc   L             ; 1:4       p32ule
    inc   E             ; 1:4       p32ule
    ld    A,(DE)        ; 1:7       p32ule
    sbc   A,(HL)        ; 1:7       p32ule
    ld    L, C          ; 1:4       p32ule
    ccf                 ; 1:4       p32ule
    sbc  HL, HL         ; 2:15      p32ule   set flag [pu32_2]u<=[pu32_1]

    push DE             ; 1:11      p32uge   ( pu32_2 pu32_1 -- pu32_2 pu32_1 flag )  flag == [pu32_2] u>= [pu32_1]  with align 4
    ld    A,(DE)        ; 1:7       p32uge
    sub (HL)            ; 1:7       p32uge
    ld    C, L          ; 1:4       p32uge
    inc   L             ; 1:4       p32uge
    inc   E             ; 1:4       p32uge
    ld    A,(DE)        ; 1:7       p32uge
    sbc   A,(HL)        ; 1:7       p32uge
    inc   L             ; 1:4       p32uge
    inc   E             ; 1:4       p32uge
    ld    A,(DE)        ; 1:7       p32uge
    sbc   A,(HL)        ; 1:7       p32uge
    inc   L             ; 1:4       p32uge
    inc   E             ; 1:4       p32uge
    ld    A,(DE)        ; 1:7       p32uge
    sbc   A,(HL)        ; 1:7       p32uge
    ld    L, C          ; 1:4       p32uge
    ex   DE, HL         ; 1:4       p32uge
    ccf                 ; 1:4       p32uge
    sbc  HL, HL         ; 2:15      p32uge   set flag [pu32_2]u>=[pu32_1]
                       ;[138:772]

Tohle plati pro peti az dvestepadesatpetibajtove cisla
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/Nova_testovaci$ ../check_word.sh 'PEQ(16) __ASM PNE(16) __ASM PULT(16) __ASM PUGT(16) __ASM PULE(16) __ASM PUGE(16)'
         
    push DE             ; 1:11      p128=   ( p128_2 p128_1 -- p128_2 p128_1 flag )  flag = [p128_1] == [p128_2]  with align 16
    ld    C, L          ; 1:4       p128=
    ld    B, 0x10       ; 2:7       p128=
    ld    A,(DE)        ; 1:7       p128=
    xor (HL)            ; 1:7       p128=
    jr   nz, $+7        ; 2:7/12    p128=
    inc   L             ; 1:4       p128=
    inc   E             ; 1:4       p128=
    djnz $-6            ; 2:8/13    p128=
    scf                 ; 1:4       p128=
    ld    L, C          ; 1:4       p128=
    ex   DE, HL         ; 1:4       p128=
    sbc  HL, HL         ; 2:15      p128=

    push DE             ; 1:11      p128<>   ( p128_2 p128_1 -- p128_2 p128_1 flag )  flag = [p128_1] != [p128_2]  with align 16
    ld    C, L          ; 1:4       p128<>
    ld    B, 0x10       ; 2:7       p128<>
    ld    A,(DE)        ; 1:7       p128<>
    xor (HL)            ; 1:7       p128<>
    jr   nz, $+6        ; 2:7/12    p128<>
    inc   L             ; 1:4       p128<>
    inc   E             ; 1:4       p128<>
    djnz $-6            ; 2:8/13    p128<>
    add   A, 0xFF       ; 2:7       p128<>   carry if not zero
    ld    L, C          ; 1:4       p128<>
    ex   DE, HL         ; 1:4       p128<>
    sbc  HL, HL         ; 2:15      p128<>

    push DE             ; 1:11      p128ult   ( pu128_2 pu128_1 -- pu128_2 pu128_1 flag )  flag == [pu128_2] u< [pu128_1]  with align 4
    ld    C, L          ; 1:4       p128ult
    ld    A,(DE)        ; 1:7       p128ult
    sub (HL)            ; 1:7       p128ult
    inc   L             ; 1:4       p128ult
    inc   E             ; 1:4       p128ult
    ld    B, 0x0F       ; 2:7       p128ult
    ld    A,(DE)        ; 1:7       p128ult
    sbc   A,(HL)        ; 1:7       p128ult
    inc   L             ; 1:4       p128ult
    inc   E             ; 1:4       p128ult
    djnz $-4            ; 2:8/13    p128ult
    ld    L, C          ; 1:4       p128ult
    ex   DE, HL         ; 1:4       p128ult
    sbc  HL, HL         ; 2:15      p128ult   set flag [pu128_2]u<[pu128_1]

    push DE             ; 1:11      p128ugt   ( pu128_2 pu128_1 -- pu128_2 pu128_1 flag )  flag == [pu128_2] u> [pu128_1]  with align 4
    ex   DE, HL         ; 1:4       p128ugt
    ld    C, L          ; 1:4       p128ugt
    ld    A,(DE)        ; 1:7       p128ugt
    sub (HL)            ; 1:7       p128ugt
    inc   L             ; 1:4       p128ugt
    inc   E             ; 1:4       p128ugt
    ld    B, 0x0F       ; 2:7       p128ugt
    ld    A,(DE)        ; 1:7       p128ugt
    sbc   A,(HL)        ; 1:7       p128ugt
    inc   L             ; 1:4       p128ugt
    inc   E             ; 1:4       p128ugt
    djnz $-4            ; 2:8/13    p128ugt
    ld    L, C          ; 1:4       p128ugt
    sbc  HL, HL         ; 2:15      p128ugt   set flag [pu128_2]u>[pu128_1]

    push DE             ; 1:11      p128ule   ( pu128_2 pu128_1 -- pu128_2 pu128_1 flag )  flag == [pu128_2] u<= [pu128_1]  with align 4
    ex   DE, HL         ; 1:4       p128ule
    ld    C, L          ; 1:4       p128ule
    ld    A,(DE)        ; 1:7       p128ule
    sub (HL)            ; 1:7       p128ule
    inc   L             ; 1:4       p128ule
    inc   E             ; 1:4       p128ule
    ld    B, 0x0F       ; 2:7       p128ule
    ld    A,(DE)        ; 1:7       p128ule
    sbc   A,(HL)        ; 1:7       p128ule
    inc   L             ; 1:4       p128ule
    inc   E             ; 1:4       p128ule
    djnz $-4            ; 2:8/13    p128ule
    ld    L, C          ; 1:4       p128ule
    ccf                 ; 1:4       p128ule
    sbc  HL, HL         ; 2:15      p128ule   set flag [pu128_2]u<=[pu128_1]

    push DE             ; 1:11      p128uge   ( pu128_2 pu128_1 -- pu128_2 pu128_1 flag )  flag == [pu128_2] u>= [pu128_1]  with align 4
    ld    C, L          ; 1:4       p128uge
    ld    A,(DE)        ; 1:7       p128uge
    sub (HL)            ; 1:7       p128uge
    inc   L             ; 1:4       p128uge
    inc   E             ; 1:4       p128uge
    ld    B, 0x0F       ; 2:7       p128uge
    ld    A,(DE)        ; 1:7       p128uge
    sbc   A,(HL)        ; 1:7       p128uge
    inc   L             ; 1:4       p128uge
    inc   E             ; 1:4       p128uge
    djnz $-4            ; 2:8/13    p128uge
    ld    L, C          ; 1:4       p128uge
    ex   DE, HL         ; 1:4       p128uge
    ccf                 ; 1:4       p128uge
    sbc  HL, HL         ; 2:15      p128uge   set flag [pu128_2]u>=[pu128_1]
                       ;[109:571]

A posledni varianta pro 256 bajtove cisla
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/Nova_testovaci$ ../check_word.sh 'PEQ(256) __ASM PNE(256) __ASM PULT(256) __ASM PUGT(256) __ASM PULE(256) __ASM PUGE(256)'
         
    push DE             ; 1:11      p2048=   ( p2048_2 p2048_1 -- p2048_2 p2048_1 flag )  flag = [p2048_1] == [p2048_2]  with align 256
    ld    A,(DE)        ; 1:7       p2048=
    xor (HL)            ; 1:7       p2048=
    jr   nz, $+7        ; 2:7/12    p2048=
    inc   L             ; 1:4       p2048=
    inc   E             ; 1:4       p2048=
    jr   nz, $-6        ; 2:7/12    p2048=
    scf                 ; 1:4       p2048=
    ld    L, 0x00       ; 2:7       p2048=
    ex   DE, HL         ; 1:4       p2048=
    sbc  HL, HL         ; 2:15      p2048=

    push DE             ; 1:11      p2048<>   ( p2048_2 p2048_1 -- p2048_2 p2048_1 flag )  flag = [p2048_1] != [p2048_2]  with align 256
    ld    A,(DE)        ; 1:7       p2048<>
    xor (HL)            ; 1:7       p2048<>
    jr   nz, $+6        ; 2:7/12    p2048<>
    inc   L             ; 1:4       p2048<>
    inc   E             ; 1:4       p2048<>
    jr   nz, $-6        ; 2:7/12    p2048<>
    add   A, 0xFF       ; 2:7       p2048<>   carry if not zero
    ld    L, 0x00       ; 2:7       p2048<>
    ex   DE, HL         ; 1:4       p2048<>
    sbc  HL, HL         ; 2:15      p2048<>

    push DE             ; 1:11      p2048ult   ( pu2048_2 pu2048_1 -- pu2048_2 pu2048_1 flag )  flag == [pu2048_2] u< [pu2048_1]  with align 4
    ld    A,(DE)        ; 1:7       p2048ult
    sub (HL)            ; 1:7       p2048ult
    inc   L             ; 1:4       p2048ult
    inc   E             ; 1:4       p2048ult
    ld    A,(DE)        ; 1:7       p2048ult
    sbc   A,(HL)        ; 1:7       p2048ult
    inc   L             ; 1:4       p2048ult
    inc   E             ; 1:4       p2048ult
    jr   nz, $-4        ; 2:7/12    p2048ult
    ex   DE, HL         ; 1:4       p2048ult
    sbc  HL, HL         ; 2:15      p2048ult   set flag [pu2048_2]u<[pu2048_1]

    push DE             ; 1:11      p2048ugt   ( pu2048_2 pu2048_1 -- pu2048_2 pu2048_1 flag )  flag == [pu2048_2] u> [pu2048_1]  with align 4
    ex   DE, HL         ; 1:4       p2048ugt
    ld    A,(DE)        ; 1:7       p2048ugt
    sub (HL)            ; 1:7       p2048ugt
    inc   L             ; 1:4       p2048ugt
    inc   E             ; 1:4       p2048ugt
    ld    A,(DE)        ; 1:7       p2048ugt
    sbc   A,(HL)        ; 1:7       p2048ugt
    inc   L             ; 1:4       p2048ugt
    inc   E             ; 1:4       p2048ugt
    jr   nz, $-4        ; 2:7/12    p2048ugt
    sbc  HL, HL         ; 2:15      p2048ugt   set flag [pu2048_2]u>[pu2048_1]

    push DE             ; 1:11      p2048ule   ( pu2048_2 pu2048_1 -- pu2048_2 pu2048_1 flag )  flag == [pu2048_2] u<= [pu2048_1]  with align 4
    ex   DE, HL         ; 1:4       p2048ule
    ld    A,(DE)        ; 1:7       p2048ule
    sub (HL)            ; 1:7       p2048ule
    inc   L             ; 1:4       p2048ule
    inc   E             ; 1:4       p2048ule
    ld    A,(DE)        ; 1:7       p2048ule
    sbc   A,(HL)        ; 1:7       p2048ule
    inc   L             ; 1:4       p2048ule
    inc   E             ; 1:4       p2048ule
    jr   nz, $-4        ; 2:7/12    p2048ule
    ccf                 ; 1:4       p2048ule
    sbc  HL, HL         ; 2:15      p2048ule   set flag [pu2048_2]u<=[pu2048_1]

    push DE             ; 1:11      p2048uge   ( pu2048_2 pu2048_1 -- pu2048_2 pu2048_1 flag )  flag == [pu2048_2] u>= [pu2048_1]  with align 4
    ld    A,(DE)        ; 1:7       p2048uge
    sub (HL)            ; 1:7       p2048uge
    inc   L             ; 1:4       p2048uge
    inc   E             ; 1:4       p2048uge
    ld    A,(DE)        ; 1:7       p2048uge
    sbc   A,(HL)        ; 1:7       p2048uge
    inc   L             ; 1:4       p2048uge
    inc   E             ; 1:4       p2048uge
    jr   nz, $-4        ; 2:7/12    p2048uge
    ex   DE, HL         ; 1:4       p2048uge
    ccf                 ; 1:4       p2048uge
    sbc  HL, HL         ; 2:15      p2048uge   set flag [pu2048_2]u>=[pu2048_1]
                       ;[89:489]

Trochu spamuji, ale toho kodu je docela dost a tohle ve skutecnosti nejsou uplne vsechny varianty, mam tam jeste treba modifikator pro malou velikost
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/Nova_testovaci$ ../check_word.sh 'define({TYP_P},small) PEQ(256) __ASM PNE(256) __ASM PULT(256) __ASM PUGT(256) __ASM PULE(256) __ASM PUGE(256)'
           
    push DE             ; 1:11      p2048=   ( p2048_2 p2048_1 -- p2048_2 p2048_1 flag )  flag = [p2048_1] == [p2048_2]  with align 256
    ld    A,(DE)        ; 1:7       p2048=
    xor (HL)            ; 1:7       p2048=
    jr   nz, $+7        ; 2:7/12    p2048=
    inc   L             ; 1:4       p2048=
    inc   E             ; 1:4       p2048=
    jr   nz, $-6        ; 2:7/12    p2048=
    scf                 ; 1:4       p2048=
    ld    L, 0x00       ; 2:7       p2048=
    ex   DE, HL         ; 1:4       p2048=
    sbc  HL, HL         ; 2:15      p2048=

    push DE             ; 1:11      p2048<>   ( p2048_2 p2048_1 -- p2048_2 p2048_1 flag )  flag = [p2048_1] != [p2048_2]  with align 256
    ld    A,(DE)        ; 1:7       p2048<>
    xor (HL)            ; 1:7       p2048<>
    jr   nz, $+6        ; 2:7/12    p2048<>
    inc   L             ; 1:4       p2048<>
    inc   E             ; 1:4       p2048<>
    jr   nz, $-6        ; 2:7/12    p2048<>
    add   A, 0xFF       ; 2:7       p2048<>   carry if not zero
    ld    L, 0x00       ; 2:7       p2048<>
    ex   DE, HL         ; 1:4       p2048<>
    sbc  HL, HL         ; 2:15      p2048<>

    push DE             ; 1:11      p2048ult   ( pu2048_2 pu2048_1 -- pu2048_2 pu2048_1 flag )  flag == [pu2048_2] u< [pu2048_1]  with align 4
    or    A             ; 1:4       p2048ult
    ld    A,(DE)        ; 1:7       p2048ult
    sbc   A,(HL)        ; 1:7       p2048ult
    inc   L             ; 1:4       p2048ult
    inc   E             ; 1:4       p2048ult
    jr   nz, $-4        ; 2:7/12    p2048ult
    ex   DE, HL         ; 1:4       p2048ult
    sbc  HL, HL         ; 2:15      p2048ult   set flag [pu2048_2]u<[pu2048_1]

    push DE             ; 1:11      p2048ugt   ( pu2048_2 pu2048_1 -- pu2048_2 pu2048_1 flag )  flag == [pu2048_2] u> [pu2048_1]  with align 4
    ex   DE, HL         ; 1:4       p2048ugt
    or    A             ; 1:4       p2048ugt
    ld    A,(DE)        ; 1:7       p2048ugt
    sbc   A,(HL)        ; 1:7       p2048ugt
    inc   L             ; 1:4       p2048ugt
    inc   E             ; 1:4       p2048ugt
    jr   nz, $-4        ; 2:7/12    p2048ugt
    sbc  HL, HL         ; 2:15      p2048ugt   set flag [pu2048_2]u>[pu2048_1]

    push DE             ; 1:11      p2048ule   ( pu2048_2 pu2048_1 -- pu2048_2 pu2048_1 flag )  flag == [pu2048_2] u<= [pu2048_1]  with align 4
    ex   DE, HL         ; 1:4       p2048ule
    or    A             ; 1:4       p2048ule
    ld    A,(DE)        ; 1:7       p2048ule
    sbc   A,(HL)        ; 1:7       p2048ule
    inc   L             ; 1:4       p2048ule
    inc   E             ; 1:4       p2048ule
    jr   nz, $-4        ; 2:7/12    p2048ule
    ccf                 ; 1:4       p2048ule
    sbc  HL, HL         ; 2:15      p2048ule   set flag [pu2048_2]u<=[pu2048_1]

    push DE             ; 1:11      p2048uge   ( pu2048_2 pu2048_1 -- pu2048_2 pu2048_1 flag )  flag == [pu2048_2] u>= [pu2048_1]  with align 4
    or    A             ; 1:4       p2048uge
    ld    A,(DE)        ; 1:7       p2048uge
    sbc   A,(HL)        ; 1:7       p2048uge
    inc   L             ; 1:4       p2048uge
    inc   E             ; 1:4       p2048uge
    jr   nz, $-4        ; 2:7/12    p2048uge
    ex   DE, HL         ; 1:4       p2048uge
    ccf                 ; 1:4       p2048uge
    sbc  HL, HL         ; 2:15      p2048uge   set flag [pu2048_2]u>=[pu2048_1]
                       ;[77:417]

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

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Unsigned deleni pomoci 1 az 256 bajtovych cisel pres pointery je hotove. Aspon prvni iterace.
Zacal jsem jednim bajtem, takze jsem pouzil neco napul mezi pointery a nactenim do registru. To me moc nepomohlo.
Takze jsem pokracoval dvoubajtovym cislem a schvalne se snazil vse drzet v pameti, abych mel lepsi predstavu co musim udelat u vetsich cisel.
A pak zacala bolest... .)
Orezal jsem ten algoritmus uplne na nejprimitivnejsi zaklad, zadne rychlostni optimilizace i tak to byla vyzva.

Prvne jsem resil 256 bajtovou variantu, protoze je nejsnazsi a nemu se drzet v pameti moc hodnot.
Pak resil obecnou variantu 3..255 bajtu.
Pri testovani jsem zjistil, ze me vubec nedoslo ze to pocitadlo o kolik bitu jsem posunul delitele vlevo se mi fakt nevleze do registru B.
Takze jsem to rozdelil na 3..32 a 33..255 varianty.
A prepisoval a prepisoval a resil neustale chyby, jak jsem zapomnel ze zrovna tady mam tuhle zavislost a nebo cekam ze carry bude zrovna nula. Nakonec se mi podarilo neco sesmolit co nebylo na prvni pohled az tak strasne.
Jenze to bylo "inline" a ja to potreboval jako funkci. Coz znamenalo ze jsem to musel prepsat zase znovu, protoze uz jsem nemohl pouzit pro inicializaci smycek neco jako

ld B, 23

kdyz delim 23 bajtove hodnoty, ale 23 musel byt parametr.

Takze dalsi kolecko prepisovani a vytvareni a opravovani novych chyb. Nakonec se ukazalo ze varianta 3..32 je ted temer totozna jako 33..255. Dokonce presneji ta posledni varianta je napsana rovnou tak aby, zvladla 1..256 bajtove hodnoty.

Takze mam 4 funkce a zobrazi se v runtime jen jedna podle toho co pouzijete v kodu. Zavedl jsem 2 nove promenne do M4.

PUDM_MIN
PUDM_MAX

a do tech se pri tokenizaci nacita co bylo pouzito.

Pokud obe ukazuji 1 tak runtine knihovna ma jen verzi pro deleni jednobajtovych hodnot.
Pokud obe ukazuji 2 tak runtine knihovna ma jen verzi pro deleni dvoubajtovych hodnot.
Pokud obe ukazuji 256 tak runtine knihovna ma jen verzi pro deleni 256 bajtovych hodnot.
Pokud obe ukazuji mene nez 32 tak runtine knihovna ma jen verzi pro deleni pri 8 bitovem citaci posunu.
Cokoliv jineho udela tu univerzalni rutinu.

Pri tom deleni potrebuji tri pointery. Protoze ten algoritmus potrebuje drzet v pameti tri.
Jeden je cislo co se deli a ktere se postupne meni ve zbytek po deleni jak se od nej odcita ruzne posunuty delitel.
Dalsi je ten delitel, ten se na konci vrati na puvodni hodnotu.
A posledni je vysledek.

Vysledek jsem umistil do TOS(HL), protoze to vetsinou ocekavate ze nejaka operace udela.
Zbytek po deleni a vlastne delene cislo je v NOS(DE).
Cim delite je jeste predtim v NNOS((SP)).

Je to trosku proti logice Forthu, kdy kdyz odcitate nebo delite tak je to

NOS TOS / --> NOS/TOS
NOS TOS - --> NOS-TOS

a ted jsou NOS a NNOS to prohozene

NNOS NOS TOS --> NNOS NOS%NNOS NOS/NNOS

Ale v algoritmu provedu swap NNOS a TOS a mam nejdulezitejsi pameti v registrech. S vysledkem uz neni tolik prace a pracuje se s nim samostante. U odcitani naopak musim mit jak delitele tak delence v registrech.

Dalsi vyhoda je ze jde rychle udelat postupne deleni.
Vemte si situaci ze mate 256 bajtove cislo a chcete ho vypsat decimalne.

Do zasobniku date

ukazatel_na_hodnotu_10 ukazatel_co_tisknete_X ukazatel_na_vysledek
Zavolate deleni a mate ve vysledku cislo 0..9 a tisknute cislo je 10x mensi.
Pokracujete tak dlouho dokud je zbytek po deleni nenulovy, desitka vam zustane a pointery jsou stale spravne nastaveny.
To je podle me pekne, jedina chybka bude, ze si asi muzete u 256 bajtoveho cisla postavit na kafe. .)

Jeste ukazi kod pro univerzalni rutinu. Popisek je vzdy pod kodem.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/Nova_testovaci$ ../check_word.sh 'PUDIVMOD(1) PUDIVMOD(200)'
 
    pop  BC             ; 1:10      p8u/mod
    ld    A, 0x01       ; 2:7       p8u/mod
    call PUDM           ; 3:17      p8u/mod
    push BC             ; 1:11      p8u/mod
    pop  BC             ; 1:10      p1600u/mod
    ld    A, 0xC8       ; 2:7       p1600u/mod
    call PUDM           ; 3:17      p1600u/mod
    push BC             ; 1:11      p1600u/mod
Takhle vypada volani, nechtelo se me resit problemy s tretim parametrem a ze se schova za navratovou hodnotu takze jsem zvolil rychlejsi reseni, ale delsi na volani, protoze se treti parametr nacte do BC a v rutine hned vrati zpet.
Kód:
;==============================================================================

; Divide 8..2048-bit unsigned value from pointer
; In: [BC], [DE], [HL]
;     A = sizeof(number) in bytes
; Out: [HL] = [DE] / [BC], [DE] = [DE] % [BC]
PUDM:                   ;           pudm
    push BC             ; 1:11      pudm
    ld    C, A          ; 1:4       pudm   C = x bytes
akumulator protrebuji, takze odted drzim sizeof(number) v registru C a je neustale nacitan na zacatku smycek do B. Takze nemam volny registr. Jen A, ve kterem budu za chvili potrebovat nejaky cas nulu.
Kód:
    xor   A             ; 1:4       pudm
    exx                 ; 1:4       pudm
    ld    B, A          ; 1:4       pudm
    ld    C, A          ; 1:4       pudm   BC' = shift_counter = 0
    exx                 ; 1:4       pudm
Pocitadlo posunu delitele je teda ve stinovem BC
Kód:
    ld    B, C          ; 1:4       pudm
    ld  (HL),A          ; 1:7       pudm
    inc   L             ; 1:4       pudm   px_res = 0
    djnz $-2            ; 2:8/13    pudm
    ex   AF, AF'        ; 1:4       pudm
    ld    A, L          ; 1:4       pudm
    sub   C             ; 1:4       pudm
    ld    L, A          ; 1:4       pudm   return to original value
Vynulovani vysledku. Vsimnete si ze abych vratil ukazatel na puvodni hodnotu tak ho musim odecist. Pokud by to cislo koncilo presne na predelu segmentu tak nastane carry. To se stane vzdy u 256 bajtovych hodnot. V teto variante kodu to ale nevadi. Pouziti pro uchovani zasobnik by usetrilo jeden bajt a bylo o 11+10-12 = 9 taktu pomalejsi. Hmm... vlastne jen o 5 protoze musim pouzit EX. To bych mel zmenit protoze je to o 2 bajty kratsi a jen 5 taktu pomalejsi, to uz prevazuje muj prevod 1 bajt = 4 takty. Ale zase je to rutina a bude volana asi vickrat jak jednou...
Kód:
    ex  (SP),HL         ; 1:19      pudm
Vysledek je inicializovan a odted potrebuji v HL delitele.
Kód:
    ld    A, L          ; 1:4       pudm   A' = original value L
    ex   AF, AF'        ; 1:4       pudm
Nove v stinovem A drzim puvodni offset delitele. Tenhle trik me taky bolel, protoze nesmite nikdy zapomenout ze prohazujete i F. V A je opet nula.
Kód:
    ld    B, C          ; 1:4       pudm
    or  (HL)            ; 1:7       pudm
    inc   L             ; 1:4       pudm
    djnz $-2            ; 2:8/13    pudm   px_3 == 0?

    or    A             ; 1:4       pudm
    jr    z, PUDM_EXIT  ; 2:7/12    pudm   exit with div 0
Test zda delitel neni nula. Dulezity test, protoze nasledujici cast posouva delitele tak dlouho dokud nepretece.
Kód:
    ex   AF, AF'        ; 1:4       pudm
    ld    L, A          ; 1:4       pudm   return to original value
    ex   AF, AF'        ; 1:4       pudm
    ld    B, C          ; 1:4       pudm
    exx                 ; 1:4       pudm
    inc   BC            ; 1:6       pudm   shift_counter++
    exx                 ; 1:4       pudm

    rl  (HL)            ; 2:15      pudm
    inc   L             ; 1:4       pudm
    djnz $-3            ; 2:8/13    pudm   px_3 *= 2

    jr   nc, $-12       ; 2:7/12    pudm   px_3 overflow?
Je to slozeno ze svou smycek. Vnitrni posouva delitele a vnejsi nastavuje spravne parametry pro vnitrni. Vraci zpet L a zveda pocitadlo HL'. Na konci je vzdy carry a L ukazuje ZA KONEC. Protoze pri posunu doprava se musi zacit od konce.
Kód:
PUDM_LOOP:              ;           pudm
    ld    B, C          ; 1:4       pudm   L = orig L + $1
    dec   L             ; 1:4       pudm
    rr  (HL)            ; 2:15      pudm
    djnz $-3            ; 2:8/13    pudm   px_3 >>= 1
Hlavni smycka. Posun o bit doprava. Poprve nacte carry, v dalsich krocich musim zajistit aby bylo carry vynulovano.
Kód:
    ex  (SP),HL         ; 1:19      pudm
    ld    A, L          ; 1:4       pudm
    ld    B, C          ; 1:4       pudm
    rl  (HL)            ; 2:15      pudm
    inc   L             ; 1:4       pudm
    djnz $-3            ; 2:8/13    pudm   result *= 2
    ld    L, A          ; 1:4       pudm   return to original value
    ex  (SP),HL         ; 1:19      pudm
Nasobeni vysledku dvema. Tady je volny A, takze jde pouzit pro uchovani puvodniho offsetu.
Kód:
    push  DE            ; 1:11      pudm
    ld    B, C          ; 1:4       pudm
    ld    A,(DE)        ; 1:7       pudm
    sbc   A,(HL)        ; 1:7       pudm
    inc   L             ; 1:4       pudm
    inc   E             ; 1:4       pudm
    djnz $-4            ; 2:8/13    pudm   (px_mod < px_3)?
    pop  DE             ; 1:10      pudm
Takove CP nad pointery. Pokud budu vychazet z predpokladu ze vysledek ma pravdepodobne stejny poctet jednickovych bitu jako nulovych tak je to stale rychlejsi jako odcitani natvrdo a pricitani zpet pri nulovem bitu. Usetrim stale jeden "ld (DE),A". Je dulezite ze na konci ukazuje L na konec, je to pripraveno pro dalsi krok smycky.
Kód:
    jr    c, PUDM_NEXT  ; 2:7/12    pudm
Pokud je vysledek carry tak nemuzeme odecist posunuteho delitele, protoze je vetsi jak zbytek.
Kód:
    ex  (SP),HL         ; 1:19      pudm
    inc (HL)            ; 1:11      pudm   result += 1
    ex  (SP),HL         ; 1:19      pudm
Pridani jednickoveho bitu k vysledku. Postupne se to nasobi dvema jak bylo videt vysse.
Kód:
    push DE             ; 1:11      pudm
    ex   AF, AF'        ; 1:4       pudm
    ld    L, A          ; 1:4       pudm   return to original value
    ex   AF, AF'        ; 1:4       pudm
Musime vratit offset na zacatek.
Kód:
    ld    B, C          ; 1:4       pudm
    ld    A,(DE)        ; 1:7       pudm
    sbc   A,(HL)        ; 1:7       pudm
    ld  (DE),A          ; 1:7       pudm
    inc   L             ; 1:4       pudm
    inc   E             ; 1:4       pudm
    djnz $-5            ; 2:8/13    pudm   px_mod -= px_3
    pop  DE             ; 1:10      pudm
Zase mame offset na konci.
Kód:
PUDM_NEXT:              ;           pudm
    exx                 ; 1:4       pudm
    dec  BC             ; 1:6       pudm
    ld    A, B          ; 1:4       pudm
    or    C             ; 1:4       pudm
    exx                 ; 1:4       pudm
    jr   nz, PUDM_LOOP  ; 2:7/12    pudm
Vynulovani carry! A djnz nad 16 bitovym BC'.
Kód:
PUDM_EXIT:              ;           pudm
    ex   AF, AF'        ; 1:4       pudm
    ld    L, A          ; 1:4       pudm   return to original value
    ex  (SP),HL         ; 1:19      pudm
    pop  BC             ; 1:10      pudm
    ret                 ; 1:10      pudm
                       ;[110:658]

Vraceni offsetu delitele. I ve variante ze je sem skoceno kdyz je delitel nulovy. Tohle jsem netestoval hmm...
A prohozeni delitele za vysledek v zasobniku a vyzvednuti do BC, aby se mohla pouzit navratova hodnota.

PS: V podstate je to takova primitivni rutina a ja to smolim nekolik dni, vcetne testovani, proc me to sakra zase nefunguje.

PPS: Zrychleni by slo udelat tim, ze by se jeste pote co se zkontroluje ze delitel je nenulovy tak od konce zjistovat zda delenec i delitel nema nejvyssi bajty nulove a pokud ano tak postupne snizovat hodnotu C, ktery drzi velikost tech cisel. Pokud by bylo na zacatku hodne nul tak to algoritmus hodne zrychli, jinak o trochu zpomali.

PPPS: Dalsi reseni by bylo mit jeste funkci pro to kdyz pouzivame sudy pocet pro velikost cisel. Tak by slo mit smycky s polovicnim citacem, ale za to uvnitre vse dvakrat. Vydelilo by to cenu skoku na polovinu. Ale moc extra by to nepomohlo. Takova cena pro jedno CP je 22 taktu plus 13 za kazdy skok. Takze z 35 taktu za bajt by to bylo neco jako (44+13)/2 = 28.5 taktu na bajt.

PPPPS: Dost jsem se strilel do nohy, protoze jsem mel misto labelu neco jako $+18 a jak ten kod hodne editujete tak... .)

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

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
PUMUL() prepsana na volani rutiny. Zrychleni pomoci testovani zda je cely bajt nulovy je ted implicitni pokud neni nastaven TYP_PUMUL na "small" a nebo pokud nenasobime cisla mensi nebo rovno 4 bajtu. Ta druha podminka je kvuli tomu, ze se me to moc nepovedlo a u malych cisel to asi ani moc nezrychluje. Dalo by se to povolit od 2 bajtu.
Kód:
__{}ifelse(eval((PUMUL_MAX<=4) || (ifelse(TYP_PUMUL,{small},1,0))),1,{dnl
__{}__{}    ex  (SP),HL         ; 1:19      pxumul
__{}__{}    dec   L             ; 1:4       pxumul
__{}__{}    ex  (SP),HL         ; 1:19      pxumul},
Tyhle 3 radky jsou bez zrychleni
Kód:
__{}{dnl
__{}__{}    ex  (SP),HL         ; 1:19      pxumul
__{}__{}    dec   L             ; 1:4       pxumul
__{}__{}    ld    A,(HL)        ; 1:7       pxumul
__{}__{}    ex  (SP),HL         ; 1:19      pxumul
__{}__{}    or    A             ; 1:4       pxumul
__{}__{}    jr   nz, PXMUL_J    ; 2:7/12    pxumul
Totozny kod navic pri zrychleni
Kód:
__{}__{}ifelse(1,0,{dnl
__{}__{}__{}    push BC             ; 1:11      pxumul
__{}__{}__{}    ld    B, C          ; 1:4       pxumul
__{}__{}__{}    ld    C, L          ; 1:4       pxumul
__{}__{}__{}    ex   AF, AF'        ; 1:4       pxumul
__{}__{}__{}    push AF             ; 1:11      pxumul
__{}__{}__{}    ld    A,(HL)        ; 1:7       pxumul
__{}__{}__{}    ex   AF, AF'        ; 1:4       pxumul
__{}__{}__{}    ld  (HL),A          ; 1:7       pxumul
__{}__{}__{}    inc   L             ; 1:4       pxumul
__{}__{}__{}    djnz $-4            ; 2:8/13    pxumul   [HL+1] = [HL]
__{}__{}__{}    pop  AF             ; 1:10      pxumul
__{}__{}__{}    ex   AF, AF'        ; 1:4       pxumul
__{}__{}__{}    ld    L, C          ; 1:4       pxumul
__{}__{}__{}    pop  BC             ; 1:10      pxumul},
O 2 bajty kratsi, ale pomale... takze se generuje to co je pod timhle i kdyz se mi nedari to lddr zinicializovat a obalit nejak efektivneji
Kód:
__{}__{}{dnl
__{}__{}__{}    push BC             ; 1:11      pxumul
__{}__{}__{}    push DE             ; 1:11      pxumul
__{}__{}__{}    dec   C             ; 1:4       pxumul
__{}__{}__{}    ld    B, 0x00       ; 2:7       pxumul
__{}__{}__{}    ld    D, H          ; 1:4       pxumul
__{}__{}__{}    ld    A, L          ; 1:4       pxumul
__{}__{}__{}    add   A, C          ; 1:4       pxumul
__{}__{}__{}    ld    E, A          ; 1:4       pxumul
__{}__{}__{}    ld    L, E          ; 1:4       pxumul
__{}__{}__{}    dec   L             ; 1:4       pxumul
__{}__{}__{}    lddr                ; 2:16/21   pxumul   [DE]-- = [HL]--
__{}__{}__{}    ex   DE, HL         ; 1:4       pxumul
__{}__{}__{}    ld  (HL),B          ; 1:7       pxumul
__{}__{}__{}    pop  DE             ; 1:10      pxumul
__{}__{}__{}    pop  BC             ; 1:10      pxumul})
__{}__{}    jr  PXMUL_N1        ; 2:12      pxumul
__{}__{}PXMUL_J:                ;           pxumul})

Cele to vypada nejak takto.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/Nova_testovaci$ ../check_word.sh 'PUMUL(20)'

    pop  BC             ; 1:10      p160u*
    ld    A, 0x14       ; 2:7       p160u*
    call PXUMUL         ; 3:17      p160u*
    push BC             ; 1:11      p160u*
;==============================================================================

; Multiplication 8..2048-bit unsigned value from pointer
; In: [BC], [DE], [HL]
;     A = sizeof(number) in bytes
; Out: [HL] = [BC] * [DE]
PXUMUL:                 ;           pxumul
    push BC             ; 1:11      pxumul
    ld    C, A          ; 1:4       pxumul   C = x bytes
    ex  (SP),HL         ; 1:19      pxumul
    add   A, L          ; 1:4       pxumul
    ld    L, A          ; 1:4       pxumul
    ex  (SP),HL         ; 1:19      pxumul   p3 += x
    ld    A, L          ; 1:4       pxumul
    add   A, C          ; 1:4       pxumul
    ld    L, A          ; 1:4       pxumul
    xor   A             ; 1:4       pxumul
    ld    B, C          ; 1:4       pxumul
    dec   L             ; 1:4       pxumul
    ld  (HL),A          ; 1:7       pxumul
    djnz $-2            ; 2:8/13    pxumul   [p1] = 0
    ld    A, C          ; 1:4       pxumul
PXMUL_L1:               ;           pxumul
    ex   AF, AF'        ; 1:4       pxumul
    ex  (SP),HL         ; 1:19      pxumul
    dec   L             ; 1:4       pxumul
    ld    A,(HL)        ; 1:7       pxumul
    ex  (SP),HL         ; 1:19      pxumul
    or    A             ; 1:4       pxumul
    jr   nz, PXMUL_J    ; 2:7/12    pxumul
    push BC             ; 1:11      pxumul
    push DE             ; 1:11      pxumul
    dec   C             ; 1:4       pxumul
    ld    B, 0x00       ; 2:7       pxumul
    ld    D, H          ; 1:4       pxumul
    ld    A, L          ; 1:4       pxumul
    add   A, C          ; 1:4       pxumul
    ld    E, A          ; 1:4       pxumul
    ld    L, E          ; 1:4       pxumul
    dec   L             ; 1:4       pxumul
    lddr                ; 2:16/21   pxumul   [DE]-- = [HL]--
    ex   DE, HL         ; 1:4       pxumul
    ld  (HL),B          ; 1:7       pxumul
    pop  DE             ; 1:10      pxumul
    pop  BC             ; 1:10      pxumul
    jr  PXMUL_N1        ; 2:12      pxumul
PXMUL_J:                ;           pxumul
    ld    B, 0x08       ; 2:7       pxumul
PXMUL_L2:               ;           pxumul
    push BC             ; 1:11      pxumul
    or    A             ; 1:4       pxumul
    ld    B, C          ; 1:4       pxumul
    ld    C, L          ; 1:4       pxumul
    rl  (HL)            ; 2:15      pxumul
    inc   L             ; 1:4       pxumul
    djnz $-3            ; 2:8/13    pxumul   result [p1] *= 2
    ld    L, C          ; 1:4       pxumul
    pop  BC             ; 1:10      pxumul
    ex  (SP),HL         ; 1:19      pxumul
    rlc (HL)            ; 2:15      pxumul   left rotation [p3] --> carry?
    ex  (SP),HL         ; 1:19      pxumul
    jr   nc, PXMUL_N2   ; 2:7/12    pxumul
    push BC             ; 1:11      pxumul
    push DE             ; 1:11      pxumul
    or    A             ; 1:4       pxumul
    ld    B, C          ; 1:4       pxumul
    ld    C, L          ; 1:4       pxumul
    ld    A,(DE)        ; 1:7       pxumul
    adc   A,(HL)        ; 1:7       pxumul
    ld  (HL),A          ; 1:7       pxumul
    inc   L             ; 1:4       pxumul
    inc   E             ; 1:4       pxumul
    djnz $-5            ; 2:8/13    pxumul
    ld    L, C          ; 1:4       pxumul
    pop  DE             ; 1:10      pxumul
    pop  BC             ; 1:10      pxumul
PXMUL_N2:               ;           pxumul
    djnz PXMUL_L2       ; 2:8/13    pxumul
PXMUL_N1:               ;           pxumul
    ex   AF, AF'        ; 1:4       pxumul
    dec   A             ; 1:4       pxumul
    jr   nz, PXMUL_L1   ; 2:7/12    pxumul
    pop  BC             ; 1:10      pxumul
    ret                 ; 1:10      pxumul
                       ;[92:598]

Muze se generovat kod jen pro jednobajtove, dvoubajtove, 256 bajtove cisla a nebo tahle univerzalni rutina.

PS: Uz se tesim ze budu psat neco lehciho. Od pulky tydne si bere jeden KP dovolenou na 10 dni. Vcetne tohoto halloweenskeho vikendu, budeme teda jen dva a ja mam odpoledni smeny. V sobotu mam byt sam, coz je silene i pro slabou sobotu, takze budu rad ze dycham a tenhle maraton programovani po asi 36 dnech prerusim.

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

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
Nebudete tomu verit, ale cely den jsem se paral jen s tim, jak napsat deleni se znamenkem. Teoreticky jsem to mel mit levou zadni, zkopirovat nejake predchozi reseni kde osetruji znamenka a volam unsigned rutinu.

Ukazalo se ale ze u pointeru je to o dost tezsi.

Prvni problem je ze mate uplne vsechny registry obsazene, vcetne A. Mysleno je tim BC,DE,HL,A,HL' a na IX a IY se nesaha.

Za druhe znamenko neziskate snadno. Musite pricist delku k offsetu. A na rozdil ode me nesmite zapomenout odecist jednicku, jinak se odkazujete pred(za) cislo. A pak zase musite offset vracet.

Za treti neresite 2 hodnoty ale uz tri hodnoty, protoze mam 3 pointery a tak musite zmenit na absolutni hodnotu i delitele A PAK TO VRACET. Nejen klasicky delence a delitele a pak nastavit spravne vysledek a zbytek.

Nakonec se mi podarilo napsat neco trosku uchazejiciho. Jak pro 1..256 bajtu tak pro 1,2 a 256 bajtovou verzi. U jednobajtove a dvoubajtove verze jsem to uz moc nehrotil, jak jsem byl unaveny a jen odmazaval a trosku optimalizoval tu univerzalni rutinu. Takze stale pouzivaji pomocnou rutinu pro negaci i kdyz se jedna o jeden (dva) bajt(y) a nepotrebuji ani zadnou smycku.

Vzhledem k tomu ze PUMUL(x) se da povazovat i za signed nasobeni tak by to uz mohlo byt komplet. Takze si uz muzete zacit hrat. Ne ze bych cekal ze to nekdo vubec vyzkousi... .)

Mala ukazka jak vypada znamenkove deleni pro 1..256, kdyz je volano beznamenkove deleni 1..32. Je tam videt, ze jsem si vypomahal dalsi rutinou "pdm_neg", bylo to pak o dost prehlednejsi a kratsi i kdyz krapet pomalejsi. Vyuzivam taky toho ze unsigned deleni saha maximalne na AF' a BC'. Takze DE' je uplne volne.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/Nova_testovaci$ ../check_word.sh 'PDIVMOD(20) PDIVMOD(32)'
 
    pop  BC             ; 1:10      p160/mod
    ld    A, 0x14       ; 2:7       p160/mod
    call PDM            ; 3:17      p160/mod
    push BC             ; 1:11      p160/mod
    pop  BC             ; 1:10      p256/mod
    ld    A, 0x20       ; 2:7       p256/mod
    call PDM            ; 3:17      p256/mod
    push BC             ; 1:11      p256/mod
;==============================================================================

; Divide 8..2048-bit signed values from pointer
; In: [BC], [DE], [HL]
;     A = sizeof(number) in bytes
; Out: [HL] = [DE] / [BC], [DE] = [DE] % [BC]
PDM:                    ;           pdm
    push BC             ; 1:11      pdm
    exx                 ; 1:4       pdm
    ex  (SP),HL         ; 1:19      pdm   save R.A.S. && [HL'] = divisor
    ld    E, A          ; 1:4       pdm   sizeof(number) in bytes

    ld    B, L          ; 1:4       pdm   save offset
    add   A, L          ; 1:4       pdm
    dec   A             ; 1:4       pdm
    ld    L, A          ; 1:4       pdm
    xor   A             ; 1:4       pdm
    or  (HL)            ; 1:7       pdm
    ld    D, A          ; 1:4       pdm   divisor sign
    call  m, PDM_NEG1   ; 3:17      pdm
    exx                 ; 1:4       pdm   abs([BC])
                        ;           pdm
    push DE             ; 1:11      pdm
    exx                 ; 1:4       pdm
    pop  HL             ; 1:10      pdm   [HL'] = dividend
    ld    B, L          ; 1:4       pdm   save offset
    ld    A, E          ; 1:4       pdm
    add   A, L          ; 1:4       pdm
    dec   A             ; 1:4       pdm
    ld    L, A          ; 1:4       pdm
    ld    A,(HL)        ; 1:7       pdm
    xor   D             ; 1:4       pdm
    push AF             ; 1:11      pdm   the sign of the result
    xor   D             ; 1:4       pdm
    push AF             ; 1:11      pdm   remainder sign
    call  m, PDM_NEG1   ; 3:17      pdm
    ld    A, E          ; 1:4       pdm   A = sizeof(number) in bytes
    exx                 ; 1:4       pdm   abs([DE])
                        ;           pdm
    call P256UDM        ; 3:17      pdm
                        ;           pdm
    push DE             ; 1:11      pdm
    exx                 ; 1:4       pdm
    pop  HL             ; 1:10      pdm   [HL'] = remainder
    pop  AF             ; 1:10      pdm   remainder sign
    call  m, PDM_NEG2   ; 3:17      pdm
    exx                 ; 1:4       pdm
                        ;           pdm
    pop  AF             ; 1:10      pdm   the sign of the result
    jp    p, $+10       ; 3:10      pdm
    push HL             ; 1:11      pdm
    exx                 ; 1:4       pdm
    pop  HL             ; 1:10      pdm   [HL'] = result
    call PDM_NEG2       ; 3:17      pdm
    exx                 ; 1:4       pdm
                        ;           pdm
    push BC             ; 1:11      pdm
    exx                 ; 1:4       pdm
    pop  HL             ; 1:10      pdm   [HL'] = divisor
    xor   A             ; 1:4       pdm
    or    D             ; 1:4       pdm   divisor sign
    call  m, PDM_NEG2   ; 3:17      pdm
    pop  HL             ; 1:10      pdm   load R.A.S.
    exx                 ; 1:4       pdm
                        ;           pdm
    ret                 ; 1:10      pdm
PDM_NEG1:               ;           pdm_neg
    ld    L, B          ; 1:4       pdm_neg   load offset
PDM_NEG2:               ;           pdm_neg
    ld    B, E          ; 1:4       pdm_neg
    ld    C, 0x00       ; 2:7       pdm_neg
    ld    A, C          ; 1:4       pdm_neg
    sbc   A,(HL)        ; 1:7       pdm_neg
    ld  (HL),A          ; 1:7       pdm_neg
    inc   L             ; 1:4       pdm_neg
    djnz $-4            ; 2:8/13    pdm_neg
    ret                 ; 1:10      pdm_neg
; Divide 8..256-bit unsigned value from pointer
; In: [BC], [DE], [HL]
;     A = sizeof(number) in bytes
; Out: [HL] = [DE] / [BC], [DE] = [DE] % [BC]
P256UDM:                ;           p256udm
    push BC             ; 1:11      p256udm
    ld    C, A          ; 1:4       p256udm   C = x bytes

    xor   A             ; 1:4       p256udm
    exx                 ; 1:4       p256udm
    ld    B, A          ; 1:4       p256udm   B' = shift_counter = 0
    exx                 ; 1:4       p256udm

    ld    B, C          ; 1:4       p256udm
    ld  (HL),A          ; 1:7       p256udm
    inc   L             ; 1:4       p256udm   px_res = 0
    djnz $-2            ; 2:8/13    p256udm
    ex   AF, AF'        ; 1:4       p256udm
    ld    A, L          ; 1:4       p256udm
    sub   C             ; 1:4       p256udm
    ld    L, A          ; 1:4       p256udm   return to original value

    ex  (SP),HL         ; 1:19      p256udm

    ld    A, L          ; 1:4       p256udm   A' = original value L
    ex   AF, AF'        ; 1:4       p256udm

    ld    B, C          ; 1:4       p256udm
    or  (HL)            ; 1:7       p256udm
    inc   L             ; 1:4       p256udm
    djnz $-2            ; 2:8/13    p256udm   px_3 == 0?

    or    A             ; 1:4       p256udm
    jr    z, P256UDM_E  ; 2:7/12    p256udm   exit with div 0

    ex   AF, AF'        ; 1:4       p256udm
    ld    L, A          ; 1:4       p256udm   return to original value
    ex   AF, AF'        ; 1:4       p256udm
    ld    B, C          ; 1:4       p256udm
    exx                 ; 1:4       p256udm
    inc   B             ; 1:4       p256udm   shift_counter++
    exx                 ; 1:4       p256udm

    rl  (HL)            ; 2:15      p256udm
    inc   L             ; 1:4       p256udm
    djnz $-3            ; 2:8/13    p256udm   px_3 *= 2

    jr   nc, $-12       ; 2:7/12    p256udm   px_3 overflow?

P256UDM_L:              ;           p256udm
    ld    B, C          ; 1:4       p256udm   L = orig L + $1
    dec   L             ; 1:4       p256udm
    rr  (HL)            ; 2:15      p256udm
    djnz $-3            ; 2:8/13    p256udm   px_3 >>= 1

    ex  (SP),HL         ; 1:19      p256udm
    ld    A, L          ; 1:4       p256udm
    ld    B, C          ; 1:4       p256udm
    rl  (HL)            ; 2:15      p256udm
    inc   L             ; 1:4       p256udm
    djnz $-3            ; 2:8/13    p256udm   result *= 2
    ld    L, A          ; 1:4       p256udm   return to original value
    ex  (SP),HL         ; 1:19      p256udm

    push  DE            ; 1:11      p256udm
    ld    B, C          ; 1:4       p256udm
    ld    A,(DE)        ; 1:7       p256udm
    sbc   A,(HL)        ; 1:7       p256udm
    inc   L             ; 1:4       p256udm
    inc   E             ; 1:4       p256udm
    djnz $-4            ; 2:8/13    p256udm   (px_mod < px_3)?
    pop  DE             ; 1:10      p256udm

    jr    c, P256UDM_N  ; 2:7/12    p256udm

    ex  (SP),HL         ; 1:19      p256udm
    inc (HL)            ; 1:11      p256udm   result += 1
    ex  (SP),HL         ; 1:19      p256udm

    push DE             ; 1:11      p256udm
    ex   AF, AF'        ; 1:4       p256udm
    ld    L, A          ; 1:4       p256udm   return to original value
    ex   AF, AF'        ; 1:4       p256udm
    ld    B, C          ; 1:4       p256udm
    ld    A,(DE)        ; 1:7       p256udm
    sbc   A,(HL)        ; 1:7       p256udm
    ld  (DE),A          ; 1:7       p256udm
    inc   L             ; 1:4       p256udm
    inc   E             ; 1:4       p256udm
    djnz $-5            ; 2:8/13    p256udm   px_mod -= px_3
    pop  DE             ; 1:10      p256udm
P256UDM_N:              ;           p256udm
    or    A             ; 1:4       p256udm
    exx                 ; 1:4       p256udm
    dec   B             ; 1:4       p256udm
    exx                 ; 1:4       p256udm
    jr   nz, P256UDM_L  ; 2:7/12    p256udm

P256UDM_E:              ;           p256udm
    ex   AF, AF'        ; 1:4       p256udm
    ld    L, A          ; 1:4       p256udm   return to original value
    ex  (SP),HL         ; 1:19      p256udm
    pop  BC             ; 1:10      p256udm
    ret                 ; 1:10      p256udm
                       ;[185:1111]

_________________
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.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 slovo P1SUB. Protoze me chybelo do paru. Uz jsem to resil asi pred tydnem, nebo dvema pro PD1SUB.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'P1SUB(1)'

    dec (HL)            ; 1:11      p8 1-   ( p8 -- p8 )  [p8] -= 1  with align 1
                       ;[ 1:11]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'P1SUB(2)'

    ld    A, 0xFF       ; 2:7       p16 1-   ( p16 -- p16 )  [p16] -= 1  with align 2
    add   A,(HL)        ; 1:7       p16 1-
    ld  (HL),A          ; 1:7       p16 1-
    jr    c, $+5        ; 2:7/12    p16 1-
    inc   L             ; 1:4       p16 1-
    dec (HL)            ; 1:11      p16 1-
    dec   L             ; 1:4       p16 1-
                       ;[ 9:47]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'P1SUB(3)'

    ld    A, 0xFF       ; 2:7       p24 1-   ( p24 -- p24 )  [p24] -= 1  with align 3
    add   A,(HL)        ; 1:7       p24 1-
    ld  (HL),A          ; 1:7       p24 1-
    jr    c, $+11       ; 2:7/12    p24 1-
    inc   L             ; 1:4       p24 1-
    add   A,(HL)        ; 1:7       p24 1-
    ld  (HL),A          ; 1:7       p24 1-
    jr    c, $+5        ; 2:7/12    p24 1-
    inc   L             ; 1:4       p24 1-
    inc (HL)            ; 1:11      p24 1-
    dec   L             ; 1:4       p24 1-
    dec   L             ; 1:4       p24 1-
                       ;[15:76]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'P1SUB(4)'

                 ;[20:33,66,91,101] p32 1-   ( p32 -- p32 )  [p32] -= 1  with align 4
    ld    A, 0xFF       ; 2:7       p32 1-
    add   A,(HL)        ; 1:7       p32 1-
    ld  (HL),A          ; 1:7       p32 1-
    jr    c, $+16       ; 2:7/12    p32 1-
    ld    C, L          ; 1:4       p32 1-
    inc   L             ; 1:4       p32 1-
    add   A,(HL)        ; 1:7       p32 1-
    ld  (HL),A          ; 1:7       p32 1-
    jr    c, $+9        ; 2:7/12    p32 1-
    inc   L             ; 1:4       p32 1-
    add   A,(HL)        ; 1:7       p32 1-
    ld  (HL),A          ; 1:7       p32 1-
    jr    c, $+4        ; 2:7/12    p32 1-
    inc   L             ; 1:4       p32 1-
    dec (HL)            ; 1:11      p32 1-
    ld    L, C          ; 1:4       p32 1-
                       ;[20:101]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'P1SUB(5)'

    ld    C, L          ; 1:4       p40 1-   ( p40 -- p40 )  [p40] -= 1  with align 5
    ld    B, 0x05       ; 2:7       p40 1-
    ld    A, 0xFF       ; 2:7       p40 1-
    add   A,(HL)        ; 1:7       p40 1-
    ld  (HL),A          ; 1:7       p40 1-
    jr    c, $+4        ; 2:7/12    p40 1-
    djnz $-4            ; 2:8/13    p40 1-
    ld    L, C          ; 1:4       p40 1-
                       ;[12:51]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'P1SUB(256)'

    ld    A, 0xFF       ; 2:7       p2048 1-   ( p2048 -- p2048 )  [p2048] -= 1  with align 256
    add   A,(HL)        ; 1:7       p2048 1-
    ld  (HL),A          ; 1:7       p2048 1-
    jr    c, $+5        ; 2:7/12    p2048 1-
    inc   L             ; 1:4       p2048 1-
    jr   nz, $-5        ; 2:7/12    p2048 1-
    ld    L, 0x00       ; 2:7       p2048 1-
                       ;[11:46]

Pro P1SUB(2) by mohla existovat verze o takt pomalejsi a bajt mensi.

_________________
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.10.2022, 09:21 
Offline
Profík

Registrován: 26.11.2018, 16:59
Příspěvky: 580
Bydliště: Holešov
Has thanked: 13 times
Been thanked: 90 times
moc pěkné, jen teď přemýšlím nad využitelností, jen zobrazení takovéhohle 256 bajtpvého čísla bude horor (dlouho trvat). je vůbec k něčemu mít tak velké integery?
Bude toto využitelné na FP aritmetiku? Možná ano, čísla by se ukládaly násobené třeba násobené miliardou a pak s tím pracovat jako s integerem a bude to na 9 desetinných míst (jen příklad)

Máš vůbec představu / nápad jak budeš pracovat s FP číslama nebo toto vůbec nebudeš řešit?


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

Registrován: 23.06.2013, 23:49
Příspěvky: 1100
Has thanked: 100 times
Been thanked: 157 times
l00k píše:
moc pěkné, jen teď přemýšlím nad využitelností, jen zobrazení takovéhohle 256 bajtpvého čísla bude horor (dlouho trvat). je vůbec k něčemu mít tak velké integery?
Bude toto využitelné na FP aritmetiku? Možná ano, čísla by se ukládaly násobené třeba násobené miliardou a pak s tím pracovat jako s integerem a bude to na 9 desetinných míst (jen příklad)

Máš vůbec představu / nápad jak budeš pracovat s FP číslama nebo toto vůbec nebudeš řešit?


Pro prakticky vypis tech dlouhych integru je ta hex rutina. Kdyz uz je tam to deleni tak by to slo pomalu i decimalne. Dalsi zpusob je to proste prevest pro vypis do kalkulacky spectra a zavolat na to rom rutinu.
Ta rychlost je fakt mala, ale neni to zamysleno pro realtime, spis pro nejaky velmi presny vypocet. Ono se to nezda, ale delal jsem geodeta a nektere vypocty proste musis delat trochu s rozmyslem, zda nekde neztracis presnost. A podle konkretniho vstupu volit treba jiny algoritmus/vypocet. Zvlast u goniometrickych funkci. Kdyz nevis co delas tak ti ani dvojita presnost nekdy nepomuze. V praxi to stejne vypada tak, ze uz to nekdo udelal a ty jen pouzivas nejaky specializovany software, takze to pak zvladne i cvicena opice a uz pri mereni musis dodrzet nejake postupy a normy a mas napr. presne dane jake rozsahy uhlu musis mit kdyz neco meris.
Teoreticka vyuzitelnost tech dlouhych integru tedy je, ne vsechno chce velkou presnost a zaroven je to vypocetne narocny na rychlost. A jak rikam je to jen teoreticka vyuzitelnost, to je tak asi vse... je to jen dalsi zarez na pazbe. .)

Floating point tam uz je udelana. Dokonce dvoji.
Jedna je EXTREMNE rychla implementace "D. A. Nagy" formatu se spoustou predpocitanych tabulek. Tzn 1 bit pro sign 7 bitu pro Exponent a 8 bitu pro Mantisu.
https://github.com/DW0RKiN/Floating-point-Library-for-Z80 v podstate jsem obalil jen tuhle knihovnu do Forth volani.

Druha implementace je ohackovani volani rutin ZX Spectra. Takze pouziva i jeho zasobnik.

256 bajtu je 2048 bitu.
ZX Spectrum ma floating point 31 bitu mantisy a exponent to posouva cca +-128 bitu. To je rozsah 128..-159 se znamenkem by to melo jit emulovat 288 bitovym fixed point aritmetikou/integerem (=36 bajtu). Aspon myslim... S tim rozdilem ze ten fixed point format zvladne pricitat i dve cisla ktera jsou od sebe posunuta o vice jak 31 bitu v mantise. To normalni floating format nezvladne, pokud teda nepouziva nejaky specialni algoritmus s vypoctem pravdepodobnosti. Neco ve smyslu ze kdyz pricitas velmi male cislo k velkemu a to male cislo je presne bit pod mantisou toho velkeho. Takze mimo rozsah, tak se k tomu budes chovat jako k pricteni carry s 50% sanci. Tu pravdepodobnost zmensujes podle toho o kolik je to mensi. Ale neznam zadnou knihovnu co by tohle delala.
V podstate kdyz pricitas v nekonecne smycce 1 tak nikdy nepreteces, ale zastavis se nekde u 0xFFFFFFFF pokud nepouzijes tu pravdepodobnost. Proc o tom vubec mluvim...

Do pousteni se do floating point aritmetiky s promenlivou mantisou jako parametrem se me fakt nechce poustet. Ty 3 floating point formaty z odkazu jsem predtim delal tak jeden rok...

_________________
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.10.2022, 13:16 
Offline
Profík

Registrován: 26.11.2018, 16:59
Příspěvky: 580
Bydliště: Holešov
Has thanked: 13 times
Been thanked: 90 times
nemyslel jsem proměnlivou mantisu, ale využít víc než 5 bajtů co má spectrum (ty 2 bajtové FP jen jsou na extrémní rychlost), a mít větší přesnost, když integery děláš s možností až tak velké.
Třeba něco jako 1 bajt znaménko čísla, 1 bajt znaménko exponentu, 2 bajty exponent (16 bitů), a třeba 28 bajtů mantisy (32 bajtů celkem)

ale klidně můžu fp číslo vynásobit trilionem nebo triliardou a budu mít 12, resp.15 desetinných míst jen posuvem a pak s tím počítat jako s integerem


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 ... 20, 21, 22, 23, 24, 25, 26 ... 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:  
cron
Založeno na phpBB® Forum Software © phpBB Group
Český překlad – phpBB.cz