Skip to main content

Gsu

Struct Gsu 

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

The Super FX GSU core — registers, status, caches, and the ROM/RAM buffer latches.

The board owns the ROM/RAM bytes and supplies them via GsuMem on each run; this struct is the pure register/state machine (so the whole thing is Clone for save-states).

Implementations§

Source§

impl Gsu

Source

pub fn new() -> Self

Power-on a GSU core (ares GSU::power + SuperFX::power).

§Panics

Never in practice: the only fallible step is sizing the fixed 512-byte cache buffer, which cannot fail for the constant length.

Source

pub const fn go(&self) -> bool

Whether the Go flag is set (the GSU is running / owns the bus).

Source

pub const fn owns_rom(&self) -> bool

Whether the GSU currently owns the ROM bus (Go + SCMR ROM-on).

Source

pub const fn owns_ram(&self) -> bool

Whether the GSU currently owns the RAM bus (Go + SCMR RAM-on).

Source

pub const fn irq_pending(&self) -> bool

Whether the GSU is asserting its IRQ line (SFR IRQ flag, gated by CFGR IRQ-mask).

Source

pub const fn instructions(&self) -> u64

The number of instructions executed since power-on.

Source

pub const fn clocks(&self) -> u64

The number of GSU clock cycles executed.

Source

pub const fn registers(&self) -> [u16; 16]

The R0-R15 general-purpose register file (R15 is also the program counter).

Source

pub const fn sfr(&self) -> u16

The status flag register (SFR).

Source

pub const fn pbr(&self) -> u8

The program bank register.

Source

pub fn step_one(&mut self, mem: &mut GsuMem<'_>) -> u32

Drain one bus-access clock checkpoint (ares SuperFX::step/Thread::synchronize granularity — sfc/coprocessor/superfx/timing.cpp) and report its clock count, running as many further GSU instructions as needed to produce one. The board’s host loop calls this in a loop, folding each returned delta into the master clock immediately, so the PPU/NMI/APU advance in step with the GSU at true per-access granularity instead of crediting an entire instruction — or an entire multi-instruction burst — all at once (which let a two-pass render, e.g. a screen split into a left-half then a right-half Go burst, desync the two halves’ notion of “now”). Each instruction still runs to completion eagerly inside Gsu::main_step — only the reporting of its accesses to the caller is paced one at a time, which is externally indistinguishable from true per-access interleaving because nothing GSU-side reads back caller/Bus state mid-instruction. Returns 0 once Go clears and there is nothing left queued.

Source

pub fn tick(&mut self, mem: &mut GsuMem<'_>)

Advance by exactly one master clock (ares SuperFX::main, scheduled by its Thread at native master-clock granularity — sfc/coprocessor/superfx/superfx.cpp). The board’s host loop calls this from inside the Bus’s own per-master-tick loop, unconditionally, every single tick — the same place the PPU dot and the APU’s SMP-cycle release happen — so the GSU genuinely interleaves with the CPU’s own instruction stream instead of a Go burst draining to completion “atomically” inside the one bus write that armed it (which left the CPU unable to do any of its own work, or service a second Go burst, until the first fully finished). owed paces Gsu::step_one’s per-access checkpoints out one master clock at a time: the instruction’s own side effects still land eagerly the moment its checkpoint is pulled (no full deferred-commit — see the field doc), but the next GSU instruction can no longer start until the real number of elapsed master clocks the current one costs has actually passed, letting the CPU run freely in between.

Source

pub fn run_until_stopped(&mut self, mem: &mut GsuMem<'_>)

Run the GSU to completion: step instructions while Go is set, capped against a runaway program. Called by the board the instant the CPU sets Go (the DSP-1 run_until_rqm analogue). Returns when the program executes STOP (Go clears) or the cap trips.

Prefer Gsu::step_one driven by the board’s host loop when master-clock-accurate interleaving matters (e.g. a screen render split across multiple Go bursts within one displayed frame) — this method is for callers that only need the final result.

Source

pub fn read_register(&mut self, address: u16) -> u8

Host read of a GSU register (address = $0000-$02FF window offset; ares readIO).

Source

pub fn write_register(&mut self, address: u16, data: u8) -> bool

Host write of a GSU register. Returns true if this write set the Go flag (0->1), so the board knows to run the GSU to completion (ares writeIO).

Source

pub fn save_state(&self, w: &mut SaveWriter)

Write this core’s full mutable state — every register, the status/control fields, both bus-buffer latches, the opcode cache, the plot pixel cache, the liveness counters, and the in-flight per-access checkpoint queue (pending_clocks/pending_idx/owed) — into a "GSU0" section. There is no firmware/ROM byte here to exclude: the GSU’s program lives in the cart’s own ROM, which System::save_state captures separately (docs/adr/0003). The checkpoint queue matters because Self::tick-driven (master-clock-interleaved) execution can leave a Go burst genuinely mid-flight at any save point, unlike the run-to-completion Self::run_until_stopped path, which always drains it back to empty first.

Source

pub fn load_state( &mut self, r: &mut SaveReader<'_>, ) -> Result<(), SaveStateError>

The inverse of Self::save_state.

§Errors

SaveStateError on truncated/corrupt input, a section with unconsumed trailing bytes, or SaveStateError::Invalid if the saved pending_clocks length exceeds MAX_SAVED_PENDING_CLOCKS or pending_idx exceeds the restored queue’s length (both would otherwise let a corrupted save-state desync Self::step_one’s cursor). sreg/dreg are masked to 4 bits — they index the 16-entry register file directly.

Trait Implementations§

Source§

impl Clone for Gsu

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Gsu

Source§

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

Formats the value using the given formatter. Read more
Source§

impl Default for Gsu

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl Freeze for Gsu

§

impl RefUnwindSafe for Gsu

§

impl Send for Gsu

§

impl Sync for Gsu

§

impl Unpin for Gsu

§

impl UnsafeUnpin for Gsu

§

impl UnwindSafe for Gsu

Blanket Implementations§

Source§

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

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

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

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

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

Source§

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

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

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

Source§

fn into(self) -> U

Calls U::from(self).

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

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

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

Source§

type Error = Infallible

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

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

Performs the conversion.
Source§

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

Source§

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

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

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

Performs the conversion.