PIC Microcontoller 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.
;
;******************************************************************
        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
	mov	W, #p
	mov	bin, W
m = (number - p * 16777216) / 65536
	mov	W, #m
	mov	bin+1, W
n = (number - p * 16777216 - m * 65536) / 256
	mov	W, #n
	mov	bin+2, W
	mov	W, #number - p * 16777216 - m * 65536 - n * 256
	mov	bin+3, W
	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
	jmp	$

;******************************************************************
; 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	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
;*** WARNING: ADDLW was expanded in three instructions! Check if previous instruction is a skip instruction. 
;	addlw	"0"
	mov	Hack, W
	mov	W, #"0"
	add	W, Hack
	mov	indf, W	; to output
	dec	fsr
	mov	W, <>temp	; process msd
	and	W, #$0f
;*** WARNING: ADDLW was expanded in three instructions! Check if previous instruction is a skip instruction. 
;	addlw	"0"
	mov	Hack, W
	mov	W, #"0"
	add	W, Hack
	mov	indf, W	; to output
	decsz	cnt	; all digits?
	jmp	bcd2a1
	ret	; 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	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