.ORIG x3000
LD R0, Test_Mul1
LD R1, Test_Mul2
JSR Mul
LD R1, Test_Res
;; At this point R2 holds the result and R1 holds the negative of the correct result
ADD R2, R2, R1
BRz RES_GOOD ;Result was zeroed out
RES_BAD
LEA R0, TEST_ERR_STR
PUTS
BR DONE
RES_GOOD
LEA R0, TEST_CORRECT_STR
PUTS
DONE
HALT
TEST_ERR_STR .STRINGZ "Result is wrong"
TEST_CORRECT_STR .STRINGZ "Reulst is correct"
Test_Mul1 .Fill #-212
Test_Mul2 .Fill #-158
Test_Res .Fill x-82D8 ;This has to the inverted test result!
Mul ;MUL function, R2<-R0*R1
AND R2, R2, #0 ;Init R2
OrigRet ;Here we will store the original return address for the subroutine
ST R7, OrigRet ;Store the original return address to OrigReg
ADD R0, R0, #0 ;Adds 0 to R0 to load it to the CC
BRz ZeroMul ;Goto ZeroMul is R0 is 0
BRp Pos ;Goto Pos if R0 is Positive
BRn Neg ;Goto Neg if R0 is Negative
Pos ;If R0 is Positive
ADD R1, R1, #0; Load R1 to the CC
BRz ZeroMul ;Goto ZeroMul if R1 is 0
BRp PosPos ;Goto PosPos is both registers are positive
BRn PosNeg ;Goto PosNeg if R0 is positive and R1 is negative
PosPos
;Add R0 to R2 and reduce R1 by 1. Repeat until R1 is 0.
ADD R2, R2, R0
ADD R1, R1, #-1
BRnp PosPos
BR MyRet
PosNeg
;ADD R0 to R2 and increase R1 by 1. Repeat until R1 is 0, then reverse by 2's complement.
ADD R2, R2, R0
ADD R1, R1, #1
BRnp PosNeg
NOT R2, R2
ADD R2, R2, #1
BR MyRet
Neg
ADD R1, R1, #0; If R0 is negative, check what R1 is by loading it to the CC
BRz ZeroMul
BRn NegNeg
BRp NegPos
NegNeg
;Simply reverse both values using 2's complement and pass them on to PosPos
NOT R0, R0
ADD R0, R0, #1
NOT R1, R1
ADD R1, R1, #1
BR PosPos
NegPos
;Simply reverse both values using 2's complement and pass them on to PosNeg
Not R0, R0
ADD R0, R0, #1
NOT R1, R1
ADD R1, R1, #1
BR PosNeg
ZeroMul
AND R2, R2, #0 ;Stores 0 in R2
BR MyRet
MyRet ;Loads the original return address back to R7
LD R7, OrigRet
Ret
.END