This project is educational and Open Source. No code is copied from other emulators. Implementation based solely on technical documentation and permitted tests.
Total Silence (Release Candidate)
Summary
This Step eliminatesallthe debug instrumentation (`printf`) of `MMU.cpp` and `CPU.cpp` to allow the emulator to run at real speed (60 FPS). Step 0252 confirmed that the functional logic (ROM protection, DMA, interrupts) is correct, but the thousands of logs were massively slowing down the execution, preventing the final result from being seen on the screen. This is the final cleanup before the "moment of truth": running Tetris at native speed.
Hardware Concept
On real hardware, the Game Boy executes instructions at ~4.19 MHz, allowing for 60 frames per second rendering. Each instruction consumes a precise number of machine cycles (M-Cycles), and the system must maintain perfect synchronization between the CPU, PPU, Timer and other components.
The instrumentation problem:Each call to `printf()` is an extremely slow I/O operation compared to the execution of a CPU instruction. In an emulation loop executing millions of instructions per second, even a single `printf()` per instruction can reduce performance from 60 FPS to an actual 0.01 FPS. For the emulated CPU, time passes normally, but for the user, the game appears frozen.
Zero-Cost Abstractions:In the critical emulation loop, each operation must be as efficient as possible. High-level abstractions (such as logging) should be removed or moved out of the critical loop. Compiled C++ code must run without I/O overhead on the critical path.
Fountain:Pan Docs - "CPU Instruction Set", "Timing", "Performance Considerations"
Implementation
Removed all active `printf()` from critical kernel files, keeping only the functional logic. The commented logs are maintained for future reference, but are not executed at runtime.
Modified components
- MMU.cpp: Deleted logs from `[TIME]`, `[SENTINEL]`, `[DMA]`, `[WRAM-WRITE]`, `[HRAM]`. Removed static variable `wram_log_count`.
- CPU.cpp: Deleted logs for `[DI]`, `[EI]`, `[INT]`, `[SNIPER]`. Removed `#include
`.
Preserved logic
All critical functional logic is kept intact:
- ROM protection(Step 0252): Prevent writes to `0x0000-0x7FFF`.
- DMA (OAM Transfer)(Step 0251): Copy 160 bytes to OAM when writing to `0xFF46`.
- Interruptions: Full processing of V-Blank, LCD STAT, Timer, Serial and Joypad.
- Hardware Logs: Dynamic read/write of STAT, DIV, TIMA, TMA, TAC, P1, LY.
Design decisions
Total Log Deletion:Instead of using conditional build flags (`#ifdef DEBUG`), all active logs were removed. This simplifies the code and ensures that there is no overhead in release builds. If debugging is needed in the future, a more sophisticated logging system (such as a circular buffer that is periodically emptied) or external tools (such as GDB) can be used.
Preservation of Comments:The commented logs are kept in the code for future reference. This allows the instrumentation to be reactivated quickly if necessary, without losing the historical context of why it was added.
Removal of Unnecessary Includes:Removed `#include
Affected Files
src/core/cpp/MMU.cpp- Removed all active `printf()` and static variable `wram_log_count`. Removed `#include`. src/core/cpp/CPU.cpp- Removed all active `printf()` in `DI`, `EI` and `handle_interrupts()`. Removed `#include`.
Tests and Verification
Verification is done by compiling and running at real speed:
- Compilation:The code compiles without errors or warnings. There are no references to undefined functions.
- Linter:No linter errors were detected in the modified files.
- Native Validation:The compiled C++ code does not contain I/O function calls in the critical loop.
Performance Test:The emulator should run at a real 60 FPS when running `python main.py roms/tetris.gb`. If the logic is correct (and Step 0252 suggests it is), Tetris should boot and display the copyright or main menu.
Note:If the game still shows a green screen after 10 seconds, the problem is not one of performance but one of logic. In that case, selective logging (for example, only in Python GPS) can be re-enabled for diagnostic purposes.
Sources consulted
- Bread Docs:CPU Instruction Set, Timing
- Optimization Principles: "Zero-Cost Abstractions" in C++
- Performance Analysis: I/O Overhead in Critical Loops
Educational Integrity
What I Understand Now
- I/O Overhead:I/O operations (`printf`, `std::cout`) are orders of magnitude slower than arithmetic or memory operations. In a critical loop running millions of iterations per second, even a single `printf()` can reduce performance from 60 FPS to less than 1 FPS.
- Critical Loop:The CPU's `step()` method executes millions of times per second. Any overhead in this method is multiplied by the number of instructions executed, making the emulator unusable.
- Instrumentation vs. Performance:Instrumentation is essential for development and debugging, but should be removed or moved out of the critical loop in release builds. Production code should be as efficient as possible.
What remains to be confirmed
- Actual Performance:Verify that the emulator runs Tetris at a real 60 FPS without logs. If performance is still poor, there may be other bottlenecks (for example, in the PPU or in the main Python loop).
- Game Behavior:Confirm that Tetris starts correctly and displays the copyright or main menu. If the screen is still green, the problem is logic, not performance.
Hypotheses and Assumptions
Main Hypothesis:The only remaining problem was the log overhead. With all `printf()` removed, the emulator should run at real speed and Tetris should boot correctly.
Assumption:If the game still won't start after clearing the logs, the problem is in the emulation logic (for example, a bug in interrupt processing or component synchronization). In that case, selective logging can be reactivated for diagnosis.
Next Steps
- [ ] Run `python main.py roms/tetris.gb` and verify that the emulator runs at a real 60 FPS.
- [ ] Confirm that Tetris starts and displays the copyright or main menu.
- [ ] If the game starts successfully, celebrate the milestone and document the success.
- [ ] If the screen is still green, reactivate selective logging (Python GPS only) for diagnostics.
- [ ] Consider implementing a more sophisticated logging system (circular buffer) for future debugging without sacrificing performance.