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

Análisis Forense de la Traza: El Origen del 0x00

Fecha: 2025-12-22 Step ID: 0238 Estado: Draft

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 0xFD en 0x2B2A - donde el fallo se manifiesta.
  • Taint (Mancha): 0x00 en el registro A - el valor incorrecto.
  • Source (Fuente): LD A, (HL) en 0x2B25 - 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

  1. Fuente del valor en A: LD A, (HL) en 0x2B25 lee de WRAM.
  2. Dirección de memoria: HL apunta a 0xE645, 0xE646, etc. (WRAM).
  3. Valor leído: Siempre 0x00, pero el juego espera 0xFD.
  4. Patrón de incremento: HL se 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

  1. Rastrear hacia atrás: Buscar en el código de Tetris qué rutina debería escribir 0xFD en WRAM antes de llegar a 0x2B20.
  2. Verificar inicialización de WRAM: Comprobar si la MMU inicializa WRAM correctamente al arranque.
  3. Analizar registros I/O: Los registros 0xFF8C y 0xFF94 no están implementados. Verificar si esto afecta el flujo.
  4. 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 0xFD en WRAM?
  • Condición de bloqueo: ¿Por qué esa rutina no se ejecutó?
  • Registros I/O: ¿Los registros 0xFF8C y 0xFF94 afectan 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 0xFF8C y 0xFF94 necesitan implementación.
  • [ ] Buscar en el código de Tetris qué debería escribir 0xFD en WRAM.
  • [ ] Implementar el fix necesario (inicialización de WRAM o implementación de registros I/O).