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