SX Microcontroller Radix Math Method

Binary to BCD unpacked 16 bit to 5 digit

From: John Payson via Scott Dattalo

see http://www.dattalo.com/technical/software/pic/bcd.txt for notes on how this works. Plan on a headache. <GRIN>
[ed: quick guess at speed is that about 200 instructions will be executed and 50 instructions + 7 registers used]

;Takes hex number in NumH:NumL  Returns decimal in ;TenK:Thou:Hund:Tens:Ones
;written by John Payson

;input
;=A3*163 + A2*162 + A1*161 + A0*160
;=A3*4096 + A2*256 + A1*16 + A0
NumH    DS      1       ;A3*16+A2
NumL    DS      1       ;A1*16+A0
;output
;=B4*104 + B3*103 + B2*102 + B1*101 + B0*100
;=B4*10000 + B3*1000 + B2*100 + B1*10 + B0
TenK    DS      1       ;B4
Thou    DS      1       ;B3
Hund    DS      1       ;B2
Tens    DS      1       ;B1
Ones    DS      1       ;B0

        mov     W, <>NumH       ;w  = A2*16+A3
        or      W, #$F0         ;w  = A3-16
        mov     Thou, W         ;B3 = A3-16
        add     Thou, W         ;B3 = 2*(A3-16) = 2A3 - 32
        mov     Hund, W
        mov     W, #$E2
        add     Hund, W         ;B2 = A3-16 - 30 = A3-46
        mov     W, #$32
        add     W, Hund
        mov     Ones, W         ;B0 = A3-46 + 50 = A3+4

        mov     W, NumH         ;w  = A3*16+A2
        and     W, #$0F         ;w  = A2
        add     Hund, W         ;B2 = A3-46 + A2 = A3+A2-46
        add     Hund, W         ;B2 = A3+A2-46  + A2 = A3+2A2-46
        add     Ones, W         ;B0 = A3+4 + A2 = A3+A2+4

        mov     Tens, W
        mov     W, #$E9
        add     Tens, W         ;B1 = A2-23
        mov     W, Tens
        add     Tens, W         ;B1 = 2*(A2-23)
        add     Tens, W         ;B1 = 3*(A2-23) = 3A2-69 (Doh! thanks NG)

        mov     W, <>NumL       ;w  = A0*16+A1
        and     W, #$0F         ;w  = A1
        add     Tens, W         ;B1 = 3A2-69 + A1 = 3A2+A1-69 range -69...-9
        add     Ones, W         ;B0 = A3+A2+4 + A1 = A3+A2+A1+4 and Carry = 0 (thanks NG)

        rl      Tens            ;B1 = 2*(3A2+A1-69) + C = 6A2+2A1-138 and Carry is now 1 as tens register had to be negitive
        rl      Ones            ;B0 = 2*(A3+A2+A1+4) + C = 2A3+2A2+2A1+9 (+9 not +8 due to the carry from prev line, Thanks NG)
        not     Ones            ;B0 = ~(2A3+2A2+2A1+9) = -2A3-2A2-2A1-10 (ones complement plus 1 is twos complement. Thanks SD)
;;Nikolai Golovchenko [golovchenko at MAIL.RU] says: complement [not Ones] can be regarded like:
;;      not     Ones
;;      inc     Ones
;;      dec     Ones
;;First two instructions make up negation. So,
;;Ones  = -Ones - 1
;;      = - 2 * (A3 + A2 + A1) - 9 - 1
;;      = - 2 * (A3 + A2 + A1) - 10
        rl      Ones            ;B0 = 2*(-2A3-2A2-2A1-10) = -4A3-4A2-4A1-20

        mov     W, NumL         ;w  = A1*16+A0
        and     W, #$0F         ;w  = A0
        add     Ones, W         ;B0 = -4A3-4A2-4A1-20 + A0 = A0-4(A3+A2+A1)-20 range -215...-5 Carry=0
        rl      Thou            ;B3 = 2*(2A3 - 32) = 4A3 - 64

        mov     W, #$07         ;w  = 7
        mov     TenK, W         ;B4 = 7

;B0 = A0-4(A3+A2+A1)-20,  -5...-200
;B1 = 6A2+2A1-138,       -18...-138
;B2 = A3+2A2-46,         -1...-46
;B3 = 4A3-64,            -4...-64
;B4 = 7,                 7

; At this point, the original number is
; equal to TenK*10000+Thou*1000+Hund*100+Tens*10+Ones
; if those entities are regarded as two's compliment
; binary.  To be precise, all of them are negative
; except TenK.  Now the number needs to be normal-
; ized, but this can all be done with simple byte
; arithmetic.

        mov     W, #$0A         ;w  = 10
Lb1:                            ;do
        add     Ones, W         ; B0 += 10
        dec     Tens            ; B1 -= 1
        sb      3.0
        ;skip no carry
        jmp     Lb1             ; while B0 < 0
        ;jmp carry
Lb2:                            ;do
        add     Tens, W         ; B1 += 10
        dec     Hund            ; B2 -= 1
        sb      3.0
        jmp     Lb2             ; while B1 < 0
Lb3:                            ;do
        add     Hund, W         ; B2 += 10
        dec     Thou            ; B3 -= 1
        sb      3.0
        jmp     Lb3             ; while B2 < 0
Lb4:                            ;do
        add     Thou, W         ; B3 += 10
        dec     TenK            ; B4 -= 1
        sb      3.0
        jmp     Lb4             ; while B3 < 0

        ret