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.
;
;******************************************************************
title "32-bit binary to ascii"
list p=pic16f84,r=dec,n=80,x=off,st=off
include <p16f84.inc>
errorlevel -302 ; no bank warnings
errorlevel -305 ; no default dest warnings
#define number 123456789
loadd macro
local m,n,p
p = number / 16777216
movlw p
movwf bin
m = (number - p * 16777216) / 65536
movlw m
movwf bin+1
n = (number - p * 16777216 - m * 65536) / 256
movlw n
movwf bin+2
movlw number - p * 16777216 - m * 65536 - n * 256
movwf bin+3
endm
CBLOCK 0x0c
bin:4 ; 32-bit binary number (unsigned)
bcd:10 ; 10 BC digits or 10 ascii chars
pti,pto ; pointers
ii
temp
cnt
ENDC
loadd ; load test value <number>
call b2bcd ; convert to 32-bit binary to 10 bcd
call bcd2a ; convert 10 bcd to 10 ascii
goto $
;******************************************************************
; Convert the 10 binary coded digits (5 bytes) starting at
; <bcd> into an ascii string also starting at <bcd>. Original
; bcd digits are lost.
bcd2a movlw bcd+9
movwf pto ; destination pointer
movlw bcd+4
movwf pti ; source pointer
movlw 5 ; 5 bytes to process
movwf cnt
bcd2a1 movf pti,w ; get current input pointer
movwf fsr
decf pti,f ; prepare for next
movf indf,w ; get 2 bcds
movwf temp ; save for later
movf pto,w ; get current output pointer
movwf fsr
decf pto,f ; prepare for next
decf pto,f
movf temp,w ; get digits back
andlw 0x0f ; process lsd
addlw "0"
movwf indf ; to output
decf fsr,f
swapf temp,w ; process msd
andlw 0x0f
addlw "0"
movwf indf ; to output
decfsz cnt ; all digits?
goto bcd2a1
return ; yes
;******************************************************************
; Convert 32-bit binary number at <bin> into a bcd number
; at <bcd>. Uses Mike Keitz's procedure for handling bcd
; adjust; Modified Microchip AN526 for 32-bits.
b2bcd movlw 32 ; 32-bits
movwf ii ; make cycle counter
clrf bcd ; clear result area
clrf bcd+1
clrf bcd+2
clrf bcd+3
clrf bcd+4
b2bcd2 movlw bcd ; make pointer
movwf fsr
movlw 5
movwf cnt
; Mike's routine:
b2bcd3 movlw 0x33
addwf indf,f ; add to both nybbles
btfsc indf,3 ; test if low result > 7
andlw 0xf0 ; low result >7 so take the 3 out
btfsc indf,7 ; test if high result > 7
andlw 0x0f ; high result > 7 so ok
subwf indf,f ; any results <= 7, subtract back
incf fsr,f ; point to next
decfsz cnt
goto b2bcd3
rlf bin+3,f ; get another bit
rlf bin+2,f
rlf bin+1,f
rlf bin+0,f
rlf bcd+4,f ; put it into bcd
rlf bcd+3,f
rlf bcd+2,f
rlf bcd+1,f
rlf bcd+0,f
decfsz ii,f ; all done?
goto b2bcd2 ; no, loop
return ; yes
end
Questions: