⚠️ 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: La Traza de 500 Instrucciones Revela la Configuración de la PPU

Fecha: 2025-12-20 Step ID: 0155 Estado: 🔍 DRAFT

Resumen

Se ejecutó el emulador con la traza extendida a 500 instrucciones para analizar qué ocurre después de que el bucle de inicialización termina. El análisis reveló que las 500 instrucciones capturadas están todas dentro del mismo bucle de limpieza de memoria (0x0293-0x0295), ejecutándose más de 100 iteraciones. Al final del log, se observa una salida del bucle en la dirección 0x0297 (opcode 0x0D, DEC C), pero el emulador se detiene al alcanzar el límite de 500 instrucciones antes de poder observar qué ocurre después.

Concepto de Hardware

Las ROMs de Game Boy ejecutan rutinas de inicialización complejas al arrancar. Estas rutinas típicamente incluyen:

  • Limpieza de memoria: Múltiples bucles que escriben valores específicos (generalmente 0x00) en regiones de memoria RAM para asegurar un estado inicial conocido.
  • Configuración de hardware: Escritura de valores en los registros de hardware (LCDC, BGP, SCY, SCX, etc.) para configurar la PPU y otros componentes.
  • Inicialización de variables: Establecimiento de valores iniciales para variables del juego.

Los bucles de limpieza de memoria son críticos porque garantizan que no haya datos residuales de ejecuciones anteriores. Estos bucles pueden ser anidados (un bucle dentro de otro) y pueden ejecutarse cientos o miles de veces dependiendo del tamaño de la región de memoria a limpiar.

Fuente: Pan Docs - Boot ROM, Memory Map, Initialization Routines

Análisis de la Traza

Se ejecutó el emulador con la ROM de Tetris y se capturó una traza completa de 500 instrucciones. El análisis de la traza reveló los siguientes hallazgos:

Patrón de Ejecución Observado

Las 500 instrucciones capturadas muestran un patrón repetitivo consistente en tres instrucciones:

  • 0x0293: LDD (HL), A (opcode 0x32) - Escribe el valor de A en la dirección apuntada por HL y decrementa HL
  • 0x0294: DEC B (opcode 0x05) - Decrementa el registro B
  • 0x0295: JR NZ, e (opcode 0x20) - Salta relativo si el flag Z no está activo

Este bucle se ejecuta más de 100 veces antes de que el límite de 500 instrucciones se alcance.

Salida del Bucle

Al final del log (línea 16903), se observa la salida exitosa del bucle:

[DEBUG DEC B] B antes: 0x01, Z antes: 0
[DEBUG DEC B] B después: 0x00, Z después: 1
[DEBUG JR NZ] B: 0x00, Z: 1, offset: 0xFC
[DEBUG JR NZ] NO SALTANDO, continuando en PC: 0x0297

El PC continúa en 0x0297, donde el opcode es 0x0D (DEC C), que está correctamente implementado en el código C++.

Limitación del Límite de Traza

El emulador se detiene al alcanzar el límite de 500 instrucciones justo después de salir del bucle, impidiendo observar qué ocurre después. Esto sugiere que:

  • El bucle de limpieza es muy extenso (más de 100 iteraciones)
  • Puede haber múltiples bucles anidados que consumen la mayoría de las 500 instrucciones
  • Necesitamos aumentar aún más el límite o implementar un mecanismo de traza más inteligente que se active solo después de ciertos puntos de interés

Archivos Afectados

  • temp_trace.log - Archivo temporal con la traza completa de 500 instrucciones
  • src/core/cpp/CPU.cpp - Código fuente de la CPU (sin modificaciones en este paso)

Tests y Verificación

Este paso fue puramente de análisis, sin modificaciones de código. La verificación consistió en:

  • Ejecución del emulador: python main.py roms/tetris.gb > temp_trace.log 2>&1
  • Análisis de la traza: Revisión de las 500 líneas de traza de CPU para identificar patrones
  • Verificación de opcodes: Confirmación de que el opcode 0x0D (DEC C) en 0x0297 está implementado
  • Conteo de iteraciones: Cálculo aproximado de cuántas veces se ejecuta el bucle antes de salir

Resultado: Se confirmó que el bucle termina correctamente, pero el límite de 500 instrucciones es insuficiente para observar la secuencia completa de inicialización.

Fuentes Consultadas

  • Pan Docs: Boot ROM, Memory Map, Initialization Routines
  • GBEDG: CPU Instruction Set (opcode 0x0D - DEC C)

Integridad Educativa

Lo que Entiendo Ahora

  • Bucles de inicialización: Las ROMs ejecutan bucles extensos de limpieza de memoria que pueden consumir cientos de instrucciones antes de avanzar a la configuración de hardware.
  • Límites de traza: Los límites fijos de traza pueden ser insuficientes para observar secuencias completas de inicialización, especialmente cuando hay bucles anidados.
  • Patrones de ejecución: El patrón LDD (HL), A -> DEC B -> JR NZ es común en rutinas de limpieza de memoria y se ejecuta hasta que B llega a 0x00.

Lo que Falta Confirmar

  • Secuencia post-bucle: Qué instrucciones se ejecutan después de 0x0297 y si hay más bucles de limpieza o si comienza la configuración de hardware.
  • Configuración de PPU: Si y cuándo el juego comienza a escribir en los registros de hardware (0xFF40-0xFF4F) para configurar la PPU.
  • Opcodes faltantes: Si hay opcodes no implementados que bloquean el progreso después de los bucles de limpieza.

Hipótesis y Suposiciones

Hipótesis principal: Después de que todos los bucles de limpieza terminan, el juego debería comenzar a configurar el hardware, especialmente los registros de la PPU. Esperamos ver instrucciones como LDH (n), A (opcode 0xE0) escribiendo en registros como 0xFF40 (LCDC) o 0xFF47 (BGP).

Suposición: El límite de 500 instrucciones es insuficiente porque el bucle de limpieza se ejecuta más de 100 veces, consumiendo la mayoría de las instrucciones disponibles antes de que podamos observar la secuencia post-inicialización.

Próximos Pasos

  • [ ] Aumentar el límite de traza a 1000 o 2000 instrucciones para capturar más información
  • [ ] Implementar un mecanismo de traza condicional que se active solo después de ciertos puntos de interés (ej: después de salir de bucles conocidos)
  • [ ] Analizar la ROM directamente para identificar qué opcodes están en las direcciones después de 0x0297
  • [ ] Verificar si hay más bucles de limpieza después de 0x0297 o si comienza la configuración de hardware
  • [ ] Identificar el primer opcode no implementado que bloquea el progreso (si existe)