Skip to main content
← PSoXide SDK guides and examples · SDK f2fec1c301f1 · All Cargo features enabled; check feature gates before use.

Cd

Struct Cd 

Source
pub struct Cd { /* private fields */ }
Expand description

The CD-ROM controller and DMA channel 3.

Implementations§

Source§

impl Cd

Source

pub fn command( &mut self, command: u8, params: &[u8], ) -> Result<Response, CdError>

Send a command and return its first response packet, waiting at most DEFAULT_COMMAND_SPINS polls for each step.

Returns CdError::Timeout when the controller never answers and CdError::DriveError when the drive reports an error. A timed-out command leaves CD-ROM IRQ output masked, as Self::try_command does.

Source

pub fn command_within( &mut self, command: u8, params: &[u8], spin_limit: u32, ) -> Result<Response, CdError>

Self::command with an explicit poll budget per step.

Source

pub fn try_command( &mut self, command: u8, params: &[u8], spin_limit: u32, ) -> Option<Response>

Try to send a command and capture its first response packet.

Returns None if the controller does not expose parameter room or a response within spin_limit polls, or if the drive reports an error (Self::command_within tells the two apart). Use this for gameplay paths where a not-ready drive should not stall rendering forever. If a dispatched command times out, CD-ROM IRQ output remains masked so a late ACK cannot interrupt a polling caller.

Source

pub fn irq_flag_value(&mut self) -> u8

Current CD-ROM IRQ flag value (0 = none, 1 = data ready, 2 = complete, 3 = ack, 5 = error).

Exposed so callers can build their own wait loops bounded by a hardware timer rather than by a poll count. A poll budget is only a proxy for time and drifts with CPU and bus speed, which matters when the thing being measured is mechanical.

Source

pub fn acknowledge_irq(&mut self, bits: u8)

Acknowledge the given CD-ROM IRQ bits.

Source

pub fn discard_response(&mut self)

Drain any pending response bytes, discarding them.

Source

pub fn dispatch_command( &mut self, command: u8, params: &[u8], spin_limit: u32, ) -> Option<u8>

Send a command without waiting for any response. Pairs with Self::irq_flag_value for caller-timed waits.

Returns the CD-ROM IRQ enable to give back to restore_irq_output, or None if the parameter FIFO never made room. Leaves CD-ROM IRQ output masked exactly as the polled helpers do, so a late ACK cannot interrupt the caller mid-measurement; call Self::restore_irq_output when done.

Source

pub fn restore_irq_output(&mut self, saved: u8)

Restore the CD-ROM IRQ enable saved by Self::dispatch_command.

Source

pub fn poll_data_sector(&mut self) -> Result<bool, SectorPollError>

Nonblocking readiness probe for a sector reader that owns the INT1 ACK. Data-ready is never acknowledged here. Other completion responses are drained (at most 256 bytes) and acknowledged; drive errors also reset the parameter FIFO. A ready data FIFO is accepted if no classified IRQ remains.

Source

pub fn try_wait_data_sector(&mut self, spin_limit: u32) -> bool

Wait for the next streamed data sector (INT1) and acknowledge it.

Use between Self::try_start_reading and Self::try_pause_until_complete to step through a sector stream. Unrelated pending IRQs are drained and acknowledged so a stale response cannot be mistaken for a sector arrival. Returns false on a drive error or if no sector arrives within spin_limit polls.

Source

pub fn status(&mut self) -> Result<Response, CdError>

Get the CD-ROM drive status byte.

Source

pub fn try_status(&mut self, spin_limit: u32) -> Option<Response>

Try to get the CD-ROM drive status byte.

Source

pub fn set_mode(&mut self, mode: u8) -> Result<Response, CdError>

Set the CD-ROM controller mode byte.

Source

pub fn try_set_mode(&mut self, mode: u8, spin_limit: u32) -> Option<Response>

Try to set the CD-ROM controller mode byte.

Source

pub fn try_set_target_lba( &mut self, lba: u32, spin_limit: u32, ) -> Option<Response>

Seek to a logical data-sector LBA (the command receives absolute BCD MSF).

Source

pub fn try_start_reading(&mut self, spin_limit: u32) -> Option<Response>

Begin a normal data-sector stream at the most recently selected location.

Source

pub fn unmute(&mut self) -> Result<Response, CdError>

Route CD-DA/XA output out of the CD-ROM controller.

Source

pub fn try_unmute(&mut self, spin_limit: u32) -> Option<Response>

Try to route CD-DA/XA output out of the CD-ROM controller.

Source

pub fn mute(&mut self) -> Result<Response, CdError>

Mute CD-DA/XA output at the CD-ROM controller.

Source

pub fn try_mute(&mut self, spin_limit: u32) -> Option<Response>

Try to mute CD-DA/XA output at the CD-ROM controller.

Source

pub fn play_track(&mut self, track: u8) -> Result<Response, CdError>

Start CD-DA playback at a 1-based track number.

The number is relative to this program’s own tracks; on a multi-program disc crate::disc_base shifts it past whatever came before.

Source

pub fn try_play_track(&mut self, track: u8, spin_limit: u32) -> Option<Response>

Try to start CD-DA playback at a 1-based track number. Shifted like Self::play_track.

Source

pub fn pause(&mut self) -> Result<Response, CdError>

Pause CD-DA/read playback.

Source

pub fn try_pause(&mut self, spin_limit: u32) -> Option<Response>

Try to pause CD-DA/read playback.

Source

pub fn try_pause_until_complete(&mut self, spin_limit: u32) -> bool

