OldComp.cz

Komunitní diskuzní fórum pro fanoušky historických počítačů
Právě je 05.10.2024, 10:30

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




Odeslat nové téma Odpovědět na téma  [ Příspěvků: 696 ]  Přejít na stránku Předchozí  1 ... 43, 44, 45, 46, 47
Autor Zpráva
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 01.10.2024, 18:43 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1335
Has thanked: 102 times
Been thanked: 195 times
Dival jsem se co me asi jeste z bignum slov chybi a nasel jsem jen to ze nemam nic pro prevod TXT->BIGNUM.
Tohle by slo sesmilit i z toho co uz je k dispozici, ale asi to stoji za to doplnit.
Opacny prevod... asi nacitat zleva a mezivysledky vzdy predtim vynasobit 10.
Nasobit 10... to je jako 2*(2*2+1).

Chtel jsem vedet zda bych dokazal napsat, respektive zda je mozne udelat bitovy posun doleva s prictenim k puvodni hodnotu na bignum, aniz by se delala pomocna kopie celeho cisla.

Zacal jsem delat nejsnazsi variantu, posun o 1 a pricteni. Nakonec jsem nazev zamenil za _3PMUL, ktery to uplne nevystihuje ale je spravny.
Pro tu 10 budu potrebovat _5PMUL.

Odpoved na otazku zni, ze 2x+x jde udelat lokalne nad bajty pro bignum. Pokud jsem nekde neudelal chybu v uvaze a nehromadi se me tam nekde nejaka hodnota, ktera pretece (nemela by).

smycka vypada idealne nejak takto...

Mam 8 bitovy registr kde mam preteceni z prechoziho vypoctu bajtu * 3. Takova alternativa carry. Nemelo by to pretikat a byt stale asi 0..3?

Nacteny bajt co nasobim 3.

Nejak to vynasobim 3 a prictu k tomu nakonec ten alternativni carry.

Ulozim spodni bajt vysledku.

Presunu horni bajt do alternativniho carry.

Zvednu index nacitaneho bajtu.

Opakuji dokud to neprojde celym bignumem.

V praxi se dost rychle narazi na to ze...

potrebuji jeden 16 bitovy registr pro indexovani bignumu

poptrebuji HL pro nasobeni dvema... a vysledek (je to 16 bitove) a jeste to mit nekde ulozene bokem pro pricteni jednou.

Potrebuji B pro pocitadlo smycky...

Takze uz ted me chybi registry.

Takze cast z toho kde me to pretika pouzivam 8 bitove pricitani a podmineny skok kdyz to pretika/nepretika.

Takze ten kod vypada dost osklive.

Netestovano:
Kód:
dworkin@dw-A15:~/repositories/M4_FORTH/M4$ ../check_word.sh '_3PMUL(8)'
.error dodelat!
    push HL             ; 1:11      1 p64lshift   ( p64 -- p64 )  aligned [p64] *= 3
    push DE             ; 1:11      1 p64lshift   hmm zapomnel jsem udelat ex de, hl, protoze potrebuji TOS v de
    ld    B, 0x08       ; 2:7       1 p64lshift
    ld    C, 0x00       ; 2:7       1 p64lshift   hmm tohle se da spojit do ld BC, 256*8
    ld    A,[DE]        ; 1:7       1 p64lshift
    ld    L, A          ; 1:4       1 p64lshift
    ld    H, 0x00       ; 2:7       1 p64lshift
    add  HL, HL         ; 1:11      1 p64lshift   2x
    add   A, L          ; 1:4       1 p64lshift   3x
    jr   nc, $+3        ; 2:7/12    1 p64lshift
    inc   H             ; 1:4       1 p64lshift
    add   A, C          ; 1:4       1 p64lshift
    jr   nc, $+3        ; 2:7/12    1 p64lshift
    inc   H             ; 1:4       1 p64lshift
    ld  [DE],A          ; 1:7       1 p64lshift
    ld    C, H          ; 1:4       1 p64lshift
    inc   E             ; 1:4       1 p64lshift   index++
    djnz $-16           ; 2:8/13    1 p64lshift
    pop  DE             ; 1:10      1 p64lshift
    pop  HL             ; 1:10      1 p64lshift
; seconds: 0           ;[26:138]


Dokonce si nejsem jisty zda neni delsi nez to rozdelit na copy bignum, 2x a pak secist.

