Názory k článku Zobrazení čísel a zpracování příznaků mikroprocesoru Zilog Z80

  • Článek je starý, nové názory již nelze přidávat.
  • 4. 4. 2023 2:19

    _dw

    Na tisk 16 bitoveho cisla se da pouzit i rom cast pro kalkulacku. Pokud se nepletu tak stejne si to v basicu uklada jako real.

    ZX Spectrum floating-point format:
        EEEE EEEE SMMM MMMM MMMM MMMM MMMM MMMM MMMM MMMM
             exp,  sign + m,        m,        m,        m
    
    ZX Spectrum integer format:
        0000 0000 SSSS SSSS LLLL LLLL HHHH HHHH 0000 0000
                0, 8x dup S,       lo,       hi,        0

    Takze staci integer spravne nacpat na vrchol kalkulacky a zavolat rutinu pro tisk.

    V M4 Forthu kdyz to chci tisknou pres rom to pak vypada takto (v rutine je navic na konci nejaka prace, aby se cislo odstranilo z TOS (HL) a nacetlo se do nej NOS (DE)).

    dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(1234) DOTZXROM'
        push DE             ; 1:11      1234
        ex   DE, HL         ; 1:4       1234
        ld   HL, 1234       ; 3:10      1234
        call ZXPRT_S16      ; 3:17      .zxrom   ( x -- )
    ;------------------------------------------------------------------------------
    ; Input: HL
    ; Output: Print signed decimal number in HL
    ; Pollutes: AF, BC, HL <- DE, DE <- (SP)
    ZXPRT_S16:              ;           zxprt_s16   ( x -- )
        push DE             ; 1:11      zxprt_s16
        ld    A, H          ; 1:4       zxprt_s16
        add   A, A          ; 1:4       zxprt_s16
        sbc   A, A          ; 1:4       zxprt_s16   sign
        ld    E, A          ; 1:4       zxprt_s16   2. byte sign
        xor   A             ; 1:4       zxprt_s16   1. byte = 0
        ld    D, L          ; 1:4       zxprt_s16   3. byte lo
        ld    C, H          ; 1:4       zxprt_s16   4. byte hi
        ld    B, A          ; 1:4       zxprt_s16   5. byte = 0
    
        ld   IY, 0x5C3A     ; 4:14      zxprt_s16   Re-initialise IY to ERR-NR.
    
        call 0x2AB6         ; 3:17      zxprt_s16   call ZX ROM STK store routine
        call 0x2DE3         ; 3:17      zxprt_s16   call ZX ROM print a floating-point number routine
        pop  HL             ; 1:10      zxprt_s16
        pop  BC             ; 1:10      zxprt_s16   load ret
        pop  DE             ; 1:10      zxprt_s16
        push BC             ; 1:11      zxprt_s16   save ret
        ret                 ; 1:10      zxprt_u16
    ; seconds: 0           ;[32:184]

    Stale je to kratsi nez psat vlastni rutinu.

    Pokud by to byl unsigned integer tak je to jeste kratsi

    dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(1234) UDOTZXROM'
        push DE             ; 1:11      1234
        ex   DE, HL         ; 1:4       1234
        ld   HL, 1234       ; 3:10      1234
        call ZXPRT_U16      ; 3:17      u.zxrom   ( u -- )
    ;------------------------------------------------------------------------------
    ; Input: HL
    ; Output: Print unsigned decimal number in HL
    ; Pollutes: AF, BC, HL <- DE, DE <- (SP)
    ZXPRT_U16:              ;           zxprt_u16   ( u -- )
        push DE             ; 1:11      zxprt_u16
        ld    B, H          ; 1:4       zxprt_u16
        ld    C, L          ; 1:4       zxprt_u16
        call 0x2D2B         ; 3:17      zxprt_u16   call ZX ROM stack BC routine
        call 0x2DE3         ; 3:17      zxprt_u16   call ZX ROM print a floating-point number routine
    
        pop  HL             ; 1:10      zxprt_u16
        pop  BC             ; 1:10      zxprt_u16   load ret
        pop  DE             ; 1:10      zxprt_u16
        push BC             ; 1:11      zxprt_u16   save ret
        ret                 ; 1:10      zxprt_u16
    ; seconds: 0           ;[22:146]
  • 4. 4. 2023 8:12

    atarist

    I po těch letech, kdy jsem na osmibitech dělal, mě vždycky znovu překvapí, jak jsou ty programy a podprogramy krátké. Třeba ten tisk čísla vypadá, že je v ROM refaktorován tak, že jeho části se používají i jinde.

    Jasně, ROM ZX Spectra (ale ani ROM Atárka atd.) toho neumí z dnešního pohledu moc, ale tehdy to na mnoho věcí stačílo (BASIC byl takovej shell) a mělo to doslova pár kilobajtů.

  • 4. 4. 2023 12:07

    Pavel Šrubař

    Před třiceti lety jsem si dal práci s nalezením všech vzájemných odkazů mezi rutinami v ZX Spectru.
    Tak například podprogram OUT-NUM-1 #1A1B je z jiných míst ROM volán celkem třikrát - z adres #1354, #135F, #2F88. Třeba se to některým infoarcheologům bude hodit: https://vitsoft.info/zxref.htm.

  • 5. 4. 2023 9:42

    Adam Přibyl

    Programovani na ZX v Z80 asm me vzdycky neuveritelne bavilo - ta efektivita kodu, moznost pouzivat kusy otimalizovaneho kodu z ROM i obchazeni obcasnych nedokonalosti jak CPU tak ROM.. nebo co lidi dokazali nacpat to tech 1k demo programu prave i za pouziti kusu kodu z ROM...

  • 5. 4. 2023 18:47

    Pavel Šrubař

    A nejlepší na tom bylo, že člověk přesně věděl jak dlouho každá instrukce trvá, takže se dalo dopředu spočítat časování kritických úloh, jako třeba zápis a čtení dat z magnetofonu, vysílání a příjem morseovky nebo ovládání sériového portu.

  • 5. 4. 2023 18:11

    Oscar_Romero

    On se tenhle procesor ještě někam montuje nebo je tenhle článek potřebný asi jako servisní manuál pro Pragu RND? Snažil jsem se nějaké zařízení najít, ale...

  • 5. 4. 2023 19:32

    atarist

    Tyjo já jakožto "konkurenční" Atarista vím minimálně o Z80 v TIčkách, EZ80 a o mikrořadicích Rabbit. Obě to jsou výkonná MCUčka (ale zase ne nějaké M0/M1). Nechci sem dávat komerční odkazy, ale snad stránky Zilogu a Rabbitu (Digi) najdeš :-)

  • 6. 4. 2023 8:23

    atarist

    jo není. Ale zase Z80 žije, na rozdíl od 6502. Tam tedy vznikla šestnáctibitová varianta s přepínačem do režimu kompatibility, ale to už není ono a ani se to IMHO už dneska nepoužívá. Kdežto Z80 kupodivu stále jo.

  • 6. 4. 2023 16:24

    Josef Pavlik

    Kdyz se tady mluvi o zajimavych algoritmech pro Z80, tak taky prispeju se svou troskou do mlyna. Tohle je muj algoritmus pro deleni. Deli se HL / C, vysledek je v HL, zbytek je v A. To jsem jednou na kolejich slysel, jak se dva kolegove bavi o rutine na deleni. Ze je to komplikovane. Poslal jsem je nekam, rikal jsem, ze se to musi vejit do 10 bajtu. Neverili. Tak jsem sedl ke compu a napsal jsem tohle:

    ; unsigned division hl/c -> hl, hl%c -> a
    div_hl_c:
        ld  b,0x10
    l1:
        add hl,hl
        rla
        jr  c, l2
        cp  c
        jr  c, l3
    l2:
        sub c
        inc l
    l3:
        djnz    l1
        ret

    No dobre, neni to 10 bajtu, je to 14, ale je to mene, nez 10 hexadecimalne :-).
    Snad je to dobre, vytahl jsem to ze 20 let stareho mailu, kde jsem to nekomu posilal s poznamkou, ze je to 15 let, co jsem tento algoritmus naposledy pouzil :-).
    Tato rutina je jednoduse pouzitelna i pro prevod cisel do ascii. Staci naplnit C=10 a volat tuto rutinu opakovane, dokud v HL neni nula. Po kazdem zavolani staci pricist 0x30 k A a zobrazit. Cislo ovsem vyleze opacne - napred jednotky, pak desitky a tak dale. S tim je potreba pocitat. Samozrejme to funguje jenom pro unsigned 16 bitova cisla.

  • 6. 4. 2023 19:19

    _dw

    Me to stale prijde slozite, je to jako hrat sachy a myslet si ze pozice je snadna a prijit o kralovnu.

    Vyzkousej si dat do A treba 0xFF nebo 0x01 a delit 30336/127. Vidis to na prvni pohled? Ja teda ne.

    I kdyz ten algoritmus muze byt jednoduchy (pujdes po tehle vyslapane cesticce v minovme poli) stale pochopit proc jdes tudy muze byt slozite (i snadne zaroven).

    A pravdepodobne pujde spis o rychlost a to se pak teprve zacne komplikovat... Protoze pro kratky kod staci pouhe odecitani, a kdyz vidis jak je to kratke tak si reknes: jeee 8 bajtu super, nez zjistit ze se to jen odecita a pak jen: argh.. to nechci.

    Div_HL_DE:
    ;Inputs:
    ;   HL / DE
    ;Outputs:
    ;   A is the quotient (HL/DE)
    ;   HL is the remainder
        xor a
        dec a
    _loop:
        inc a
        sbc hl,de
        jr nc,_loop
        add hl,de

    Mozna spis 10 bajtu, kdyz to zmenime na

    Div_HL_DE:
    ;Inputs:
    ;   HL / DE
    ;Outputs:
    ;   A is the quotient (HL/DE)
    ;   HL is the remainder
        xor a
        ld  bc,-1
    _loop:
        inc bc
        sbc hl,de
        jr nc,_loop
        add hl,de

    6. 4. 2023, 19:24 editováno autorem komentáře

  • 6. 4. 2023 19:39

    atarist

    neni to pres bitovy posuny a sub nasobne rychlejsi? Aspon na MOSu to nakonec nebyl nejak dlouhej algoritmus, pokud si pamatuju a pokud se jednalo o unsigned (ale stejne se tomu vsichni vyhybali, ono to deleni zas tak casto potreba neni).

  • 6. 4. 2023 20:11

    _dw

    Ano, cokoliv co neni proste odecitani je prakticky lepsi. Ta metoda co ma smycku opakujici se 16x ma konstantni rychlost a je jen o par bajtu delsi nez pouhe odecitani. Odecitani bude rychlejsi jen pro nejmensi vysledky.

    Vlastne jsem se nezminil, ze existuji varianty kdy delenec je kladny. To dokaze usnadnit/zkra­tit/zrychlit kod, kdyz mas jistotu ze nejvyssi bit bude nula. Da se to pouzit kdyz delite znamenkove a pred volanim deleni si to upravite na absolutni hodnoty.

  • 6. 4. 2023 20:29

    _dw

    Odectani ale pouzivam u vypisu cisla v desitkove soustave. Je to kratke, a pro kazdy rad se to provede ne vic jak 10x+1. Opakovane deleni pro kazdy rad by bylo zavisle na te metode deleni (slozitejsi smycka 16x) a navic i delsi.

    dworkin@dw-A15:~/Programovani/ZX/Forth/Pasmo_test$ ../check_word.sh 'UDOT'
        call PRT_U16        ; 3:17      u.   ( u -- )
    ;------------------------------------------------------------------------------
    ; Input: HL
    ; Output: Print unsigned decimal number in HL
    ; Pollutes: AF, BC, HL <- DE, DE <- (SP)
    PRT_U16:                ;           prt_u16
        xor   A             ; 1:4       prt_u16   HL=103 & A=0 => 103, HL = 103 & A='0' => 00103
        ld   BC, -10000     ; 3:10      prt_u16
        call BIN16_DEC      ; 3:17      prt_u16
        ld   BC, -1000      ; 3:10      prt_u16
        call BIN16_DEC      ; 3:17      prt_u16
        ld   BC, -100       ; 3:10      prt_u16
        call BIN16_DEC      ; 3:17      prt_u16
        ld    C, -10        ; 2:7       prt_u16
        call BIN16_DEC      ; 3:17      prt_u16
        ld    A, L          ; 1:4       prt_u16
        pop  HL             ; 1:10      prt_u16   load ret
        ex  (SP),HL         ; 1:19      prt_u16
        ex   DE, HL         ; 1:4       prt_u16
        jr   BIN16_DEC_CHAR ; 2:12      prt_u16
    ;------------------------------------------------------------------------------
    ; Input: A = 0 or A = '0' = 0x30 = 48, HL, IX, BC, DE
    ; Output: if ((HL/(-BC) > 0) || (A >= '0')) print number -HL/BC
    ; Pollutes: AF, HL
        inc   A             ; 1:4       bin16_dec
    BIN16_DEC:              ;           bin16_dec
        add  HL, BC         ; 1:11      bin16_dec
        jr    c, $-2        ; 2:7/12    bin16_dec
        sbc  HL, BC         ; 2:15      bin16_dec
        or    A             ; 1:4       bin16_dec
        ret   z             ; 1:5/11    bin16_dec   does not print leading zeros
    BIN16_DEC_CHAR:         ;           bin16_dec
        or   '0'            ; 2:7       bin16_dec   1..9 --> '1'..'9', unchanged '0'..'9'
        rst   0x10          ; 1:11      bin16_dec   putchar(reg A) with ZX 48K ROM
        ld    A, '0'        ; 2:7       bin16_dec   reset A to '0'
        ret                 ; 1:10      bin16_dec
    ; seconds: 0           ;[47:256]
  • 6. 4. 2023 19:47

    _dw

    Jinak u toho deleni vidim dve zakladni cesty. Podle toho na jakou stranu budes posouvat registrovy par. Jedna dela kratkou a rychlu smycku, ale musis to udelat pokazde 16x (mluvim o 16 bitove deleni). Druhy zpusob se musi inicializovat a ma slozitejsi kod, a je dokonce pomalejsi pro deleni nahodnych cisel, ale dokaze ukoncit vypocet drive, takze pro deleni kde vysledek nema tolik bitu je to rychlejsi.

    Pokud pises prekladac a nemas tuseni na co se to bude pouzivat (nemas zadny vzorek co tam poleze) tak si muzes fakt vybrat... .) Tak napises vic verzi a, ktera se vlozi do runtime zavisi na parametru.

    Pokud ti jde o rychlost tak oba zpusoby se navic daji napsat o to sloziteji.

    dworkin@dw-A15:~/Programovani/ZX/Forth/Pasmo_test$ ../check_word.sh 'UDIV'
        call UDIVIDE        ; 3:17      u/
        pop  DE             ; 1:10      u/
    ;==============================================================================
    ; Divide 16-bit unsigned values (with 16-bit result)
    ; In: DE / HL
    ; Out: HL = DE / HL, DE = DE % HL
    UDIVIDE:
                            ;[51:cca 900] # default version can be changed with "define({TYPDIV},{name})", name=old_fast,old,fast,small,synthesis
                            ; /3 --> cca 1551, /5 --> cca 1466, 7/ --> cca 1414, /15 --> cca 1290, /17 --> cca 1262, /31 --> cca 1172, /51 --> cca 1098, /63 --> cca 1058, /85 --> cca 1014, /255 --> cca 834
        ld    A, H          ; 1:4
        or    L             ; 1:4       HL = DE / HL
        ret   z             ; 1:5/11    HL = DE / 0?
    
        ld   BC, 0x0000     ; 3:10
    if 0
    UDIVIDE_LE:
        inc   B             ; 1:4       B++
        add  HL, HL         ; 1:11
        jr    c, UDIVIDE_GT ; 2:7/12
        ld    A, H          ; 1:4
        sub   D             ; 1:4
        jp    c, UDIVIDE_LE ; 3:10
        jp   nz, UDIVIDE_GT ; 3:10
        ld    A, E          ; 1:4
        sub   L             ; 1:4
    else
        ld    A, D          ; 1:4
    UDIVIDE_LE:
        inc   B             ; 1:4       B++
        add  HL, HL         ; 1:11
        jr    c, UDIVIDE_GT ; 2:7/12
        cp    H             ; 1:4
    endif
        jp   nc, UDIVIDE_LE ; 3:10
        or    A             ; 1:4       HL > DE
    
    UDIVIDE_GT:             ;
        ex   DE, HL         ; 1:4       HL = HL / DE
        ld    A, C          ; 1:4       CA = 0x0000 = result
    UDIVIDE_LOOP:
        rr    D             ; 2:8
        rr    E             ; 2:8       DE >> 1
        sbc  HL, DE         ; 2:15
        jr   nc, $+3        ; 2:7/12
        add  HL, DE         ; 1:11      back
        ccf                 ; 1:4       inverts carry flag
        adc   A, A          ; 1:4
        rl    C             ; 2:8
        djnz UDIVIDE_LOOP   ; 2:8/13    B--
    
        ex   DE, HL         ; 1:4
        ld    L, A          ; 1:4
        ld    H, C          ; 1:4
        ret                 ; 1:10
    ; seconds: 0           ;[55:255]
    dworkin@dw-A15:~/Programovani/ZX/Forth/Pasmo_test$ ../check_word.sh 'define({TYPDIV},small) UDIV'
        call UDIVIDE        ; 3:17      u/
        pop  DE             ; 1:10      u/
    ;==============================================================================
    ; Divide 16-bit unsigned values (with 16-bit result)
    ; In: DE / HL
    ; Out: HL = DE / HL, DE = DE % HL
    UDIVIDE:
        ld    A, H          ; 1:4       small version
        or    L             ; 1:4       HL = DE / HL
        ret   z             ; 1:5/11    HL = DE / 0
        ld   BC, 0x0000     ; 3:10
        ld    A, D          ; 1:4
    UDIVIDE_LE:
        inc   B             ; 1:4       B++
        add  HL, HL         ; 1:11
        jr    c, UDIVIDE_GT ; 2:7/12
        cp    H             ; 1:4
        jp   nc, UDIVIDE_LE ; 3:10
        or    A             ; 1:4       HL > DE
    UDIVIDE_GT:             ;
        ex   DE, HL         ; 1:4       HL = HL / DE
        ld    A, C          ; 1:4       CA = 0x0000 = result
    UDIVIDE_LOOP:
        rr    D             ; 2:8
        rr    E             ; 2:8       DE >> 1
        sbc  HL, DE         ; 2:15
        jr   nc, $+3        ; 2:7/12
        add  HL, DE         ; 1:11      back
        ccf                 ; 1:4       inverts carry flag
        adc   A, A          ; 1:4
        rl    C             ; 2:8
        djnz UDIVIDE_LOOP   ; 2:8/13    B--
    
        ex   DE, HL         ; 1:4
        ld    L, A          ; 1:4
        ld    H, C          ; 1:4
        ret                 ; 1:10
    ; seconds: 0           ;[41:197]

    A ted to prijde, snadnost deleni

    dworkin@dw-A15:~/Programovani/ZX/Forth/Pasmo_test$ ../check_word.sh 'define({TYPDIV},fast) UDIV'
        call UDIVIDE        ; 3:17      u/
        pop  DE             ; 1:10      u/
    ;==============================================================================
    ; Divide 16-bit unsigned values (with 16-bit result)
    ; In: DE / HL
    ; Out: HL = DE / HL, DE = DE % HL
    UDIVIDE:
        ld    A, H          ; 1:4       fast version
        or    L             ; 1:4       HL = DE / HL
        ret   z             ; 1:5/11    HL = DE / 0
        ld   BC, 0x00FF     ; 3:10
    if 1
        ld    A, D          ; 1:4
    UDIVIDE_LE:
        inc   B             ; 1:4       B++
        add  HL, HL         ; 1:11
        jr    c, UDIVIDE_GT ; 2:7/12
        cp    H             ; 1:4
        jp   nc, UDIVIDE_LE ; 3:10
        or    A             ; 1:4       HL > DE
    else
    UDIVIDE_LE:
        inc   B             ; 1:4       B++
        add  HL, HL         ; 1:11
        jr    c, UDIVIDE_GT ; 2:7/12
        ld    A, H          ; 1:4
        sub   D             ; 1:4
        jp    c, UDIVIDE_LE ; 3:10
        jp   nz, UDIVIDE_GT ; 3:10
        ld    A, E          ; 1:4
        sub   L             ; 1:4
        jp   nc, UDIVIDE_LE ; 3:10
        or    A             ; 1:4       HL > DE
    endif
    UDIVIDE_GT:             ;
        ex   DE, HL         ; 1:4       HL = HL / DE
        ld    A, C          ; 1:4       CA = 0xFFFF = inverted result
    ;1
        rr    D             ; 2:8
        rr    E             ; 2:8       DE >> 1
        sbc  HL, DE         ; 2:15
        jr   nc, $+3        ; 2:7/12
        add  HL, DE         ; 1:11      back
        adc   A, A          ; 1:4
        dec   B             ; 1:4       B--
        jr    z, UDIVIDE_END; 2:7/12
    ;2
        srl   D             ; 2:8
        rr    E             ; 2:8       DE >> 1
        sbc  HL, DE         ; 2:15
        jr   nc, $+3        ; 2:7/12
        add  HL, DE         ; 1:11      back
        adc   A, A          ; 1:4
        dec   B             ; 1:4       B--
        jr    z, UDIVIDE_END; 2:7/12
    ;3
        srl   D             ; 2:8
        rr    E             ; 2:8       DE >> 1
        sbc  HL, DE         ; 2:15
        jr   nc, $+3        ; 2:7/12
        add  HL, DE         ; 1:11      back
        adc   A, A          ; 1:4
        dec   B             ; 1:4       B--
        jr    z, UDIVIDE_END; 2:7/12
    ;4
        srl   D             ; 2:8
        rr    E             ; 2:8       DE >> 1
        sbc  HL, DE         ; 2:15
        jr   nc, $+3        ; 2:7/12
        add  HL, DE         ; 1:11      back
        adc   A, A          ; 1:4
        dec   B             ; 1:4       B--
        jr    z, UDIVIDE_END; 2:7/12
    ;5
        srl   D             ; 2:8
        rr    E             ; 2:8       DE >> 1
        sbc  HL, DE         ; 2:15
        jr   nc, $+3        ; 2:7/12
        add  HL, DE         ; 1:11      back
        adc   A, A          ; 1:4
        dec   B             ; 1:4       B--
        jr    z, UDIVIDE_END; 2:7/12
    ;6
        srl   D             ; 2:8
        rr    E             ; 2:8       DE >> 1
        sbc  HL, DE         ; 2:15
        jr   nc, $+3        ; 2:7/12
        add  HL, DE         ; 1:11      back
        adc   A, A          ; 1:4
        dec   B             ; 1:4       B--
        jr    z, UDIVIDE_END; 2:7/12
    ;7
        srl   D             ; 2:8
        rr    E             ; 2:8       DE >> 1
        sbc  HL, DE         ; 2:15
        jr   nc, $+3        ; 2:7/12
        add  HL, DE         ; 1:11      back
        adc   A, A          ; 1:4
        dec   B             ; 1:4       B--
        jr    z, UDIVIDE_END; 2:7/12
    ;8
        srl   D             ; 2:8
        rr    E             ; 2:8       DE >> 1
        sbc  HL, DE         ; 2:15
        jr   nc, $+3        ; 2:7/12
        add  HL, DE         ; 1:11      back
        adc   A, A          ; 1:4
        dec   B             ; 1:4       B--
        jr    z, UDIVIDE_END; 2:7/12
    
    UDIVIDE_LOOP:
        srl   D             ; 2:8
        rr    E             ; 2:8       DE >> 1
        sbc  HL, DE         ; 2:15
        jr   nc, $+3        ; 2:7/12
        add  HL, DE         ; 1:11      back
        adc   A, A          ; 1:4
        rl    C             ; 2:8
        djnz UDIVIDE_LOOP   ; 2:8/13    B--
    
        ex   DE, HL         ; 1:4
        cpl                 ; 1:4
        ld    L, A          ; 1:4
        ld    A, C          ; 1:4
        cpl                 ; 1:4
        ld    H, A          ; 1:4
        ret                 ; 1:10
    
    UDIVIDE_END:
        ex   DE, HL         ; 1:4
        cpl                 ; 1:4
        ld    L, A          ; 1:4
        ld    H, B          ; 1:4
        ret                 ; 1:10
    ; seconds: 0           ;[170:815]

    Nebudu ukazovat radsi vsechny verze.

  • 6. 4. 2023 19:53

    _dw

    Zajimava cast je kdyz vite cim budete delit. Delite konstantou. A nebo vite cim budete nasobit.

    U nasobeni je to relativne snadne. Existuje jedna metoda ktera je v cca 98% pripadu nejlepsi. Ale u deleni je to magie pro kazdou konstantu, kde zkousite nekolik cest (zakladni metoda je ze to proste nasobite 2^(8 nebo 16 nebo ...) / constanta) a muste si vse overovat, ze do toho nasypete vsechny mozne vstupy, abyste meli jistotu.

    dworkin@dw-A15:~/Programovani/ZX/Forth/Pasmo_test$ ../check_word.sh '_10UDIV'
                            ;[36:209]   10u/   Variant HL/10 = HL*(2*65536/2*65536)/10 = HL*(2*65536/10)/(2*65536) = HL*13107/(2*65536) = HL*51*257/(2*65536)
                            ;           10u/   = HL*b_0011_0011*(1+1/256) >> (1+8)
        ld    B, H          ; 1:4       10u/
        ld    C, L          ; 1:4       10u/   1     1x = base
        xor   A             ; 1:4       10u/
        add  HL, HL         ; 1:11      10u/   1
        adc   A, A          ; 1:4       10u/      *2 AHL = 2x
        add  HL, BC         ; 1:11      10u/
        adc   A, 0x00       ; 2:7       10u/      +1 AHL = 3x
        add  HL, HL         ; 1:11      10u/   0
        adc   A, A          ; 1:4       10u/      *2 AHL = 6x
        add  HL, HL         ; 1:11      10u/   0
        adc   A, A          ; 1:4       10u/      *2 AHL = 12x
        add  HL, HL         ; 1:11      10u/   1
        adc   A, A          ; 1:4       10u/      *2 AHL = 24x
        add  HL, BC         ; 1:11      10u/
        adc   A, 0x00       ; 2:7       10u/      +1 AHL = 25x
        add  HL, HL         ; 1:11      10u/   1
        adc   A, A          ; 1:4       10u/      *2 AHL = 50x
        add  HL, BC         ; 1:11      10u/
        ld   BC, 0x0033     ; 3:10      10u/         rounding down constant
        adc   A, B          ; 1:4       10u/      +1 AHL = 51x
        add  HL, BC         ; 1:11      10u/
        adc   A, B          ; 1:4       10u/      +0 AHL = 51x with rounding down constant
        ld    B, A          ; 1:4       10u/        (AHL * 257) >> 16 = (AHL0 + 0AHL) >> 16 = AH.L0 + A.HL = A0 + H.L + A.H
        ld    C, H          ; 1:4       10u/         _BC = "A.H" 51x/256 = 0.19921875x
        add  HL, BC         ; 1:11      10u/         _HL = "H.L" + "A.H" = 51.19921875x
        adc   A, 0x00       ; 2:7       10u/         AHL = 51.19921875x
        rra                 ; 1:4       10u/
        rr    H             ; 2:8       10u/
        ld    L, H          ; 1:4       10u/
        ld    H, A          ; 1:4       10u/         HL = HL/10 = (HL*51*257)>>17 = (HL*51.19921875)>>8 = HL*0.099998474
    ; seconds: 0           ;[36:209]