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

Forensic Trace Analysis: The Origin of 0x00

Date:2025-12-22 StepID:0238 State: draft

Summary

Analysis of the Step 0237 trace revealed the origin of the incorrect value in the accumulator. The loop in0x2B20-0x2B2Cexecutes a sequence that reads from WRAM memory usingLD A, (HL)in0x2B25, but gets0x00when the game wait0xFD. The problem is not in the charge of the accumulator, but in that the memory WRAM does not contain the expected values because an initialization routine did not run or failed.

Hardware Concept

Reverse Taint Analysis: Debugging technique where An incorrect value ("blob") is traced from its manifestation (sink) to its origin (source).

  • Sink: CP 0xFDin0x2B2A- where the failure manifests itself.
  • Taint: 0x00in the registryTO- the wrong value.
  • Source: LD A, (HL)in0x2B25- the instruction that introduces the stain.

However, analysis revealed that the source is not the problem:LD A, (HL)read correctly from memory. The real problem is that the WRAM memory at the pointed addresses byH.L.contains0x00rather0xFD.

This shifts the problem:Who should have written0xFDin those directions of WRAM before?Probably an initialization or data copy routine that is not executed or failed silently.

Trace Analysis

Identified Instruction Sequence

2B20: 23 → INC HL (HL increases: E644→E645, E645→E646...)
2B21: F0 8C → LDH A, (8C) (Read I/O 0xFF8C → A=44, 48, 4C, 50...)
2B23: E0 94 → LDH (94), A (Write A to I/O 0xFF94)
2B25: 7E → LD A, (HL) (Read memory in HL → A=00 ALWAYS)
2B26: FE FF → CP 0xFF (Compare A with 0xFF)
2B28: 28 C7 → JR Z, -57 (Jump if A==0xFF)
2B2A: FE FD → CP 0xFD (Compare A with 0xFD) ← FAULT HERE
2B2C: 20 0E → JR NZ, +14 (Jump if A!=0xFD → return to 2B20)

Key Findings

  1. Source of value in A: LD A, (HL)in0x2B25reads from WRAM.
  2. memory address: H.L.points to0xE645, 0xE646, etc. (WRAM).
  3. Read value: Always0x00, but the game waits0xFD.
  4. Increment pattern: H.L.it increases with each iteration, suggesting a verification loop.

Problem Hypothesis

The code appears to be checking that a WRAM region contains specific values ​​(0xFD). These values ​​should have been written by a previous initialization routine that:

  • Did not execute (blocked by a precondition that was never met).
  • Failed silently (error in address calculation or exit condition).
  • You wrote to a different address (offset or address calculation error).

Affected Files

  • docs/bitacora/entries/2025-12-22__0238__analisis-trace-forense.html- This analysis

Next Research Steps

  1. Trace back: Search the Tetris code for which routine you should write0xFDin WRAM before reaching0x2B20.
  2. Verify WRAM initialization: Check if the MMU initializes WRAM correctly at boot.
  3. Analyze I/O logs: Records0xFF8Cand0xFF94are not implemented. Check if this affects the flow.
  4. Find copy routines: Search instructionsLDI, LDD, or copy loops that should have populated WRAM.

Sources consulted

  • Bread Docs:CPU Instruction Set- Instructions LD, LDH, CP, JR
  • Bread Docs:Memory Map- WRAM, HRAM, I/O Ports
  • Debugging techniques: Reverse Taint Analysis

Educational Integrity

What I Understand Now

  • Trace analysis: The "Reverse Taint Analysis" technique allows you to trace incorrect values ​​back to their origin.
  • verification loop: The code is checking that memory contains expected values, not loading values.
  • Displaced problem: The problem is not in the reading, but rather that the memory was not initialized correctly.

What remains to be confirmed

  • Initialization routine: What code should I write0xFDin WRAM?
  • Lock condition: Why wasn't that routine executed?
  • I/O registers: Do the records0xFF8Cand0xFF94Do they affect the flow?

Hypotheses and Assumptions

Main hypothesis: An initialization routine that should copy data to WRAM was not executed because a precondition (perhaps related to unimplemented I/O registers) was never fulfilled, leaving WRAM uninitialized.

Next Steps

  • [ ] Expand the trace range back to find the initialization routine.
  • [ ] Check if the I/O registers0xFF8Cand0xFF94they need implementation.
  • [ ] Search the Tetris code for what you should write0xFDin WRAM.
  • [ ] Implement the necessary fix (WRAM initialization or I/O register implementation).