A uz varianta pro 16 bitu je dost silena.
Kód:
dworkin@dw-A15:~/repositories/M4_FORTH/M4$ ../check_word.sh '_3PMUL(2)'
    push DE             ; 1:11      1 p16lshift  ( p16 -- p16 )  aligned [p16] *= 3
    ld    E,[HL]        ; 1:7       1 p16lshift
    ld    C, E          ; 1:4       1 p16lshift
    inc   L             ; 1:4       1 p16lshift
    ld    D,[HL]        ; 1:7       1 p16lshift
    ld    B, D          ; 1:4       1 p16lshift
    ex   DE, HL         ; 1:4       1 p16lshift
    add  HL, HL         ; 1:11      1 p16lshift
    add  HL, BC         ; 1:11      1 p16lshift
    ex   DE, HL         ; 1:4       1 p16lshift
    ld  [HL],D          ; 1:7       1 p16lshift
    dec   L             ; 1:4       1 p16lshift
    ld  [HL],E          ; 1:7       1 p16lshift
    pop  DE             ; 1:10      1 p16lshift
; seconds: 0           ;[14:95]


PS: To obecne reseni by asi slo napsat kdyz se to "nasobi" jen trema jako trojity soucet... takze predchozi carry by si drzelo samotne A.
Kód:
dworkin@dw-A15:~/repositories/M4_FORTH/M4$ ../check_word.sh '_3PMUL(8)'
.error dodelat!
    push HL             ; 1:11      1 p64lshift   ( p64 -- p64 )  aligned [p64] *= 3
    ld   BC, 0x08       ; 3:10      1 p64lshift
    xor   A             ; 1:4       1 p64lshift
    add   A,[HL]        ; 1:7       1 p64lshift
    rl    C             ; 2:8       1 p64lshift   C  = carry
    add   A,[HL]        ; 1:7       1 p64lshift
    jr   nc, $+3        ; 2:7/12    1 p64lshift
    inc   C             ; 1:4       1 p64lshift   C += carry
    add   A,[HL]        ; 1:7       1 p64lshift
    ld  [HL],A          ; 1:7       1 p64lshift
    ld    A, C          ; 1:4       1 p64lshift
    ld    C, 0x00       ; 2:7       1 p64lshift
    adc   A, C          ; 1:4       1 p64lshift   A += carry
    inc   L             ; 1:4       1 p64lshift   index++
    djnz $-14           ; 2:8/13    1 p64lshift
    pop  HL             ; 1:10      1 p64lshift
; seconds: 0           ;[22:109]


PPS: Predelaval jsem 16 bitovou variantu na jine reseni a doslo me... ze mohu vyhodit jednu instrukci v me univrzalni metode. Nepotrebuji pricitat nulu abych ziskal carry do A. Stejne budu priste neco k A pricitat... takze me staci zmenit add na adc!

Kód:
dworkin@dw-A15:~/repositories/M4_FORTH/M4$ ../check_word.sh '_3PMUL(2)'
    ld   BC, 0x0000     ; 3:10      3p16mul  ( p16 -- p16 )  aligned [p16] *= 3
    ld    A,[HL]        ; 1:7       3p16mul
    add   A, A          ; 1:4       3p16mul   2x lo
    rl    C             ; 2:8       3p16mul   C  = carry = 0..1
    add  A,[HL]         ; 1:7       3p16mul   3x lo
    ld [HL],A           ; 1:7       3p16mul
    inc   L             ; 1:4       3p16mul
    ld    A, C          ; 1:4       3p16mul   0..1
    adc   A,[HL]        ; 1:7       3p16mul
    add   A,[HL]        ; 1:7       3p16mul
    add   A,[HL]        ; 1:7       3p16mul
    ld  [HL],A          ; 1:7       3p16mul
    dec   L             ; 1:4       3p16mul
; seconds: 0           ;[16:83]
dworkin@dw-A15:~/repositories/M4_FORTH/M4$ ../check_word.sh '_3PMUL(8)'
    push HL             ; 1:11      3p64mul   ( p64 -- p64 )  aligned [p64] *= 3
    ld   BC, 0x08       ; 3:10      3p64mul   C+carry = overflow
    xor   A             ; 1:4       3p64mul
    adc   A,[HL]        ; 1:7       3p64mul   0..2 + 0..1 + [HL]
    rl    C             ; 2:8       3p64mul   C  = carry = 0..1
    add   A,[HL]        ; 1:7       3p64mul   0..3 + 2*[HL]
    jr   nc, $+3        ; 2:7/12    3p64mul
    inc   C             ; 1:4       3p64mul   C += carry = 0..2
    add   A,[HL]        ; 1:7       3p64mul   0..3 + 3*[HL]
    ld  [HL],A          ; 1:7       3p64mul
    ld    A, C          ; 1:4       3p64mul   A = 0..2
    ld    C, 0x00       ; 2:7       3p64mul
    inc   L             ; 1:4       3p64mul   index++
    djnz $-13           ; 2:8/13    3p64mul
    pop  HL             ; 1:10      3p64mul
; seconds: 0           ;[21:105]

