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
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
- Source of value in A:
LD A, (HL)in0x2B25reads from WRAM. - memory address:
H.L.points to0xE645,0xE646, etc. (WRAM). - Read value: Always
0x00, but the game waits0xFD. - 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
- Trace back: Search the Tetris code for which routine you should write
0xFDin WRAM before reaching0x2B20. - Verify WRAM initialization: Check if the MMU initializes WRAM correctly at boot.
- Analyze I/O logs: Records
0xFF8Cand0xFF94are not implemented. Check if this affects the flow. - Find copy routines: Search instructions
LDI,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 write
0xFDin WRAM? - Lock condition: Why wasn't that routine executed?
- I/O registers: Do the records
0xFF8Cand0xFF94Do 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 registers
0xFF8Cand0xFF94they need implementation. - [ ] Search the Tetris code for what you should write
0xFDin WRAM. - [ ] Implement the necessary fix (WRAM initialization or I/O register implementation).