This project is educational and Open Source. No code is copied from other emulators. Implementation based solely on technical documentation and permitted tests.
Extended Analysis and Alternative Techniques
Summary
Implementation of alternative analysis techniques to identify when tiles are loaded in Pokémon Red. Analysis of Step 0295 confirmed that the loading code does NOT exist in the first 12 seconds (all accesses are cleanup from PC:0x36E3). Additional monitors were implemented to track state changes, screen transitions, VRAM access timelines, and initial VRAM dump.
Aim: Run extended analysis (30-60 seconds) and detect patterns that indicate transitions to phases of the game where tiles would be loaded.
Hardware Concept
Game Initialization Phases
Game Boy games typically have multiple initialization phases:
- Boot/Reset: Basic hardware initialization
- Nintendo logo: If there is boot ROM, it shows the logo
- Title screen: Main game menu
- Menus: Option selection
- Main game screen: Where the game is rendered
The tiles can be loaded in different phases depending on the screen to be displayed. The loading code may not exist in the initial phase (first 12 seconds) and appear later.
Tiles pre-loading
Some games pre-load basic tiles during initialization, while others load tiles dynamically when changing screens. The tiles can be compressed in ROM and decompressed before being loaded into VRAM.
Checking the initial state of VRAM after loading the ROM allows you to determine if the game expects pre-loaded data or if the loading is the responsibility of the game code.
Screen Transitions
Screen changes are usually accompanied by:
- Scroll changes (SCX/SCY)
- Tilemap changes
- Loading new tiles
- Palette changes
Detecting these changes allows you to identify moments where tiles could be loaded.
Code Jumps and State Changes
Large jumps in the Program Counter (PC) can indicate transitions to new routines or phases of the game. Significant changes in records (e.g. HL) can also indicate context changes.
Fountain: Pan Docs - "Video RAM (VRAM)", "Scroll Registers (SCX/SCY)", "Tile Data", "CPU Instruction Set"
Implementation
Implemented four additional monitors and a dump function for extended analysis:
Monitor [STATE-CHANGE] - Game State Changes
Detects state changes that could indicate transitions to new screens or phases where tiles would be loaded.
- big jumps: Detects JP nn (0xC3) or CALL nn (0xCD) instructions with jumps greater than 0x1000 bytes
- Changes in HL: Detects significant changes in the HL register (more than 0x1000 bytes difference)
- Sample Limit: Reports up to 50 large jumps and 30 changes in HL to avoid saturation
Location: src/core/cpp/CPU.cpp- FunctionCPU::step()
Monitor [SCREEN-TRANSITION] - Screen Transitions
Detects patterns that indicate screen transitions, which could be moments where new tiles are loaded.
- Periodic verification: Checks for changes in SCX (0xFF43) and SCY (0xFF42) every 1000 instructions
- Change detection: Reports when SCX or SCY changes value
- Sample Limit: Report up to 20 transitions to avoid saturation
Location: src/core/cpp/CPU.cpp- FunctionCPU::step()
Monitor [TIMELINE-VRAM] - VRAM Access Timeline
Create a timeline of VRAM accesses with relative timestamps to identify temporal patterns.
- Integration with [VRAM-ACCESS-GLOBAL]: Reported when VRAM access is detected
- Relative time: Calculates approximate time in seconds from start (based on instruction_counter)
- Format:
[TIMELINE-VRAM] T+~Xs | PC:0xXXXX | Write XXXX=XX | DATA/CLEAR - Sample Limit: Report up to 200 samples to avoid saturation
Location: src/core/cpp/CPU.cpp- Inside the block[VRAM-ACCESS-GLOBAL]
dump_vram_initial_state() Function - Initial Dump of VRAM
Create a detailed dump of the initial VRAM state after loading the ROM to check for pre-loaded data.
- Tile Data: Dump of the first 128 bytes (8 tiles) in hexadecimal format
- Tile Map: Dump of the first 64 bytes of the tilemap in hexadecimal format
- Format: Hexadecimal address followed by 16 bytes per line
Location: src/core/cpp/MMU.cpp- FunctionMMU::dump_vram_initial_state()
Call: Called automatically fromMMU::load_rom()after loading the ROM
Design Decisions
- Sample limits: All monitors have limits to avoid log and context saturation
- Periodic verification: [SCREEN-TRANSITION] checks every 1000 instructions to balance detection and performance
- Integration with existing monitors: [TIMELINE-VRAM] integrates with [VRAM-ACCESS-GLOBAL] to avoid duplicating logic
- Initial dump: It is executed only once when loading the ROM so as not to affect performance during execution
Affected Files
src/core/cpp/CPU.cpp- Added [STATE-CHANGE], [SCREEN-TRANSITION] and [TIMELINE-VRAM] monitorssrc/core/cpp/MMU.cpp- Added functiondump_vram_initial_state()and call fromload_rom()src/core/cpp/MMU.hpp- Added declarationdump_vram_initial_state()
Tests and Verification
The implementation was validated by:
- Successful build: Cython extension compiled without errors
- C++ Compiled Module Validation: Monitors are built into the execution loop
Next verification steps:
- Run the emulator for 30-60 seconds with Pokémon Red
- Redirect output to a log file
- Analyze the logs to identify:
- If accesses with data appear after 12 seconds
- If state changes are detected that indicate transitions
- If there is data pre-loaded in VRAM
- If the timeline shows temporal patterns
Suggested run command:
python main.py roms/pkmn.gb > debug_step_0297_extended.log 2>&1
Suggested analysis commands(PowerShell):
# Search for accesses with data after 12 seconds
Select-String -Path "debug_step_0297_extended.log" -Pattern "\[TIMELINE-VRAM\].*T\+~1[2-9]|T\+~[2-9][0-9]|T\+~[0-9][0-9][0-9].*DATA" | Select-Object -First 50
# Search for state changes
Select-String -Path "debug_step_0297_extended.log" -Pattern "\[STATE-CHANGE\]" | Select-Object -First 50
# Find screen transitions
Select-String -Path "debug_step_0297_extended.log" -Pattern "\[SCREEN-TRANSITION\]" | Select-Object -First 20
# See initial VRAM dump
Select-String -Path "debug_step_0297_extended.log" -Pattern "\[VRAM-INIT-DUMP\]" | Select-Object -First 100
Sources consulted
- Bread Docs:Video RAM (VRAM)
- Bread Docs:Scroll Registers (SCX/SCY)
- Bread Docs:Tile Data
- Bread Docs:CPU Instruction Set
Educational Integrity
What I Understand Now
- Initialization phases: Games have multiple phases and tiles can load at different times
- Screen transitions: Changes in scroll and tilemap can indicate times where tiles are loaded
- Temporal analysis: An access timeline allows you to identify patterns that are not visible in static analyzes
- VRAM Initial State: Checking for pre-loaded data helps understand if the game expects data from startup
What remains to be confirmed
- Extended Analysis: If the loading code appears after 12 seconds of execution
- Detected transitions: If state changes and screen transitions correspond to moments where tools are loaded
- Pre-loaded data: Whether there is data in VRAM from startup or whether it is completely empty
- Temporal patterns: If the timeline shows patterns that indicate when tiles should load
Hypotheses and Assumptions
Hypothesis A: The game loads tiles LATER (after 12 seconds) -Pending verification with extended analysis
Hypothesis B: The game loads tiles in ANOTHER PHASE (screen change, menu, etc.) -The [STATE-CHANGE] and [SCREEN-TRANSITION] monitors will help verify
Hypothesis C: The game should have tiles pre-loaded from the start (Boot ROM or special initialization) -The initial VRAM dump will help verify
Hypothesis D: There is a bug in the emulation that prevents the game from reaching the loading phase -Pending verification with extended analysis
Next Steps
- [ ] Run extended scan (30-60 seconds) with Pokémon Red
- [ ] Analyze logs to identify accesses with data after 12 seconds
- [ ] Check if state changes indicating transitions are detected
- [ ] Check if there is pre-loaded data in VRAM (initial dump)
- [ ] Analyze VRAM access timeline to identify temporal patterns
- [ ] Determine if the game loads tiles later or requires emulator intervention
- [ ] (Optional) Create script to analyze tile data in ROM