Skip to main content

Hg51b

Struct Hg51b 

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

The HG51B S169 core (CX4’s CPU).

Free-runs synchronously to its next halt/wait state via Hg51b::run_until_halt — the same run-to-completion host-sync pattern this project’s GSU (Go-bit) and DSP-1 (RQM) engines use, since the pc-write trigger ($7f4f while halted) is the only observable coupling to the S-CPU (docs/cart.md §CX4).

Implementations§

Source§

impl Hg51b

Source

pub fn new() -> Self

Construct a powered-off HG51B (inert until Hg51b::load_data_rom supplies the constant table — docs/adr/0003).

Source

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

Load the 3072-byte (1024 x 24-bit, 3 bytes/word little-endian) data-ROM constant table (cx4.rom). Returns false (and leaves the chip inert) if the dump is the wrong size.

Source

pub const fn data_rom_loaded(&self) -> bool

Whether the data-ROM constant table has been supplied (the chip is functional).

Source

pub const fn instructions_run(&self) -> u64

Total instructions executed since power-on (debugger/diagnostics).

Source

pub fn read_dram(&self, offset: u32) -> u8

Read the 3 KiB data RAM at a chip-relative offset ($000-$FFF, folded per the >=$C00 hardware quirk — see fold_dram).

Source

pub fn write_dram(&mut self, offset: u32, data: u8)

Write the 3 KiB data RAM at a chip-relative offset (see Self::read_dram).

Source

pub fn read_io(&mut self, local: u32) -> u8

Read the fixed IO register block ($7F40-$7FEF, DMA/cache/wait/IRQ/vector/GPR-mirror controls — ares HitachiDSP::readIO). local is the address already folded to 0x7C00 | (address & 0x3FF) by the caller (the board owns the bus-window decode).

Source

pub fn write_io(&mut self, local: u32, data: u8, bus: &mut impl Hg51bBus)

Write the fixed IO register block (see Self::read_io). bus supplies the chip-ROM access this may need to kick off (a cache-page refill on the pc-write trigger).

Source

pub const fn running(&self) -> bool

Whether the chip is doing anything at all (cache/dma/bus pending, or not halted).

Source

pub const fn busy(&self) -> bool

Whether the chip is mid-cache/dma/bus-access (narrower than Self::running).

Source

pub const fn irq_pending(&self) -> bool

Whether the host IRQ line should be asserted (raised when the chip halts with IRQs enabled — docs/cart.md §CX4’s execution-model note).

Source

pub fn run_until_halt(&mut self, bus: &mut impl Hg51bBus)

Run the chip to its next halt (or RUN_CAP instructions, whichever comes first) — the host-sync run-to-completion pattern (see the struct doc).

Source

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

Write this core’s mutable state — every register, the IO block, the two cached program pages, the 3 KiB data RAM, and the 8-deep call stack — into an "HG51" section. The data ROM (cx4.rom, firmware) is deliberately NOT written, per docs/adr/0003’s “never embed a chip-ROM dump in a save-state” posture: it is reloaded fresh via Self::load_data_rom before a matching Self::load_state call. instructions_run (a debugger counter, not emulated-hardware state) is also omitted.

Source

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

The inverse of Self::save_state.

§Errors

SaveStateError on truncated/corrupt input (the section framing itself already rejects a wrong tag or a truncated read) or a section with unconsumed trailing bytes. Every hardware register narrower than its Rust storage type is masked to its real width on load (pb/p/cache.pb are 15-bit, a/mdr/rom/ram/mar/dpr/gpr are 24-bit, mul is 48-bit, wait.rom/wait.ram are 3-bit) — the same “apply the engine’s own normal-operation width invariant on load” reasoning already applied to the NEC DSP engine’s pc/rp/dp/sp, extended here to every register (this core happens to have no field whose valid range is narrower than its type in a way that risks an out-of-bounds array index, but an unmasked wide value would still desync subsequent arithmetic from hardware behavior, which matters for save-state fidelity even without a panic risk).

Trait Implementations§

Source§

impl Debug for Hg51b

Source§

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

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

impl Default for Hg51b

Source§

fn default() -> Self

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

Auto Trait Implementations§

§

impl Freeze for Hg51b

§

impl RefUnwindSafe for Hg51b

§

impl Send for Hg51b

§

impl Sync for Hg51b

§

impl Unpin for Hg51b

§

impl UnsafeUnpin for Hg51b

§

impl UnwindSafe for Hg51b

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.