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

La Autopsia: Diagnóstico Post-Arranque

Fecha: 2025-12-22 Step ID: 0225 Estado: DRAFT

Resumen

Ante la persistencia de la pantalla en blanco (verde) sin errores aparentes, cambiamos la estrategia de depuración. En lugar de trazar la ejecución paso a paso (que introduce latencia y distorsiona el comportamiento), dejamos correr el emulador durante 3 segundos (180 frames) y realizamos un volcado de estado completo ("Autopsia"). Esto revelará si el juego logró avanzar más allá de la inicialización, si configuró los registros de vídeo correctamente y si llegó a escribir datos gráficos en la VRAM.

Concepto de Hardware

Cuando un juego de Game Boy arranca, sigue una secuencia típica de inicialización:

  1. Inicialización de registros: Configura los valores iniciales de la CPU y periféricos.
  2. Espera de V-Blank: Espera a que la PPU entre en modo V-Blank (LY = 144) antes de tocar VRAM.
  3. Copia de gráficos: Usa DMA o instrucciones de carga/almacenamiento para copiar tiles a VRAM (0x8000-0x97FF).
  4. Configuración del mapa: Escribe índices de tiles en el Tile Map (0x9800-0x9BFF).
  5. Habilitación de la pantalla: Activa el bit 7 de LCDC (0xFF40) para encender la pantalla.
  6. Configuración de paleta: Escribe valores en BGP (0xFF47) para definir los colores.

Si el emulador funciona a 60 FPS, en 3 segundos habrá ejecutado millones de ciclos. Si la pantalla sigue verde después de 3 segundos, el estado de la máquina en ese momento nos dirá exactamente por qué:

  • Si PC sigue en 0x02B4 (o cerca): El problema es el Timing. La CPU no ve avanzar a LY, probablemente porque la PPU no está actualizando el registro correctamente.
  • Si BGP es 0x00: El juego corre pero la paleta está negra/blanca. Tetris normalmente escribe 0xFC o 0xE4 en BGP.
  • Si LCDC Bit 0 es OFF: El juego corre pero no ha encendido la pantalla (el bit 7 también debe estar ON).
  • Si VRAM Tile Data son todos 0x00: El juego corre pero no copia gráficos (falla DMA o instrucciones LDI/LDD).
  • Si VRAM Tile Map son todos 0x00: El juego tiene gráficos pero el mapa está vacío (dibuja el tile 0 en todas partes).

La "Autopsia" es una técnica forense: en lugar de intentar rastrear el problema en tiempo real (que introduce latencia), dejamos que el sistema corra libremente y luego "congelamos" el estado para analizarlo. Es como tomar una fotografía del estado interno del hardware después de un tiempo determinado.

Implementación

Se añadió un bloque de código en el método run() de viboy.py que se ejecuta una sola vez cuando el contador de frames alcanza 180 (aproximadamente 3 segundos a 60 FPS).

Componentes modificados

  • viboy.py: Añadido bloque de autopsia que imprime el estado completo del sistema cuando frame_count >= 180. El bloque incluye:
    • Estado de la CPU (PC, SP, registros AF/BC/DE/HL, flags, estado HALT)
    • Registros de vídeo (LCDC, STAT, LY, BGP)
    • Muestra de VRAM Tile Data (0x8010-0x801F)
    • Muestra de VRAM Tile Map (0x9900-0x990F)
    • Estado de interrupciones (IE, IF)
    • Estadísticas del sistema (ciclos totales, frames)

Decisiones de diseño

Se usa una bandera _autopsy_done para garantizar que la autopsia se ejecute solo una vez, evitando saturar la consola con volcados repetidos. El volcado se hace después de completar el frame 180, no durante su ejecución, para no interferir con el timing.

La autopsia solo está disponible en modo C++ porque es donde se está ejecutando el emulador actualmente. Si se detecta modo Python, se imprime un aviso.

Archivos Afectados

  • src/viboy.py - Añadido bloque de autopsia en el método run()

Tests y Verificación

Para validar la implementación:

  1. Ejecutar el emulador: python main.py roms/tetris.gb
  2. Esperar 3 segundos: El emulador debe ejecutarse normalmente durante 180 frames.
  3. Analizar la salida: La consola mostrará el volcado de estado completo con el formato:
    ========================================
    💀 AUTOPSIA DEL SISTEMA (Frame 180)
    ========================================
    CPU State:
      PC: 0xXXXX | SP: 0xXXXX
      AF: 0xXXXX | BC: 0xXXXX | DE: 0xXXXX | HL: 0xXXXX
      Flags: Z=X, N=X, H=X, C=X
      Halted: True/False
    
    Video Registers:
      LCDC: 0xXX (Bit 7=ON/OFF, BG=ON/OFF)
      STAT: 0xXX | LY: XXX (Decimal)
      BGP:  0xXX (Palette)
    
    VRAM Tile Data (0x8010 - Primeros bytes del logo?):
      XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX
    
    VRAM Tile Map (0x9900 - Centro aprox):
      XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX
    
    Interrupts:
      IE: 0xXX | IF: 0xXX
    
    System State:
      Total Cycles: X,XXX,XXX
      Frames: 180
    ========================================
  4. Interpretar los resultados: Según los valores obtenidos, determinar el tipo de fallo:
    • Timing (PC atascado)
    • Lógico (LCDC apagado)
    • Datos (VRAM vacía)

Fuentes Consultadas

Integridad Educativa

Lo que Entiendo Ahora

  • Diagnóstico Forense: En lugar de rastrear el problema en tiempo real (que introduce latencia y distorsiona el comportamiento), es más efectivo dejar que el sistema corra libremente y luego "congelar" el estado para analizarlo.
  • Secuencia de Inicialización: Los juegos de Game Boy siguen una secuencia típica: inicialización → espera V-Blank → copia gráficos → configura mapa → habilita pantalla → configura paleta.
  • Preguntas Binarias: El estado después de 3 segundos responde preguntas binarias: ¿avanzó la CPU? ¿Se configuró LCDC? ¿Se escribió VRAM? Esto reduce el espacio de búsqueda del problema.

Lo que Falta Confirmar

  • Interpretación de Resultados: Una vez obtenido el volcado de estado, necesitamos interpretar los valores para determinar el tipo exacto de fallo (Timing, Lógico, o Datos).
  • Valores Esperados: Necesitamos conocer los valores "normales" que Tetris debería tener después de 3 segundos para comparar con los obtenidos.

Hipótesis y Suposiciones

Asumimos que 180 frames (3 segundos) es tiempo suficiente para que Tetris complete su secuencia de inicialización. Si el juego es más lento o tiene bucles de espera más largos, podríamos necesitar aumentar el umbral.

Próximos Pasos

  • [ ] Ejecutar el emulador y obtener el volcado de estado completo
  • [ ] Analizar los valores obtenidos y determinar el tipo de fallo
  • [ ] Implementar la corrección según el diagnóstico
  • [ ] Verificar que Tetris carga y muestra gráficos correctamente