197. Инструкция php
реализовать поведение PHP.
Урок 197 из 356 · tests/chapter_01_cpu/test_197_instruction_php.py
На этом шаге измените только `emulator/cpu/instructions.py, добавив php(cpu). Предварительное условие: FlagsHandler.set_break_flag` уже существует.
Зачем нужен этот шаг
PHP проталкивает P с установленным маркером Break эмулятора, а затем очищает этот временный маркер из текущего состояния CPU. Как и при любом проталкивании, запись происходит в $0100 | S перед уменьшением 8-битного S.
Предлагаемая реализация
def php(cpu: CPU):
cpu.flags.set_break_flag(True)
cpu.flags.set_one_flag(True)
cpu.bus.write(STACK_BASE | cpu.s, cpu.p)
cpu.flags.set_break_flag(False)
cpu.flags.set_one_flag(False)
cpu.s = (cpu.s - 1) & 0xFFИнварианты: сохраните каждый ранее существовавший бит статуса; установите Break и ONE в проталкиваемой копии; очистите оба этих бита из текущего P после этого; записывайте перед уменьшением и заворачивайте S; не вычисляйте Z или N из байта статуса.
Заблуждение: Break не остаётся включённым в `cpu.p` после PHP только потому, что он установлен в байте, записанном в стек.
Вне рамок: регистрация опкода $08 относится к шагу 198. Любые последующие изменения правил проталкиваемого байта статуса относятся к своим собственным пронумерованным шагам.
Запустить этот урок
uv run pytest tests/chapter_01_cpu/test_197_instruction_php.py -v