pub struct Vi { /* private fields */ }Expand description
The Video Interface register file (the 0x0440_0000 block).
Implementations§
Source§impl Vi
impl Vi
Sourcepub const fn new() -> Self
pub const fn new() -> Self
Construct at power-on: every register zero, so VI_CTRL.TYPE == 0 (the
VI is off) — the correct cold-boot state.
Sourcepub const fn reset_scan(&mut self)
pub const fn reset_scan(&mut self)
Rebase the scan timeline to a fresh master_ticks == 0 (a warm reset),
clearing the accumulated position and the delta baseline without
touching the programmed registers. Without this, prev_ticks would keep
the pre-reset value and every post-reset delta would saturate to 0 until
the new run caught up — suppressing the VI interrupt across a reset.
Sourcepub fn tick(&mut self, master_ticks: u64) -> bool
pub fn tick(&mut self, master_ticks: u64) -> bool
Advance the scan position by the master ticks elapsed since the last call and report whether the VI interrupt should fire.
VI_V_CURRENT advances one half-line every ticks_per_halfline master
ticks (accumulating the fractional remainder), wrapping at VI_V_TOTAL + 1. The interrupt fires when the position lands on VI_V_INTR — the
per-half-line step means no crossing is skipped even when a call spans
many half-lines — and only while the VI is on (VI_CTRL.TYPE != 0;
N64brew Video Interface §VI_V_INTR). A VI_V_INTR beyond the field
(>= VI_V_TOTAL + 1) is unreachable, so it never fires. The position is
kept relative, so a mid-run VI_V_TOTAL change re-bases without a scale
jump. The scheduler calls this each RCP step and raises MI_INTR.vi on a
true return.
Sourcepub const fn read(&self, word_offset: u32) -> u32
pub const fn read(&self, word_offset: u32) -> u32
Read a VI register by word offset within the block (mirrored to 16).
VI_V_CURRENT reads back the scan position advanced by Vi::tick.
Sourcepub const fn write(&mut self, word_offset: u32, value: u32) -> bool
pub const fn write(&mut self, word_offset: u32, value: u32) -> bool
Write a VI register by word offset. Returns true iff this write should
acknowledge the VI interrupt — a write to VI_V_CURRENT, which the
caller turns into MI_INTR.vi = false.
VI_V_CURRENT is not otherwise latched here: its value reflects the scan
position, which the scheduler will drive; a software write only clears
the interrupt.