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