To multiply the 16-bit value stored in ACC_H, ACC_L by 128, I am currently repeating the snipet below, 7 times
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.
It would be quicker to rotate right once, which divides by 2, and then multiply by 256 by moving the contents of each register to the next one.
Code:
RRCF ACC_U,F ;rotate right to divide by 2
;although there is only one bit we are interested in
;and that goes into the carry bit
RRCF ACC_H, W ;rotate right into W, bringing in the carry bit
MOVWF ACC_U ;move into ACC_U, which multiplies by 256
RRCF ACC_L, W ;rotate right into W, bringing in a carry bit
MOVWF ACC_H ;mov into ACC_H, which multiplies by 256
CLR ACC_L
RRCF ACC_L, F ;bring in final carry bit
The multiplier would work, but it is only multiplies 8 bits by 8 bits, so to multiply by 128 would need three multiplies, and loads of additions. You could ignore carries in this case. The results are always in PRODHRODL so those would need to be moved several times.
It would be quicker to rotate right once, which divides by 2, and then multiply by 256 by moving the contents of each register to the next one.
Well that is 7 lines, so 4 times smaller.
...
My apologies Diver300, I only looked at your method ie; div->mult and didn't analyse your code sample. You code does preserve the lowest bit in the carry bit and restores it at the end.
My preferred code probably would have been;
Code:
MOVF ACC_H ; multiply 16bit by 256 into a 24bit result
MOVWF ACC_U
MOVF ACC_L
MOVWF ACC_H
CLRF ACC_L
CLRC ; 24bit divide by 2
RRCF ACC_U,F
RRCF ACC_H,F
RRCF ACC_L,F
Which is easier to understand but is inferior to your code as it is 2 instructions longer and only handles a 16bit input where yours handles a 17bit input.