;----------------------------------------------------------------------------------------
;Function name: mul_16x16_signed
;Descprition..: Multiplies 2 signed 16-bit operands resulting in a signed 32-bit number.
; Control flag MathLib_Res1Neg is set with negative result.
;
;
;Function name: mul_16x16_unsigned
;Descprition..: Multiplies 2 unsigned 16-bit operands resulting in a unsigned 32-bit number.
;
;
;Function name: mul_16x16_signed_op1
;Descprition..: Multiplies signed 16-bit operand (op1) by
; unsigned 16-bit operand (op2) resulting in a signed 32-bit number.
; Control flag MathLib_Res1Neg is set with negative result.
;
;
;Input....: Operand 1 HB = MathLib_Op1+0
; LB = MathLib_Op1+1
;
; Operand 2 HB = MathLib_Op2+0
; LB = MathLib_Op2+1
;
;Output...: Result HB = MathLib_Res1+0
; MathLib_Res1+1
; MathLib_Res1+2
; LB = MathLib_Res1+3
;
; Negative result: MathLib_Res1Neg = 1
;------------------------------------------------------------------------------------
;
mul_16x16_signed: mov MathLib_Flags,#0 ;Clear control flags
push b ;Save used registers by routine
mov b,#16 ;Initialize loop counter
jmp M16_signed_init
mul_16x16_unsigned: mov MathLib_Flags,#0 ;Clear control flags
push b ;Save used registers by routine
mov b,#16 ;Initialize loop counter
jmp M16_unsigned_init
mul_16x16_signed_op1: mov MathLib_Flags,#0 ;Clear control flags
push b ;Save used registers by routine
mov b,#16 ;Initialize loop counter
jmp M16_signed_op1_init
;----------------------------------------------------------------------------------------
;Do Calculation
;
M16_signed_init: mov a,MathLib_Op2+0 ;Is the signed operand 2 negative?
rlc a
jnc M16_000 ;If not, skip complementing
cpl MathLib_NegateResult ;Toggle negate result flag
xrl MathLib_Op2+1,#0FFh ;Complement operand 2
xrl MathLib_Op2+0,#0FFh
mov a,MathLib_Op2+1 ;Increment operand 2 LB
add a,#1
mov MathLib_Op2+1,a
jnc M16_000 ;If carry also increment LB
inc MathLib_Op2+0 ;Propagate carry into HB
M16_000:
M16_signed_op1_init: mov a,MathLib_Op1+0 ;Is the signed operand 1 negative?
rlc a
jnc M16_001 ;If not, skip complementing
cpl MathLib_NegateResult ;Toggle negate result flag
xrl MathLib_Op1+1,#0FFh ;Complement operand 1
xrl MathLib_Op1+0,#0FFh
mov a,MathLib_Op1+1 ;Increment operand 1 LB
add a,#1
mov MathLib_Op1+1,a
jnc M16_001 ;If carry also increment LB
inc MathLib_Op1+0 ;Propagate carry into HB
M16_001:
M16_unsigned_init: ;Initialize result 'register'
mov MathLib_Res1+3,MathLib_Op2+1 ;Put 16-bit multiplier in byte 3 of product/multiplier
mov MathLib_Res1+2,MathLib_Op2+0 ;Put 16-bit multiplier in byte 2 of product/multiplier
mov MathLib_Res1+1,#0 ; Clear byte 1 of product/multiplier
mov MathLib_Res1+0,#0 ; Clear byte 0 of product/multiplier
M16_loop: mov a,MathLib_Res1+3 ;Is low bit of multiplier set?
rrc a
jnc M16_DoShift
M16_DoAdd: mov a,MathLib_Res1+1 ;Upper 16 bits of product/multiplier += multiplicand
add a,MathLib_Op1+1 ;Add LSB of multiplicand
mov MathLib_Res1+1,a
mov a,MathLib_Res1+0
addc a,MathLib_Op1+0 ;Add MSB of multiplicand
mov MathLib_Res1+0,a
M16_DoShift: mov a,MathLib_Res1+0 ;Shift entire product/multiplier right once
rrc a
mov MathLib_Res1+0,a
mov a,MathLib_Res1+1
rrc a
mov MathLib_Res1+1,a
mov a,MathLib_Res1+2
rrc a
mov MathLib_Res1+2,a
mov a,MathLib_Res1+3
rrc a
mov MathLib_Res1+3,a
djnz b,M16_loop ;Check all loops done
M16_CalculationsDone: pop b ;Restore registers used by routine
M16_CheckNegateResult: jnb MathLib_NegateResult,M16_End ;Should the answer be negative?
setb MathLib_Res1Neg ;Set bit negative result
xrl MathLib_Res1+3,#0FFh ;Yes, complement the answer
xrl MathLib_Res1+2,#0FFh
xrl MathLib_Res1+1,#0FFh
xrl MathLib_Res1+0,#0FFh
mov a,MathLib_Res1+3 ;Increment result LB
add a,#1
mov MathLib_Res1+3,a
jnc M16_End ;No carry: we're done
mov a,MathLib_Res1+2 ;Propagate carry into byte 2
addc a,#0
mov MathLib_Res1+2,a
jnc M16_End ;No carry: we're done
mov a,MathLib_Res1+1 ;Propagate carry into byte 1
addc a,#0
mov MathLib_Res1+1,a
jnc M16_End ;No carry: we're done
mov a,MathLib_Res1+0 ;Propagate carry into byte 0
addc a,#0
mov MathLib_Res1+0,a
M16_End: ret