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.
El Rastreador del Centinela
Resumen
Tras confirmar un bucle infinito en 0x2B24 donde el juego escanea la WRAM buscando el byte 0xFD (que nunca encuentra porque la memoria está inicializada a 0x00), se implementa un rastreador del centinela (sentinel search) en la MMU para detectar cualquier intento de escritura de este valor mágico. Esto permitirá determinar si el juego intentó escribir el marcador y falló, o si nunca llegó a ejecutar la instrucción de escritura.
Concepto de Hardware
Marcadores Mágicos en Memoria (Sentinel Values): Muchos programas usan valores especiales (marcadores o "sentinels") para indicar estados o marcar posiciones en memoria. En el caso de Tetris, el juego parece estar buscando el byte 0xFD en la WRAM como un marcador que indica que alguna fase de inicialización se completó correctamente.
Diagnóstico de Bucle Infinito: Cuando un programa entra en un bucle infinito buscando un valor que nunca encuentra, hay dos posibles causas:
- Opción A: El programa intentó escribir el marcador, pero la escritura falló (problema en la MMU o en la lógica de escritura).
- Opción B: El programa nunca llegó a ejecutar la instrucción que escribe el marcador (problema anterior en la ejecución, posiblemente en la CPU o en la lógica de inicialización).
El rastreador del centinela es una técnica de debugging que consiste en instrumentar el punto de escritura (en este caso, el método MMU::write) para detectar y registrar cualquier intento de escribir el valor buscado. Si el rastreador detecta la escritura, sabemos que el juego intentó escribir el marcador (y debemos investigar por qué no se guardó correctamente). Si el rastreador nunca se activa, sabemos que el problema está antes de la escritura (posiblemente en la lógica de inicialización o en un salto condicional incorrecto).
Área de Memoria Monitoreada: El rastreador monitorea direcciones >= 0xC000, que incluyen:
- WRAM (
0xC000-0xDFFF): Memoria de trabajo interna del Game Boy (8 KB). - Echo RAM (
0xE000-0xFDFF): Espejo de WRAM (redirigido a WRAM por la MMU desde Step 0239).
Implementación
Se añade un bloque de diagnóstico al inicio del método MMU::write que detecta cualquier intento de escribir el valor 0xFD en direcciones de RAM (>= 0xC000). El diagnóstico se ejecuta antes de cualquier redirección de Echo RAM o manejo de registros especiales, para capturar todas las escrituras relevantes.
Componentes modificados
src/core/cpp/MMU.cpp: Añadido bloque de diagnóstico enMMU::writepara detectar escrituras de0xFDen RAM.
Código añadido
// --- Step 0244: SENTINEL SEARCH (Buscando al 0xFD) ---
// El juego se cuelga buscando este valor. ¿Alguien lo escribe?
// Detectamos cualquier intento de escribir 0xFD en la zona de RAM (WRAM/Echo RAM)
// Direcciones >= 0xC000 corresponden a WRAM (0xC000-0xDFFF) y Echo RAM (0xE000-0xFDFF)
if (value == 0xFD && addr >= 0xC000) {
printf("[SENTINEL] ¡Detectada escritura de 0xFD en Address: %04X!\n", addr);
}
// -----------------------------------------
Decisiones de diseño
- Ubicación del diagnóstico: Se coloca justo después de enmascarar el valor y antes de los registros especiales, para capturar todas las escrituras relevantes, incluyendo las que se redirigen desde Echo RAM.
- Condición de detección: Se verifica tanto el valor (
0xFD) como la dirección (>= 0xC000) para evitar falsos positivos en otras áreas de memoria. - Formato del mensaje: El mensaje incluye el prefijo
[SENTINEL]para facilitar su búsqueda en los logs y muestra la dirección exacta donde se intentó escribir.
Archivos Afectados
src/core/cpp/MMU.cpp- Añadido bloque de diagnóstico del rastreador del centinela enMMU::writedocs/bitacora/entries/2025-12-22__0244__rastreador-del-centinela.html- Entrada de bitácoradocs/bitacora/index.html- Actualizado con nueva entradaINFORME_FASE_2.md- Actualizado con Step 0244
Tests y Verificación
El diagnóstico se valida ejecutando el emulador con Tetris y observando la consola:
- Recompilar la extensión C++:
.\rebuild_cpp.ps1 - Ejecutar Tetris:
python main.py roms/tetris.gb - Observar la consola:
- Si aparece
[SENTINEL] ¡Detectada escritura de 0xFD en Address: XXXX!: El juego intentó escribir el marcador. Anotar la dirección y verificar si es Echo RAM (0xE...) o WRAM (0xC...). Investigar por qué la escritura no se guardó correctamente. - Si NO aparece ningún mensaje y el emulador entra en el bucle GPS (
PC:2B24): El juego nunca escribió el marcador. El problema está antes de la escritura, posiblemente en la lógica de inicialización o en un salto condicional incorrecto.
- Si aparece
Nota: Este diagnóstico es intencionalmente visible (usa printf) para facilitar su detección en los logs. Una vez identificada la causa del problema, el diagnóstico puede ser removido o convertido en un log condicional.
Fuentes Consultadas
- Pan Docs: Memory Map - Descripción de WRAM y Echo RAM
- Pan Docs: Echo RAM - Comportamiento del espejo de memoria
Integridad Educativa
Lo que Entiendo Ahora
- Marcadores Mágicos: Los programas usan valores especiales para marcar estados o posiciones en memoria. El byte
0xFDparece ser un marcador que Tetris usa para indicar que alguna fase de inicialización se completó. - Diagnóstico de Bucle Infinito: Cuando un programa busca un valor que nunca encuentra, hay dos posibles causas: el valor nunca se escribió (problema anterior) o se escribió pero no se guardó (problema en la escritura).
- Rastreador del Centinela: Técnica de debugging que instrumenta el punto de escritura para detectar intentos de escribir un valor específico. Permite distinguir entre problemas de escritura y problemas de lógica.
Lo que Falta Confirmar
- ¿El juego escribe el marcador?: Necesitamos ejecutar el emulador y observar si aparece el mensaje
[SENTINEL]en los logs. - Si se escribe, ¿por qué no se guarda?: Si el rastreador detecta la escritura pero el juego no encuentra el valor, debemos investigar por qué la escritura no se guardó correctamente (posible problema en Echo RAM o en la lógica de redirección).
- Si no se escribe, ¿dónde falla la inicialización?: Si el rastreador nunca se activa, debemos investigar la lógica de inicialización del juego para encontrar dónde se supone que debería escribirse el marcador.
Hipótesis y Suposiciones
Hipótesis Principal: El juego intenta escribir 0xFD en WRAM o Echo RAM como marcador de inicialización, pero algo falla en el proceso (ya sea la escritura misma o la lógica que decide cuándo escribirla).
Suposición: El valor 0xFD es un marcador mágico específico de Tetris, no un valor estándar del hardware. Esta suposición se basa en el análisis del código que busca este valor específico en la memoria.
Próximos Pasos
- [ ] Recompilar la extensión C++:
.\rebuild_cpp.ps1 - [ ] Ejecutar Tetris:
python main.py roms/tetris.gb - [ ] Observar la consola para detectar mensajes
[SENTINEL] - [ ] Si aparece el mensaje: Investigar por qué la escritura no se guardó correctamente (verificar redirección de Echo RAM, lógica de escritura, etc.)
- [ ] Si NO aparece el mensaje: Investigar la lógica de inicialización del juego para encontrar dónde se supone que debería escribirse el marcador (posible problema en saltos condicionales o en la lógica de inicialización)