Skip to main content

System

Struct System 

Source
pub struct System {
    pub cpu: Cpu,
    pub bus: Bus,
    /* private fields */
}
Expand description

Owns the run loop and ties the CPU to the Bus on one timeline.

Determinism contract: same seed + ROM + input ⇒ bit-identical A/V (ADR 0004).

Fields§

§cpu: Cpu

The CPU.

§bus: Bus

The Bus — owns everything else mutable (RDRAM / RSP / RDP / AI / cart / controllers / RCP registers).

Implementations§

Source§

impl System

Source

pub fn new(seed: u64) -> Self

Power on with a determinism seed (drives the per-domain phase alignment).

Source

pub fn reset(&mut self)

Reset (warm). Re-derives the SAME phase alignment from the retained seed so a reset mid-run stays deterministic.

Source

pub const fn master_ticks(&self) -> u64

Master ticks elapsed since power-on. The canonical time position.

Source

pub const fn cpu_cycles(&self) -> u64

The CPU’s position on the timeline, in PClocks. Derived, not stored.

This is a position, not a count of work done — with a nonzero seeded phase it is nonzero before the CPU has stepped, which is correct and is what the residue invariant pins. For work retired, use Cpu::retired.

Source

pub const fn rcp_cycles(&self) -> u64

The RCP’s position on the timeline, in MClocks. Derived, not stored.

Source

pub const fn count_ticks(&self) -> u64

The COP0 Count offset since power-on, at half PClock.

Not the architectural register: Count is guest-writable via MTC0, so the real value is affine — epoch_value + (master_ticks - epoch_tick) / COUNT_DIVIDER, re-based on every write. The affine half lives in the CPU (rustyn64_cpu::cop0, T-12-003) and is fed from here via tick_at; this is the timeline half.

Source

pub fn step_to_next_edge(&mut self) -> u64

Advance to the next tick at which any domain is due, and step every domain due at that tick. Returns the tick landed on.

Edge-to-edge: the master tick is never iterated. Hot path — allocation-free.

Note the tick the machine currently sits on is never re-stepped, so tick 0 is a position rather than an executed edge. Only the intervals between ticks carry work, which is what keeps the residue invariant constant.

Source

pub fn run_until(&mut self, target: u64)

Run until master_ticks() == target, stepping every domain on every edge in (now, target] — and not one past it.

Overshooting would make “how many CPU steps in N ticks” depend on where the edges happened to fall, which is exactly the kind of off-by-a-phase error the residue invariant is meant to make impossible.

Trait Implementations§

Source§

impl Debug for System

Source§

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

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

impl<'de> Deserialize<'de> for System

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Serialize for System

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

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> 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, 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.
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,