197. Instrucción php
implementar el comportamiento de PHP.
Lección 197 de 356 · tests/chapter_01_cpu/test_197_instruction_php.py
En este paso, modifica únicamente `emulator/cpu/instructions.py añadiendo php(cpu). Requisito previo: FlagsHandler.set_break_flag` ya existe.
Por qué existe este paso
PHP apila P con la marca Break del emulador activada y después borra esa marca transitoria del estado real de la CPU. Como en todo push, escribe en $0100 | S antes de decrementar el S de 8 bits.
Implementación sugerida
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) & 0xFFInvariantes: conserva todos los bits de estado preexistentes; activa Break y ONE en la copia apilada; borra ambos del P real después; escribe antes de decrementar y ajusta S; no derives Z ni N a partir del byte de estado.
Concepto erróneo: Break no queda activado en `cpu.p` tras PHP solo porque esté activado en el byte escrito en la pila.
Fuera de alcance: el registro del opcode $08 corresponde al paso 198. Cualquier cambio posterior a las reglas del byte de estado apilado corresponde a sus propios pasos numerados.
Ejecutar esta lección
uv run pytest tests/chapter_01_cpu/test_197_instruction_php.py -v