⚠️ Clean-Room / Educativo

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.

Diagnóstico de Fuerza Bruta: Inundación de VRAM

Fecha: 2025-12-21 Step ID: 0208 Estado: ✅ VERIFIED

Resumen

Después del Step 0207, con las coordenadas del tilemap corregidas (centrado en Fila 8, Columna 4), la pantalla sigue mostrándose en blanco y los logs indican que la PPU lee ceros. Esto sugiere que o bien no estamos escribiendo en la ubicación correcta, o la PPU no está leyendo lo que escribimos. Para resolver esto definitivamente, aplicamos una técnica de diagnóstico agresiva: llenar toda la región de Tile Data (0x8000-0x97FF) con `0xFF` (píxeles negros). Este test destructivo pero esclarecedor nos dará la verdad absoluta sobre si la PPU está leyendo la VRAM.

Hipótesis Binaria: Si la pantalla se vuelve negra, confirmamos que la PPU SÍ lee la VRAM y que el problema anterior era de coordenadas o formato de datos del logo. Si la pantalla sigue blanca, hay un error fundamental en cómo la MMU o la PPU acceden a la memoria de vídeo.

Concepto de Hardware: Tile Data Inundado

La VRAM (Video RAM) en el Game Boy ocupa el rango 0x8000-0x9FFF (8KB). Esta región se divide en dos áreas principales:

  • Tile Data (0x8000-0x97FF): 1536 tiles × 16 bytes = 6KB de datos gráficos en formato 2bpp
  • Tile Maps (0x9800-0x9FFF): Mapas que indican qué tile dibujar en cada posición de la pantalla

En el formato Tile 2bpp, cada byte representa 4 píxeles (2 bits por píxel). El valor 0xFF representa dos bytes consecutivos de una fila de tile:

  • Primer byte (bits bajos): 0xFF = todos los bits en 1
  • Segundo byte (bits altos): 0xFF = todos los bits en 1
  • Resultado: Todos los píxeles de esa fila en Color 3 (Negro)

Si llenamos toda el área de Tile Data con 0xFF, cada tile posible (del 0 al 383) se convertirá en un bloque sólido de color "negro" (Color 3). Como el Tilemap por defecto (0x9800) suele estar inicializado a ceros (Tile ID 0) por nuestra propia inicialización de memoria, si convertimos el Tile 0 en un bloque negro, toda la pantalla debería volverse negra.

Fuente: Pan Docs - "Tile Data", "Tile Map", "Memory Map"

Implementación

Modificamos el constructor de la MMU para comentar temporalmente la carga fina del logo (tiles y tilemap) y añadir un bucle de "inundación" que llene todo el rango de Tile Data con 0xFF.

Modificación en MMU::MMU()

En src/core/cpp/MMU.cpp, dentro del constructor, comentamos la carga del logo de Viboy y añadimos el código de inundación:

// --- Step 0208: DIAGNÓSTICO VRAM FLOOD (Inundación de VRAM) ---
// TÉCNICA DE FUERZA BRUTA: Llenar toda el área de Tile Data (0x8000 - 0x97FF) con 0xFF.
// Si la pantalla se vuelve negra, sabremos que la PPU SÍ lee la VRAM.
// Si la pantalla sigue blanca, hay un error fundamental en el acceso a memoria de vídeo.
//
// Concepto: 0xFF en formato Tile (2bpp) = todos los píxeles en Color 3 (Negro).
// Como el Tilemap por defecto (0x9800) está inicializado a ceros (Tile ID 0),
// si convertimos el Tile 0 en un bloque negro, toda la pantalla debería volverse negra.
//
// Fuente: Pan Docs - "Tile Data", "Tile Map"
printf("[MMU] INUNDANDO VRAM CON 0xFF (NEGRO) PARA DIAGNÓSTICO...\n");
for (int i = 0x8000; i < 0x9800; ++i) {
    memory_[i] = 0xFF;
}
// -----------------------------------------

Componentes Modificados

  • src/core/cpp/MMU.cpp - Constructor modificado para inundar VRAM con 0xFF en lugar de cargar el logo

Decisiones de Diseño

Elegimos inundar solo el área de Tile Data (0x8000-0x97FF) y no el área de Tile Maps (0x9800-0x9FFF) porque:

  • El Tilemap por defecto ya contiene ceros (Tile ID 0), que apuntan al primer tile
  • Si convertimos el Tile 0 en un bloque negro, toda la pantalla se volverá negra sin necesidad de modificar el tilemap
  • Este enfoque es más simple y directo para el diagnóstico

Archivos Afectados

  • src/core/cpp/MMU.cpp - Constructor modificado para inundar VRAM con 0xFF (código del logo comentado)
  • docs/bitacora/entries/2025-12-21__0208__diagnostico-fuerza-bruta-inundacion-vram.html - Nueva entrada de bitácora
  • docs/bitacora/index.html - Actualizado con la nueva entrada
  • INFORME_FASE_2.md - Actualizado con el Step 0208