hm.. kdybych to chtel urychlit tak bych misto toho podmineneho skoku mohl delat jedno RL C (s tim ze se to nacte do nejnizsiho a z nejvysiho vypadne predchozi)
Pak druhe RL C.

a sude kroky smycek by mely RR C a pak zase RR C.

Takze by vypadlo
Kód:
    jr   nc, $+3        ; 2:7/12    3p64mul
    inc   C             ; 1:4       3p64mul   C += carry = 0..2


a

Kód:
    ld    A, C          ; 1:4       3p64mul   A = 0..2
    ld    C, 0x00       ; 2:7       3p64mul


za jedno RR/RL C navic a ld A,0.

_________________
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: 02.10.2024, 15:20 
Offline
Óm Nejvyšší

Registrován: 22.05.2013, 21:14
Příspěvky: 3829
Bydliště: Bratislava
Has thanked: 375 times
Been thanked: 811 times
_dworkin píše:
A uz varianta pro 16 bitu je dost silena.
Tu som asi nie celkom uplne pochopil. Ako funguje ?
Napriklad mas tam za sebou ADD HL,HL a potom ADD HL,BC, kde v HL mas 16 bitov z cisla. Tym padom ale stratis pretecenie z prveho ADD lebo druhe ADD ti ho zmaze a rutinka nemoze fungovat spravne.

Inak, len cisto pre zaujimavost, aku rutinku pouzivas na prevod TXT => 16bit cislo ? Napriklad MRS (z roku 1986) pouziva takuto rutinku:
Kód:
   dcbn   - konverzia  retazca  decimalnych  cislic  na  16-bitovu   binarnu
            hodnotu
            vstup:  <hl> = adresa retazca
            vystup: <hl> = adresa konca retazca  (retazec  konci  lubovolnym
            symbolom mimo cislic 0-9.
                    <de> = konvertovana binarna hodnota
                    <a>  = ukoncovaci znak
            meni sa:  <af>, <de>, <hl>

dcbn:   ld      de,0
        ld      a,(hl)
        cp      #3a
        ret     nc
        sub     #30
        ret     c
        ex      de,hl
        push    bc
        add     hl,hl
        ld      b,h
        ld      c,l
        add     hl,hl
        add     hl,hl
        add     hl,bc
        ld      c,a
        ld      b,0
        add     hl,bc
        pop     bc
        ex      de,hl
        inc     hl
        jr      dcbn+3


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

Registrován: 23.06.2013, 23:49
Příspěvky: 1335
Has thanked: 102 times
Been thanked: 195 times
Preteceni mimo rozsah prece nevadi. Nevadi to ani pro zaporna cisla. Pokud ma byt "bignum" 16 bitove tak 16 bitove zustane.

Ptas se me jakou rutinu pouzivam na prevod TXT->BIGNUM kdyz jsem psal ze presne tohle je neco co asi stoji za to dodelat do slov a kvuli tomu resim ze nasobeni 10 se da rozepsat jako 2*(2*2+1), takze je to duvod zjistit zda jde udelat bitovy posun s prictenim puvodni hodnoty v bignum jako serii kroku, kde se cte jeden bajt za druhym, bez toho ze bych delal kopii toho bignum bokem.

Ve zkratce... nemam TXT->BIGNUM?
??? --> ??? --> ??? --> ???
Aha takze zacnu resit nasobeni trema... .)

Proste jsem si nebyl jisty zda tam neco nepretika. Ale zbytecne jsem se bal, nakonec je to jednoducha zalezitost kdy si to muzes predstavit misto

x = (x << 1) + x

jako

x *= 3
x = x + x + x + prechozi_preteceni

3*255 = 10 1111 1101

a kdybych pricetl predchozi carry tak je max 10 1111 1111 (= maximalni preteceni zustava konstantni)

A tohle plati i pro nasobeni 5.

5*255 = 100 1111 1011

K te rutine se snazim teprve dopracovat. Presneji cilem je ted _10MUL. A to je vic jak posun a pricteni. Jen to vlastne nemusi vadit, pokud nebudu mit nedostatek registru az by to bylo neefektivni delat v jednom kroku najednou.

Delam jen navrhy rutin pro _3PMUL a zrovna ted pro _5MUL.
A ani jsem je netestoval.
Kód:
dworkin@dw-A15:~/repositories/M4_FORTH/M4$ ../check_word.sh '_5PMUL(1)'
    ld   A,[HL]         ; 1:7       5p8mul   ( p8 -- p8 )  aligned [p8] *= 5
    add  A, A           ; 1:4       5p8mul   2x
    add  A, A           ; 1:4       5p8mul   4x
    add  A,[HL]         ; 1:7       5p8mul   5x
    ld [HL],A           ; 1:7       5p8mul
