; Fast 16-Bit Binary to Decimal by Peter Hemsley
; Input: 16-bit binary in NUMHI and NUMLO
; Output: Decimal (BCD) digits in D4(msd),D3,D2,D1,D0(lsd)
; No temporary variables required
; Code size: 46 instructions
; Execution time: Variable, approx 150 to 170 cycles

Bin2DecFast
	movf	NUMHI,w		;Hex Digit 0X00 (H2)
	iorlw	0xF0		;w=H2-16
	movwf	D0		;D0=H2-16
	movwf	D1		;D1=H2-16
	addwf	D1,f		;D1=H2*2-32
	addwf	D1,f		;D1=H2*3-48, C=1
	movwf	D2		;D2=H2-16
	rlf	D2,f		;D2=H2*2-31

	swapf	NUMHI,w		;Hex Digit X000 (H3)
	iorlw	0xF0		;w=H3-16
	addwf	D2,f		;D2=H3+H2*2-47 Done!
	movwf	D3		;D3=H3-16
	addwf	D3,f		;D3=H3*2-32
	addlw	D'52'		;w=H3+36
	addwf	D0,f		;D0=H3+H2+20

	swapf	NUMLO,w		;Hex Digit 00X0 (H1)
	iorlw	0xF0		;w=H1-16
	addwf	D1,f		;D1=H2*3+H1-64
	addwf	D0,f		;D0=H3+H2+H1+4, C=1
	rlf	D0,f		;D0=(H3+H2+H1)*2+9, C=0
	comf	D0,f		;D0=-(H3+H2+H1)*2-10
	rlf	D0,f		;D0=-(H3+H2+H1)*4-20

	movf	NUMLO,w		;Hex Digit 000X (H0)
	andlw	0x0F		;w=H0
	addwf	D0,f		;D0=H0-(H3+H2+H1)*4-20 Done!
	rlf	D1,f		;C=0, D1=H2*6+H1*2-128 Done!

	movlw	D'7'
	movwf	D4		;D4=7

	addlw	D'3'		;w=10, C=0
	rlf	D3,f		;D3=H3*4-64 Done!
mod0
	addwf	D0,f		;D(X)=D(X)mod10
	decf	D1,f		;D(X+1)=D(X+1)+D(X)div10
	skpc
	goto	mod0
mod1
	addwf	D1,f
	decf	D2,f
	skpc
	goto	mod1
mod2
	addwf	D2,f
	decf	D3,f
	skpc
	goto	mod2
mod3
	addwf	D3,f
	decf	D4,f
	skpc
	goto	mod3

	return


; Bonus 12-Bit version
; Leaner and Meaner, 36 instructions
; Ideal for displaying A/D values
Bin2DecFast
	movf	NUMHI,w
	iorlw	0xF0		;w=H2-16
	movwf	D1		;D1=H2-16
	addwf	D1,f		;D1=H2*2-32
	addwf	D1,f		;D1=H2*3-48
	movwf	D2		;D2=H2-16
	addlw	-D'5'		;w=H2-21
	addwf	D2,f		;D2=H2*2-37 Done!
	addlw	D'41'		;w=H2+20
	movwf	D0		;D0=H2+20

	swapf	NUMLO,w
	iorlw	0xF0		;w=H1-16
	addwf	D1,f		;D1=H2*3+H1-64
	addwf	D0,f		;D0=H2+H1+4, C=1
	rlf	D0,f		;D0=(H2+H1)*2+9, C=0
	comf	D0,f		;D0=-(H2+H1)*2-10
	rlf	D0,f		;D0=-(H2+H1)*4-20

	movf	NUMLO,w
	andlw	0x0F		;w=H0
	addwf	D0,f		;D0=H0-(H2+H1)*4-20 Done!
	rlf	D1,f		;C=0, D1=H2*6+H1*2-128 Done!	

	movlw	D'5'
	movwf	D3

	movlw	D'10'
mod0
	addwf	D0,f		;D(X)=D(X)mod10
	decf	D1,f		;D(X+1)=D(X+1)+D(X)div10
	skpc
	goto	mod0
mod1
	addwf	D1,f
	decf	D2,f
	skpc
	goto	mod1
mod2
	addwf	D2,f
	decf	D3,f
	skpc
	goto	mod2

	return
