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.
Triage Real "No Veo Gráficos" (MBC Requerido + VRAM Raw + Headless Funcional)
Resumen
Implementación de herramientas de diagnóstico robustas para triage real del problema "no veo gráficos". Añadido preflight check en headless para detectar módulo C++ no compilado, API de lectura RAW en MMU para diagnóstico sin restricciones, herramienta de análisis de headers ROM para detectar soporte MBC, y contadores de writes MBC para evidencia de banking. Modificado headless para usar read_raw() en VRAMnz y generar resumen de MBC writes. Objetivo: determinar causa raíz (MBC/banking vs PPU/paletas vs CPU/IRQ) con evidencia confiable.
Concepto de Hardware
Memory Bank Controllers (MBC): Los cartuchos de Game Boy usan controladores de banco de memoria para mapear ROMs grandes (>32KB) y RAM externa en el espacio de direcciones de 16 bits. Los writes a rangos 0x0000-0x7FFF se interpretan como comandos MBC (no como escrituras a ROM). Tipos comunes: MBC1 (0x01-0x03), MBC3 (0x0F-0x13), MBC5 (0x19-0x1E). Si el emulador no soporta el MBC requerido por la ROM, los writes de banking no tienen efecto y el juego no puede acceder a bancos ROM/RAM necesarios, resultando en ejecución incorrecta o bloqueo.
Restricciones de Acceso a VRAM: En modo PPU Mode 3 (transferencia de datos a OAM), la CPU no puede acceder a VRAM (0x8000-0x9FFF). Si se intenta leer, el hardware devuelve 0xFF. Esto puede falsear diagnósticos que usan mmu.read() para medir VRAMnz. Para diagnóstico confiable, se necesita acceso RAW que bypass estas restricciones.
Header ROM (0x0100-0x014F): Contiene metadatos del cartucho: título (0x0134-0x0143), tipo de cartucho (0x0147), tamaño ROM (0x0148), tamaño RAM (0x0149), flag CGB (0x0143). El tipo de cartucho determina qué MBC se requiere.
Implementación
Implementación en 5 fases: preflight check, API RAW, ROM info, contadores MBC, y modificación headless.
Fase A: Headless "A Prueba de Mentiras"
Añadido preflight check en tools/rom_smoke_0442.py que verifica:
- Import de
viboy_coreexitoso - Creación de instancia
PyMMUexitosa (detecta errores de linking)
Si falla, imprime error claro con instrucciones de compilación y exit code != 0. Esto evita que headless genere tablas falsas cuando el módulo no está compilado.
Fase B: API de Lectura RAW en MMU
Añadidos métodos en MMU C++ y wrapper Cython:
read_raw(uint16_t addr): Leememory_[]directo sin restriccionesdump_raw_range(uint16_t start, uint16_t length, uint8_t* buffer): Dump rápido de rango de memoria
WARNING: Solo para diagnóstico/tools, NO para emulación normal. Bypassa restricciones de modo PPU, banking, etc.
Fase C: ROM Info Tool
Creado tools/rom_info_0450.py que:
- Lee header ROM (0x0100-0x014F)
- Extrae: título, tipo cartucho, MBC name, CGB flag, tamaños ROM/RAM
- Detecta si el emulador soporta el MBC requerido (según
SUPPORTED_MBCS) - Imprime tabla: ROM | cart_type(hex) | MBC name | CGB flag | soportado
Fase D: Contadores de MBC Writes
Añadidos contadores en MMU para writes a rangos MBC (0x0000-0x7FFF):
mbc_write_count_: Total de writes MBC- Ring buffer de últimos 8 writes: addr, val, PC
- Log limitado (primeras 20) con rango identificado (RAM_EN, ROM_BANK, RAM_BANK, MODE)
- Método
log_mbc_writes_summary()para resumen al final de ejecución
Fase E: Modificación Headless
Modificado tools/rom_smoke_0442.py:
- Añadido método
_sample_vram_nonzero_raw()que usaread_raw() - Métricas incluyen tanto
vram_nonzero(normal) comovram_nonzero_raw(RAW) - Resumen muestra ambas métricas para comparación
- Al final, llama a
log_mbc_writes_summary()si está disponible - Diagnóstico preliminar compara VRAM normal vs RAW para detectar restricciones de acceso
Archivos Afectados
tools/rom_smoke_0442.py- Preflight check, método _sample_vram_nonzero_raw(), métricas RAW, log MBC writessrc/core/cpp/MMU.hpp- Declaraciones read_raw(), dump_raw_range(), log_mbc_writes_summary(), contadores MBCsrc/core/cpp/MMU.cpp- Implementación read_raw(), dump_raw_range(), log_mbc_writes_summary(), lógica contadores MBC en write()src/core/cython/mmu.pxd- Declaraciones Cython de nuevos métodossrc/core/cython/mmu.pyx- Wrappers Python de read_raw(), dump_raw_range(), log_mbc_writes_summary()tools/rom_info_0450.py- Herramienta nueva para análisis de headers ROM
Tests y Verificación
Compilación: BUILD_EXIT=0, TEST_BUILD_EXIT=0
Preflight Check: Verificado que headless falla correctamente si módulo no compilado:
# Test: Intentar ejecutar sin compilar
python3 tools/rom_smoke_0442.py roms/mario.gbc
# Resultado: Error claro con instrucciones, exit code != 0
ROM Info Tool: Verificado que detecta correctamente tipos MBC:
# Test: Analizar ROMs
python3 tools/rom_info_0450.py roms/mario.gbc roms/pkmn.gb
# Resultado: Tabla con cart_type, MBC name, soporte
Validación Nativa: Módulo C++ compilado correctamente, métodos RAW disponibles en Python.
Fuentes Consultadas
- Pan Docs: Memory Bank Controllers (MBC1/MBC3/MBC5)
- Pan Docs: Cartridge Header (0x0100-0x014F)
- Pan Docs: VRAM Access Restrictions (Mode 3)
Integridad Educativa
Lo que Entiendo Ahora
- MBC Writes: Los writes a 0x0000-0x7FFF son comandos MBC, no escrituras a ROM. Si el emulador no soporta el MBC, estos writes no tienen efecto y el juego no puede acceder a bancos necesarios.
- VRAM Access Restrictions: En modo PPU Mode 3, la CPU no puede leer VRAM. Para diagnóstico confiable, se necesita acceso RAW que bypass estas restricciones.
- ROM Header: El tipo de cartucho (0x0147) determina qué MBC se requiere. Es crítico verificar soporte antes de ejecutar.
Lo que Falta Confirmar
- MBC Implementation: Verificar qué MBCs están realmente implementados en el emulador (MBC1, MBC3, MBC5 según código).
- VRAM RAW vs Normal: Ejecutar comparación real para verificar si hay diferencia entre read() y read_raw() en VRAMnz.
- MBC Write Patterns: Analizar patrones de writes MBC en ROMs reales para determinar si banking está funcionando.
Hipótesis y Suposiciones
Hipótesis Principal: Si una ROM requiere MBC no soportado, los writes de banking no tienen efecto, el juego no puede acceder a bancos ROM/RAM necesarios, y el framebuffer queda blanco porque el código de inicialización gráfica está en un banco no accesible.
Suposición: read_raw() será más confiable que read() para diagnóstico VRAMnz
porque bypassa restricciones de modo PPU. Esto se validará en ejecución real.
Próximos Pasos
- [ ] Ejecutar
tools/rom_info_0450.pysobre todas las ROMs para clasificar por MBC - [ ] Ejecutar headless con VRAM RAW y MBC writes para 4 ROMs (Mario, Pokémon, Tetris, Tetris DX)
- [ ] Analizar resultados: PC progresa + MBC writes existen + VRAM raw nonzero
- [ ] Determinar causa raíz: MBC/banking vs PPU/paletas vs CPU/IRQ
- [ ] Step 0451: Implementar MBC faltante o corregir bug identificado