Files
psxrecomp/runtime
Matthew Stanley c5993a9dee cdrom: response arbiter + fixed command-completion latency
Two CD-controller correctness fixes toward universal fast disc loads
(disc_speed=4x/instant) without per-game tuning.

1. Response arbiter (the core fix). The PS1 CD controller serializes
   responses: only one occupies the IRQ slot (irq_flag + response FIFO)
   at a time, and a later response is not exposed until the guest ACKs
   the current one. set_irq() previously OVERWROTE irq_flag directly,
   so when responses arrived faster than the guest acked (fast disc
   timing) it silently DROPPED them. Proven: 24 dropped responses at
   MMX6 boot under disc_speed=instant (INT2 completion clobbering an
   unacked INT3 ACK), which wedged the loader.

   set_irq() now snapshots the response bytes and either exposes (slot
   free, gap elapsed) or QUEUES behind the visible response. The guest
   ACK edge actively pumps the arbiter (cd_arbiter_pump): drain queued
   responses in order, then start a command latched while the controller
   was busy. cdrom_advance also pumps once the inter-IRQ gap elapses, so
   a queued response is delivered even when no further ACK edge arrives.
   Commands written while busy are latched and executed on ACK.

   Result: 0 dropped responses at 1x/4x/instant. 1x boots to title
   identically (no regression). The overwrite counter is retained as a
   regression detector (now only counts true queue overflow).

2. Command-completion latency is now fixed, not speed-scaled. Pause/
   Init/SeekL/GetID/ReadTOC second responses are controller/firmware
   operations whose timing does NOT scale with read speed on real HW.
   They used apply_speed() (divides by the disc-speed divisor), so at
   4x the Pause completed 4x too fast and desynced the BIOS CD driver.
   New cmd_latency() keeps them at authentic timing; only sector DATA
   delivery (sector_delay_cycles) scales with disc_speed — which is
   where essentially all load time lives, so loads still get fast.

Runtime-only (no regen). 1x verified clean on MMX6. A downstream
load-timing race still wedges 4x/instant at boot (guest spins with
interrupts disabled after a clean Pause) — tracked separately.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 20:37:45 -07:00
..