From: Scott Dattalo, notes
Comments added by Alex Forencich
;********************************
;binary_to_bcd - 8-bits
;
;Input
; bin - 8-bit binary number
; A1*16+A0
;Outputs
; hundreds - the hundreds digit of the BCD conversion
; tens_and_ones - the tens and ones digits of the BCD conversion
binary_to_bcd:
CLRF hundreds
SWAPF bin, W ; swap the nibbles
ADDWF bin, W ; so we can add the upper to the lower
ANDLW B'00001111' ; lose the upper nibble (W is in BCD from now on)
SKPNDC ; if we carried a one (upper + lower > 16)
ADDLW 0x16 ; add 16 (the place value) (1s + 16 * 10s)
SKPNDC ; did that cause a carry from the 1's place?
ADDLW 0x06 ; if so, add the missing 6 (carry is only worth 10)
ADDLW 0x06 ; fix max digit value by adding 6
SKPDC ; if was greater than 9, DC will be set
ADDLW -0x06 ; if if it wasn't, get rid of that extra 6
BTFSC bin,4 ; 16's place
ADDLW 0x16 - 1 + 0x6 ; add 16 - 1 and check for digit carry
SKPDC
ADDLW -0x06 ; if nothing carried, get rid of that 6
BTFSC bin, 5 ; 32nd's place
ADDLW 0x30 ; add 32 - 2
BTFSC bin, 6 ; 64th's place
ADDLW 0x60 ; add 64 - 4
BTFSC bin, 7 ; 128th's place
ADDLW 0x20 ; add 128 - 8 % 100
ADDLW 0x60 ; has the 10's place overflowed?
RLF hundreds, F ; pop carry in hundreds' LSB
BTFSS hundreds, 0 ; if it hasn't
ADDLW -0x60 ; get rid of that extra 60
MOVWF tens_and_ones ; save result
BTFSC bin,7 ; remeber adding 28 - 8 for 128?
INCF hundreds, F ; add the missing 100 if bit 7 is set
RETURN ; all done!
Note: SKPDC is equivalent to BTFSS STATUS, DC and SKPNDC is equivalent to BTFSC STATUS, DC
Same code optimized for the PIC18F instruction set:
binary_to_bcd:
clrf hundreds
swapf bin, W, A ; swap the nibbles
addwf bin, W, A ; so we can add the upper to the lower
andlw B'00001111' ; and lose the upper nibble (W is in BCD from now on)
btfsc STATUS, DC, A ; if we carried a one (upper + lower > 16)
addlw 0x16 ; add 16 (the place value) (1s + 16 * 10s)
daw ; check for digit overflows
btfsc bin, 4, A ; 16's place
addlw 0x16 - 1 ; add 16 - 1
btfsc bin, 5, A ; 32nd's place
addlw 0x30 ; add 32 - 2
btfsc bin, 6, A ; 64th's place
addlw 0x60 ; add 64 - 4
btfsc bin, 7, A ; 128th's place
addlw 0x20 ; add 128 - 8 % 100
daw ; check for digit overflows
rlcf hundreds, F ; pop carry in hundreds' LSB
movwf tens_and_ones
btfsc bin,7, A ; remember adding 28 - 8 for 128?
incf hundreds, F ; add the missing 100 if bit 7 is set
return
Don't need the hundreds? Get rid of everything after the second daw up to the return. The result will end up in W in that case, just add a movwf if the result is needed elsewhere. Want to pass in the byte in W? Just add a movwf bin at the beginning.
Comments:
I am a Newbie and this is the exact information i was looking for, it works great. The only thing is i don't know how this code actually works, maybe i try to figure it out when i learn more about asm.
Questions:
Archive: