I'm confused as to why this code isn't working as expected. From what I understand BTST.L #1,D1
checks if the last bit of the value stored in D1 is 1, in which case the value in D1 would be odd and the program would branch to ADDSUM.
It seems to work correctly with some values (9*2, 8*2 or 10*10), but fails when I try and do others (11*11 gives me 110, same as 10*11). I believe it is whenever the multiplier is odd.
START:
MOVE.W #MULTIPLICAND,D0 ; Set D0 equal to the multiplicand
MOVE.W #MULTIPLIER,D1 ; Set D1 equal to the multiplier
MOVE.L #00000000,D2 ; Clear D2 as it will be used to store the product
LOOP BTST.L #1,D1 ; Check if D1 is odd
BEQ ADDSUM ; If so branch to ADDSUM
RETURN CMP #$01,D1 ; Check if the multiplier is equal to 1
BEQ END ; If so, terminate the loop
ASL #1,D0 ; Multiply the multiplicand by 2
ASR #1,D1 ; Divide the multiplier by two
BRA LOOP ; Branch back to the top of the loop
ADDSUM ADD.W D0,D2 ; Add D0 to D2
BRA RETURN ; After adding, we have to branch back to where we were in the loop
END SIMHALT
I figured it out. I figured I'd post it as an answer just in case anybody else ever stumbles upon this.
It turns out I didn't understand how the BTST.L #1,D1
instruction works. I thought the code in the original example was supposed to be checking if the last bit in D1 was equal to 1. In reality, BTST
works by setting the Z condition code flag to 1
when the bit being tested is 0. The #1
in the instruction was specifying that it was testing the second bit from the right.
In order to determine even/odd, the rightmost bit is the one that has to be tested. I fixed my code by changing it to have the following:
LOOP BTST.L #0,D1 ; Check if D1 is even (Z-flag will be set to 1 if bit is zero)
BNE ADDSUM ; BNE will branch to ADDSUM if Z-flag is not set (meaning D1 is odd)
Hopefully this is able to help somebody else who is having the same problem.