can someone point me to a good tutorial for doing math on a pic?
I want to multiply a 8bit unsigned variable with a 16bit signed variable…
thanks,
Michaël
can someone point me to a good tutorial for doing math on a pic?
I want to multiply a 8bit unsigned variable with a 16bit signed variable…
thanks,
Michaël
piclist Source Code Library ![]()
I love that list!
Hi Stryd,
I couldn’t find an example there and most of the code over there
takes no advantage of the hardware multiplier
will this solution work?
it first takes the absolute value of the 16bit signed value,
does the 16x8 multiply and makes it signed again
if someone knows of a better solution let me know
(note that the code below is inline assembler called from an interrupt routine)
the C equivalent:
out[HL] = out[HL] *cutoff /256
...
;out = out*cutoff/256 (8*16 multiply, keep 2 MS bytes)
; calculate the absolute value of out
movff _out_h, _IRQ_TMP2
movff _out_l, _IRQ_TMP1
btfss _IRQ_TMP2, 7 ; if sign bit is not set goto get_abs_pos
bra _get_abs_pos
_get_abs_neg
comf _IRQ_TMP2, F
comf _IRQ_TMP1, F
incf _IRQ_TMP1, F
skpnz
incf _IRQ_TMP2, F
_get_abs_pos
; multiply lsb of abs(out) with cutoff
banksel _cutoff
movf _cutoff,W, B
mulwf _IRQ_TMP1
movff _PRODH, _IRQ_TMP1
; multiply msb of abs(out) with cutoff
mulwf _IRQ_TMP2
movf _PRODL, W
addwf _IRQ_TMP1, F
skpnc
incf _PRODH, F
movff _PRODH, _IRQ_TMP2
; if out was negative, convert to negative value
banksel _out_h
btfss _IRQ_TMP2, 7,B ; if sign bit is not set goto mult_end
bra _mult_res_pos
_mult_result_neg
comf _IRQ_TMP2, F
comf _IRQ_TMP1, F
incf _IRQ_TMP1, F
skpnz
incf _IRQ_TMP2, F
_mult_result_pos
movff _IRQ_TMP1, _out_l
movff _IRQ_TMP2, _out_h
...
![]()
Did it work? Seems OK here…
I’ve been thinking about making a new sdcclib which uses the hardware mul’ wherever possible, whatya think? Could save a lot of time and effort in optimising… I need some divide routines which return a remainder too…
That said, it’s 1030am and I am still awake and cutting code, my head could be rolling down the street for all I know ;D
I haven’t tried it yet, I’ve been rewriting the core sound stuff in asm
because most of the code was inline asm anyway
right now I’m studying for my exams so it will take some time
before I can verify this code snippet
maybe it’s better to use the 16x16 signed multiplication from the datasheet
and take out the stuff that you don’t need (compensation for sign bit etc)
an optimised version of the sdcc lib would be nice
but there are too many things on my todo list already ![]()