262. Helpers de pila de la CPU e importación de flags
Refactorizar el soporte de interrupciones de la CPU en torno a flags compartidos y helpers de pila.
Lección 262 de 356 · tests/chapter_04_ppu_timing_and_vblank/test_262_cpu_stack_helpers_and_flag_imports.py
Archivos a actualizar
emulator/cpu/cpu.py
emulator/cpu/flags_handler.pyPor qué existe este paso
Antes de implementar y probar CPU.interrupt_nmi(), el núcleo de la CPU necesita dos pequeñas piezas de limpieza:
1. CPU should import status flag constants from flags_handler.py.
2. CPU should expose stack helpers for interrupt code:
push_stack(value)
pop_stack() -> intEste es un paso de refactorización/helpers, no la prueba del comportamiento de la interrupción NMI todavía.
Contexto importante
Las pruebas antiguas de la CPU a menudo declaraban constantes de flags locales. Eso estaba bien mientras el capítulo de la CPU se construía de forma incremental. Ahora que las interrupciones necesitan un manejo correcto del byte de estado, la fuente de verdad compartida debe ser:
emulator/cpu/flags_handler.pyDisposición correcta de los bits de estado
CARRY_FLAG = 1 << 0
ZERO_FLAG = 1 << 1
INTERRUPT_FLAG = 1 << 2
DECIMAL_FLAG = 1 << 3
B_FLAG = 1 << 4
ONE_FLAG = 1 << 5
OVERFLOW_FLAG = 1 << 6
NEGATIVE_FLAG = 1 << 7Regla de la pila
push:
write to $0100 | S
decrement S
pop/pull:
increment S
read from $0100 | SEjemplo de implementación sugerido
from emulator.cpu.flags_handler import (
B_FLAG,
INTERRUPT_FLAG,
NEGATIVE_FLAG,
ONE_FLAG,
ZERO_FLAG,
)
STACK_BASE = 0x0100
class CPU:
...
def push_stack(self, value: int) -> None:
self.bus.write(STACK_BASE | self.s, value & 0xFF)
self.s = (self.s - 1) & 0xFF
def pop_stack(self) -> int:
self.s = (self.s + 1) & 0xFF
return self.bus.read(STACK_BASE | self.s)Por qué se añade pop_stack ahora: CPU.interrupt_nmi() solo necesita push_stack, pero las pruebas correspondientes y la futura limpieza de interrupciones de la CPU necesitan también un helper de extracción claro. Añadir ambos helpers juntos hace explícita la invariante de la pila antes de probar el comportamiento de NMI.
Fuera de alcance
- Comportamiento de CPU.interrupt_nmi()
- consumo de la solicitud NMI de la PPU
- interrupciones IRQ/APU/mapper
- refactorización de cada instrucción antigua de pila para usar estos helpers
Ejecutar esta lección
uv run pytest tests/chapter_04_ppu_timing_and_vblank/test_262_cpu_stack_helpers_and_flag_imports.py -v