⚠️ Clean-Room / Educational

This project is educational and Open Source. No code is copied from other emulators. Implementation based solely on technical documentation and permitted tests.

Debug: Final Extension of CPU Trace to 2000 Instructions

Date:2025-12-20 StepID:0156 State: 🔍 DRAFT

Summary

Analysis of the 500 instruction trace (Step 0155) confirmed that the Tetris ROM memory cleanup loops are extremely long and consume the entire current debug window. Increased CPU trace limit from 500 to 2000 instructions to ensure capture of the code sequence that is executed after all initialization loops have finished. However, analysis of the new trace revealed that even with 2000 instructions, we are still inside the initialization loops, indicating that these loops are even longer than expected.

Hardware Concept

Game Boy ROM boot routines can be extremely complex and extensive. Memory cleanup loops not only clean a single region, but can clean multiple memory regions in sequence:

  • WRAM (0xC000-0xDFFF):8 KB working memory that must be initialized to zero.
  • HRAM (0xFF80-0xFFFE):127 byte high speed memory.
  • OAM (0xFE00-0xFE9F):Object attribute memory (sprites).
  • Other regions:Depending on the game, other memory areas may be cleared.

Each region may require hundreds or thousands of iterations of a loop, and these loops may be nested (an outer loop controlling multiple inner loops). This explains why even 2000 instructions may not be enough to observe the complete end of initialization.

Fountain:Pan Docs - Memory Map, Boot ROM, Initialization Routines

Implementation

The constant was changedDEBUG_INSTRUCTION_LIMITin the filesrc/core/cpp/CPU.cppto increase the limit of traced instructions from 500 to 2000.

Modified components

  • CPU.cpp:Increase ofDEBUG_INSTRUCTION_LIMITfrom 500 to 2000.

Change made

// Static variables for diagnostic logging
static int debug_instruction_counter = 0;
// We increased the limit drastically to 2000 to overcome all the initialization loops.
static const int DEBUG_INSTRUCTION_LIMIT = 2000;

Affected Files

  • src/core/cpp/CPU.cpp- Increase ofDEBUG_INSTRUCTION_LIMITfrom 500 to 2000.

Tests and Verification

This change does not require specific unit tests, as it only modifies the diagnostic logging limit. Validation was carried out using:

  • Recompiling C++ module:Executed.\rebuild_cpp.ps1successfully.
  • Running the emulator:Executedpython main.py roms/tetris.gbto generate the new extended trace.
  • Trace analysis:Exactly 2000 instructions were captured.

Analysis Results

Trace statistics:

  • Total instructions captured:2000
  • Main loop (0x0293-0x0295):Each address is executed 663 times
  • Instructions outside the main loop:Only 2 occurrences of 0x0297 and 0x0298
  • Last 20 instructions:They are all inside the loop (0x0293-0x0295)

Key Findings

Analysis revealed that even with 2000 instructions, we are still inside the initialization loops:

  • The main loop (0x0293-0x0295) is executed more than 660 times, consuming approximately 1989 instructions out of the 2000 available.
  • There is evidence of nested loops: instructions are observed at 0x0297 (DEC C) and 0x0298 (JR NZ), suggesting that there is an outer loop controlling the inner loop.
  • No hardware configuration opcodes (0xE0, 0xEA, 0xCD) were observed in the trace, indicating that we have not yet reached the PPU configuration phase.

Fragment of the Final Trace

[CPU TRACE 1995] PC: 0x0294 | Opcode: 0x05
[CPU TRACE 1996] PC: 0x0295 | Opcode: 0x20
[CPU TRACE 1997] PC: 0x0293 | Opcode: 0x32
[CPU TRACE 1998] PC: 0x0294 | Opcode: 0x05
[CPU TRACE 1999] PC: 0x0295 | Opcode: 0x20

Sources consulted

  • Analysis of Step 0155: Confirmation that 500 instructions are insufficient.
  • Pan Docs - Memory Map: Description of the memory regions that should be cleared during initialization.
  • Behavior observed in CPU traces: Initialization loops can be extremely long.

Educational Integrity

What I Understand Now

  • Extensive initialization loops:Memory cleanup loops can run hundreds or thousands of times, consuming thousands of instructions.
  • Nested loops:There can be multiple levels of nested loops, where one outer loop controls multiple inner loops.
  • Trace limits:Even seemingly large limits (2000 instructions) may be insufficient to capture complete initialization routines.

What remains to be confirmed

  • Full exit point:We need to identify how many more iterations are required to completely exit all initialization loops.
  • Alternative strategy:We might need to implement a conditional tracing mechanism that activates only after certain points of interest, instead of tracing all instructions from the beginning.
  • Hardware configuration:Once we get out of the loops, we need to identify which opcodes are used to configure the PPU and other hardware components.

Hypotheses and Assumptions

Main hypothesis:Tetris initialization loops are extremely long, possibly clearing multiple memory regions of 8 KB each. We may need to increase the limit even further (to 5000 or 10000) or implement a conditional trace strategy so we can observe what happens after initialization.

Next Steps

  • [ ] Evaluate whether it is necessary to increase the limit further (to 5000 or 10000 instructions).
  • [ ] Consider implementing a conditional trace mechanism that activates only after certain points of interest.
  • [ ] Analyze the ROM directly to identify which opcodes are in the addresses after the initialization loops.
  • [ ] Check if there are more cleanup loops after 0x0298 or if hardware configuration starts.
  • [ ] Once we identify the end of the loops, implement the missing opcodes so the game can continue execution.