From: Scott Dattalo
rrf bcd, W andlw 01111000b ;W = tens*8 movwf temp clrc rrf temp, F ;temp = tens*4 rrf temp, F ;temp = tens*2 subwf bcd, W ;W = tens*16 + ones - tens*8 ;W = tens*8 + ones addwf temp, W ;W = tens*10 + ones
Code:
; ========================================================== ; From: Scott Dattalo ; ; This version saves one cycle. ; swapf bcd, W andlw 0x0F ; W=tens movwf temp addwf temp, W ; W=2*tens addwf temp, F ; temp=3*tens (note carry is cleared) rlf temp, W ; W=6*tens subwf bcd, W ; W = 16*tens+ones - 6*tens ; ========================================================== ; From: Silvan Minghetti ; ; Does not require an additional temp register, but trashes ; the content of the bcd register. ; ; Expects bcd value in 'bcd', returns binary value in WREG. ; To return the binary value in 'bcd', change the last line ; to subwf bcd, F ; swapf bcd, F rlf bcd, W andlw b'00011110' ; WREG = tens * 2 swapf bcd, F subwf bcd, F ; bcd = (tens * 16) - (tens * 2) + ones subwf bcd, F ; bcd = (tens * 14) - (tens * 2) + ones subwf bcd, W ; WREG = (tens * 12) - (tens * 2) + ones ; ========================================================== ; From: Scott Dattalo ; ; The upper method adapted for the PIC18 Family, saves one ; more cycle. ; swapf bcd, W andlw 0x0F ; W= tens rlncf WREG, W ; W= 2*tens subwf bcd, F ; 16*tens + ones - 2*tens subwf bcd, F ; 14*tens + ones - 2*tens subwf bcd, W ; 12*tens + ones - 2*tens
Comments:
RRCF BCD, W ; BCD/2 in WREG
RRCF WREG, W ; BCD/2/2 in WREG
ANDLW 0x3C ; mask upper nibble as 4 * tens
SUBWF BCD, F ; BCD = (16 * tens) - (4 * tens) = 12 * tens + ones
RRNCF WREG, W ; BCD/2/2/2 in WREG = (2 * tens)
SUBWF BCD, F ; BCD = (12 * tens) - (2 * tens) = 10 * tens + ones
Tomas Kocian Says:
Another method, using 6 cycles without additional registers:
swapf bcd,w ;separate tenths
andlw 0F
mullw 0A ;multiply by 10
movf bcd,w
andlw 0F ;separate below 10
addwf PRODL,w ;add to multiply result