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.
MBC Activity Monitor
Resumen
Este Step instrumenta el código MBC1 implementado en el Step 0260 para monitorear cambios de banco ROM y detectar intentos de lectura fuera de rango. El objetivo es confirmar si el juego está seleccionando bancos de ROM correctamente y si nuestra MMU está respondiendo adecuadamente. Si el juego intenta cambiar de banco pero no vemos logs, significa que hay un problema en la lógica de detección. Si vemos cambios de banco pero la VRAM sigue vacía, el problema está en la lectura de datos desde los bancos correctos.
Concepto de Hardware
MBC1 (Memory Bank Controller 1) es un chip presente en cartuchos grandes (>32KB) que permite al juego cambiar dinámicamente qué banco de ROM aparece en el espacio de memoria `0x4000-0x7FFF`. El juego selecciona el banco escribiendo un valor en el rango `0x2000-0x3FFF` (que normalmente es ROM de solo lectura, pero el MBC intercepta estas escrituras).
Cuando un juego necesita acceder a datos gráficos, código o recursos almacenados en bancos ROM distintos del banco 0, primero debe seleccionar el banco correcto escribiendo en `0x2000-0x3FFF`, y luego leer desde `0x4000-0x7FFF`. Si el juego intenta cambiar de banco pero el MBC no responde, el juego leerá datos incorrectos (posiblemente ceros o basura) y copiará esos datos a la VRAM, resultando en una pantalla vacía.
Diagnóstico de Integridad: Si implementamos MBC1 pero los logs de VRAM siguen mostrando ceros, necesitamos saber: 1. ¿El juego está intentando cambiar de banco? (Si no vemos logs de cambio, el juego puede estar fallando antes de llegar ahí). 2. ¿La lectura desde el banco seleccionado está funcionando? (Si vemos cambios de banco pero lecturas fuera de rango, hay un error en el cálculo de offset).
Fuente: Pan Docs - "MBC1", "Memory Bank Controllers", "Cartridge Types"
Implementación
Se modificó el método `write()` de `MMU.cpp` para registrar cambios de banco ROM solo cuando el banco realmente cambia (evitando saturar los logs con escrituras repetidas al mismo banco). También se añadió un log de seguridad en el método `read()` para detectar intentos de lectura fuera del rango válido de la ROM.
Componentes modificados
- MMU::write(): Modificado para comparar el banco nuevo con el banco actual antes de loguear. Solo se registra cuando hay un cambio real.
- MMU::read(): Añadido log crítico cuando se intenta leer desde un offset que excede el tamaño de la ROM cargada.
Decisiones de diseño
Log condicional de cambios de banco: En lugar de loguear cada escritura en `0x2000-0x3FFF`, solo logueamos cuando el banco realmente cambia. Esto evita saturar los logs con escrituras repetidas al mismo banco (algunos juegos escriben el mismo valor múltiples veces por seguridad).
Log crítico de lecturas fuera de rango: Si el cálculo de offset es incorrecto o el banco seleccionado excede el tamaño de la ROM, el juego leerá datos inválidos. Este log nos permite detectar estos casos y corregir la lógica de cálculo de offset o validación de bancos.
Formato de log: Los logs incluyen el Program Counter (PC) actual para correlacionar los cambios de banco con las instrucciones del juego que los provocan. Esto facilita el debugging si hay problemas de sincronización.
Archivos Afectados
src/core/cpp/MMU.cpp- Modificado métodowrite()para loguear cambios de banco ROM solo cuando cambian (Step 0261). Modificado métodoread()para loguear intentos de lectura fuera de rango (Step 0261).
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
[MBC1] PC:XXXX -> ROM Bank Switch: N -> M- Confirma que el juego está cambiando bancos. - Si ves cambios de banco (ej:
1 -> 2,2 -> 6), el juego está intentando acceder a datos de diferentes bancos. - Si NO ves cambios, el juego puede estar fallando antes de llegar a la selección de bancos, o puede estar usando un cartucho sin MBC.
- Buscar
[MBC1 CRITICAL]- Indica que hay un error en el cálculo de offset o que el banco seleccionado excede el tamaño de la ROM.
- Buscar
Validación esperada: Si MBC1 funciona correctamente, deberías ver múltiples cambios de banco durante la inicialización del juego, especialmente cuando el juego carga gráficos desde diferentes bancos ROM.
Fuentes Consultadas
- Pan Docs: MBC1
- Pan Docs: Memory Bank Controllers
- Pan Docs: Cartridge Types
Integridad Educativa
Lo que Entiendo Ahora
- MBC1 Banking: El juego selecciona bancos escribiendo en `0x2000-0x3FFF`, pero el MBC intercepta estas escrituras y no modifican la ROM (que es de solo lectura). El banco seleccionado aparece en `0x4000-0x7FFF`.
- Diagnóstico de actividad: Si el juego no cambia de banco, puede estar fallando antes de llegar a la selección de bancos, o puede estar usando un cartucho sin MBC. Si cambia de banco pero la VRAM sigue vacía, el problema está en la lectura de datos desde los bancos correctos.
- Validación de offset: El cálculo de offset `(banco * 0x4000) + (addr - 0x4000)` debe validarse para evitar lecturas fuera de rango que resulten en datos inválidos.
Lo que Falta Confirmar
- Actividad del juego: ¿El juego está realmente intentando cambiar de banco? Los logs nos dirán si vemos cambios de banco o si el juego nunca llega a esa parte del código.
- Integridad de lectura: ¿Las lecturas desde los bancos seleccionados están funcionando correctamente? El log crítico nos dirá si hay errores en el cálculo de offset.
- Correlación con VRAM: Si vemos cambios de banco pero la VRAM sigue vacía, necesitamos verificar si el juego está leyendo los datos correctos desde los bancos seleccionados.
Hipótesis y Suposiciones
Hipótesis principal: Si implementamos MBC1 en el Step 0260 pero los logs de VRAM siguen mostrando ceros, es posible que: 1. El juego no esté cambiando de banco (falla antes de llegar ahí). 2. El juego esté cambiando de banco pero leyendo datos incorrectos (error en el cálculo de offset). 3. El juego esté leyendo datos correctos pero no copiándolos a la VRAM (problema en la lógica de copia de datos).
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 cambio de banco. - [ ] Si vemos cambios de banco, verificar que los datos leídos desde esos bancos sean correctos (no ceros).
- [ ] Si no vemos cambios de banco, investigar por qué el juego no llega a la selección de bancos.
- [ ] Si vemos logs críticos de lecturas fuera de rango, corregir el cálculo de offset o la validación de bancos.
- [ ] Correlacionar los cambios de banco con las escrituras en VRAM para determinar si los datos correctos están llegando a la VRAM.