⚠️ 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.

Analysis: 500 Instruction Trace Reveals PPU Configuration

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

Summary

The emulator was run with the trace extended to 500 instructions to analyze what happens after the initialization loop ends. Analysis revealed that the 500 captured instructions are all within the same memory cleanup loop (0x0293-0x0295), running over 100 iterations. At the end of the log, an exit from the loop is observed at address 0x0297 (opcode 0x0D, DEC C), but the emulator stops upon reaching the 500 instruction limit before being able to observe what happens next.

Hardware Concept

Game Boy ROMs run complex initialization routines upon booting. These routines typically include:

  • Memory cleaning:Multiple loops that write specific values ​​(usually 0x00) to regions of RAM to ensure a known initial state.
  • Hardware configuration:Writing values ​​to hardware registers (LCDC, BGP, SCY, SCX, etc.) to configure the PPU and other components.
  • Variable initialization:Establishing initial values ​​for game variables.

Memory cleanup loops are critical because they ensure that there is no residual data from previous runs. These loops can be nested (one loop within another) and can be executed hundreds or thousands of times depending on the size of the memory region to be cleaned.

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

Trace Analysis

The emulator was run with the Tetris ROM and a complete trace of 500 instructions was captured. Trace analysis revealed the following findings:

Observed Execution Pattern

The 500 captured instructions show a repetitive pattern consisting of three instructions:

  • 0x0293: LDD (HL), A(opcode 0x32) - Write the value of A to the address pointed to by HL and decrement HL
  • 0x0294: DEC B(opcode 0x05) - Decrements register B
  • 0x0295: JR NZ, e(opcode 0x20) - Jump relative if the Z flag is not active

This loop is executed more than 100 times before the 500 instruction limit is reached.

Loop Output

At the end of the log (line 16903), the successful exit of the loop is observed:

[DEBUG DEC B] B before: 0x01, Z before: 0
[DEBUG DEC B] B after: 0x00, Z after: 1
[DEBUG JR NZ] B: 0x00, Z: 1, offset: 0xFC
[DEBUG JR NZ] NOT JUMPING, continuing on PC: 0x0297

The PC continues at 0x0297, where the opcode is 0x0D (DEC C), which is correctly implemented in C++ code.

Trace Limit Limitation

The emulator stops when it reaches the limit of 500 instructions just after exiting the loop, making it impossible to see what happens next. This suggests that:

  • The cleanup loop is very long (more than 100 iterations)
  • There may be multiple nested loops that consume most of the 500 instructions
  • We need to increase the limit further or implement a smarter trace mechanism that activates only after certain points of interest

Affected Files

  • temp_trace.log- Temporary file with the complete trace of 500 instructions
  • src/core/cpp/CPU.cpp- CPU source code (no modifications in this step)

Tests and Verification

This step was purely analysis, with no code modifications. The verification consisted of:

  • Running the emulator: python main.py roms/tetris.gb > temp_trace.log 2>&1
  • Trace analysis:Reviewing all 500 CPU trace lines to identify patterns
  • Opcode verification:Confirmation that opcode 0x0D (DEC C) at 0x0297 is implemented
  • Iteration count:Approximate calculation of how many times the loop is executed before exiting

Result:The loop was confirmed to terminate correctly, but the 500 instruction limit is insufficient to observe the entire initialization sequence.

Sources consulted

  • Pan Docs: Boot ROM, Memory Map, Initialization Routines
  • GBEDG: CPU Instruction Set (opcode 0x0D - DEC C)

Educational Integrity

What I Understand Now

  • Initialization loops:ROMs run extensive memory cleanup loops that can consume hundreds of instructions before advancing to hardware configuration.
  • Trace limits:Fixed trace limits may be insufficient to observe complete initialization sequences, especially when there are nested loops.
  • Execution patterns:The LDD (HL) pattern, A -> DEC B -> JR NZ is common in memory cleanup routines and runs until B reaches 0x00.

What remains to be confirmed

  • Post-loop sequence:What instructions are executed after 0x0297 and whether there are more cleanup loops or whether hardware configuration begins.
  • PPU configuration:If and when the game starts writing to the hardware registers (0xFF40-0xFF4F) to configure the PPU.
  • Missing Opcodes:If there are unimplemented opcodes that block progress after cleanup loops.

Hypotheses and Assumptions

Main hypothesis:After all the cleanup loops finish, the game should start configuring the hardware, especially the PPU registers. We hope to see instructions likeLDH (n), A(opcode 0xE0) writing to registers as 0xFF40 (LCDC) or 0xFF47 (BGP).

Assumption:The 500 instruction limit is insufficient because the cleanup loop is executed more than 100 times, consuming most of the available instructions before we can observe the post-initialization sequence.

Next Steps

  • [ ] Increase the trace limit to 1000 or 2000 instructions to capture more information
  • [ ] Implement a conditional trace mechanism that activates only after certain points of interest (e.g. after exiting known loops)
  • [ ] Analyze the ROM directly to identify which opcodes are at addresses after 0x0297
  • [ ] Check if there are more cleanup loops after 0x0297 or if hardware configuration starts
  • [ ] Identify the first unimplemented opcode that blocks progress (if it exists)