086. Instruction dey

Add DEY instruction behavior.

Lesson 86 of 356 · tests/chapter_01_cpu/test_086_instruction_dey.py

In this step, add only dey; Test 087 wires the opcode after the behavior exists.

Production location and symbol

emulator/cpu/instructions.py: `dey(cpu: CPU)`

Why this step exists

DEY owns the Y-register decrement and status effects independently of decoding. Masking is required to model underflow in an 8-bit register.

Suggested implementation

def dey(cpu: CPU):
    result = cpu.y - 1
    result_8 = result & 0xFF

    # Set flags
    cpu.flags.set_negative_flag((result_8 & 0b1000_0000) != 0)
    cpu.flags.set_zero_flag(result_8 == 0)

    cpu.y = result_8

Important invariants

  • Y wraps from 0x00 to 0xFF
  • Zero and Negative reflect the masked 8-bit result
  • Carry and Overflow are preserved; memory is not accessed

Common misconception

DEY is not SBC applied to Y and must not use Carry as a borrow input.

Out of scope

  • importing dey and mapping opcode 0x88 (test 087)
  • prior INY behavior and dispatch
  • later ASL work and cycle timing

Run this lesson

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