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