Try to pause CD-DA/read playback and wait for the completion IRQ.

Unlike Self::try_stop, this leaves the drive spun up, which makes it the right handoff before gameplay code starts issuing data-read commands.

Source

pub fn stop(&mut self) -> Result<Response, CdError>

Stop the CD-ROM motor/playback.

Source

pub fn try_stop(&mut self, spin_limit: u32) -> Option<Response>

Try to stop the CD-ROM motor/playback.

This returns when the command is ACCEPTED, not when the drive is done. On real hardware the motor then winds down for one to two seconds, during which GetStat reports no activity bits and data-read commands fail; an emulator answers instantly and hides the window (proven by a demo-disc burn whose every chain-load died this way). If data reads follow, either call Self::stop_and_settle, or better, keep the drive spun up with Self::try_pause_until_complete.

Source

pub fn stop_and_settle(&mut self, spin_limit: u32, max_polls: u32) -> bool

Stop playback and wait until the drive has genuinely gone quiet: GetStat reporting neither playing nor seeking on two consecutive polls, with a short pause between polls. Bounded by max_polls so a wedged drive cannot hang the caller; returns whether the drive settled.

This is the safe prelude to issuing data-read commands after CD-DA. Self::try_pause_until_complete is the faster choice when the next reads are imminent, since it keeps the motor spinning.

Source

pub fn play_position(&mut self) -> Result<Response, CdError>

Get the current physical play position (CdlGetlocP). The 8-byte reply is [Track(bcd), Index(raw), RMM, RSS, RSECT, AMM, ASS, ASECT]; parse it with PlayPosition::parse.

Source

pub fn try_play_position(&mut self, spin_limit: u32) -> Option<Response>

Try to get the current physical play position, giving up after spin_limit.

Source

pub fn try_command_until_complete( &mut self, command: u8, params: &[u8], spin_limit: u32, ) -> bool

Send a command and wait for its SECOND response (the completion IRQ), not just the initial acknowledgement.

Seek, read and init all acknowledge immediately and finish much later, so timing them against the ack measures command dispatch rather than the mechanical operation. Returns false if either response fails to arrive within spin_limit polls.

Source

pub fn set_audio_mixer( &mut self, left_to_left: u8, left_to_right: u8, right_to_right: u8, right_to_left: u8, )

Program the drive’s audio mixer (CD-DA and XA-ADPCM on their way to the SPU’s CD input) and apply it. Volumes are 0..=0xFF with 0x80 as unity; (0x80, 0, 0x80, 0) is plain stereo. The SPU side still needs its CD input enabled and a CD volume (psx-spu).

Source§

impl Cd

Register-level steps, for a driver that sequences commands itself, such as the polled reader::SectorReader.

Each is one controller access or a short fixed run of them, and each leaves register index 0 selected, so the byte steps that follow need not select it again.

Source

pub fn acknowledge_all_and_reset_parameters(&mut self)

Acknowledge every controller IRQ (writing 0x5F, which also resets the parameter FIFO) and the CD-ROM bit of I_STAT.

Source

pub fn irq_enable_mask(&mut self) -> u8

The controller’s IRQ enable bits.

Source

pub fn set_irq_enable_mask(&mut self, mask: u8)

Set the controller’s IRQ enable bits (five are defined).

Source

pub fn drain_response_limited(&mut self, limit: u32)

Pop and discard up to limit response bytes. The FIFO is 16 bytes deep; the bound is for a controller wedged “not empty”.

Source

pub fn is_data_fifo_ready(&mut self) -> bool

Whether the data FIFO holds sector bytes to pop.

Source

pub fn wait_parameter_room(&mut self, spins: u32) -> bool

Wait for the parameter FIFO to have room, for at most spins more status reads. false on timeout.

Source

pub fn reset_parameter_fifo(&mut self)

Empty the parameter FIFO.

Source

pub fn send_parameter_byte(&mut self, byte: u8)

Push one parameter byte. Wait for room first.

Source

pub fn send_command_byte(&mut self, byte: u8)

Write the command byte, which starts the command.

Source

pub fn read_response_byte(&mut self) -> u8

Pop one response byte.

Source

pub fn status_register(&mut self) -> u8

The status register: FIFO flags and the busy bit.

Source

pub fn request_data(&mut self)

Arm the data FIFO so the drive’s buffered sector can be popped with read_data_byte once is_data_fifo_ready says it filled.

Source

pub fn clear_data_request(&mut self)

Drop the data request, which resets the data FIFO.

Source

pub fn read_data_byte(&mut self) -> u8

Pop one byte of sector data.

Source§

impl Cd

Source

pub const unsafe fn steal() -> Self

Make a token without going through psx_rt::Peripherals::take().

§Safety

The caller must not use this token while another one of the same type is in use: two owners of one device each assume they are the only driver programming it.

Trait Implementations§

Source§

impl Debug for Cd

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl Freeze for Cd

§

impl RefUnwindSafe for Cd

§

impl Send for Cd

§

impl Sync for Cd

§

impl Unpin for Cd

§

impl UnsafeUnpin for Cd

§

impl UnwindSafe for Cd

Blanket Implementations§

§

impl<T> Any for T
where T: 'static + ?Sized,

§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<T> Borrow<T> for T
where T: ?Sized,

§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
§

impl<T> BorrowMut<T> for T
where T: ?Sized,

§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> From<T> for T

§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T, U> Into<U> for T
where U: From<T>,

§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of [From]<T> for U chooses to do.

§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.