; seconds: 1           ;[ 5:29]
dworkin@dw-A15:~/repositories/M4_FORTH/M4$ ../check_word.sh '_5PMUL(2)'
    push DE             ; 1:11      5p16mul   ( p16 -- p16 )  aligned [p16] *= 5
    ld    E,[HL]        ; 1:7       5p16mul
    ld    C, E          ; 1:4       5p16mul
    inc   L             ; 1:4       5p16mul
    ld    D,[HL]        ; 1:7       5p16mul
    ld    B, D          ; 1:4       5p16mul
    ex   DE, HL         ; 1:4       5p16mul
    add  HL, HL         ; 1:11      5p16mul   2x
    add  HL, HL         ; 1:11      5p16mul   4x
    add  HL, BC         ; 1:11      5p16mul   5x
    ex   DE, HL         ; 1:4       5p16mul
    ld  [HL],D          ; 1:7       5p16mul
    dec   L             ; 1:4       5p16mul
    ld  [HL],E          ; 1:7       5p16mul
    pop  DE             ; 1:10      5p16mul
; seconds: 1           ;[15:106]
dworkin@dw-A15:~/repositories/M4_FORTH/M4$ ../check_word.sh '_5PMUL(3)'
    push DE             ; 1:11      5p24mul   ( p24 -- p24 )  aligned [p24] *= 5
    ld    E,[HL]        ; 1:7       5p24mul
    ld    C, E          ; 1:4       5p24mul
    inc   L             ; 1:4       5p24mul
    ld    D,[HL]        ; 1:7       5p24mul
    ld    B, D          ; 1:4       5p24mul
    inc   L             ; 1:4       5p24mul
    ld    A,[HL]        ; 1:7       5p24mul
    ex   DE, HL         ; 1:4       5p24mul
    add  HL, HL         ; 1:11      5p24mul
    adc   A, A          ; 1:4       5p24mul   2x
    add  HL, HL         ; 1:11      5p24mul
    adc   A, A          ; 1:4       5p24mul   4x
    add  HL, BC         ; 1:11      5p24mul
    adc   A,[HL]        ; 1:7       5p24mul   5x
    ex   DE, HL         ; 1:4       5p24mul
    ld  [HL],A          ; 1:7       5p24mul
    dec   L             ; 1:4       5p24mul
    ld  [HL],D          ; 1:7       5p24mul
    dec   L             ; 1:4       5p24mul
    ld  [HL],E          ; 1:7       5p24mul
    pop  DE             ; 1:10      5p24mul
; seconds: 0           ;[22:143]
dworkin@dw-A15:~/repositories/M4_FORTH/M4$ ../check_word.sh '_5PMUL(4)'
    push HL             ; 1:11      5p32mul   ( p32 -- p32 )  aligned [p32] *= 5
    push DE             ; 1:11      5p32mul
    ld   BC, 0x0400     ; 3:10      5p32mul   C = 0
    ld    D, C          ; 1:4       5p32mul
    ld    A,[HL]        ; 1:7       5p32mul   1x
    add   A, A          ; 1:4       5p32mul   2x
    ld    E, C          ; 1:4       5p32mul   E = 0
    rl    E             ; 2:8       5p32mul   E  = carry = 0..1
    add   A, A          ; 1:4       5p32mul   4x
    rl    E             ; 2:8       5p32mul   E  = carry = 0..3
    add   A,[HL]        ; 1:7       5p32mul   5x
    jr   nc, $+3        ; 2:7/12    5p32mul
    inc   E             ; 1:4       5p32mul   E  = carry = 0..4
    add   A, D          ; 1:4       5p32mul   + previous carry
    ld  [HL],A          ; 1:7       5p32mul
    ld    A, E          ; 1:4       5p32mul
    adc   A, C          ; 1:4       5p32mul   + carry
    ld    D, A          ; 1:4       5p32mul   D = carry = 0..5
    inc   L             ; 1:4       5p32mul   index++
    djnz $-18           ; 2:8/13    5p32mul
    pop  DE             ; 1:10      5p32mul
    pop  HL             ; 1:10      5p32mul
; seconds: 0           ;[28:144]


Takze me spoilerujes hotove reseni :D
Coz me asi usetri praci.

PS: Aha ukazujes pouze variantu pro 16 bit a ja se snazim to mit 8..8*256 bit (pravdepodobne to nebude inline jako tyhle subrutiny, ale kdo vi... zda to vubec nekdy bude) a to jeste kdyz to lezi v pameti a ty si budes drzet jen pointer na retezec a pointer na bignum.
Jak jsem rekl, reseni jeste nemam. Pokud bych to ted nesesmolil rovnou pomoci FORTH slov, protoze moznosti na to uz ted existuji. Jen to nebude tak odladene jako asm.

