This project is educational and Open Source. No code is copied from other emulators. Implementation based solely on technical documentation and permitted tests.
The Sentinel Tracker
Summary
After confirming an infinite loop in0x2B24where the game scans the WRAM looking for the byte0xFD(which it never finds because the memory is initialized to0x00), a sentinel search is implemented in the MMU to detect any attempts to write this magic value. This will allow you to determine if the game attempted to write the marker and failed, or if the game never executed the write instruction.
Hardware Concept
Magic Markers in Memory (Sentinel Values): Many programs use special values (markers or "sentinels") to indicate states or mark positions in memory. In the case of Tetris, the game seems to be looking for the byte0xFDin WRAM as a marker indicating that some initialization phase completed successfully.
Infinite Loop Diagnosis: When a program enters an infinite loop searching for a value that it never finds, there are two possible causes:
- Option A: The program attempted to write the marker, but the write failed (problem in the MMU or write logic).
- Option B: The program never executed the instruction that writes the marker (previous problem in execution, possibly in the CPU or in the initialization logic).
Hesentinel trackeris a debugging technique that consists of instrumenting the write point (in this case, the methodMMU::write) to detect and log any attempt to write the searched value. If the tracker detects writing, we know that the game tried to write the marker (and we need to investigate why it wasn't saved correctly). If the tracer never fires, we know the problem is before the write (possibly in the initialization logic or a bad conditional jump).
Monitored Memory Area: Tracker monitors addresses>= 0xC000, including:
- WRAM (
0xC000-0xDFFF): Internal working memory of the Game Boy (8 KB). - Echo RAM (
0xE000-0xFDFF): WRAM mirror (redirected to WRAM by the MMU from Step 0239).
Implementation
A diagnostic block is added at the beginning of the methodMMU::writewhich detects any attempt to write the value0xFDin RAM addresses (>= 0xC000). The diagnostic runs before any Echo RAM redirection or special register handling, to capture all relevant writes.
Modified components
src/core/cpp/MMU.cpp: Added diagnostic block inMMU::writeto detect writes0xFDin RAM.
Code added
// --- Step 0244: SENTINEL SEARCH (Searching for 0xFD) ---
// The game crashes looking for this value. Does anyone write it?
// We detect any attempt to write 0xFD in the RAM area (WRAM/Echo RAM)
// Addresses >= 0xC000 correspond to WRAM (0xC000-0xDFFF) and Echo RAM (0xE000-0xFDFF)
if (value == 0xFD && addr >= 0xC000) {
printf("[SENTINEL] 0xFD writing detected at Address: %04X!\n", addr);
}
// -----------------------------------------
Design decisions
- Diagnostic Location: Placed right after masking the value and before the special registers, to capture all relevant writes, including those redirected from Echo RAM.
- Detection condition: Both the value (
0xFD) as the address (>= 0xC000) to avoid false positives in other memory areas. - Message format: The message includes the prefix
[SENTINEL]to facilitate its search in the logs and shows the exact address where an attempt was made to write.
Affected Files
src/core/cpp/MMU.cpp- Added sentinel tracker diagnostic block inMMU::writedocs/bitacora/entries/2025-12-22__0244__rastreador-del-sentinel.html- Log entrydocs/bitacora/index.html- Updated with new entryREPORT_PHASE_2.md- Updated with Step 0244
Tests and Verification
The diagnosis is validated by running the emulator with Tetris and observing the console:
- Recompile the C++ extension:
.\rebuild_cpp.ps1 - Run Tetris:
python main.py roms/tetris.gb - Observe the console:
- If it appears
[SENTINEL] 0xFD writing detected at Address: XXXX!: The game tried to write the score. Write down the address and check if it is Echo RAM (0xE...) or WRAM (0xC...). Investigate why the writing was not saved correctly. - If NO message appears and the emulator enters the GPS loop (
PC:2B24): The game never wrote the score. The problem is before the write, possibly in the initialization logic or an incorrect conditional jump.
- If it appears
Note: This diagnostic is intentionally visible (useprintf) to facilitate its detection in the logs. Once the cause of the problem is identified, the diagnosis can be removed or converted to a conditional log.
Sources consulted
- Bread Docs:Memory Map- Description of WRAM and Echo RAM
- Bread Docs:Echo RAM- Memory mirror behavior
Educational Integrity
What I Understand Now
- Magic Markers: Programs use special values to mark states or positions in memory. The byte
0xFDIt appears to be a marker that Tetris uses to indicate that some initialization phase has been completed. - Infinite Loop Diagnosis: When a program looks for a value that it never finds, there are two possible causes: the value was never written (previous problem) or it was written but not saved (write problem).
- Sentinel Tracker: Debugging technique that instruments the write point to detect attempts to write a specific value. It allows you to distinguish between writing problems and logic problems.
What remains to be confirmed
- Does the game write the score?: We need to run the emulator and see if the message appears
[SENTINEL]in the logs. - If it is written, why is it not saved?: If the tracker detects the write but the game does not find the value, we need to investigate why the write was not saved correctly (possible issue in Echo RAM or redirection logic).
- If not written, where does the initialization fail?: If the tracer never activates, we need to investigate the game's initialization logic to find where the marker is supposed to be written.
Hypotheses and Assumptions
Main Hypothesis: The game tries to write0xFDin WRAM or Echo RAM as an initialization marker, but something fails in the process (either the write itself or the logic that decides when to write it).
Assumption: The value0xFDis a Tetris-specific magic marker, not a standard hardware value. This assumption is based on analysis of the code that looks for this specific value in memory.
Next Steps
- [ ] Recompile the C++ extension:
.\rebuild_cpp.ps1 - [ ] Run Tetris:
python main.py roms/tetris.gb - [ ] Watch the console for messages
[SENTINEL] - [ ] If the message appears: Investigate why the write was not saved correctly (check Echo RAM redirection, write logic, etc.)
- [ ] If the message does NOT appear: Investigate the game's initialization logic to find where the marker is supposed to be written (possible problem in conditional jumps or initialization logic)