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