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.
Análisis Forense de la Traza: El Origen del 0x00
Resumen
El análisis de la traza del Step 0237 reveló el origen del valor incorrecto en el acumulador.
El bucle en 0x2B20-0x2B2C ejecuta una secuencia que lee de memoria WRAM mediante
LD A, (HL) en 0x2B25, pero obtiene 0x00 cuando el juego
espera 0xFD. El problema no está en la carga del acumulador, sino en que la memoria
WRAM no contiene los valores esperados porque una rutina de inicialización no se ejecutó o falló.
Concepto de Hardware
Reverse Taint Analysis (Análisis de Mancha Inverso): Técnica de depuración donde se rastrea un valor incorrecto ("mancha") desde su manifestación (sink) hasta su origen (source).
- Sink (Sumidero):
CP 0xFDen0x2B2A- donde el fallo se manifiesta. - Taint (Mancha):
0x00en el registroA- el valor incorrecto. - Source (Fuente):
LD A, (HL)en0x2B25- la instrucción que introduce la mancha.
Sin embargo, el análisis reveló que la fuente no es el problema: LD A, (HL) lee
correctamente de memoria. El problema real es que la memoria WRAM en las direcciones apuntadas
por HL contiene 0x00 en lugar de 0xFD.
Esto desplaza el problema: ¿Quién debería haber escrito 0xFD en esas direcciones
de WRAM antes? Probablemente una rutina de inicialización o copia de datos que no se
ejecutó o falló silenciosamente.
Análisis de la Traza
Secuencia de Instrucciones Identificada
2B20: 23 → INC HL (HL se incrementa: E644→E645, E645→E646...)
2B21: F0 8C → LDH A, (8C) (Lee I/O 0xFF8C → A=44, 48, 4C, 50...)
2B23: E0 94 → LDH (94), A (Escribe A en I/O 0xFF94)
2B25: 7E → LD A, (HL) (Lee memoria en HL → A=00 SIEMPRE)
2B26: FE FF → CP 0xFF (Compara A con 0xFF)
2B28: 28 C7 → JR Z, -57 (Salta si A==0xFF)
2B2A: FE FD → CP 0xFD (Compara A con 0xFD) ← AQUÍ FALLA
2B2C: 20 0E → JR NZ, +14 (Salta si A!=0xFD → vuelve a 2B20)
Hallazgos Clave
- Fuente del valor en A:
LD A, (HL)en0x2B25lee de WRAM. - Dirección de memoria:
HLapunta a0xE645,0xE646, etc. (WRAM). - Valor leído: Siempre
0x00, pero el juego espera0xFD. - Patrón de incremento:
HLse incrementa en cada iteración, sugiriendo un bucle de verificación.
Hipótesis del Problema
El código parece estar verificando que una región de WRAM contiene valores específicos (0xFD).
Estos valores deberían haber sido escritos por una rutina de inicialización anterior que:
- No se ejecutó (bloqueada por una condición previa que nunca se cumplió).
- Falló silenciosamente (error en el cálculo de direcciones o condición de salida).
- Escribió en una dirección diferente (error de offset o cálculo de dirección).
Archivos Afectados
docs/bitacora/entries/2025-12-22__0238__analisis-trace-forense.html- Este análisis
Próximos Pasos de Investigación
- Rastrear hacia atrás: Buscar en el código de Tetris qué rutina debería escribir
0xFDen WRAM antes de llegar a0x2B20. - Verificar inicialización de WRAM: Comprobar si la MMU inicializa WRAM correctamente al arranque.
- Analizar registros I/O: Los registros
0xFF8Cy0xFF94no están implementados. Verificar si esto afecta el flujo. - Buscar rutinas de copia: Buscar instrucciones
LDI,LDD, o bucles de copia que deberían haber poblado WRAM.
Fuentes Consultadas
- Pan Docs: CPU Instruction Set - Instrucciones LD, LDH, CP, JR
- Pan Docs: Memory Map - WRAM, HRAM, I/O Ports
- Técnicas de depuración: Reverse Taint Analysis
Integridad Educativa
Lo que Entiendo Ahora
- Análisis de traza: La técnica de "Reverse Taint Analysis" permite rastrear valores incorrectos hasta su origen.
- Bucle de verificación: El código está verificando que la memoria contiene valores esperados, no cargando valores.
- Problema desplazado: El problema no está en la lectura, sino en que la memoria no fue inicializada correctamente.
Lo que Falta Confirmar
- Rutina de inicialización: ¿Qué código debería escribir
0xFDen WRAM? - Condición de bloqueo: ¿Por qué esa rutina no se ejecutó?
- Registros I/O: ¿Los registros
0xFF8Cy0xFF94afectan el flujo?
Hipótesis y Suposiciones
Hipótesis principal: Una rutina de inicialización que debería copiar datos a WRAM no se ejecutó porque una condición previa (quizás relacionada con registros I/O no implementados) nunca se cumplió, dejando WRAM sin inicializar.
Próximos Pasos
- [ ] Expandir el rango de trazado hacia atrás para encontrar la rutina de inicialización.
- [ ] Verificar si los registros I/O
0xFF8Cy0xFF94necesitan implementación. - [ ] Buscar en el código de Tetris qué debería escribir
0xFDen WRAM. - [ ] Implementar el fix necesario (inicialización de WRAM o implementación de registros I/O).