PPS: A ani to nevypada po rychlem skrolovani ze bych mel USTRING nebo ISTRING prevod do UINT nebo INT. On je to pro FORTH totiz nesmysl, tohle resi parser. I kdyz mam pocit ze jsem cisla od uzivatele uz nekde nacital, jen nevim zda i viceciferne a zda jsem to resil ctenim po znaku nebo to bylo jedno slovo... Chamurabi by to mel mit!
Kód:
: input ( a_message len_message -- u )
    type cr
    begin
      s\"           " ( -- astr ulen )
      over swap       ( astr ulen -- astr astr ulen )
      accept          ( astr astr ulen -- astr uload )
      s>number?       ( astr uload -- d bool )
      .\"   \20\0\n"
    0= while          ( d bool -- d )
        2drop         ( d -- )
        .\" \20\3[Please re-enter a valid number.]\n"
    repeat
    d>s               ( d -- s )
;


a preklada me to jako STR_TO_DNUM
Kód:
dworkin@dw-A15:~/repositories/M4_FORTH/M4$ ../check_word.sh 'STR_TO_DNUM'
    call STR2D          ; 3:17      str>dnum   ( a1_str ulen1 -- d a2_str ulen2 )
;#==============================================================================
;# Ignores all initial characters with a value less than '-', including '+' and commas.
;# An even number of '-' characters are converted to '+'
;# Number stored as a string to an signed 16-bit number.
;# It also returns the unused rest of the string.
;# ( ret a1_str ulen1 -- d2 a2_str ulen2 )
;#  s" 87654321+123"        str>d (  87654321 s"+123" )
;#  s" 0000087654321+123"   str>d (  87654321 s"+123" )
;#  s"   87654321+123"      str>d (  87654321 s"+123" )
;#  s"   0000087654321+123" str>d (  87654321 s"+123" )
;#  s" , 87654321+123"      str>d (  87654321 s"+123" )
;#  s" , 0000087654321+123" str>d (  87654321 s"+123" )
;#  s" ++87654321+123"      str>d (  87654321 s"+123" )
;#  s" ++0000087654321+123" str>d (  87654321 s"+123" )
;#  s" --87654321+123"      str>d (  87654321 s"+123" )
;#  s" --0000087654321+123" str>d (  87654321 s"+123" )
;#  s" -87654321+123"       str>d ( -87654321 s"+123" )
;#  s" -0000087654321+123"  str>d ( -87654321 s"+123" )
;#  In: [SP] = ret,  DE = a1_str, HL = ulen1
;# Out: [SP] = x,    DE = a2_str, HL = ulen2
STR2DNEG:               ;           str>d
    push BC             ; 1:11      str>d
    push BC             ; 1:11      str>d
    call STR2UD         ; 3:17      str>d  ( ret 0. a1_str ulen1 -- ret ud a2_str ulen2 )
    exx                 ; 1:4       str>d  negate_32
    pop  BC             ; 1:10      str>d  negate_32 BC = lo16
    xor   A             ; 1:4       str>d  negate_32
    sub   C             ; 1:4       str>d  negate_32
    ld    C, A          ; 1:4       str>d  negate_32
    ld    A, 0x00       ; 2:7       str>d  negate_32
    sbc   A, B          ; 1:4       str>d  negate_32
    ld    B, A          ; 1:4       str>d  negate_32
    pop  DE             ; 1:10      str>d  negate_32 DE = hi16
    ld    A, 0x00       ; 2:7       str>d  negate_32
    sbc   A, E          ; 1:4       str>d  negate_32
    ld    E, A          ; 1:4       str>d  negate_32
    sbc   A, D          ; 1:4       str>d  negate_32
    sub   E             ; 1:4       str>d  negate_32
    ld    D, A          ; 1:4       str>d  negate_32
    pop  AF             ; 1:10      str>d  negate_32 ret
    push DE             ; 1:11      str>d  negate_32 -hi16
    push BC             ; 1:11      str>d  negate_32 -lo16
    push AF             ; 1:11      str>d  negate_32 ret
    exx                 ; 1:4       str>d  negate_32
    ret                 ; 1:10      str>d
STR2D:                  ;           str>d  ( x1 ret a1_str ulen1 )
    ld   BC, 0x0000     ; 3:10      str>d
    jr  STR2D3          ; 2:12      str>d
STR2D1:                 ;           str>d
    inc   C             ; 1:4       str>d  invert zero bit
STR2D2:                 ;           str>d
    inc  DE             ; 1:6       str>d  str++
    dec  HL             ; 1:6       str>d  ulen
STR2D3:                 ;           str>d
    ld    A, L          ; 1:4       str>d
    or    H             ; 1:4       str>d
    jr    z, STR2D4     ; 2:7/12    str>d
    ld    A,[DE]        ; 1:7       str>d
    cp   '-'            ; 2:7       str>d
    jr    z, STR2D1     ; 2:7/12    str>d
    jr    c, STR2D2     ; 2:7/12    str>d
