Regulus Berdin wrote: > > > > > Close, but try X = 0x95 and Y = 0x95. The correct answer should > > be Y=0x80 and C=1. However, this routine will produce Y=0x2A and > > C=1. You still need that annoying normalization step. > > This code will produce 90 with C=1. > Should be the right answer 95+95 = 190 not _180_. > The code must be correct! Uhh, yeah. Sorry. But what about this case: 95 + 90 BCD_ADD: ;Y = Y + X MOVLW 66 W = 66 ADDWF X,W W = 95 + 66 = FB ADDWF Y,F Y = 90 + FB = 8B, C=1, DC=0 MOVLW -60 W = -60 = 0xa0 SKPDC NOT SKIPPED MOVLW -66 W = -66 = 0x9a SKPC SKIPPED ADDWF Y,F NO ADD, SO RESULT = 8B, C=1 RETLW 0 If C=1 AND the sum of the least significant nibbles is less than 10 then the result will be incorrect. > > > > > > BCD_MINUS: ;Y = Y - X > > > MOVF X,W > > > SUBWF Y,F > > > MOVLW -6 > > > SKPC > > > MOVLW -66 > > > SKPDC > > > ADDWF Y,F > > > RETLW 0 > > > > Try X=0x25, Y=0x16. This produces 0xf1 instead of 0x91. > I goofed on this one :(. > > How about this: > BCD_MINUS: ;Y = Y - X > MOVF X,W > SUBWF Y,F > ANDLW 0 ;Set Zero flag > SKPDC > IORLW 6 > SKPC > IORLW 60 > SUBWF Y,F ;Zero flag is cleared > RETLW 0 > Test ZERO flag for underflow. Excellent! However from my simulation results, Z is set only when the result is 0 (and not for an underflow). If you macro-ize this routine then the upper nibble of W will have the carry information. Or perhaps, you can add : SUBWF Y,F ANDLW 0x60 ;Set Z if underflow occurred RETLW 0 Scott