SDK crate

psx-cdstream

Interrupt-driven CD-ROM streaming: queued reads, abort, chaining and an audio lease

On this page

Use psx-cdstream to read data from the disc while a game keeps running. You queue reads; the CD interrupt handler pops one sector per drive interrupt straight into your buffer; the main loop only submits, cancels and asks how far a read has got. For reads that happen once, at boot, the polled SectorReader in psx-io is still the simpler tool.

How the crate is organized

Engine is the whole state machine and is generic over CdHw, the controller as the machine sees it. On the console, install puts an exception wrapper in front of psx-rt's handler that calls one global engine once per CD interrupt, and the free functions (submit, cancel, state, request_audio_lease) reach it. On the host, the crate's tests drive the same engine against a scripted drive, so every phase, cancel point, error path, chaining rule and lease transition runs without hardware.

A Request names a run of sectors and the memory they go to. Priority orders waiting requests, Ticket names a submitted one, and RequestState and Completion say where it is and how it ended.

Integration notes

Every transfer is Setloc, SeekL, Setmode (double speed), ReadN: the sequence the BIOS uses. A bare Setloc plus ReadN began delivering while the mechanism was still settling and corrupted long streams on a console. Sectors are popped by the CPU, because chopped CD DMA was unreliable on a console; that costs CPU time while a read runs, so read in bursts when there is work.

cancel only sets a flag. The handler drops the next sector and pauses the drive itself, because a Pause sent from the main loop while sectors were arriving lost its acknowledge on silicon. The request ends Cancelled with the number of sectors that had landed, and Request::remaining_after builds the request that continues it. Request::with_resumes makes the transport do that itself after a drive error.

Up to QUEUE_DEPTH requests wait behind the active one, most urgent Priority first. A waiting request that starts at the sector after the active one's last continues without a Pause or a seek, so a group of regions laid out in reading order costs one seek.

CD-DA and XA playback cannot share the drive with data reads. request_audio_lease stops the read in flight, waits for the drive to stop, closes the CD interrupt source and lets you collect the controller token with take_audio_lease; release_audio_lease takes it back and queued reads carry on. End audio with Pause, not Stop: after Stop the motor spins down and reads started in the next second or two failed on a console.

A lease that was asked for and left pending is granted the moment the drive stops, ahead of any read queued meanwhile, so a read submitted in between waits for audio to finish. Audio that should not hold up reads calls try_take_audio_lease, which takes the drive only if it is free and otherwise leaves nothing behind, or ends the pending request with withdraw_audio_lease.

install takes the controller token that SectorReader::release returns, so the compiler keeps the polled reader and the interrupt transport from using the drive at once. uninstall hands the token back.

The counters (StreamStats) are published as the PSX_CD_STATS symbol for tools that read guest memory. The trace feature also records the last 128 controller events.

The state machine and the scripted drive are covered by host tests. The console wrapper and the register sequences are the same ones the earlier game-local transports shipped, but this crate has been run only in the emulator so far; a console run is still to do.

Example

hello-cdstream streams a known file off a disc through the crate and checks every byte: single and chained reads, priority, abort and resume, a sustained stream, an audio lease and a failing read.

API, dependencies and source structure

SDK revision f2fec1c301f1. Structure, dependencies and features below come from this revision.

The PS1 reference includes all Cargo features. The manifest below shows which features are enabled by default.

Dependencies

  • psx-hw (shared repository crate): all targets
  • psx-io: all targets
  • psx-rt: all targets

Cargo features

FeatureEnables
defaultNo additional dependency features
traceNo additional dependency features

Read the complete manifest and feature comments.

Source layout

The list includes internal implementation and test files. Public modules, types, functions and their signatures are indexed in the API reference above.

8 source and manifest files
  • Cargo.toml
  • src/console.rs: The console side: the real drive, the one global Engine, and the
  • src/engine.rs: The transport state machine (Engine) and its configuration and counters.
  • src/fake.rs: A scripted CD drive for the host tests.
  • src/hw.rs: The drive as the transport state machine sees it.
  • src/lib.rs: Interrupt-driven CD-ROM sector streaming.
  • src/request.rs: Read requests and what comes back from them.
  • src/tests.rs: The transport state machine against a scripted drive.