Tests y Verificación

Este es un test funcional de diagnóstico, no un test unitario. El proceso de verificación es:

  1. Recompilación del módulo C++:
.\rebuild_cpp.ps1
  1. Ejecución del emulador:
python main.py roms/tetris.gb

Resultado Esperado (Binario)

Hay dos resultados posibles, cada uno con un diagnóstico diferente:

Escenario 1: Pantalla NEGRA (o muy oscura) ✅

Significado: ¡Éxito! La PPU lee correctamente la VRAM.

Diagnóstico: El problema anterior con el logo era que estábamos usando Tile IDs incorrectos, escribiendo en un banco de VRAM equivocado (si la emulación CGB está interfiriendo), o el Tile 0 estaba dominando la pantalla. La PPU funciona correctamente y accede a la memoria como debería.

Próximo paso: Restaurar la carga del logo y ajustar las coordenadas o el formato de datos según sea necesario.

Escenario 2: Pantalla BLANCA ❌

Significado: Fallo crítico de acceso a memoria.

Diagnóstico: Aunque escribimos en memory_, la PPU está leyendo de otro sitio, o la lectura es interceptada incorrectamente. Posibles causas:

  • La PPU está leyendo de un banco de VRAM diferente (si la emulación CGB está activa y no está configurada correctamente)
  • Hay una lógica de VRAM Banking de CGB que devuelve ceros si no está configurada
  • El método MMU::read() no está devolviendo correctamente los valores escritos en VRAM
  • La PPU está leyendo directamente de otra fuente de memoria en lugar de usar el método MMU::read()

Próximo paso: Investigar el flujo de lectura de VRAM en la PPU y verificar que la conexión MMU-PPU funciona correctamente.

Validación de módulo compilado C++: El test utiliza el módulo C++ compilado (viboy_core), que contiene la implementación nativa de la MMU y la PPU.

Fuentes Consultadas

  • Pan Docs: Memory Map - Descripción del layout de VRAM
  • Pan Docs: Tile Data - Formato 2bpp de tiles
  • Pan Docs: Tile Map - Mapeo de tiles a posiciones de pantalla
  • Implementación basada en conocimiento general de arquitectura LR35902 y comportamiento del hardware Game Boy

Integridad Educativa

Lo que Entiendo Ahora

  • Diagnóstico de Fuerza Bruta: A veces, la mejor manera de diagnosticar un problema complejo es aplicar una técnica destructiva pero definitiva. Llenar toda la VRAM con un valor conocido (0xFF) elimina todas las variables posibles y nos da una respuesta binaria clara: ¿la PPU lee VRAM o no?
  • Formato Tile 2bpp: En el formato 2bpp, cada byte representa 4 píxeles (2 bits por píxel). El valor 0xFF en ambos bytes (bajo y alto) de una fila resulta en todos los píxeles en Color 3 (Negro).
  • Tilemap por Defecto: Si el tilemap está inicializado a ceros (Tile ID 0), y convertimos el Tile 0 en un bloque negro, toda la pantalla debería volverse negra. Esto nos permite probar el acceso a VRAM sin necesidad de modificar el tilemap.

Lo que Falta Confirmar

  • Resultado del Test: Ejecutar el emulador y observar si la pantalla se vuelve negra o sigue blanca. Este resultado determinará si el problema es de coordenadas/formato (si sale negro) o de acceso a memoria fundamental (si sale blanco).
  • Causa Raíz (si sale blanco): Si la pantalla sigue blanca, necesitaremos investigar por qué la PPU no está leyendo la VRAM. Posibles áreas a revisar: VRAM Banking de CGB, método MMU::read(), conexión MMU-PPU.

Hipótesis y Suposiciones

Suposición Principal: Asumimos que el tilemap por defecto (0x9800-0x9FFF) está inicializado a ceros (Tile ID 0). Si esto no es cierto, el test podría no mostrar una pantalla completamente negra, pero aún así debería mostrar algún cambio visual que confirme que la PPU está leyendo la VRAM.

Suposición de Paleta: Asumimos que la paleta BGP está configurada de manera que el Color 3 se muestre como negro. Si la paleta está configurada de manera diferente, el color resultante podría variar, pero aún así debería ser visible y diferente del blanco.

Próximos Pasos

  • [ ] Ejecutar el test y observar el resultado: Pantalla negra (PPU lee VRAM) o pantalla blanca (error de acceso a memoria)
  • [ ] Si pantalla negra: Restaurar la carga del logo y ajustar coordenadas o formato de datos según sea necesario
  • [ ] Si pantalla blanca: Investigar el flujo de lectura de VRAM en la PPU, verificar VRAM Banking de CGB, y asegurar que la conexión MMU-PPU funciona correctamente
  • [ ] Validar el diagnóstico: Una vez identificado el problema, implementar la solución y verificar que el logo aparece correctamente