Code:
; 14bit by 10bit unsigned multiply ; by Martin Sturm 2010 ; tested over all 14, 10bit input combinations ; ; Useful for 10bit ADC and result that fit in 24bits ; ; a (14bit) = aH:aL (not modified) ; b (10bit) = bH:bL (not modified) ; r3:r2:r1 is 24-bit result ; ; ignores non-zero bits above 10th for b, ; incorrect result if a has non-zero bits above the 14th ; unless optional ANDLW are used ; ; r = a*b = r3:r2:r1 ; r = 2^8*(aH:aL * bH) + (aH:aL * bL) ; 14x2 14x8 ; ; 83 instructions, 71-83 cycles, 77 avg ; ; helper macro mmac MACRO A,bit, u2,u1 BTFSC A,bit ADDWF u2,F RRF u2,F RRF u1,F ENDM MULT_14x10_FAST MACRO aH,aL, bH,bL, r3,r2,r1 LOCAL g1, g2 ; r3:r2:r1 = aH:aL * bL ; 65 cycles CLRF r3 CLRF r2 CLRF r1 CLRC MOVFW bL mmac aL,0, r3,r1 mmac aL,1, r3,r1 mmac aL,2, r3,r1 mmac aL,3, r3,r1 mmac aL,4, r3,r1 mmac aL,5, r3,r1 mmac aL,6, r3,r1 mmac aL,7, r3,r1 mmac aH,0, r3,r2 mmac aH,1, r3,r2 mmac aH,2, r3,r2 mmac aH,3, r3,r2 mmac aH,4, r3,r2 mmac aH,5, r3,r2 RRF r3,F RRF r2,F RRF r3,F RRF r2,F ; carry always clear by here ; r3:r2 += aH:aL * bH ; 6-18 cycles, 12 avg BTFSS bH,0 GOTO g1 MOVFW aL ADDWF r2,F SKPNC INCF r3,F MOVFW aH ; ANDLW 0x3F ; (optional) if aH has nonzero bits above 14th ADDWF r3,F ; never sets carry g1 BTFSS bH,1 GOTO g2 RLF aH,W ; carry always clear before here ; ANDLW 0x7E ; (optional) if aH has nonzero bits above 14th, ; CLRC ; and, clear any carry ADDWF r3,F ; never sets carry RLF aL,W ; W = (2*aL & 0xFF) ADDWF r2,F SKPNC INCF r3,F BTFSC aL,7 ; 9th bit of 2*aL INCF r3,F g2 ENDM