⚠️ 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.

Modo Rayos X: Renderizado Forzado

Fecha: 2025-12-18 Step ID: 0059 Estado: Draft

Resumen

Se implementó el "Modo Rayos X", una herramienta de diagnóstico que fuerza el renderizado de la VRAM incluso cuando el LCD está apagado (LCDC bit 7=0). Esto permite visualizar qué contenido hay en la VRAM durante los momentos en que el juego apaga rápidamente el LCD, lo cual es especialmente útil para diagnosticar problemas de arranque en juegos como Pokémon Red que encienden y apagan el LCD en milisegundos.

Concepto de Hardware

En la Game Boy real, cuando el Bit 7 del registro LCDC está en 0, el LCD está completamente desactivado y no se renderiza nada. El hardware de la PPU (Picture Processing Unit) simplemente no genera señales de vídeo, y la pantalla muestra un estado en blanco o apagado.

Durante el arranque de muchos juegos, especialmente los que tienen secuencias de inicialización complejas, el juego puede encender el LCD brevemente (LCDC=0x80), verificar el estado, y luego apagarlo de nuevo (LCDC=0x00) para realizar configuraciones adicionales antes de mostrar la pantalla final. Este comportamiento es normal y permite al juego configurar la VRAM, paletas, sprites y otros componentes sin que el usuario vea contenido incompleto o corrupto.

Sin embargo, cuando estamos depurando un emulador, puede ser muy útil ver qué hay en la VRAM incluso cuando el LCD está apagado. Esto nos permite entender:

  • Si la VRAM se está cargando correctamente (DMA, copias manuales)
  • Si los tiles están en las direcciones esperadas
  • Si el tilemap tiene datos válidos
  • Qué está viendo el juego (o qué intentaría ver) cuando enciende el LCD

El "Modo Rayos X" es una herramienta de diagnóstico que NO representa el comportamiento real del hardware. Es puramente educativa y permite "ver a través" del estado del LCD para inspeccionar el contenido de la VRAM en cualquier momento.

Fuente: Pan Docs - LCD Control Register, PPU States

Implementación

Se modificó la función render_frame() en src/gpu/renderer.py para implementar el Modo Rayos X. En lugar de retornar inmediatamente cuando el LCD está apagado, ahora forzamos una configuración de LCDC que permite renderizar el contenido de la VRAM.

Cambio realizado

Se eliminó el return temprano cuando lcdc_bit7 == 0 y se reemplazó con lógica que fuerza un valor de LCDC apropiado para renderizado. Específicamente:

  • LCDC forzado: 0x91
    • Bit 7 = 1: LCD ON (forzado para permitir renderizado)
    • Bit 4 = 1: Tile Data desde 0x8000 (unsigned addressing)
    • Bit 3 = 0: Tile Map desde 0x9800
    • Bit 0 = 1: BG Display ON
  • Se establece lcdc_bit7 = True para que el resto del código de renderizado funcione normalmente
  • Se registra un mensaje de debug indicando que se está usando el Modo Rayos X

Decisiones de diseño

Se eligió LCDC=0x91 como configuración forzada porque:

  • Es una configuración común que muchos juegos usan durante la inicialización
  • Permite renderizar tanto el fondo (Background) como usar tiles desde 0x8000
  • Es una configuración "razonable" que probablemente represente lo que el juego intentaría ver si el LCD estuviera encendido

Nota importante: Esta es una herramienta temporal de diagnóstico. No representa el comportamiento real del hardware y solo debe usarse para debugging. En un emulador completo, cuando el LCD está apagado, no debería renderizarse nada.

Archivos Afectados

  • src/gpu/renderer.py - Modificación en render_frame() para implementar Modo Rayos X

Tests y Verificación

Esta implementación es una herramienta de diagnóstico y no requiere tests unitarios formales, ya que no representa comportamiento real del hardware. Se validó ejecutando el emulador con Pokémon Red.

Ejecución de prueba con Pokémon Red

Comando ejecutado: python main.py pkmn.gb

Entorno: Windows 10, Python 3.13.5, pygame-ce 2.5.6

ROM: Pokémon Red (ROM aportada por el usuario, no distribuida)

Salida de consola:

pygame-ce 2.5.6 (SDL 2.32.10, Python 3.13.5)
Viboy Color - Sistema Iniciado
==================================================

📦 Cartucho cargado:
   Título: POKEMON RED
   Tipo: 0x13
   ROM: 1024 KB
   RAM: 32 KB
   Tamaño total: 1048576 bytes

🖥️  CPU inicializada:
   PC = 0x0100
   SP = 0xFFFE

✅ Sistema listo para ejecutar
   Presiona Ctrl+C para detener

WARNING: 🔥 HACK: Forzando BGP 0x00 -> 0xE4 para visibilidad (el juego intentó escribir paleta blanca, forzamos paleta estándar)

