Good to know! Is there any other cases where shifting doesn't equal multiplication/division with power of 2?
tokumaru wrote:
I guess that comparing against a negative number can easily cause an overflow, rendering the N flag useless. Hopefully the V flag will signal if this is the case (yeah, looking at the section about signed comparisons it says that you need both the N and V flags to find the result of a signed comparison).
Yes the signed comparison result is in N XOR V after the subtraction. That's another difference between CMP and SBC I failed to mention, CMP does not affect V unlike a SEC, SBC-sequence (also CMP subtractions are not affected by the D flag, but that's irrelevant on NES). I've corrected my post again. So for that reason CMP cannot be used in signed comparison, SEC, SBC-sequence are used instead so that V is affected.
In order to do a signed comparison you can use a SEC, SBC-sequence and then use a trick to get the signed comparison result (N XOR V) into N:
Code:
;8-bit signed comparison
SEC
SBC NUM ;subtract NUM from A to compare them
BVC label1 ;if V = 0 then V XOR N = N
EOR #$80 ;1 XOR N, V XOR N = N
label1:
BMI label2 ;if N = 0, A >= NUM, goto label2
BPL label3 ;if N = 1, A < NUM, goto label3
label2:
label3:
Details are explained in the above-linked tutorial. Basically if V is cleared after the subtraction, then N already is the same as V XOR N. Else if V is set, EOR with $80 (N is bit 7) to get N = 1 XOR N = V XOR N. Now when result is in N, BMI or BPL can be used to branch.
Code:
;16-bit signed comparison
LDA NUM1_L
CMP NUM2_L ;compare low byte using CMP
LDA NUM1_H
SBC NUM2_H ;compare high byte using SBC to include C and V
BVC label ;if V = 0 then V XOR N = N
EOR #$80 ;1 XOR N, V XOR N = N
label:
BMI label2 ;if N = 0, NUM1 >= NUM2, goto label2
BPL label3 ;if N = 1, NUM1 < NUM2, goto label3
label2:
label3:
Higher than 8-bit is done the same way only each byte must be compared and the C flag must be included. Only the low byte can use CMP, the rest all have to use SBC (without a SEC) for the subtraction so the carry is included and so that the overflow flag is affected.
Signed comparison is useful if you are making an action game with acceleration-based movement. That way you can use positive and negative acceleration and velocity to move objects with.