// retroDE_ps2 — DobieStation headless trace runner // // Minimal harness for the golden-reference harness. Loads a BIOS image, // boots the EE in interpreter mode, runs a bounded number of frames, and // exits. The EE instruction-fetch trace is emitted by the tap added in // third_party/DobieStation/src/core/ee/emotion.cpp when the environment // variable RETRODE_PS2_EE_TRACE is set to a file path. // // Intended for Wave 1 / Checkpoint 2 of the harness: NOP-sled BIOS, // short run, compare first-N fetches against the RTL stub trace. // // Usage: // RETRODE_PS2_EE_TRACE=/path/to/dobie_ee.trace ./trace_runner [frames] // // Notes: // - BIOS image must be exactly 4 MiB. Anything shorter is zero-padded; // anything longer is truncated. // - `frames` defaults to 1. One frame is ~4.9M EE cycles, which is far // more than Checkpoint 2 needs; keep it small. #include #include #include #include #include #include #include "emulator.hpp" int main(int argc, char** argv) { if (argc < 2) { std::fprintf(stderr, "usage: %s [frames]\n" "env: RETRODE_PS2_EE_TRACE= enable EE fetch trace\n", argv[0]); return 2; } const char* bios_path = argv[1]; int max_frames = (argc >= 3) ? std::atoi(argv[2]) : 1; if (max_frames <= 0) max_frames = 1; constexpr size_t BIOS_SIZE = 4 * 1024 * 1024; std::vector bios(BIOS_SIZE, 0); std::ifstream f(bios_path, std::ios::binary); if (!f) { std::fprintf(stderr, "[trace_runner] cannot open %s\n", bios_path); return 2; } f.read(reinterpret_cast(bios.data()), BIOS_SIZE); std::fprintf(stderr, "[trace_runner] loaded %zd bytes from %s\n", f.gcount(), bios_path); Emulator emu; emu.reset(); emu.load_BIOS(bios.data()); emu.set_ee_mode(CPU_MODE::INTERPRETER); emu.set_vu0_mode(CPU_MODE::INTERPRETER); emu.set_vu1_mode(CPU_MODE::INTERPRETER); for (int i = 0; i < max_frames; i++) { std::fprintf(stderr, "[trace_runner] running frame %d/%d\n", i + 1, max_frames); emu.run(); } std::fprintf(stderr, "[trace_runner] done\n"); return 0; }