; Integer multiplication - * ; ========================================== ; Multiply two 32-bit integers without using MUL instruction ; ; On entry, r4=RHS b0-b15, r3=RHS b16-b31 ; r2=LHS b0-b15, r1=LHS b16-b31 ; ; On exit, r4=SUM b0-b15, r3=SUM b16-b31 ; .Mul32int mov r4,r0 ; r0=b0-b15 of RHS mov r3,r5 ; r5=b16-b31 of RHS clr r4 ; Initial total=0 clr r3 mov #32,-(sp) ; 32 bits to shift and add ; .fnMultiplyLp ror r1 ; Rotate LHS through carry ror r2 bcc fnMultNoAdd ; No carry, no add needed add r0,r4 ; total=total+RHS adc r3 add r5,r3 bmi fnMultiplyOverflow ; Too big for 31-bit integer .fnMultNoAdd rol r0 ; Rotate LHS rol r5 dec (sp) ; Decrement counter bne fnMultiplyLp ; Loop for all bits tst (sp)+ ; Drop counter ; ; On exit, r4=SUM b0-b15, r3=SUM b16-b31 ; r5,r2,r1,r0=corrupted .... .fnMultiplyOverflow tst (sp)+ ; Drop counter ; ; On exit, all registers corrupted ; Integer multiplication - * ; ========================================== ; Multiply two 16-bit integers using MUL instruction giving 32-bit result ; ; On entry, r4=RHS b0-b15, r3=RHS b16-b31 ; sp=>retaddr, exp, LHS b0-b15, LHS b16-b31 ; ; On exit, r1=SUM b0-b15, r0=SUM b16-b31 ; ; Using schoolbook long multiplication: ; ; r3 r4 ; 6(sp) 4(sp) x ; ----------- ; ; aaaa bbbb ; cccc dddd x ; --------- ; ( b * d ) ; ( a * d ) 0 ; ( b * c ) 0 ; ( a * c ) 0 0 + ; ----------------- ; ; .Mul16 mov r3,r2 ; r2=aaaa bis 6(sp),r2 ; aaaa>0 or cccc>0, not 16-bit inputs bne fnMultiplyBigInts ; Will be too big for 32-bit result mov r4,r0 ; r0=bbbb bmi fnMultiplyBigInts ; Will overflow into bit 31 ; We now have a maximum of &FFFF*&7FFF = &7FFF8001 mul 4(sp),r0 ; r0:r1=bbbb * dddd ; a=0 and c=0, so a*d=0 and b*c=0 ; So r0:r1 is the result. bmi fnMultiplyBigInts ; Has become negative, should be positive ; ; On exit, r1=SUM b0-b15, r0=SUM b16-b31 ; r2 corrupted ; r3,r4,r5 preserved ; .... .fnMultiplyBigInts ; ; On exit, r0,r1,r2 corrupted ; r3,r4,r5 preserved ; Integer multiplication - * ; ========================================== ; Multiply two 32-bit integers using MUL instruction giving 32-bit result ; ; On entry, r4=RHS b0-b15, r3=RHS b16-b31 ; sp=>retaddr, exp, LHS b0-b15, LHS b16-b31 ; ; On exit, r1=SUM b0-b15, r0=SUM b16-b31 ; ; Using schoolbook long multiplication: ; ; r3 r4 ; 6(sp) 4(sp) x ; ----------- ; ; aaaa bbbb ; cccc dddd x ; --------- ; ( b * d ) ; ( a * d ) 0 ; ( b * c ) 0 ; ( a * c ) 0 0 + ; ----------------- ; ; ; .Mul32 mov r3,r0 bic 6(sp),r0 ; r0=a AND a bne fnMultiplyBigInts ; a*c>0, more than 32 bits mov r3,r0 ; r0=a mul 4(sp),r0 ; r0:r1=a*d bcs fnMultiplyBigInts ; Overflow mov r1,r2 ; r2=a*d mov r4,r0 ; r0=b mul 6(sp),r0 ; r0:r1=b*c bcs fnMultiplyBigInts ; Overflow add r1,r2 ; r2=(a*d)+(b*c) bcs fnMultiplyBigInts ; Overflow mov r4,r0 ; r0=b mul 4(sp),r0 ; r0:r1=b*d add r2,r0 bcs fnMultiplyBigInts ; Overflow bmi fnMultiplyBigInts ; Overflow ; ; On exit, r1=SUM b0-b15, r0=SUM b16-b31 ; r2 corrupted ; r3,r4,r5 preserved ; .... .fnMultiplyBigInts ; ; On exit, r0,r1,r2 corrupted ; r3,r4,r5 preserved