146. Instruction cmp

implement addressing-independent CMP behavior.

Lesson 146 of 356 · tests/chapter_01_cpu/test_146_instruction_cmp.py

Why this step exists

CMP needs one value-oriented definition of no-borrow Carry, equality Zero, and wrapped-subtraction Negative semantics before adding any addressing modes.

In this step, before the addressing-specific compare lessons, add exactly this symbol to `emulator/cpu/instructions.py`:

def cmp(cpu: CPU, value: int):
    result_8 = (cpu.a - value) & 0xFF

    # Flags:
    cpu.flags.set_carry_flag(cpu.a >= value)
    cpu.flags.set_zero_flag(cpu.a == value)
    cpu.flags.set_negative_flag((result_8 & 0b1000_0000) !=0)

CMP performs an unsigned comparison while using the wrapped subtraction only for N. C means no borrow (A >= value), Z means equality, and N is result bit 7. A, Overflow, memory, X, Y, and PC are invariant.

Misconception: Carry is set, not cleared, when A is at least the operand, and the subtraction result is never stored. Out of scope: importing `cmp` and CMP opcodes are lessons 147 onward; CPX/CPY are lessons 155-162.

Run this lesson

uv run pytest tests/chapter_01_cpu/test_146_instruction_cmp.py -v