Resultado visual:

Pantalla observada: Pantalla completamente blanca

Interpretación: La pantalla blanca indica que:

  • El Modo Rayos X está funcionando correctamente (está forzando el renderizado cuando el LCD está apagado)
  • La VRAM está vacía o contiene solo ceros (todos los tiles tienen índice de color 0)
  • Con la paleta estándar (BGP=0xE4), el color índice 0 corresponde a blanco, por lo que una VRAM vacía se renderiza como pantalla blanca
  • El hack de BGP está activo (se muestra el warning), pero no ayuda porque no hay datos en VRAM para renderizar

Conclusiones del diagnóstico:

Estado: Draft - Diagnóstico completo, pendiente de implementar solución

El hecho de ver pantalla blanca con Modo Rayos X activo revela que el problema no es solo el timing de encendido/apagado del LCD, sino que la VRAM nunca se está cargando con datos. Esto sugiere que:

  • Problema principal: La VRAM no está siendo poblada con tiles/logos durante la inicialización
  • Posibles causas:
    • El DMA (Direct Memory Access) no está funcionando correctamente
    • Las copias manuales de datos a VRAM no se están ejecutando
    • El código de inicialización del juego no se está ejecutando completamente
    • Hay un bloqueo o error en la CPU antes de que el juego pueda cargar los gráficos

Próximo paso de diagnóstico: Verificar si el código del juego está ejecutando las instrucciones que copian datos a VRAM. Esto puede requerir logging de escrituras a VRAM o ejecución paso a paso para ver dónde se detiene la inicialización.

Nota legal: La ROM de Pokémon Red es aportada por el usuario para pruebas locales. No se distribuye ni se incluye en el repositorio.

Fuentes Consultadas

Nota: El Modo Rayos X es una herramienta de diagnóstico propia y no está documentada en especificaciones oficiales, ya que no representa comportamiento real del hardware.

Integridad Educativa

Lo que Entiendo Ahora

  • Control del LCD: El Bit 7 de LCDC controla si el LCD está encendido o apagado. Cuando está apagado, el hardware real no genera señal de vídeo, pero la VRAM sigue siendo accesible y puede contener datos válidos.
  • Timing de arranque: Muchos juegos apagan y encienden el LCD durante la inicialización para configurar el hardware sin mostrar contenido parcial al usuario.
  • Debugging visual: Para entender qué está pasando en el emulador, puede ser útil visualizar el contenido de la VRAM incluso cuando el LCD está apagado, aunque esto no represente el comportamiento real del hardware.

Lo que Falta Confirmar

  • Configuración óptima de LCDC forzado: Se eligió 0x91 como valor por defecto, pero podría no ser la configuración más apropiada para todos los juegos. Podría ser útil hacer este valor configurable o intentar "adivinar" mejor la configuración que el juego usaría si el LCD estuviera encendido.
  • Impacto en el rendimiento: Renderizar cuando el LCD está apagado consume recursos innecesarios. En el futuro, debería ser opcional o desactivarse cuando no se necesite debugging.

Hipótesis y Suposiciones

Hipótesis principal: Si Pokémon Red (u otro juego) muestra pantalla azul o pantalla en blanco, podría ser porque:

  • El juego enciende el LCD brevemente pero lo apaga inmediatamente porque no recibe la interrupción V-Blank esperada
  • La VRAM no se ha cargado correctamente (problema de DMA o copias manuales)
  • El timing de las interrupciones no coincide con lo que el juego espera

El Modo Rayos X permite visualizar la VRAM en estos momentos críticos para determinar cuál de estas hipótesis es la correcta.

Próximos Pasos

Con el Modo Rayos X activo, se confirmó que la VRAM está vacía (pantalla blanca). Esto cambia completamente el enfoque del diagnóstico:

  • [x] Ejecutar Pokémon Red con Modo Rayos X activo y observar qué contenido hay en la VRAM → Resultado: Pantalla blanca (VRAM vacía)
  • [ ] Verificar si el código del juego está ejecutando las instrucciones que copian datos a VRAM
    • Implementar logging de escrituras a VRAM (0x8000-0x9FFF) para ver si se están escribiendo datos
    • Verificar si el DMA (Direct Memory Access) está funcionando correctamente
    • Ejecutar paso a paso para identificar dónde se detiene la inicialización antes de cargar gráficos
  • [ ] Si el código no se está ejecutando: verificar si hay un bloqueo en la CPU o un error antes de llegar a las instrucciones de carga
  • [ ] Si el código se está ejecutando pero la VRAM no se llena: verificar la implementación de DMA y copias manuales a VRAM
  • [ ] Una vez identificado y corregido el problema, desactivar el Modo Rayos X para volver al comportamiento real del hardware