mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-27 18:52:11 -04:00
c5993a9dee
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>