mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-25 18:05:12 -04:00
a3e8f2818b
Stage-2's biggest cost gap closed. MULT/MULTU/DIV/DIVU now set a completion deadline; MFLO/MFHI stall guest cycles until it — exactly like Beetle's muldiv_ts_done. Latencies transcribed from cpu.cpp: DIV/DIVU=37; MULT via MULT_Tab24 (14/10/7) on the first-operand magnitude. Native previously charged ZERO for this. - Per-instruction cycle charging is now the DEFAULT on this audit branch (PSX_CODEGEN_CYCLE_PER_INSN), required so the stall absorbs correctly (the running cycle count must be accurate mid-block). Validated cycle-neutral for the identity base model; Tomba 2 still reaches the FMV. - runtime: CPUState.muldiv_ts_done + psx_muldiv_set/stall + psx_mult_latency_s/u in psx_cycles.c. Emitted at the mult/div/mflo/mfhi sites in the GAME emitter (gated PSX_ENABLE_BLOCK_CYCLES). Stall fires even for mflo/mfhi to $zero. - ruler #2 native half: tools/cycle_testrom/CMakeLists.txt builds psx-cyctest (links the recompiled test EXE), boots disc/cyctest.cue (serial CYCT-00101 so disc-identity matches, no warning dialog). measure.py --port 4600. VALIDATION (native vs Beetle oracle, per-iteration component cost): div +38 vs +38 EXACT | div_spaced +38 vs +38 EXACT (absorb works) | mult +15 vs +15 EXACT | baseline/alu match. Remaining: load native +7 vs Beetle +5 (memory.c flat +6 wait-state needs calibration to ~4) — a smaller refinement. BIOS emitter still block-mode (ruler #1 unchanged at 30) — applying per-insn + muldiv there is the next step to close ruler #1's div-stall gap. No FMV regression (i_stat 0x8D, screenshot verified). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>