191. Instruction rti
implement RTI behavior.
Lesson 191 of 356 · tests/chapter_01_cpu/test_191_instruction_rti.py
In this step, change only `emulator/cpu/instructions.py by adding rti(cpu)`. Prerequisite: step 188 introduced the required interrupt and Break flag APIs.
Why this step exists
Interrupt entry leaves status, return-PC low, and return-PC high at the next three stack slots. RTI must pull those bytes in that LIFO order and restore the exact PC; unlike RTS, it must not add one.
Suggested implementation
cpu.s = (cpu.s + 1) & 0xFF
flags = cpu.bus.read(0x0100 | cpu.s)
cpu.p = flags & 0b1100_1111
cpu.s = (cpu.s + 1) & 0xFF
low = cpu.bus.read(0x0100 | cpu.s)
cpu.s = (cpu.s + 1) & 0xFF
high = cpu.bus.read(0x0100 | cpu.s)
cpu.pc = (high << 8) | lowPlace those statements in `def rti(cpu: CPU)`.
Invariants: increment the 8-bit S before every read; read only stack page $0100; replace P after masking bits 4 and 5; pull low before high; increase S three times; leave the restored PC unincremented.
Misconception: RTI is not RTS for interrupts. Applying RTS's final `+ 1` returns to the wrong instruction.
Out of scope: opcode import/registration at $40 belongs to step 192. NMI behavior belongs to later steps and must not be added here.
Run this lesson
uv run pytest tests/chapter_01_cpu/test_191_instruction_rti.py -v