On Fri, 17 Oct 1997 08:52:19 -0300 Ricardo Seixas writes: > Here is a 16 bit BIN->BCD. > I don't know who's the original author but it works fine. [code removed] The routine is in a Microchip app note, though it's probably much older than that. The principle that it uses is to repeatedly multiply the BCD number by 2 (first by 'adjusting' it, then shifting left 1 bit). After the shift, the low bit is taken from the binary number. The first bit shifted into the BCD number is the MSB of the binary number, so it is multiplied by 2 n times. This isn't a bad way to convert to decimal, especially for large numbers. I've rewritten the app note code a little to make it smaller. This code also converts 24-bit numbers, producing an 8 digit result. (2^^24 = 16,777,216). The code below has been tested. It requires use of the indirect addressing system (FSR), a 1 byte loop counter (ii), 3 bytes for the original number (bin..bin+2, LSB first), and 4 bytes for the BCD result (bcd..bcd+3, LSB first). ;--------- ; b2bcd ; Converts a 24-bit binary number to 8 digits of BCD. ; Derived from AN526. ; Input: Number at bin...bin+2 LSB first ; Output: Packed BCD at bcd...bcd+3 LSB first. ; RAM : ii, FSR, 4 bytes at bcd. ; Input number at bin is destroyed. b2bcd movlw d'24' ;Do 24 bits movwf ii clrf bcd+0 ;Clear the result clrf bcd+1 clrf bcd+2 clrf bcd+3 b2bcdl rlf bin+0,f ;Rotate one bit out of left end of bin rlf bin+1,f rlf bin+2,f ; If you want to return with the original value in bin (rather than ; garbage), copy the C bit into the low bit of bin here. ; (Not tested) ;; bcf bin+0,0 ;Assume C=0, ;; skpnc ;if it is, OK ;; bsf bin+0,0 ;otherwise put 1 in. rlf bcd+0,f ;and into the low byte of BCD. rlf bcd+1,f rlf bcd+2,f rlf bcd+3,f decfsz ii,f ;Decrement count goto b2bcd2 ;Not done yet, adjust. retlw 0 b2bcd2 movlw bcd+0 movwf FSR call adjbcd incf FSR,f ;to bcd+1 call adjbcd incf FSR,f call adjbcd incf FSR,f ;Last one. call adjbcd goto b2bcdl ;--------- ; adjbcd adjusts the byte at FSR. Used by b2bcd. ; Rewritten adjbcd. Doesn't require tmp. adjbcd movlw h'33' addwf INDF,f ;Add to low and high nybbles btfsc INDF,3 andlw b'11110000' ;Result >7 . OK btfsc INDF,7 andlw b'00001111' ;Hi > 7 OK. subwf INDF,f ;Result <=7, subtract back. return