191. Инструкция rti

реализовать поведение RTI.

Урок 191 из 356 · tests/chapter_01_cpu/test_191_instruction_rti.py

На этом шаге измените только `emulator/cpu/instructions.py, добавив rti(cpu)`. Предварительное условие: шаг 188 ввёл необходимые API для прерываний и флага Break.

Зачем нужен этот шаг

При входе в прерывание в следующие три слота стека записываются статус, младший байт адреса возврата и старший байт адреса возврата. RTI должен извлечь эти байты в этом порядке LIFO и восстановить точный PC; в отличие от RTS, он не должен прибавлять единицу.

Предлагаемая реализация

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) | low

Поместите эти инструкции в `def rti(cpu: CPU)`.

Инварианты: увеличивайте 8-битный S перед каждым чтением; читайте только страницу стека $0100; заменяйте P после маскирования битов 4 и 5; извлекайте младший байт перед старшим; увеличивайте S три раза; оставляйте восстановленный PC без инкремента.

Заблуждение: RTI — это не RTS для прерываний. Применение финального `+ 1` из RTS приводит к возврату не на ту инструкцию.

Вне рамок: импорт/регистрация опкода по адресу $40 относится к шагу 192. Поведение NMI относится к более поздним шагам и не должно добавляться здесь.

Запустить этот урок

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