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.
Hard Reset y Marcador Radiactivo
Resumen
El análisis del log del Francotirador (Step 0241) revela una secuencia de instrucciones absurda en `0x2B20`: múltiples ejecuciones de `LD (nn), SP` (opcode `0x08`) mezcladas con operaciones aritméticas sin sentido. Esto sugiere que la CPU está ejecutando **datos ("basura")** en lugar de código válido, o que estamos sufriendo un problema de persistencia de binarios compilados antiguos en Windows. Se implementa un "marcador radiactivo" (printf muy visible) dentro del `case 0x08` para confirmar que estamos ejecutando la versión correcta del código C++ y no una DLL/PYD cacheada.
Concepto de Hardware
Problema de Persistencia de Binarios en Windows: En sistemas Windows, Python puede cachear extensiones compiladas (archivos `.pyd` o `.dll`) en memoria o en el directorio de trabajo. Si se modifica el código fuente C++ pero no se limpia correctamente el caché, Python puede seguir usando la versión antigua del binario, causando comportamientos inesperados o "fantasmas" de código anterior.
Marcador Radiactivo (Canary Debugging): Es una técnica de debugging que consiste en añadir un marcador muy visible (como un `printf` con un mensaje único) en un punto específico del código para confirmar que se está ejecutando la versión correcta. Si el marcador aparece en los logs, confirmamos que el código nuevo se está ejecutando. Si no aparece pero el comportamiento sugiere que debería ejecutarse, entonces hay un problema de caché o compilación.
Hard Reset: Consiste en eliminar manualmente todos los artefactos de compilación (carpetas `build/`, archivos `.pyd`, `.dll`, `.so`) antes de recompilar. Esto asegura que no queden residuos de compilaciones anteriores que puedan interferir con la nueva versión.
Implementación
Se añade un marcador radiactivo (printf muy visible) dentro del `case 0x08` en `CPU.cpp` para confirmar que el opcode se está ejecutando con la versión correcta del código.
Componentes modificados
src/core/cpp/CPU.cpp: Añadido marcador radiactivo en el `case 0x08`.
Decisiones de diseño
El marcador se coloca al inicio del `case 0x08`, antes de cualquier otra operación, para que se ejecute inmediatamente cuando se detecte el opcode. El mensaje es muy visible (`!!! EJECUTANDO OPCODE 0x08 EN C++ !!!`) para que sea fácil de identificar en los logs, incluso si hay mucha salida.
Nota importante: Este marcador es temporal y debe eliminarse una vez que confirmemos que estamos ejecutando la versión correcta del código. Los `printf` ralentizan la ejecución, especialmente si se ejecutan frecuentemente.
Código añadido
case 0x08: // LD (nn), SP
{
// --- Step 0242: MARCADOR RADIACTIVO ---
// DEBUG: Confirmar ejecución real del fix
// Este printf es un "canario" para verificar que estamos ejecutando
// la versión correcta del código C++ y no una DLL/PYD cacheada.
printf("!!! EJECUTANDO OPCODE 0x08 EN C++ !!!\n");
// ---------------------------------------
uint16_t addr = fetch_word();
mmu_->write(addr, regs_->sp & 0xFF);
mmu_->write(addr + 1, (regs_->sp >> 8) & 0xFF);
cycles_ += 5;
return 5;
}
Instrucciones de Hard Reset
Para asegurar que no hay artefactos de compilación anteriores:
- Cerrar todas las terminales de Python: Cerrar cualquier ventana de PowerShell o CMD que esté ejecutando Python o el emulador.
- Eliminar carpeta `build/`: Si existe, eliminar manualmente la carpeta `build/` del proyecto.
- Eliminar archivos `.pyd`: Buscar y eliminar cualquier archivo `.pyd` en la raíz del proyecto (ej: `viboy_core*.pyd`).
- Recompilar: Ejecutar `.\rebuild_cpp.ps1` para recompilar desde cero.
- Ejecutar: Ejecutar `python main.py roms/tetris.gb` y observar los logs.
Archivos Afectados
src/core/cpp/CPU.cpp- Añadido marcador radiactivo en el `case 0x08`docs/bitacora/entries/2025-12-22__0242__hard-reset-marcador-radiactivo.html- Entrada de bitácora
Tests y Verificación
Para validar esta implementación, se debe:
- Realizar Hard Reset:
- Cerrar todas las terminales de Python.
- Eliminar manualmente la carpeta `build/` si existe.
- Eliminar cualquier archivo `.pyd` en la raíz del proyecto.
- Recompilar la extensión C++:
.\rebuild_cpp.ps1 - Ejecutar el emulador con Tetris:
python main.py roms/tetris.gb - Analizar los logs:
- Si se ve `!!! EJECUTANDO OPCODE 0x08 EN C++ !!!` mezclado con los logs del Francotirador: Confirmamos que el código es real. La CPU está ejecutando esa secuencia. El problema es CÓMO llegamos ahí (un salto incorrecto anterior).
- Si NO se ve el mensaje pero el Francotirador dice `OP:08`: El binario no se actualizó. Estamos corriendo una versión vieja fantasma. Necesitamos hacer un Hard Reset más agresivo o verificar que la compilación se completó correctamente.
Estado actual: Pendiente de ejecución y análisis de logs.
Fuentes Consultadas
- Pan Docs: Game Boy Pan Docs - Referencia general de arquitectura LR35902
- Documentación de Python: Extending Python on Windows - Gestión de extensiones compiladas en Windows
Nota: Esta implementación es una técnica de debugging estándar para verificar la ejecución de código compilado.
Integridad Educativa
Lo que Entiendo Ahora
- Problema de Caché en Windows: Python puede cachear extensiones compiladas, causando que se ejecute código antiguo incluso después de recompilar. Esto es especialmente problemático en Windows con archivos `.pyd`.
- Marcador Radiactivo: Añadir un marcador muy visible en un punto específico del código permite confirmar que se está ejecutando la versión correcta. Es una técnica de debugging estándar para verificar la ejecución de código compilado.
- Hard Reset: Eliminar manualmente todos los artefactos de compilación antes de recompilar asegura que no queden residuos de compilaciones anteriores.
- Análisis de Secuencias Anómalas: Si el log muestra una secuencia de instrucciones absurda (como múltiples `LD (nn), SP` en un bucle corto), puede indicar que estamos ejecutando datos en lugar de código, o que hay un problema de desalineamiento causado por una compilación anterior incorrecta.
Lo que Falta Confirmar
- Ejecución del Marcador: ¿Aparece el mensaje `!!! EJECUTANDO OPCODE 0x08 EN C++ !!!` en los logs? Esto confirmará que estamos ejecutando la versión correcta del código.
- Origen del Desalineamiento: Si el marcador aparece pero la secuencia sigue siendo absurda, el problema es que la CPU saltó incorrectamente a una zona de datos. Necesitamos investigar qué causó ese salto.
- Persistencia de Binarios: Si el marcador no aparece, confirmamos que hay un problema de caché. Necesitamos hacer un Hard Reset más agresivo o verificar la configuración de compilación.
Hipótesis y Suposiciones
Hipótesis principal: El problema de la secuencia absurda puede deberse a:
- Un salto incorrecto anterior que llevó a la CPU a una zona de datos (gráficos, tablas) en lugar de código.
- Un problema de caché de binarios en Windows que está ejecutando una versión antigua del código donde el opcode `0x08` no estaba implementado correctamente.
- Un desalineamiento causado por una implementación anterior incorrecta del opcode `0x08` (ej: si antes consumía 1 byte en lugar de 3, el PC habría avanzado incorrectamente).
El marcador radiactivo nos dirá cuál de estas hipótesis es correcta.
Próximos Pasos
- [ ] Realizar Hard Reset: Cerrar terminales, eliminar `build/` y archivos `.pyd`.
- [ ] Recompilar la extensión C++ con el marcador radiactivo.
- [ ] Ejecutar Tetris y capturar los logs.
- [ ] Analizar si aparece el mensaje `!!! EJECUTANDO OPCODE 0x08 EN C++ !!!`.
- [ ] Si aparece: Confirmar que el código es real y investigar el origen del salto incorrecto.
- [ ] Si no aparece: Hacer un Hard Reset más agresivo o verificar la configuración de compilación.
- [ ] Una vez confirmado, eliminar el marcador radiactivo para no ralentizar la ejecución.