;unsigned long (32BIT) multiply
;(b3)(b2)(b1)(b0)(a3)(a2)(a1)(a0) = (c3)(c2)(c1)(c0) * (a3)(a2)(a1)(a0)
; tmp register is (b3)(b2)(b1)(b0)
; aux register is r0
mul_u32
banksel mb
clrf mb
clrf (mb+1)
clrf (mb+2)
clrf (mb+3)
movlw 33
movwf r0 ; shift count
clrc
mul_u32_1_
rrf (mb+3), f
rrf (mb+2), f
rrf (mb+1), f
rrf mb, f
rrf (ma+3), f
rrf (ma+2), f
rrf (ma+1), f
rrf ma, f
skpc
goto mul_u32_2_
; b += c
; LSB0
movf mc, w
addwf mb, f
; LSB1
movf (mc+1), w
bc mul_u32_2_1_
addwf (mb+1), f ; C=0
goto mul_u32_2_2_
mul_u32_2_1_
incf (mb+1), f ; C=1, add with C
bz mul_u32_2_1_a_
addwf (mb+1), f
goto mul_u32_2_2_
mul_u32_2_1_a_
addwf (mb+1), f
setc
mul_u32_2_2_
; LSB2
movf (mc+2), w
bc mul_u32_2_3_
addwf (mb+2), f
goto mul_u32_2_4_
mul_u32_2_3_
incf (mb+2), f
bz mul_u32_2_3_a_
addwf (mb+2), f
goto mul_u32_2_4_
mul_u32_2_3_a_
addwf (mb+2), f
setc
mul_u32_2_4_
; LSB3
movf (mc+3), w
bc mul_u32_2_5_
addwf (mb+3), f
goto mul_u32_2_6_
mul_u32_2_5_
incf (mb+3), f
bz mul_u32_2_5_a_
addwf (mb+3), f
goto mul_u32_2_6_
mul_u32_2_5_a_
addwf (mb+3), f
setc
mul_u32_2_6_
mul_u32_2_
decfsz r0, f
goto mul_u32_1_
return
; unsigned long division
; (a3)(a2)(a1)(a0) = (a3)(a2)(a1)(a0) / (c3)(c2)(c1)(c0)
; remainder (b3)(b2)(b1)(b0)
div_u32
banksel mb
clrf mb
clrf (mb+1)
clrf (mb+2)
clrf (mb+3)
movlw 32
movwf r0 ; shift count
clrc
div_u32_1_
rlf ma, f
rlf (ma+1), f
rlf (ma+2), f
rlf (ma+3), f
rlf mb, f
rlf (mb+1), f
rlf (mb+2), f
rlf (mb+3), f
;
movf (mc+3), w ; check LSB3
subwf (mb+3), w ; f-W; CY=0, f=W
skpz
goto div_u32_2_no_chk
movf (mc+2), w
subwf (mb+2), w ; check LSB2
skpz
goto div_u32_2_no_chk
movf (mc+1), w
subwf (mb+1), w ; check LSB1
skpz
goto div_u32_2_no_chk
movf mc, w
subwf mb, w ; check LSB0
div_u32_2_no_chk
skpc
goto div_u32_3_ ; CY=0, b
; b=b-c
; CY=1, b>=c, b=b-c, result bit=1
; calc LSB0
movf mc, w
subwf mb, f
; LSB1
movf (mc+1), w
bnc div_u32_2_1_ ; carry clr if mb0
subwf (mb+1), f ; C=1
goto div_u32_2_2_
div_u32_2_1_
subwf (mb+1), f
decf (mb+1), f ; C=0, result subtract with CARRY BIT
div_u32_2_2_
; LSB2
movf (mc+2), w
bnc div_u32_2_3_
subwf (mb+2), f
goto div_u32_2_4_
div_u32_2_3_
subwf (mb+2), f
decf (mb+2), f
div_u32_2_4_
; LSB3
movf (mc+3), w
bnc div_u32_2_5_
subwf (mb+3), f
goto div_u32_2_6_
div_u32_2_5_
subwf (mb+3), f
decf (mb+3), f
div_u32_2_6_
setc ; result bit = 1
div_u32_3_
decfsz r0, f
goto div_u32_1_ ; ! don't miss
rlf ma, f ; last bit
rlf (ma+1), f
rlf (ma+2), f
rlf (ma+3), f
return