⚠️ 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 STAT Profundo: Monitoreo de Escrituras

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

Resumen

Se añadió instrumentación de diagnóstico profundo para monitorear todas las escrituras en el registro STAT (0xFF41) y detectar si el juego intenta activar el bit 6 (LYC interrupt enable). Además, se mejoró el logging en la PPU para incluir el valor de IE (Interrupt Enable) cuando se detecta una señal STAT activa. El objetivo es determinar si el juego realmente intenta usar la interrupción STAT por LYC o si el problema está en otro lugar.

Hallazgo crítico: El juego Pokémon Red NO activa el bit 6 de STAT ni configura LYC. Solo hay una escritura en STAT que desactiva todas las interrupciones (0x00). Esto significa que el problema NO es que la interrupción STAT no se dispare, sino que el juego simplemente no la está usando.

Concepto de Hardware

El registro STAT (0xFF41) de la Game Boy permite al software configurar qué condiciones de la PPU generan interrupciones:

  • Bit 3: Habilita interrupción cuando la PPU entra en Mode 0 (H-Blank)
  • Bit 4: Habilita interrupción cuando la PPU entra en Mode 1 (V-Blank)
  • Bit 5: Habilita interrupción cuando la PPU entra en Mode 2 (OAM Search)
  • Bit 6: Habilita interrupción cuando LY == LYC (coincidencia de línea)

Si un juego quiere usar la interrupción STAT por LYC, debe: 1. Escribir un valor en LYC (0xFF45) para establecer la línea objetivo 2. Activar el bit 6 de STAT escribiendo un valor con el bit 6 a 1

Si el juego NO hace estas dos cosas, entonces NO está intentando usar la interrupción STAT por LYC, y el problema de congelamiento debe estar en otro lugar (otra interrupción, polling de STAT, espera de V-Blank, etc.).

Fuente: Pan Docs - LCD Status Register (STAT), LYC Register (0xFF45)

Implementación

Se añadieron dos mejoras de logging para diagnóstico:

1. Monitoreo de Escrituras en STAT (MMU)

En src/memory/mmu.py, se mejoró el logging cuando se escribe en STAT (0xFF41):

  • Se guarda el valor anterior de STAT antes de escribir el nuevo
  • Se muestra explícitamente si se activa el bit 6 (LYC interrupt enable) con el formato: LYC_INT_ENABLE=True/False
  • Se muestra el valor anterior y nuevo en formato hexadecimal

Esto permite identificar inmediatamente si el juego intenta activar la interrupción STAT por LYC.

2. Logging de IE en Señales STAT Activas (PPU)

En src/gpu/ppu.py, se añadió el valor de IE (Interrupt Enable, 0xFFFF) en todos los logs de "STAT SIGNAL ACTIVE":

  • Se lee IE cuando se detecta una señal STAT activa
  • Se muestra el valor de IE y si el bit 1 (STAT interrupt enable) está activo
  • Esto permite determinar si la PPU genera la señal pero la CPU la ignora porque IE bit 1 está desactivado

Decisiones de diseño

Se decidió usar logging a nivel INFO para que estos mensajes sean visibles durante el diagnóstico, pero pueden desactivarse fácilmente cambiando el nivel del logger si se satura la salida.

Archivos Afectados

  • src/memory/mmu.py - Mejora del logging de escrituras en STAT para mostrar LYC_INT_ENABLE
  • src/gpu/ppu.py - Añadido valor de IE en logs de señales STAT activas

Tests y Verificación

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

Comando ejecutado: python main.py pkmn.gb 2>&1 | Select-String -Pattern "LYC_INT_ENABLE|STAT SIGNAL|STAT UPDATE"

Entorno: Windows 10, Python 3.10+

Resultado:

  • Se detectó UNA SOLA escritura en STAT: STAT UPDATE: Old=01 New=00 | LYC_INT_ENABLE=False
  • El juego escribe 0x00 en STAT, desactivando todas las interrupciones STAT
  • NO se detectó ninguna escritura con LYC_INT_ENABLE=True
  • NO se detectó ninguna escritura en LYC (0xFF45)
  • NO se detectó ninguna señal STAT activa por LYC

Interpretación:

  • El juego NO está intentando usar la interrupción STAT por LYC
  • El problema de congelamiento NO es que la interrupción STAT no se dispare
  • El juego probablemente está esperando otra cosa (polling de STAT, otra interrupción, etc.)

Estado: draft - Se necesita más investigación para determinar qué está esperando el juego.

Fuentes Consultadas

Integridad Educativa

Lo que Entiendo Ahora

  • El juego NO usa la interrupción STAT por LYC: El diagnóstico muestra claramente que Pokémon Red no activa el bit 6 de STAT ni configura LYC. Esto descarta la hipótesis de que el problema sea que la interrupción STAT no se dispare.
  • El problema está en otro lugar: Si el juego no intenta usar la interrupción STAT por LYC, entonces el congelamiento debe deberse a otra causa: polling de STAT esperando un modo específico, espera de V-Blank, otra interrupción, o un problema de timing.
  • Diagnóstico sistemático: Añadir logging detallado permite identificar exactamente qué está haciendo el juego y qué está esperando, lo que es esencial para diagnosticar problemas de emulación.

Lo que Falta Confirmar

  • ¿Qué está esperando el juego? Si no es la interrupción STAT por LYC, ¿qué es? ¿Polling de STAT esperando V-Blank? ¿Otra interrupción? ¿Un problema de timing?
  • ¿Por qué se congela? Necesito investigar más a fondo qué está haciendo el código del juego cuando se congela. ¿Está en un bucle infinito esperando algo? ¿Qué condición está esperando?
  • ¿Funciona con otros juegos? Sería útil probar con otros juegos para ver si el problema es específico de Pokémon Red o es general.

Hipótesis y Suposiciones

Hipótesis actual: El juego está haciendo polling del registro STAT esperando que la PPU entre en un modo específico (probablemente V-Blank o H-Blank) antes de continuar. Si la PPU no está actualizando STAT correctamente o si hay un problema de timing, el juego se queda esperando eternamente.

Suposición no verificada: Asumo que el juego está haciendo polling de STAT, pero no he verificado esto directamente. Necesito añadir más logging para ver qué está leyendo el juego y qué está esperando.

Próximos Pasos

  • [ ] Añadir logging de lecturas de STAT para ver si el juego está haciendo polling
  • [ ] Añadir logging de lecturas de LY para ver si el juego está esperando una línea específica
  • [ ] Investigar qué está haciendo el código del juego cuando se congela (trazado de ejecución)
  • [ ] Probar con otros juegos para ver si el problema es específico de Pokémon Red
  • [ ] Verificar si hay problemas de timing que impidan que la PPU llegue a V-Blank