Skip to main content

Cart

Struct Cart 

Source
pub struct Cart {
    pub header: Header,
    pub board: Box<dyn Board>,
}
Expand description

A loaded cartridge: a parsed Header + the Board that implements its mapping and any coprocessor. The crate::board module decodes the header into the right board.

Replace the stub internals with the real ROM/SRAM storage; pin behavior against the test ROMs FIRST (test-ROM-is-spec), then implement until they pass.

Fields§

§header: Header

The parsed cartridge header (map mode, region, coprocessor id, sizes).

§board: Box<dyn Board>

The active memory-map board (LoROM / HiROM / ExHiROM + coprocessor hooks).

Implementations§

Source§

impl Cart

Source

pub fn load(rom: &[u8]) -> Result<Self, HeaderError>

Decode a raw ROM image into a Cart (header detection + board selection).

Strips a 512-byte copier prefix when present, detects the internal header, and builds the matching board backed by the real ROM bytes + a zeroed, header-sized SRAM.

§Errors

Returns HeaderError if the image is too small or no internal header scores a valid map mode at any candidate offset (LoROM $7FC0 / HiROM $FFC0 / ExHiROM $40FFC0).

Source

pub fn from_rom(rom: &[u8]) -> Result<Self, HeaderError>

Decode a raw ROM image into a Cart. Alias of Cart::load.

§Errors

See Cart::load.

Source

pub fn read24(&mut self, addr24: u32, open_bus: u8) -> u8

Read a byte at a 24-bit CPU address (bank << 16) | addr via the active board.

open_bus is the caller’s current open-bus latch (the CPU’s MDR — the last value actually driven on the data bus), echoed back verbatim when the board’s own MappedAddr::Open decode says this address is genuinely unmapped. Ported from ares’ Bus::read(address, data) (sfc/memory/inline.hpp), which threads the same fallback value through for exactly this reason: Board::read24’s own default (and every coprocessor board’s override) has no access to the shared bus latch and would otherwise have to invent a placeholder value — every board here returns a bare 0 for that case, which is wrong for real open bus (a 0 opcode fetch is BRK, so a wild jump into unmapped cart space reliably BRK-storms in this emulator even on titles where real hardware’s open bus echoes back a harmless, non-zero value). See docs/audit/spc7110-boot-crash-2026-07-08.md for the investigation that found this.

Source

pub fn write24(&mut self, addr24: u32, val: u8)

Write a byte at a 24-bit CPU address (bank << 16) | addr via the active board.

Source

pub fn save_sram(&self) -> &[u8]

Borrow the current SRAM contents (for a battery save). Empty if the cart has no SRAM.

Source

pub fn load_sram(&mut self, data: &[u8])

Restore SRAM contents (from a battery save). Copies up to the board’s SRAM length; a shorter slice leaves the tail zeroed, a longer one is truncated.

Source

pub fn sram_mut(&mut self) -> &mut [u8]

The mutable counterpart to Self::save_sram — for a host embedder that needs a raw memory-map pointer (e.g. a libretro core’s RETRO_MEMORY_SAVE_RAM, which some frontends write through directly rather than only calling Self::load_sram).

Source

pub fn coprocessor_tick(&mut self)

Advance any on-cart coprocessor by one of its clock units. Default boards no-op.

Source

pub fn install_coprocessor_firmware(&mut self, bytes: &[u8]) -> bool

Supply a coprocessor firmware dump (the user-provided chip ROM, e.g. DSP-1 dsp1.rom).

Returns true if this cart’s board carried a chip-ROM-dump coprocessor that accepted the image. A cart without such a coprocessor (or a dump of the wrong size) returns false and is unchanged — the honesty posture of docs/adr/0003: absent the dump the coprocessor is non-functional, never silently degraded.

Source

pub fn firmware_hint(&self) -> Option<&'static str>

The specific firmware file name this cart’s board expects, if it knows exactly which chip dump it needs (see crate::board::Board::firmware_hint). None for boards that accept any same-family dump (or carry no firmware-dependent coprocessor at all).

Source

pub fn coprocessor_host_accesses(&self) -> u64

Count of host accesses to the coprocessor’s data ports since power-on (debugger/diag).

Trait Implementations§

Source§

impl Debug for Cart

Source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl Freeze for Cart

§

impl !RefUnwindSafe for Cart

§

impl Send for Cart

§

impl !Sync for Cart

§

impl Unpin for Cart

§

impl UnsafeUnpin for Cart

§

impl !UnwindSafe for Cart

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.