186. Инструкция rts

добавить независимое от режима адресации поведение RTS.

Урок 186 из 356 · tests/chapter_01_cpu/test_186_instruction_rts.py

Предусловие: на шагах 184–185 были добавлены поведение JSR и привязка опкода. На этом шаге добавьте `emulator/cpu/instructions.py::rts`:

Инструкция

RTS -> Return from Subroutine

Цель

реализовать rts(cpu) в instructions.py.

Рекомендации

RTS — парная инструкция возврата для JSR. JSR сохраняет адрес возврата в стеке, а RTS извлекает этот адрес обратно, затем прибавляет 1, чтобы продолжить выполнение после исходной инструкции JSR.

Важные детали

  • Стек располагается на странице $0100.
  • S — только младший байт адреса стека.
  • При извлечении сначала увеличивается S, затем выполняется чтение из $0100 | S.
  • RTS извлекает сначала младший байт, затем старший.
  • RTS устанавливает PC равным извлечённый_адрес + 1.

Пример

If the stack contains return address $8002:

    $01FC = $02  low byte
    $01FD = $80  high byte
    S = $FB

Then RTS pulls $8002 and sets PC to $8003.

Примерная структура реализации

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)

addr = (high << 8) | low
cpu.pc = (addr + 1) & 0xFFFF

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

JSR сохранила PC-минус-один, поэтому RTS восстанавливает это слово и увеличивает его на единицу до адреса продолжения. Инварианты: каждое извлечение увеличивает 8-битный S перед чтением; младший байт извлекается раньше старшего; итоговый PC оборачивается до 16 бит; статус, остальные регистры и память не изменяются. Заблуждение: чтение до увеличения S или пропуск финального инкремента PC не инвертирует протокол стека JSR.

За рамками шага: импорт и привязка опкода $60 — шаг 187. BRK/RTI и общие вспомогательные функции стека CPU относятся к последующим шагам.

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

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