STR2D4:                 ;           str>d
    rr    C             ; 2:8       str>d
    ld    C, B          ; 1:4       str>d
    jr    c, STR2DNEG   ; 2:7/12    str>d
    pop  AF             ; 1:10      str>d  ret
    push BC             ; 1:11      str>d
    push BC             ; 1:11      str>d
    push AF             ; 1:11      str>d  ( 0. ret a1_str ulen1 )
    ;... fall to str>ud
;#==============================================================================
;# Adds a number stored as a string to an unsigned 32-bit number.
;# It also returns the unused rest of the string.
;# ( ud1 ret a1_str ulen1 -- ud2 a2_str ulen2 )
;#  12345. s" 67890+123"      >number ( 1234567890. s"+123" )
;#      0. s" 1234567890+123" >number ( 1234567890. s"+123" )
;#  In: [SP+4] = hi16, [SP+2] = lo16, [SP] = ret,  DE = a1_str, HL = ulen1
;# Out:                [SP+2] = hi16, [SP] = lo16, DE = a2_str, HL = ulen2
STR2UD:                 ;           str>ud
    pop  BC             ; 1:10      str>ud  ret
    exx                 ; 1:4       str>ud
    pop  DE             ; 1:10      str>ud  lo16
    ex  [SP],HL         ; 1:19      str>ud  hi16, [SP] = R.A.S.
    ex   DE, HL         ; 1:4       str>ud  HL = lo16, DE = hi16
    exx                 ; 1:4       str>ud
    jr   STR2UD2        ; 2:7/12    str>ud
STR2UD1:                ;           str>ud
    inc  DE             ; 1:6       str>ud  str++
    dec  HL             ; 1:6       str>ud  ulen--
    exx                 ; 1:4       str>ud
    add  HL, HL         ; 1:11      str>ud
    rl    E             ; 2:8       str>ud
    rl    D             ; 2:8       str>ud  2x
    ld    C, L          ; 1:4       str>ud
    ld    B, H          ; 1:4       str>ud
    push DE             ; 1:11      str>ud
    add  HL, HL         ; 1:11      str>ud
    rl    E             ; 2:8       str>ud
    rl    D             ; 2:8       str>ud  4x
    add  HL, HL         ; 1:11      str>ud
    rl    E             ; 2:8       str>ud
    rl    D             ; 2:8       str>ud  8x
    add  HL, BC         ; 1:11      str>ud
    pop  BC             ; 1:10      str>ud
    ex   DE, HL         ; 1:4       str>ud
    adc  HL, BC         ; 2:15      str>ud  10x
    ex   DE, HL         ; 1:4       str>ud
    add   A, L          ; 1:4       str>ud  If L contains the value
    ld    L, A          ; 1:4       str>ud   25-->250,  51-->254,  76-->248, 102-->252,
    jr   nc, $+6        ; 2:7/12    str>ud  153-->250, 179-->254, 204-->248, 230-->252
    inc   H             ; 1:4       str>ud  so there is a risk that it could exceed 255
    jr   nz, $+3        ; 2:7/12    str>ud   6553*10-->0xfffa,13107*10-->0xfffe,19660*10-->0xfff8,26214*10-->0xfffc,
    inc  DE             ; 1:6       str>ud  39321*10-->0xfffa,45875*10-->0xfffe,52428*10-->0xfff8,58982*10-->0xfffc
    exx                 ; 1:4       str>ud
STR2UD2:                ;           str>ud
    ld    A, L          ; 1:4       str>ud
    or    H             ; 1:4       str>ud
    jr    z, STR2UD3    ; 2:7/12    str>ud
    ld    A,[DE]        ; 1:7       str>ud
    sub  '0'            ; 2:7       str>ud
    cp   10             ; 2:7       str>ud
    jr    c, STR2UD1    ; 2:7/12    str>ud
STR2UD3:                ;           str>ud
    exx                 ; 1:4       str>ud
    ex   DE, HL         ; 1:4       str>ud  HL = hi16, DE = lo16
    ex  [SP],HL         ; 1:19      str>ud  HL = R.A.S., [SP] = hi16
    push DE             ; 1:11      str>ud  lo16
    exx                 ; 1:4       str>ud
    push BC             ; 1:11      str>ud  ret
    ret                 ; 1:10      str>ud
; seconds: 1           ;[121:694]

A kdyz existuje DNUM tak bude existovat i STR_TO_NUM
Kód:
dworkin@dw-A15:~/repositories/M4_FORTH/M4$ ../check_word.sh 'STR_TO_NUM'
    call STR2S          ; 3:17      str>num   ( a1_str ulen1 -- x a2_str ulen2 )
