mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-28 10:59:16 -04:00
eaa8c69836
THE BUG. cd_diff proved the two emulators' CD request streams are
byte-identical through the palette load (125054, 125071, 125088,
125105..109, 125111, 125113 on both), and cd_verify proved every request
was executed exactly: delivered == requested, data heads matching the
ISO, lost=0. Identical asks, identical answers, different result -- so
the divergence was in the BUFFERING between them.
psx-runtime had ONE 2340-byte sector buffer. Real hardware has eight
rotating ones (nocash; DuckStation NUM_SECTOR_BUFFERS = 8). The game's
loader drains TWO sectors per Setloc+ReadN cycle -- the requested sector,
then its continuation via the following data-ready -- and with a single
buffer the continuation overwrote the buffer mid-drain, so the second
drain re-read stale bytes. The palette load shifted by one sector and
raw file data was rendered as vertex colours: the hard-edged wedges.
Implements the ring faithfully:
- a delivered sector fills the NEXT slot, never the one being drained;
- the INT1 that announces a sector latches the read slot (DS: read =
write at DataReady delivery);
- a drain that empties a slot re-announces a sector already waiting in
the newest slot, matching DS's redeliver-missed-sector behaviour --
without it a game draining two per cycle never hears about the second;
- multi-sector DMA steps across slot boundaries inline, preserving the
seamless-refill shape but without clobbering;
- drive-state changes reset the whole ring (DS ClearSectorBuffers);
- the savestate carries all eight slots plus both indices; the section
is length-checked, so older states are rejected rather than misparsed.
New counters ring_dropped (guest a full ring behind -- hardware drops
too) and int1_redelivered (missed sectors recovered) in cdrom_state.
Builds and links clean in build-release.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>