Este proyecto es educativo y Open Source. No se copia código de otros emuladores. Implementación basada únicamente en documentación técnica y tests permitidas.
Verificación Conexión MMU-PPU y Limpieza de Debug
Resumen
Se verificó y confirmó que la conexión entre MMU y PPU para la lectura del registro
LY (0xFF44) está correctamente implementada. El código existente ya manejaba correctamente
la lectura de LY desde la PPU cuando el juego accede a la dirección 0xFF44. Se eliminaron los prints
de debug temporales que se habían añadido en el paso anterior (sonda de diagnóstico) para limpiar
el código y mejorar el rendimiento. El test test_ly_read_from_mmu confirma que la
funcionalidad está operativa.
Concepto de Hardware
El registro LY (Línea actual) en la dirección 0xFF44 es un registro
de solo lectura que indica qué línea de escaneo se está dibujando actualmente
(rango 0-153). Los juegos leen constantemente este registro para sincronizarse y saber cuándo
pueden actualizar la VRAM de forma segura (durante V-Blank, cuando LY >= 144).
En hardware real, el registro LY está conectado directamente a la PPU (Pixel Processing Unit), no a la memoria RAM. Cuando el software lee 0xFF44, el hardware devuelve el valor actual de LY desde la PPU, no desde una celda de memoria. Si el juego lee un valor incorrecto (por ejemplo, 0 constante), puede quedarse en un bucle infinito esperando que LY cambie.
Fuente: Pan Docs - LCD Timing, LY Register (0xFF44)
Implementación
Se verificó que la implementación existente en src/memory/mmu.py ya maneja correctamente
la lectura de LY:
# En read_byte(), líneas 232-237
if addr == IO_LY:
if self._ppu is not None:
return self._ppu.get_ly() & 0xFF
else:
return 0
La conexión PPU-MMU se establece correctamente en src/viboy.py mediante el método
set_ppu() después de crear ambas instancias (evitando dependencias circulares).
Limpieza de código de debug
Se eliminaron los prints de debug temporales que se habían añadido en el paso anterior:
- Eliminado: Print de "DEBUG PROBE" cada 1000 iteraciones (líneas 313-325)
- Eliminado: Límite de seguridad con prints de emergencia (líneas 327-332)
- Eliminado: Print de "V-BLANK DETECTADO" (líneas 348-354)
- Mantenido: Heartbeat con
logger.info()cada 60 frames (línea 364)
Estos prints estaban ralentizando la ejecución y ya no son necesarios ahora que se confirmó que la conexión MMU-PPU funciona correctamente.
Archivos Afectados
src/viboy.py- Eliminados prints de debug temporales del bucle principal
Tests y Verificación
Se ejecutó el test existente que verifica la lectura de LY desde la MMU:
- Comando ejecutado:
pytest tests/test_ppu_timing.py::TestPPUTiming::test_ly_read_from_mmu -v - Entorno: Windows, Python 3.13.5
- Resultado:
PASSED(1 passed in 0.25s) - Qué valida:
- La MMU puede leer LY desde la PPU a través del registro 0xFF44
- El valor devuelto por MMU coincide con el valor interno de la PPU
- El valor cambia correctamente cuando la PPU avanza líneas
Código del test:
def test_ly_read_from_mmu(self) -> None:
"""Test: La MMU puede leer LY desde la PPU a través del registro 0xFF44."""
mmu = MMU(None)
ppu = PPU(mmu)
mmu.set_ppu(ppu)
# Inicialmente LY debe ser 0
assert mmu.read_byte(0xFF44) == 0
# Avanzar algunas líneas
ppu.step(456 * 5) # 5 líneas
# LY debe ser 5
assert ppu.get_ly() == 5
# La MMU debe devolver el mismo valor
assert mmu.read_byte(0xFF44) == 5
Por qué este test demuestra algo del hardware: Este test verifica que cuando el software (juego) lee la dirección 0xFF44, obtiene el valor actual de LY desde la PPU, no desde la memoria RAM. Esto es crítico porque los juegos dependen de este valor para sincronizarse y saber cuándo pueden actualizar la VRAM de forma segura. Si la MMU devolviera un valor incorrecto (por ejemplo, siempre 0), el juego se quedaría en un bucle infinito esperando que LY cambie.
Fuentes Consultadas
- Pan Docs: LCD Timing, LY Register (0xFF44)
Integridad Educativa
Lo que Entiendo Ahora
- Registro LY (0xFF44): Es un registro de solo lectura conectado directamente a la PPU. Cuando el software lee esta dirección, el hardware devuelve el valor actual de LY desde la PPU, no desde la memoria RAM.
- Conexión MMU-PPU: La MMU necesita una referencia a la PPU para poder devolver el valor correcto de LY cuando se lee 0xFF44. Esta conexión se establece después de crear ambas instancias para evitar dependencias circulares.
- Importancia crítica: Si el juego lee un valor incorrecto de LY (por ejemplo, siempre 0), puede quedarse en un bucle infinito esperando que LY cambie, lo que causa el síntoma de "pantalla blanca eterna" o "emulador congelado".
Lo que Falta Confirmar
- Comportamiento en hardware real: Según la documentación, LY es de solo lectura y escribir en él no tiene efecto. Esto ya está implementado correctamente en el código (se ignora silenciosamente).
- Timing exacto: La PPU avanza LY cada 456 T-Cycles. Esto está implementado y verificado por los tests, pero podría necesitar ajustes finos si se detectan problemas de sincronización en juegos reales.
Hipótesis y Suposiciones
Hipótesis principal: El problema de "pantalla blanca eterna" que se observó en el paso anterior (0040) NO se debe a un problema de conexión MMU-PPU, ya que el código está correctamente implementado y los tests pasan. El problema probablemente se debe a otro factor, como:
- El juego está esperando una interrupción V-Blank que no se está procesando correctamente
- El juego está esperando que pase un tiempo específico (contando ciclos) antes de continuar
- Hay algún otro registro de I/O que no está implementado correctamente
Esta hipótesis se validará en pasos posteriores cuando se pruebe el emulador con ROMs reales y se observe el comportamiento detallado.
Próximos Pasos
- [ ] Si el problema de "pantalla blanca" persiste, investigar el manejo de interrupciones V-Blank
- [ ] Verificar que las interrupciones se procesan correctamente cuando IME está habilitado
- [ ] Probar el emulador con ROMs de test para validar el comportamiento completo
- [ ] Continuar con la implementación de características faltantes según sea necesario