;#==============================================================================
;# Ignores all initial characters with a value less than '-', including '+' and commas.
;# An even number of '-' characters are converted to '+'
;# Number stored as a string to an signed 16-bit number.
;# It also returns the unused rest of the string.
;# ( ret a1_str ulen1 -- x2 a2_str ulen2 )
;#  s" 4321+123"        str>s (  4321 s"+123" )
;#  s" 000004321+123"   str>s (  4321 s"+123" )
;#  s"   4321+123"      str>s (  4321 s"+123" )
;#  s"   000004321+123" str>s (  4321 s"+123" )
;#  s" , 4321+123"      str>s (  4321 s"+123" )
;#  s" , 000004321+123" str>s (  4321 s"+123" )
;#  s" ++4321+123"      str>s (  4321 s"+123" )
;#  s" ++000004321+123" str>s (  4321 s"+123" )
;#  s" --4321+123"      str>s (  4321 s"+123" )
;#  s" --000004321+123" str>s (  4321 s"+123" )
;#  s" -4321+123"       str>s ( -4321 s"+123" )
;#  s" -000004321+123"  str>s ( -4321 s"+123" )
;#  In: [SP] = ret,  DE = a1_str, HL = ulen1
;# Out: [SP] = x,    DE = a2_str, HL = ulen2
STR2SNEG:               ;           str>s
    push BC             ; 1:11      str>s
    call STR2U          ; 3:17      str>s  ( ret 0 a1_str ulen1 -- ret u a2_str ulen2 )
    pop  BC             ; 1:10      str>s
    xor   A             ; 1:4       str>s  negate
    sub   C             ; 1:4       str>s  negate
    ld    C, A          ; 1:4       str>s  negate
    sbc   A, B          ; 1:4       str>s  negate
    sub   C             ; 1:4       str>s  negate
    ld    B, A          ; 1:4       str>s  negate
    pop  AF             ; 1:10      str>s  ret
    push  BC            ; 1:11      str>s
    push  AF            ; 1:11      str>s ( -u ret a2_str ulen2 )
    ret                 ; 1:10      str>s
STR2S:                  ;           str>s  ( x1 ret a1_str ulen1 )
    ld   BC, 0x0000     ; 3:10      str>s
    jr  STR2S3          ; 2:12      str>s
STR2S1:                 ;           str>s
    inc   C             ; 1:4       str>s  invert zero bit
STR2S2:                 ;           str>s
    inc  DE             ; 1:6       str>s  str++
    dec  HL             ; 1:6       str>s  ulen
STR2S3:                 ;           str>s
    ld    A, L          ; 1:4       str>s
    or    H             ; 1:4       str>s
    jr    z, STR2S4     ; 2:7/12    str>s
    ld    A,[DE]        ; 1:7       str>s
    cp   '-'            ; 2:7       str>s
    jr    z, STR2S1     ; 2:7/12    str>s
    jr    c, STR2S2     ; 2:7/12    str>s
STR2S4:                 ;           str>s
    rr    C             ; 2:8       str>s
    ld    C, B          ; 1:4       str>s
    jr    c, STR2SNEG   ; 2:7/12    str>s
    pop  AF             ; 1:10      str>s  ret
    push BC             ; 1:11      str>s
    push AF             ; 1:11      str>s
    ;... fall to str>u
;#==============================================================================
;# Adds a number stored as a string to an unsigned 16-bit number.
;# It also returns the unused rest of the string.
;# ( u1 ret a1_str ulen1 -- u2 a2_str ulen2 )
;#  54 s" 321+123"   rot s>d 2swap >number 2swap d>s -rot ( 54321 s"+123" )
;#   0 s" 54321+123" rot s>d 2swap >number 2swap d>s -rot ( 54321 s"+123" )
;#  In: [SP+2] = u1, [SP] = ret,  DE = a1_str, HL = ulen1
;# Out:              [SP] = u2,   DE = a2_str, HL = ulen2
STR2U:                  ;           str>u  ( u1 ret a1_str ulen1 )
    pop  BC             ; 1:10      str>u  ret
    exx                 ; 1:4       str>u
    ex  [SP],HL         ; 1:19      str>u  u1
    exx                 ; 1:4       str>u
    jr   STR2U2         ; 2:7/12    str>u
STR2U1:                 ;           str>u
    inc  DE             ; 1:6       str>u  str++
    dec  HL             ; 1:6       str>u  ulen
    exx                 ; 1:4       str>u
    add  HL, HL         ; 1:11      str>u  2x
    ld    C, L          ; 1:4       str>u
    ld    B, H          ; 1:4       str>u  BC = 2x
    add  HL, HL         ; 1:11      str>u  4x
    add  HL, HL         ; 1:11      str>u  8x
    add  HL, BC         ; 1:11      str>u  10x
    add   A, L          ; 1:4       str>u  If L contains the value
    ld    L, A          ; 1:4       str>u  25-->250, 51-->254, 76-->248, 102-->252,
    jr   nc, $+3        ; 2:7/12    str>u  153-->250, 179-->254, 204-->248, 230-->252,
    inc   H             ; 1:4       str>u  so there is a risk that it could exceed 255
    exx                 ; 1:4       str>u
