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