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.
ROM Read Probe
Resumen
Este Step instrumenta el método MMU::read() para monitorear las lecturas en el área de ROM conmutada (0x4000-0x7FFF). El Step 0261 confirmó que MBC1 funciona (vemos cambios de banco), pero las escrituras en VRAM siguen siendo ceros. La hipótesis es que MMU::read() podría estar devolviendo ceros al leer del banco conmutado, a pesar de que el cambio de banco se registra correctamente. Esta instrumentación nos permitirá verificar qué valores está devolviendo realmente la MMU cuando el juego lee desde los bancos ROM seleccionados.
Concepto de Hardware
Lectura de ROM conmutada: Cuando un juego necesita acceder a datos almacenados en bancos ROM distintos del banco 0, primero selecciona el banco escribiendo en 0x2000-0x3FFF, y luego lee desde 0x4000-0x7FFF. El MBC1 mapea el banco seleccionado a este espacio de memoria, permitiendo que el juego acceda a hasta 16KB de datos del banco elegido.
El problema de los ceros en VRAM: Si el juego cambia de banco correctamente (vemos logs de cambio en el Step 0261), pero las escrituras en VRAM siguen siendo ceros, hay dos posibilidades:
- El juego está limpiando la VRAM intencionalmente: Algunos juegos escriben ceros en la VRAM antes de copiar los gráficos reales para asegurar que el área esté limpia.
- La lectura del banco conmutado devuelve ceros: Si
MMU::read()está devolviendo ceros cuando lee desde0x4000-0x7FFF, el juego copiará esos ceros a la VRAM, resultando en una pantalla vacía.
La sonda de lectura ROM: Para distinguir entre estos casos, necesitamos verificar qué valor está devolviendo realmente MMU::read() cuando el juego lee desde el área conmutada. Si devuelve ceros (o 0xFF), nuestra lógica de lectura de rom_data_ está fallando. Si devuelve valores variados (0x3E, 0xCD, etc.), entonces la lectura es correcta y el problema está en otro lado (posiblemente en la lógica de copia de datos a VRAM o en el timing).
Fuente: Pan Docs - "MBC1", "Memory Bank Controllers", "Memory Map"
Implementación
Se modificó el método read() de MMU.cpp para registrar las primeras 50 lecturas del área de ROM conmutada (0x4000-0x7FFF). El log incluye el Program Counter (PC) actual, la dirección leída, el banco actual, el offset calculado en rom_data_, y el valor devuelto.
Componentes modificados
- MMU::read(): Añadido contador estático
rom_read_counterpara limitar los logs a las primeras 50 lecturas (evitando saturar la salida). El log se imprime antes de devolver el valor, mostrando exactamente qué está leyendo el juego y qué valor se está devolviendo.
Decisiones de diseño
Límite de 50 lecturas: Para evitar saturar los logs con miles de lecturas, limitamos el registro a las primeras 50. Esto es suficiente para verificar si la lectura está funcionando correctamente durante la inicialización del juego, cuando se cargan los gráficos principales.
Información completa en el log: El log incluye el PC actual (para correlacionar con las instrucciones del juego), la dirección leída, el banco actual, el offset calculado en rom_data_, y el valor devuelto. Esto nos permite verificar si el cálculo de offset es correcto y si el valor devuelto corresponde a los datos reales de la ROM.
Log después del cálculo de offset: El log se imprime después de calcular el offset pero antes de devolver el valor, asegurando que vemos exactamente qué valor se está devolviendo al juego.
Archivos Afectados
src/core/cpp/MMU.cpp- Modificado métodoread()para loguear las primeras 50 lecturas del área de ROM conmutada (Step 0262).
Tests y Verificación
Para validar esta instrumentación:
- Recompilar:
.\rebuild_cpp.ps1 - Ejecutar:
python main.py roms/pkmn.gb(Pokémon Red es ideal porque tiene 1024KB de ROM y necesita múltiples bancos). - Observar los logs:
- Buscar
[ROM-READ] PC:XXXX -> Read ROM[YYYY] (Bank N, Offset ZZZZ) = VV- Muestra qué está leyendo el juego y qué valor se está devolviendo. - Si Val = 00: La lectura está devolviendo ceros, lo que indica un fallo en la carga de ROM o en el cálculo de offset. El vector
rom_data_podría estar vacío o el offset calculado podría estar fuera de rango. - Si Val variados (3E, CD, etc.): La lectura es correcta y está devolviendo datos reales de la ROM. En este caso, si la VRAM sigue vacía, el problema está en otro lado (posiblemente en la lógica de copia de datos a VRAM o en el timing).
- Buscar
Validación esperada: Si MBC1 funciona correctamente y la ROM está cargada, deberías ver valores variados (no solo ceros) en las lecturas del área conmutada. Si todos los valores son ceros, hay un problema en la carga de ROM o en el cálculo de offset.
Correlación con VRAM: Si las lecturas ROM devuelven valores variados pero las escrituras en VRAM siguen siendo ceros, el problema está en la lógica de copia de datos a VRAM o en el timing (el juego podría estar limpiando la VRAM antes de copiar los gráficos reales).
Fuentes Consultadas
- Pan Docs: MBC1
- Pan Docs: Memory Bank Controllers
- Pan Docs: Memory Map
Integridad Educativa
Lo que Entiendo Ahora
- Lectura de ROM conmutada: Cuando el juego lee desde
0x4000-0x7FFF, el MBC1 mapea el banco seleccionado a este espacio. El cálculo de offset es(banco * 0x4000) + (addr - 0x4000). - Diagnóstico de lectura: Si el juego cambia de banco pero las escrituras en VRAM siguen siendo ceros, necesitamos verificar si la lectura está devolviendo los datos correctos o si está devolviendo ceros.
- Validación de datos: Si las lecturas ROM devuelven valores variados, la lectura es correcta y el problema está en otro lado. Si devuelven ceros, hay un problema en la carga de ROM o en el cálculo de offset.
Lo que Falta Confirmar
- Valores devueltos: ¿Qué valores está devolviendo realmente
MMU::read()cuando el juego lee desde el área conmutada? Los logs nos dirán si devuelve ceros o valores variados. - Correlación con VRAM: Si las lecturas ROM devuelven valores variados pero la VRAM sigue vacía, ¿el problema está en la lógica de copia de datos a VRAM o en el timing?
- Limpieza intencional: ¿El juego está escribiendo ceros en la VRAM intencionalmente antes de copiar los gráficos reales? Si es así, necesitamos esperar más tiempo para ver los datos reales.
Hipótesis y Suposiciones
Hipótesis principal: Si MBC1 funciona (vemos cambios de banco en el Step 0261) pero las escrituras en VRAM siguen siendo ceros, es posible que:
- La lectura del banco conmutado devuelve ceros: Si
MMU::read()está devolviendo ceros cuando lee desde0x4000-0x7FFF, el juego copiará esos ceros a la VRAM. Esto indicaría un fallo en la carga de ROM o en el cálculo de offset. - El juego está limpiando la VRAM intencionalmente: Algunos juegos escriben ceros en la VRAM antes de copiar los gráficos reales. Si este es el caso, necesitamos esperar más tiempo para ver los datos reales.
- La lectura es correcta pero el problema está en otro lado: Si las lecturas ROM devuelven valores variados pero la VRAM sigue vacía, el problema está en la lógica de copia de datos a VRAM o en el timing.
Esta instrumentación nos permitirá distinguir entre estos casos y determinar dónde está el problema real.
Próximos Pasos
- [ ] Ejecutar
python main.py roms/pkmn.gby observar los logs de lectura ROM. - [ ] Si las lecturas devuelven ceros, verificar la carga de ROM y el cálculo de offset.
- [ ] Si las lecturas devuelven valores variados, verificar la lógica de copia de datos a VRAM o el timing.
- [ ] Correlacionar las lecturas ROM con las escrituras en VRAM para determinar si los datos correctos están llegando a la VRAM.
- [ ] Si el juego está limpiando la VRAM intencionalmente, esperar más tiempo para ver los datos reales.