STR2U2:                 ;           str>u
    ld    A, L          ; 1:4       str>u
    or    H             ; 1:4       str>u
    jr    z, STR2U3     ; 2:7/12    str>u
    ld    A,[DE]        ; 1:7       str>u
    sub  '0'            ; 2:7       str>u
    cp   10             ; 2:7       str>u
    jr    c, STR2U1     ; 2:7/12    str>u
STR2U3:                 ;           str>u  ( ret a2_str u2 )  BC = ulen2
    exx                 ; 1:4       str>u
    ex  [SP],HL         ; 1:19      str>u  u2
    exx                 ; 1:4       str>u
    push BC             ; 1:10      str>u  ret
    ret                 ; 1:10      str>u
; seconds: 0           ;[82:478]


Takze je to rozdelene na dve pomocne rutiny, jedna co prevadi signed na unsigned a druha co nasobi mezivysledek 10 a pricita desitkovou cifru. A ta druha je ekvivalent toho co si ukazoval ty.

_________________
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: 02.10.2024, 17:19 
Offline
Óm Nejvyšší

Registrován: 22.05.2013, 21:14
Příspěvky: 3829
Bydliště: Bratislava
Has thanked: 375 times
Been thanked: 811 times
_dworkin píše:
Preteceni mimo rozsah prece nevadi. Nevadi to ani pro zaporna cisla. Pokud ma byt "bignum" 16 bitove tak 16 bitove zustane.
Ptas se me jakou rutinu pouzivam na prevod TXT->BIGNUM ...
Aha, pravdepodobne asi (zase) doslo k informacnemu sumu.

Predpokladal som ze pod pojmom BIGNUM myslis cisla takej velkosti, ktora sa uz neda spracovat cela naraz v registroch a musis ich spracovavat ako retazec cislic a bajtov hodnoty ulozeny v pameti.
Naproti tomu 8,16 a dokonca aj 32 bitove hodnoty za BIGNUM nepovazujem, pretoze tie sa daju zvladnut "cele naraz" v registroch.

Rutinku pre nacitanie 16bit hodnoty som poslal, 32bit hodnota sa este v pohode da poriesit podobnou filozofiou.
Niekedy zaciatkom 90-tych rokov som napisal aj rutinku na nacitanie BIGNUM cisla neobmedzenej velkosti, ale teraz pozeram ze je nejaka dlha a pomala, ze by sa dala napisat uplne inak a lepsie.
V kazdom pripade, som zvedavy k comu doiterujes a mozeme to potom porovnat :)


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 03.10.2024, 13:18 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1335
Has thanked: 102 times
Been thanked: 195 times
; z rov n a te d mam vlhkos t v k l a v e snic i t akze si musim dat nedobrovolne pauzu

_________________
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: 03.10.2024, 14:02 
Offline
Óm Nejvyšší

Registrován: 22.05.2013, 21:14
Příspěvky: 3829
Bydliště: Bratislava
Has thanked: 375 times
Been thanked: 811 times
Ja som medzitym trosku popracoval na tej mojej rutinke na prevod retazca cislic na hodnotu a zatial mam taketo vysledky:

- Dlzka rutinky 51 bajtov
- Vsetky pointre plne 16-bitove
- Nepotrebuje ziadne dalsie buffre v pameti
- Na vystupe vrati v BC pocet bajtov vyslednej binarnej hodnoty
- Neobmedzena dlzka retazca cislic a neobmedzena bitova sirka vyslednej binarnej hodnoty
- Retazec 323170...30656 (dokopy 618 cislic) zodpovedajuci hodnote 2^2048 spracuje za 2.88 sekundy

Tak drzim palce tvojej klavesnici aby bola zase co najskor sucha a dalo sa na nej pisat :)


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ů: 696 ]  Přejít na stránku Předchozí  1 ... 43, 44, 45, 46, 47

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


Kdo je online

Uživatelé procházející toto fórum: Žádní registrovaní uživatelé a 2 návštevníků


Nemůžete zakládat nová témata v tomto fóru
Nemůžete odpovídat v tomto fóru
Nemůžete upravovat své příspěvky v tomto fóru
Nemůžete mazat své příspěvky v tomto fóru
Nemůžete přikládat soubory v tomto fóru

Hledat:
Přejít na:  
cron
Založeno na phpBB® Forum Software © phpBB Group
Český překlad – phpBB.cz