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.
Step 0258: VRAM Vital Signs (VRAM Sum)
Resumen
Este Step añade un diagnóstico de integridad de VRAM en el monitor GPS de `src/viboy.py`. Calculamos la suma de bytes de la VRAM (muestreo cada 16 bytes) para determinar si contiene gráficos o está completamente vacía. Si la VRAM está llena de ceros, la PPU renderizará píxeles de índice 0 (verdes/blancos), funcionando "correctamente" sobre datos vacíos.
Con la paleta forzada en C++ (Step 0257) y Python (Step 0256), si la pantalla sigue verde incluso con juegos que tienen el LCD encendido (como Pokémon Red, `LCDC:E3`), la única explicación lógica que queda es que la VRAM está llena de ceros. Si la VRAM es todo 0, la PPU dibuja el "Color 0" perfectamente, que es... verde.
Concepto de Hardware
La VRAM (Video RAM) en la Game Boy ocupa el rango `0x8000-0x9FFF` (8KB) y contiene:
- Tile Data (0x8000-0x97FF): Datos de los tiles (gráficos) que se usan para renderizar el fondo y los sprites. Cada tile ocupa 16 bytes (2 bytes por línea de 8 píxeles).
- Tile Map (0x9800-0x9FFF): Mapas de tiles que indican qué tile se dibuja en cada posición del fondo. Cada byte del mapa apunta a un tile en el Tile Data.
Problema Crítico: Si la VRAM está completamente vacía (todo ceros), la PPU renderizará píxeles de índice 0 (que corresponde al color más claro de la paleta). Con la paleta de debug de Python (Step 0256), el índice 0 se mapea a verde/blanco, lo que explica por qué vemos una pantalla completamente verde incluso cuando el LCD está encendido.
Diagnóstico de VRAM: Al calcular la suma de bytes de la VRAM (usando un muestreo cada 16 bytes para no matar el rendimiento), podemos determinar:
- Sum = 0: La VRAM está vacía. El juego no ha copiado gráficos. Esto indica un problema de CPU/DMA (el juego no está ejecutando el código que copia los tiles desde la ROM a la VRAM).
- Sum > 0: Hay datos en la VRAM. Si la pantalla sigue verde, el problema está en la PPU (no está leyendo correctamente los tiles desde VRAM) o en el mapeo de tiles (Tile Map apunta a tiles vacíos).
Fuente: Pan Docs - VRAM, Tile Data, Tile Maps
Implementación
Se modificó el monitor GPS en `src/viboy.py` para añadir un cálculo de suma de VRAM después de los logs de `[VIDEO]` y `[SPRITE]`:
Modificación en `src/viboy.py` (Monitor GPS)
Se añadió código para calcular la suma de bytes de la VRAM usando un muestreo cada 16 bytes:
# --- Step 0258: VRAM CHECKSUM ---
# Leer muestras masivas para ver si hay vida
# Nota: Esto es lento, pero solo ocurre 1 vez por segundo
vram_sum = 0
# Muestreo rápido: leer cada 16 bytes para no matar el rendimiento
for addr in range(0x8000, 0xA000, 16):
vram_sum += self._mmu.read(addr)
logger.info(f"[MEMORY] VRAM_SUM: {vram_sum} (Si es 0, no hay gráficos)")
# -------------------------------------------------
Este código se añadió tanto en el bloque de C++ como en el bloque de Python (fallback) del monitor GPS, justo después de los logs de `[VIDEO]` y `[SPRITE]`.
Decisiones de Diseño
- Muestreo cada 16 bytes: Se eligió leer cada 16 bytes en lugar de todos los bytes para no matar el rendimiento. El muestreo es suficiente para detectar si la VRAM está completamente vacía (suma = 0) o contiene datos (suma > 0).
- Frecuencia de ejecución: El diagnóstico se ejecuta solo una vez por segundo (cada 60 frames), igual que el resto del monitor GPS, para no impactar el rendimiento.
- Log claro: Se usa un mensaje de log claro que indica explícitamente que si la suma es 0, no hay gráficos en la VRAM.
Archivos Afectados
src/viboy.py- Modificado el monitor GPS (Step 0240) para añadir cálculo de suma de VRAM (Step 0258).
Tests y Verificación
Validación de Diagnóstico:
- Ejecución: Ejecutar
python main.py roms/pkmn.gb(o cualquier ROM con LCD encendido). - Observación del Log: Buscar en el log el mensaje
[MEMORY] VRAM_SUM: Xcada segundo. - Interpretación:
- Si X = 0: La VRAM está vacía. El juego no ha copiado gráficos. Esto indica un problema de CPU/DMA (el juego no está ejecutando el código que copia los tiles desde la ROM a la VRAM).
- Si X > 0: Hay datos en la VRAM. Si la pantalla sigue verde, el problema está en la PPU (no está leyendo correctamente los tiles desde VRAM) o en el mapeo de tiles (Tile Map apunta a tiles vacíos).
Comando de Prueba:
python main.py roms/pkmn.gb
Resultado Esperado: El log debe mostrar [MEMORY] VRAM_SUM: X cada segundo, donde X es un número que indica si hay datos en la VRAM.
Validación de Módulo Python: El código se ejecuta en Python puro, sin necesidad de recompilar módulos C++. El diagnóstico se integra directamente en el monitor GPS existente.
Fuentes Consultadas
- Pan Docs: Video Display
- Pan Docs: Tile Data
- Pan Docs: Tile Maps
Integridad Educativa
Lo que Entiendo Ahora
- Diagnóstico por Capas: Al añadir diagnósticos en diferentes capas (paleta en Step 0256/0257, VRAM en Step 0258), podemos aislar el problema: si la VRAM está vacía, el problema está en la CPU/DMA; si la VRAM contiene datos pero la pantalla sigue verde, el problema está en la PPU o en el mapeo de tiles.
- VRAM Vacía: Si la VRAM está completamente vacía (todo ceros), la PPU renderizará píxeles de índice 0 (que corresponde al color más claro de la paleta). Con la paleta de debug de Python, el índice 0 se mapea a verde/blanco, lo que explica por qué vemos una pantalla completamente verde.
- Muestreo de Memoria: Para diagnosticar grandes rangos de memoria sin matar el rendimiento, podemos usar muestreo (leer cada N bytes) en lugar de leer todos los bytes. Esto es suficiente para detectar si la memoria está completamente vacía o contiene datos.
Lo que Falta Confirmar
- Estado Real de VRAM: Ejecutar el diagnóstico con Pokémon Red (o cualquier ROM con LCD encendido) y verificar el valor de `VRAM_SUM`. Si es 0, confirmamos que la VRAM está vacía y el problema está en la CPU/DMA.
- Timing de Carga: Si la VRAM está vacía, debemos investigar por qué el juego no está copiando los tiles desde la ROM a la VRAM. Esto puede ser un problema de timing (el juego espera que algo ocurra antes de copiar) o un problema de DMA (el juego intenta usar DMA pero no está funcionando).
- Lectura de Tiles: Si la VRAM contiene datos pero la pantalla sigue verde, debemos investigar por qué la PPU no está leyendo correctamente los tiles desde VRAM o por qué el Tile Map apunta a tiles vacíos.
Hipótesis y Suposiciones
Hipótesis Principal: Con la paleta forzada en C++ (Step 0257) y Python (Step 0256), si la pantalla sigue verde incluso con juegos que tienen el LCD encendido (como Pokémon Red, `LCDC:E3`), la única explicación lógica que queda es que la VRAM está llena de ceros. Si la VRAM es todo 0, la PPU dibuja el "Color 0" perfectamente, que es... verde.
Suposición: Asumimos que el diagnóstico de VRAM (suma de bytes) es suficiente para detectar si la VRAM está completamente vacía o contiene datos. Si la suma es 0, la VRAM está vacía; si la suma es > 0, hay datos en la VRAM.
Próximos Pasos
- [ ] Ejecutar
python main.py roms/pkmn.gb(¡Usa Pokémon o Mario, que sabemos que encienden el LCD!). - [ ] Observar el log y buscar
[MEMORY] VRAM_SUM: Xcada segundo. - [ ] Si X = 0:
- Confirmar que la VRAM está vacía. El juego no ha copiado gráficos.
- Investigar por qué el juego no está ejecutando el código que copia los tiles desde la ROM a la VRAM (problema de CPU/DMA).
- Verificar que el juego está ejecutando correctamente (PC avanza, no está en un bucle infinito).
- Verificar que DMA está funcionando (si el juego intenta usar DMA para copiar tiles).
- [ ] Si X > 0:
- Confirmar que hay datos en la VRAM.
- Si la pantalla sigue verde, investigar por qué la PPU no está leyendo correctamente los tiles desde VRAM.
- Verificar que el Tile Map apunta a tiles válidos (no a tiles vacíos).
- Verificar que la PPU está decodificando correctamente los tiles desde VRAM.