mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-28 10:59:16 -04:00
88f2500ca8
THE MECHANISM, measured on the palette load with guest cycle stamps:
0 SECTOR 125109 pend=0 lost=0
225,792 SECTOR 125110 pend=0 lost=0
236,023 CMD Setloc(125111) <- guest asks 10k cycles after 110
237,956 CMD ReadN
689,540 SECTOR 125111 pend=1 lost=1
915,332 SECTOR 125112 pend=1 lost=1
2,273,594 CMD Setloc(125111) <- the game times out and retries
2,275,306 CMD ReadN
2,726,890 SECTOR 125111 pend=0 lost=0
Sector 111 arrives while the guest has not yet acked the ReadN's INT3,
so its data-ready pends. Sector 112 arrives 225,792 cycles later and
REPLACES that pend, destroying 111's notification outright. The guest is
never told 111 arrived, times out after ~1.6M cycles, and re-issues
Setloc+ReadN. That retry is the entire 2.5M-cycle gap that appears
before every individually requested sector, and it is why the palette
sector is not drained on the first pass.
gap_anatomy attributed 100% of the gap to after the guest asked; the
guest issues its command within ~10,000 cycles every time. The delay was
never guest-side.
With the ring, both sectors are already safe in their own slots, so
there is nothing to drop: the newer sector's announcement now WAITS and
is raised once the guest drains the one already announced
(cdrom_announce_next_held, delayed and guarded like the ack path).
Announcements stay in arrival order and none is lost. int1_lost must now
stay 0; int1_deferred counts the sectors held.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>