SX Microcontroller Radix Math Method

Binary to BCD packed and ASCII, 32 bit to 10 digits

from Ron Kreymborg and Mike Keitz

[ed: rough guess is that about 2200 instructions will be executed]

see also:

;******************************************************************
;
; Test program for 32-bit unsigned binary to BCD and BCD to ASCII.
;
;******************************************************************
        DEVICE SX28
        RESET Start

loadd   macro hi, m0, m1, lo
        mov     W, #hi
        mov     bin, W
        mov     W, #m0
        mov     bin+1, W
        mov     W, #m1
        mov     bin+2, W
        mov     W, #lo
        mov     bin+3, W
        endm

        ORG     $8
temp    DS      1
bin     DS      4       ; 32-bit binary number (unsigned)
bcd     DS      10      ; 10 BCD digits (5 bytes) or 10 ascii chars
pti     DS      1       ; pointer
pto     DS      1       ; pointer
cnt     DS      1       ; counter
ii      DS      1       ; counter

        ORG     $0
Start
        loadd $01, $00, $00, $00   ; load test value 16777216
        call    b2bcd   ; convert to 32-bit binary to 10 bcd
        call    bcd2a   ; convert 10 bcd to 10 ascii
        jmp     $

;******************************************************************
; Convert the 10 binary coded digits (5 bytes) starting at
;  into an ascii string also starting at . Original
; bcd digits are lost.

bcd2a   mov     W, #bcd+9
        mov     pto, W  ; destination pointer
        mov     W, #bcd+4
        mov     pti, W  ; source pointer
        mov     W, #5   ; 5 bytes to process
        mov     cnt, W

bcd2a1  mov     W, pti  ; get current input pointer
        mov     fsr, W
        dec     pti     ; prepare for next
        mov     W, indf ; get 2 bcds
        mov     temp, W ; save for later
        mov     W, pto  ; get current output pointer
        mov     fsr, W
        dec     pto     ; prepare for next
        dec     pto
        mov     W, temp ; get digits back
        and     W, #$0f ; process lsd
        or      W, #$30 ; add '0' offset
        mov     indf, W ; to output
        dec     fsr
        mov     W, <>temp   ; process msd
        and     W, #$0f
        or      W, #$30 ; add '0' offset
        mov     indf, W ; to output
        decsz   cnt     ; all digits?
        jmp     bcd2a1
        ret     ; yes


;******************************************************************
; Convert 32-bit binary number at  into a bcd number
; at . Uses Mike Keitz's procedure for handling bcd
; adjust; Modified Microchip AN526 for 32-bits.

b2bcd   mov     W, #32  ; 32-bits
        mov     ii, W   ; make cycle counter
        clr     bcd     ; clear result area
        clr     bcd+1
        clr     bcd+2
        clr     bcd+3
        clr     bcd+4

b2bcd2  mov     W, #bcd ; make pointer
        mov     fsr, W
        mov     W, #5
        mov     cnt, W

; Mike's routine:

b2bcd3  mov     W, #$33
        add     indf, W ; add to both nybbles
        snb     indf.3  ; test if low result > 7
        and     W, #$f0 ; low result >7 so take the 3 out
        snb     indf.7  ; test if high result > 7
        and     W, #$0f ; high result > 7 so ok
        sub     indf, W ; any results <= 7, subtract back
        inc     fsr     ; point to next
        decsz   cnt
        jmp     b2bcd3

        rl      bin+3   ; get another bit
        rl      bin+2
        rl      bin+1
        rl      bin+0
        rl      bcd+4   ; put it into bcd
        rl      bcd+3
        rl      bcd+2
        rl      bcd+1
        rl      bcd+0
        decsz   ii      ; all done?
        jmp     b2bcd2  ; no, loop
        ret     ; yes

        end