16-bit value multiplied by 128

Thread Starter

atferrari

Joined Jan 6, 2004
4,771
PIC 18F family.

Three registers ACC_U, ACC_H, ACC_L

To multiply the 16-bit value stored in ACC_H, ACC_L by 128, I am currently repeating the snipet below, 7 times

Rich (BB code):
BCF STATUS,C               ;ensure that LSB will get a 0 into b0
RLCF ACC_L,F                ;rotate to left and retain new value.
RLCF ACC_H,F                ;rotate to left and retain new value.
RLCF ACC_U,F                ;rotate to left and retain new value.
which, no surprise, takes 28 lines of code.

Do you know of any trick to do it faster?
 

Markd77

Joined Sep 7, 2009
2,806
It can be done this way:

Rich (BB code):
; ACC = ACC * 128
; Temp = TEMP
; ACC size = 16 bits
; Error = 0.5 %
; Bytes order = little endian
; Round = no

; ALGORITHM:
; Clear accumulator
; Add input * 128 to accumulator
; Move accumulator to result
;
; Approximated constant: 128, Error: 0 %

;     Input: ACC0 .. ACC1, 16 bits
;    Output: ACC0 .. ACC2, 23 bits
; Code size: 7 instructions

	cblock
	ACC0
	ACC1
	endc

;shift accumulator left 7 times
	clrc
	rrf	ACC1, w
	movwf	ACC2
	rrf	ACC0, w
	movwf	ACC1
	clrf	ACC0
	rrf	ACC0, f


; Generated by www.piclist.com/cgi-bin/constdivmul.exe (1-May-2002 version)
; Sun Apr 17 18:03:56 2011  GMT
 

John P

Joined Oct 14, 2008
2,026
Surely multiplying by 128 in an 8-bit machine is better done by dividing by 2?

Right-shift ACC_H and ACC_L. Hold onto the Cy bit that shifted out of ACC_L. Then move ACC_H to ACC_U, ACC_L to ACC_H, clear ACC_L and put the value of Cy into its top bit.

Done.
 
Top