andrewem wrote:
It says on tutorials/compare_beyond.html that "both [CMP and SBC] affect the N, Z, and C flags in exactly the same way".
Not quite. It says that CMP and the sequence SEC SBC affect the N, Z, and C flags in the same way. The D flag is assumed to be zero, so really the SBC sequence is CLD SEC SBC. Anyway, you don't have to take my word for it. Here is a program that demonstrates that it is true. Conveniently, it stops at the first counterexample. It takes about 4 seconds (assuming it passes) at 1 MHz. If it doesn't work on the emulator, then the emulator has a bug.
Code:
; Compare N, Z, and C flag results of CMP and SBC
;
; Returns with ERROR = 0 if the test passes, ERROR = 1 if the test fails
;
; Four additional memory locations are used: ERROR, N1, N2, and SNZC
; These may be located anywhere convenient in RAM
;
TEST CLD ; just in case
LDA #1 ; store 1 in ERROR until the test passes
STA ERROR
LDA #0 ; initialize N1 and N2
STA N1
STA N2
TEST1 LDA N1
CMP N2 ; compare N2 to N1
PHP ; push CMP flags
SEC ; subtract N2 from N1
SBC N2
PHP ; store SEC SBC flags in SNZC
PLA
STA SNZC
PLA ; pull CMP flags
EOR SNZC
AND #$83 ; mask N, z, and C flags
BNE TEST2
INC N2
BNE TEST1
INC N1
BNE TEST1
LDA #0 ; the test passes, so store 0 in ERROR
STA ERROR
TEST2 RTS
I really didn't intend for the tutorial to be an introduction to the CMP instruction. It's more of a compilation of different comparison techniques and optimization tips. The title is "Beyond 8-bit unsigned comparisons" and one section is named "Review of compare instructions', so a familarity with the CMP instruction was assumed.
andrewem wrote:
Given this information I took the source code for my emulated SBC instruction and poped into my CMP instruction (ignoring the carry, not modifying the registers, and ignoring the BCD handling) and the results are NOT the same. Obviously something is wrong.
I can only guess where the problem might be, but when you "ignore" BCD handling, you must subtract as though the D flag is ZERO, and when you "ignore" the carry you must subtract as though it were ONE.
Also, CMP does not affect the V flag, unlike SBC.