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 Bloqueo de Interrupciones
Resumen
Se implementó un sistema de diagnóstico crítico para identificar por qué la CPU ignora las peticiones de interrupción V-Blank. El diagnóstico añade logs específicos con el símbolo ⚠️ cuando se detecta una petición V-Blank en IF pero no se atiende, indicando si el problema es que IE no tiene el bit activado o si IME está desactivado. Adicionalmente, se añadió un log informativo cada vez que se escribe en el registro IE (0xFFFF) para monitorizar cuándo y cómo el juego configura las interrupciones.
Concepto de Hardware
En la Game Boy, para que una interrupción se procese correctamente, deben cumplirse tres condiciones simultáneas:
- IF tiene el bit activado: El hardware (PPU, Timer, etc.) ha generado una petición de interrupción y ha activado el bit correspondiente en el registro IF (0xFF0F).
- IE tiene el bit activado: El software ha habilitado esa interrupción escribiendo el bit correspondiente en el registro IE (0xFFFF). Esto permite que el juego seleccione qué interrupciones quiere recibir.
- IME está activado: La CPU tiene las interrupciones habilitadas globalmente. IME se activa con la instrucción
EI(Enable Interrupts) y se desactiva conDI(Disable Interrupts).
Si alguna de estas condiciones no se cumple, la interrupción no se procesa, aunque el hardware siga generando la petición en IF. Esto es especialmente crítico para V-Blank, ya que muchos juegos dependen de esta interrupción para avanzar en su inicialización.
El diagnóstico implementado verifica específicamente la interrupción V-Blank (bit 0 de IF/IE) porque es la primera que debería ocurrir después de encender el LCD. Si V-Blank no se procesa, el juego se queda esperando indefinidamente.
Fuente: Pan Docs - Interrupts, Interrupt Enable Register (IE), Interrupt Flag Register (IF), IME
Implementación
Se añadieron dos puntos de diagnóstico estratégicos:
1. Diagnóstico de V-Blank en handle_interrupts() (CPU)
En src/cpu/core.py, método handle_interrupts(), se añadió un bloque de diagnóstico
antes de verificar si hay interrupciones pendientes. El diagnóstico verifica específicamente si hay
una petición V-Blank en IF (bit 0) y por qué no se está atendiendo:
- Si IE no tiene el bit 0 activado: Se logea
⚠️ V-Blank IGNORADO: No habilitado en IE (IE=XX) - Si IME está desactivado: Se logea
⚠️ V-Blank IGNORADO: IME desactivado (DI ejecutado)
Este diagnóstico se ejecuta cada vez que handle_interrupts() se llama, incluso si no hay interrupciones pendientes, lo que permite detectar el problema en tiempo real.
2. Log de Escritura en IE (MMU)
En src/memory/mmu.py, método write_byte(), se añadió un log informativo que se activa
cada vez que se escribe en el registro IE (0xFFFF). El log muestra:
- El valor escrito en IE (formato hexadecimal)
- Qué interrupciones se están habilitando (V-Blank, STAT, Timer) en formato legible
Este log permite identificar si el juego nunca escribe en IE (lo cual sería un bug del juego o un problema de emulación anterior) o si escribe un valor incorrecto.
Decisiones de diseño
- Nivel de log DEBUG para diagnóstico V-Blank: Se usa
logging.debug()para que el log sea visible cuando se active el modo debug, pero no sature la consola en modo normal. - Nivel de log INFO para escritura en IE: Se usa
logging.info()porque es un evento menos frecuente y crítico para entender el flujo de inicialización del juego. - Símbolo ⚠️ para alertas: Se añadió un símbolo visual distintivo para facilitar la búsqueda en los logs y distinguir estos mensajes de diagnóstico de otros logs.
- Verificación antes de calcular pending: El diagnóstico se ejecuta antes de calcular
pendingpara poder distinguir entre "IE no tiene el bit" y "IME desactivado", ya que ambos casos resultan enpending == 0.
Archivos Afectados
src/cpu/core.py- Añadido diagnóstico de V-Blank enhandle_interrupts()antes de verificar IMEsrc/memory/mmu.py- Añadido log informativo cuando se escribe en IE (0xFFFF)
Tests y Verificación
Modo de ejecución: Manual con ROM comercial (Pokémon Red, aportada por el usuario, no distribuida)
Comando ejecutado: python main.py pkmn.gb
Entorno: Windows 10, Python 3.13.5
Criterio de éxito:
- Ver mensajes de diagnóstico
⚠️ V-Blank IGNORADOen la consola cuando se ejecuta el emulador - Ver mensajes
SET IE REGISTERsi el juego intenta configurar IE - Identificar la causa raíz del bloqueo de interrupciones (IE no configurado o IME desactivado)
Observación esperada:
Al ejecutar el emulador, deberían aparecer en la consola mensajes de diagnóstico que indiquen por qué la interrupción V-Blank
no se está procesando. Si el mensaje es ⚠️ V-Blank IGNORADO: No habilitado en IE, significa que el juego nunca
escribió en IE para habilitar V-Blank. Si el mensaje es ⚠️ V-Blank IGNORADO: IME desactivado, significa que
el juego ejecutó DI y nunca ejecutó EI o RETI.
Resultado: Pendiente de ejecución
Notas legales: La ROM de Pokémon Red es aportada por el usuario para pruebas locales. No se distribuye ni se incluye en el repositorio. No se enlazan descargas de ROMs comerciales.
Fuentes Consultadas
- Pan Docs: Interrupts
- Pan Docs: Interrupt Enable Register (IE, 0xFFFF)
- Pan Docs: Interrupt Flag Register (IF, 0xFF0F)
- Pan Docs: EI (Enable Interrupts)
- Pan Docs: DI (Disable Interrupts)
Integridad Educativa
Lo que Entiendo Ahora
- Condiciones para procesar interrupciones: Una interrupción requiere tres condiciones simultáneas: IF activado, IE activado, e IME activado. Si cualquiera de estas falla, la interrupción no se procesa.
- Diagnóstico proactivo: Para identificar problemas de interrupciones, es necesario verificar cada condición por separado, no solo el resultado final (pending == 0).
- Flujo de inicialización: Muchos juegos encienden el LCD (LCDC=0x80) y luego esperan V-Blank para configurar el resto de los gráficos. Si V-Blank no se procesa, el juego se congela.
Lo que Falta Confirmar
- Causa raíz del bloqueo: Necesito ejecutar el emulador y ver qué mensaje de diagnóstico aparece para identificar si el problema es IE no configurado o IME desactivado.
- Timing de escritura en IE: No estoy seguro de cuándo exactamente los juegos escriben en IE. Algunos juegos pueden hacerlo muy temprano en la inicialización, otros pueden hacerlo después de encender el LCD.
- Comportamiento de IME en inicialización: No estoy seguro si la CPU inicia con IME activado o desactivado por defecto. Esto podría afectar el diagnóstico.
Hipótesis y Suposiciones
Hipótesis principal: El juego nunca escribe en IE para habilitar V-Blank, o lo hace después de encender
el LCD pero la interrupción ya se perdió. Alternativamente, el juego ejecutó DI en algún momento y nunca
ejecutó EI o RETI.
Suposición sobre IME inicial: Asumo que la CPU inicia con IME desactivado (como en muchos sistemas embebidos), pero esto necesita confirmación con documentación o tests.
Próximos Pasos
- [ ] Ejecutar el emulador con
python main.py pkmn.gby buscar mensajes⚠️ V-Blank IGNORADO - [ ] Si aparece
No habilitado en IE: Verificar si hay mensajesSET IE REGISTERen los logs - [ ] Si aparece
IME desactivado: Buscar en los logs dónde se ejecutóDIy por qué no se ejecutóEI - [ ] Implementar fix según la causa identificada (forzar IE, forzar IME, o corregir lógica de EI/DI)
- [ ] Verificar que el juego avance después del fix ejecutando nuevamente la ROM