288. No-op de registro de audio de la apu
Añadir un comportamiento explícito de no-op para los registros de APU/audio en CpuBus.
Lección 288 de 356 · tests/chapter_06_rom_startup_preparation/test_288_apu_audio_register_noop.py
Archivo a actualizar
emulator/bus/cpu_bus.pyPor qué existe este paso
Las ROMs reales del NES suelen acceder a los registros de APU/audio durante el arranque. El audio está fuera del alcance actual de este tutorial, pero fallar en cada acceso a un registro de audio hace que los experimentos manuales con ROMs se detengan antes de poder observar el comportamiento de CPU/PPU/mando.
Este paso enseña un no-op intencionado
recognized address + documented out-of-scope behaviorno una implementación amplia de hardware simulado.
¿Qué es la APU? La APU, o Unidad de Procesamiento de Audio, es el bloque de hardware del NES responsable de generar sonido. La CPU la controla mediante registros mapeados en memoria.
Ejemplo mínimo
CPU writes $4000
real NES: configure pulse channel audio
this tutorial for now: accept the write and produce no soundConcepto erróneo común
"If the emulator accepts APU writes, APU is implemented."No. En este paso, la APU/audio se reconoce explícitamente como fuera de alcance. El emulador solo evita fallar en esas direcciones.
Ejemplo de implementación sugerida
def read(self, addr: int) -> int:
...
# APU/audio registers are intentionally out of scope.
if 0x4000 <= addr <= 0x4013:
return 0
if addr == 0x4015:
return 0
# Controller port 2 / expansion input is also out of scope for now.
# Returning 0 means "no controller-2 buttons pressed" in this simplified model.
if addr == 0x4017:
return 0
...
def write(self, addr: int, value: int) -> None:
...
# APU/audio registers are intentionally out of scope.
if 0x4000 <= addr <= 0x4013:
return
if addr == 0x4015:
return
# $4017 writes control the APU frame counter on the NES.
# Audio/APU timing is intentionally out of scope, so this is a no-op.
if addr == 0x4017:
return
...Por qué estas direcciones
$4000-$4013
APU sound-channel registers
$4015
APU status/control register
$4017
Writes: APU frame counter register, intentionally no-op for now.
Reads: controller port 2 / expansion input, intentionally returns 0 for now.Exclusiones importantes
$4014 is OAMDMA, not audio.
Writing $02 to $4014 should later copy CPU $0200-$02FF into PPU OAM.
Do not swallow it as an APU no-op.
$4016 is controller port 1, not audio.
It will be implemented intentionally in the controller chapter.
Do not fake it by returning 0 here.Fuera de alcance
- generación de sonido real
- temporizadores/envolventes/barrido/contadores de longitud de la APU
- temporización de IRQ/contador de fotogramas
- OAMDMA $4014
- mando $4016
- lecturas de entrada de expansión/puerto de mando 2 desde $4017
- gestión genérica para todas las direcciones de E/S no soportadas
Ejecutar esta lección
uv run pytest tests/chapter_06_rom_startup_preparation/test_288_apu_audio_register_noop.py -v