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

HALT Wakeup Fix (IME=0)

Fecha: 2025-12-23 Step ID: 0264 Estado: Draft

Resumen

Este Step revisa y corrige la lógica de despertar de HALT en la CPU. El Step 0263 confirmó que el Tile Map contiene datos válidos (tile 0x7F), pero la pantalla sigue estática. El GPS muestra `IME:0`, `IE:0D`, `IF:01`, lo que indica que hay una interrupción V-Blank pendiente pero la CPU no la está atendiendo porque IME está desactivado. La hipótesis es que el juego está usando HALT y esperando que la CPU se despierte cuando ocurre una interrupción, incluso si IME=0. Según Pan Docs, cuando IME=0 y hay una interrupción pendiente habilitada, la CPU debe salir de HALT pero NO saltar al vector de interrupción.

Concepto de Hardware

HALT Instruction: La instrucción HALT pone la CPU en estado de bajo consumo. La CPU deja de ejecutar instrucciones hasta que ocurre una interrupción o se despierta manualmente.

Comportamiento de HALT con IME=0: Según Pan Docs, cuando IME=0 y hay una interrupción pendiente habilitada en IE:

  1. La CPU DEBE SALIR DE HALT (despertar).
  2. Pero NO salta al vector de interrupción (porque IME=0).
  3. Simplemente continúa la ejecución en la siguiente instrucción.

El problema del "HALT Bug": Si la CPU se queda en HALT eternamente porque IME=0, el juego se congela esperando que la interrupción ocurra. Esto es especialmente problemático en juegos que usan HALT para esperar V-Blank, ya que si IME nunca se activa, la CPU nunca despierta y el juego se queda congelado.

El caso de Pokémon Red: El GPS muestra `IME:0`, `IE:0D`, `IF:01`, lo que indica que hay una interrupción V-Blank pendiente (`IF:01`) y está habilitada en IE (`IE:0D` tiene el bit 0 activo). Si el juego está en HALT esperando V-Blank, la CPU debe despertar incluso si IME=0, permitiendo que el juego continúe su ejecución.

Fuente: Pan Docs - "HALT Instruction", "Interrupts", "IME (Interrupt Master Enable)"

Implementación

Se revisó y mejoró la lógica de despertar de HALT en el método handle_interrupts() de CPU.cpp. La lógica ya estaba implementada correctamente, pero se mejoraron los comentarios para explicar claramente el comportamiento cuando IME=0.

Componentes modificados

  • CPU::handle_interrupts(): Mejorados los comentarios para explicar claramente que la CPU debe despertar de HALT cuando hay una interrupción pendiente habilitada, incluso si IME=0. La lógica ya estaba correcta, pero ahora está mejor documentada.

Decisiones de diseño

Despertar de HALT independiente de IME: La CPU debe despertar de HALT si hay CUALQUIER interrupción pendiente habilitada en IE, independientemente del estado de IME. Esto permite que el juego continúe su ejecución incluso si IME está desactivado.

No saltar al vector si IME=0: Si IME es false, la CPU no consume ciclos extra ni salta al vector de interrupción. Simplemente continúa la ejecución normal (HALT termina).

Comentarios mejorados: Se añadieron comentarios detallados explicando el comportamiento según Pan Docs, incluyendo referencias a la documentación oficial.

Archivos Afectados

  • src/core/cpp/CPU.cpp - Mejorados comentarios en método handle_interrupts() para explicar el comportamiento de despertar de HALT cuando IME=0 (Step 0264).

Tests y Verificación

Para validar esta corrección:

  1. Recompilar: .\rebuild_cpp.ps1
  2. Ejecutar: python main.py roms/pkmn.gb (Pokémon Red es ideal porque usa HALT para esperar V-Blank).
  3. Observar el comportamiento:
    • Si la animación avanza: La corrección funciona correctamente. La CPU está despertando de HALT cuando hay interrupciones pendientes, incluso si IME=0.
    • Si la pantalla sigue estática: Puede haber otro problema (posiblemente en el renderizado de sprites o en la lógica de actualización de frames).

Validación esperada: Si la corrección funciona, deberías ver la animación de la intro de Pokémon (estrellas cayendo, Game Freak, etc.) avanzando correctamente, incluso si IME está desactivado.

Correlación con GPS: El GPS debería mostrar que la CPU está ejecutando instrucciones (PC cambiando) incluso cuando IME=0, confirmando que la CPU está despertando de HALT correctamente.

Fuentes Consultadas

Integridad Educativa

Lo que Entiendo Ahora

  • HALT con IME=0: Cuando IME=0 y hay una interrupción pendiente habilitada, la CPU debe despertar de HALT pero NO saltar al vector de interrupción. Simplemente continúa la ejecución normal.
  • El problema del congelamiento: Si la CPU se queda en HALT eternamente porque IME=0, el juego se congela esperando que la interrupción ocurra. Esto es especialmente problemático en juegos que usan HALT para esperar V-Blank.
  • Despertar independiente de IME: La CPU debe despertar de HALT si hay CUALQUIER interrupción pendiente habilitada en IE, independientemente del estado de IME. Esto permite que el juego continúe su ejecución incluso si IME está desactivado.

Lo que Falta Confirmar

  • Comportamiento en tiempo real: ¿La CPU está despertando de HALT correctamente cuando hay interrupciones pendientes, incluso si IME=0? Los tests nos dirán si la corrección funciona.
  • Correlación con animación: Si la corrección funciona, ¿la animación de la intro de Pokémon avanza correctamente? Esto confirmaría que el problema estaba en el despertar de HALT.
  • Otros problemas potenciales: Si la pantalla sigue estática después de la corrección, puede haber otro problema (posiblemente en el renderizado de sprites o en la lógica de actualización de frames).

Hipótesis y Suposiciones

Hipótesis principal: Si el Tile Map contiene datos válidos (Step 0263) pero la pantalla sigue estática, y el GPS muestra `IME:0`, `IE:0D`, `IF:01`, es posible que:

  1. La CPU está en HALT y no se despierta: Si la CPU se queda en HALT eternamente porque IME=0, el juego se congela esperando que la interrupción ocurra. Esta corrección debería resolver este problema.
  2. El problema está en otro lado: Si la corrección no resuelve el problema, puede haber otro problema (posiblemente en el renderizado de sprites o en la lógica de actualización de frames).

Esta corrección debería permitir que la CPU despierte de HALT correctamente, permitiendo que el juego continúe su ejecución y que la animación avance.

Próximos Pasos

  • [ ] Ejecutar python main.py roms/pkmn.gb y observar si la animación avanza.
  • [ ] Si la animación avanza, confirmar que la corrección funciona correctamente.
  • [ ] Si la pantalla sigue estática, investigar otros problemas potenciales (renderizado de sprites, lógica de actualización de frames, etc.).
  • [ ] Correlacionar el comportamiento con el GPS para confirmar que la CPU está ejecutando instrucciones incluso cuando IME=0.