ON 20011029@8:39:55 AM at page: http://www.piclist.com/techref/microchip/math/radix/b2a-16b3a2-ng.htm JMN-EFP-786 James Newton edited the page ON 20011029@8:41:43 AM at page: http://www.piclist.com/techref/microchip/math/radix/b2a-16b3a2-ng.htm JMN-EFP-786 James Newton added 'Code: ;Fast binary to decimal conversion (0..999) ; ;Input: NumH:NumL ;Output Hund:Tens_Ones (packed BCD) ; ; ; ;Size: 56 instructions ;Execution time (with return): 57 ; ;8-July-2000 by Nikolai Golovchenko ;23-Aug-2001 ;Based on 8bit BIN2BCD of Scott Dattalo ;------------------------------------------- cblock NumH NumL Hund Tens_Ones endc ifdef __18C452 cblock TempStatus ; Deal with instruction set changes from 16c to 18c endc endif bin2dec999fast ; convert ; add b[3:0] + b[7:4] for ones swapf NumL, w ;Add the upper and lower nibbles addwf NumL, w ;to get the one's digit andlw 0x0F ; if sum is bigger than 15 (DC is set), add 16 to BCD result skpndc ;Go through a binary to bcd addlw 0x16 ;conversion for just the one's ; if lower digit overflowed again, add 16 again skpndc ;digit addlw 0x06 ; make sure the lower digit is in 0..9 range. If not, do BCD ; correction (add 6) addlw 0x06 skpdc addlw -0x06 ; add now 5*b[4] to ones accumulator and b[4] to tens, doing the ; BCD correction at the same time btfsc NumL, 4 ;bit 4 is a special case addlw 0x16 - 1 + 0x6 skpdc addlw -0x06 ; here we have converted already bits 0 to 4: ; ones = b[3:0] + b[7:4] + b[9:8] + 5*b[4] + 5*b[8] ; --------------- ------- ; tens = 2*b[6:5] + b[4] + b[6:5] + 2*b[7] + 5*b[8] + b[9] ; ---- ; hund = b[9:7] + b[9] ; now just test bits 5 to 7 and add their decimal weights to ; tens only (bit 7 also affects hundreds). We can add maximum ; 11 to tens digit here, so it will be less than 16 and not overflow. ;now adjust the ten's digit btfsc NumL, 5 ;2^5 = 32, so add 3 to the ten's addlw 0x30 ;digit if bit 5 is set btfsc NumL, 6 ;2^6 = 64, so add 6 addlw 0x60 ;if bit 6 is set btfsc NumL, 7 ;2^7 = 128, so add 2 (the ten's addlw 0x20 ;digit) if bit 7 is set ; do decimal correction for tens and propagate carry to hundreds addlw 0x60 ;convert the ten's digit to bcd clrf Hund rlf Hund, f ;if there's a carry, then the input btfss Hund, 0 ;was greater than 99. addlw -0x60 movwf Tens_Ones ; Here we are done with bits 5 to 7 (except bit 7 for hundreds): ; ones = b[3:0] + b[7:4] + b[9:8] + 5*b[4] + 5*b[8] ; --------------- ------- ; tens = 2*b[6:5] + b[4] + b[6:5] + 2*b[7] + 5*b[8] + b[9] ; -------- ---- ------ ------ ; hund = b[9:7] + b[9] ; test bit 8, and add what it contributes to ones and tens movlw 0x66 ;2^8 = 256, so add 0x56 to Tens_Ones btfsc NumH, 0 movlw 0x56 + 0x66 ;add 0x66 for decimal adjust addwf Tens_Ones, f ; do decimal correction ifdef __18C452 movff status, tempstatus ; Save status so incf doesn't mess up C and DC endif skpnc incf Hund, f ifdef __18C452 movff tempstatus,status ; Restore the status endif clrw skpc iorlw 0x60 skpdc iorlw 0x06 subwf Tens_Ones, f ; Here we are done with bit 8: ; ones = b[3:0] + b[7:4] + 2*b[9] + b[8] + 5*b[4] + 5*b[8] ; --------------- ----- ------- ------ ; tens = 2*b[6:5] + b[4] + b[6:5] + 2*b[7] + 5*b[8] + b[9] ; -------- ---- ------ ------ ------ ; hund = b[9:7] + b[9] ; test bit 9 (it adds 2 to ones, 1 to tens, and 5 to hundreds), ; but ignore hundreds yet movlw 0x66 ;2^9 = 512, so add 0x12 to Tens_Ones btfsc NumH, 1 movlw 0x12 + 0x66 addwf Tens_Ones, f ifdef __18C452 movff status, tempstatus ; Save so incf doesn't mess up C and DC endif skpnc incf Hund, f ifdef __18C452 movff tempstatus,status ; Restore saved status endif clrw skpc iorlw 0x60 skpdc iorlw 0x06 subwf Tens_Ones, f ; Now we have a ready result for ones and tens: ; ones = b[3:0] + b[7:4] + 2*b[9] + b[8] + 5*b[4] + 5*b[8] ; --------------- ------ ----- ------- ------ ; tens = 2*b[6:5] + b[4] + b[6:5] + 2*b[7] + 5*b[8] + b[9] ; -------- ---- ------ ------ ------ ----- ; hund = b[9:7] + b[9] ; now just test bits 7, 8, and 9 and add their share to hundreds ; (without any BCD correction, because we assume input value is ; between 0 and 999, so hundreds can't be more than 9) ; btfsc NumL, 7 ;finish with hundreds ; incf Hund, f ; movlw 2 ; btfsc NumH, 0 ; addwf Hund, f ; movlw 5 ; btfsc NumH, 1 ; addwf Hund, f ;That's it! ;Wait, let's optimize the last few lines... ; hund = b[9:7] + b[9] rlf NumL, w ; copy bit 7 to carry rlf NumH, w ; load w with bits 9 to 7 btfsc NumH, 1 ; add b[9] addlw 1 ; addwf Hund, f ; add it to hundreds return ' ON 20011029@8:42:28 AM at page: http://www.piclist.com/techref/microchip/math/radix/b2a-16b3a2-ng.htm JMN-EFP-786 James Newton edited the page