PIC Microcontroller MathMethod

BCD (packed) addition

From: Scott Dattalo

Translated and optimized for the Scenix SX by Nikolai Golovchenko

;******************************************
;bcd_add
;
; Computes  x = x + y
; where x and y are all 8-bit packed BCD numbers
; Exits with C=1 if x+y > 0x99 and with z=1 if
; x+y = 0x100 or x+y = 0.
;
; Size: 15 instructions
; Execution time including return: 14/15 cycles

bcd_add
	mov	W, #$66	;x = x + y + 0x66
	add	W, y
	add	x, W

	clr	W
	sb	DC		;if lsn of x + lsn of y < 10 (dec)
	 or	W, #$06	;then remove the extra 6 added above
	snb	C		;Similarly for the msn
	 jmp	bcd_add2

	or	W, #$60
	sub	x, W		;correct result
	clrb	C		;restore carry
	ret
bcd_add2
	sub	x, W		;correct result
	setb	C		;restore carry
	ret

If you don't need to check the carry the routine can be simplified:

;******************************************
;bcd_add_nc
;
; where x and y are all 8-bit packed BCD numbers
; Exits with z=1 if x+y = 0x100 or x+y = 0.
;
; Size: 10 instructions
; Execution time including return: 12 cycles

bcd_add_nc
	mov	W, #$66	;x = x + y + 0x66
	add	W, y
	add	x, W

	clr	W
	 sb	DC		;if lsn of x + lsn of y < 10 (dec)
	or	W, #$06	;then remove the extra 6 added above
	 sb	C		;Similarly for the msn
	or	W, #$60

	sub	x, W		;correct result
	ret

If you don't want to influence input registers, the following routine computes s = x + y:

 

;******************************************
;bcd_add_to
;
; Computes  s = x + y
; where x and y are all 8-bit packed BCD numbers
; Exits with C=1 if x+y > 0x99 and with z=1 if
; x+y = 0x100 or x+y = 0.
;
; Size: 16 instructions
; Execution time including return: 15/16 cycles

bcd_add_to
	mov	W, #$66	;x = x + y + 0x66
	add	W, y
	add	W, x
	mov	s, W

	clr	W
	sb	DC		;if lsn of x + lsn of y < 10 (dec)
	 or	W, #$06	;then remove the extra 6 added above
	snb	C		;Similarly for the msn
	 jmp	bcd_add_to2

	or	W, #$60
	sub	s, W            ;correct result
	clrb	C		;restore carry
	ret
bcd_add_to2
	sub	s, W		;correct result
	setb	C		;restore carry
	ret