mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-28 10:59:16 -04:00
17e05f5cc2
Strips the ring probe (ring_starved stays as an O(1) tripwire, since a stranded slot once starved 1.1M drains) and fixes the timing the ring exposed. With the ring in place the regression is gone -- lost=0, one record per LBA, no retried Setlocs -- but the buffers still fill 109,111,111,113,113 where DuckStation fills 109,110,111,112,113. The game only Setlocs the odd sectors; it expects the evens as continuations. Native reads every even sector (record [D], never lost) and still misses them. The reason is when the guest is TOLD. present_pending_dataready() ran synchronously inside the guest's IRQ-ack store, so the moment the ISR cleared sector 110's interrupt, 111's response FIFO and read slot were installed -- before the ISR had set up its DMA. That DMA then drained 111 into the buffer meant for 110, and every later pair inherited the shift. DuckStation guards exactly this window in QueueDeliverAsyncInterrupt: after an ack the elapsed time is 0, so it always schedules rather than delivering inline -- "give it enough time to read the response out ... the real console does something similar anyway, the INT1 task won't run immediately after the INT3 is cleared." The ack now arms pending_present_due (500 cycles) and cdrom_advance releases it once elapsed and irq_flag is genuinely clear. The deadline joins cdrom_cycles_to_irq so the event slicer cannot step over it, is cancelled wherever the pend is cancelled, and rides the savestate as a relative remaining like read_delay. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>