pub struct LengthCounter {
pub count: u8,
pub halt: bool,
pub new_halt: bool,
pub enabled: bool,
pub reload_val: u8,
pub previous_count: u8,
}Expand description
Length counter shared by pulse, triangle, noise channels.
Fields§
§count: u8Current count (0..=254). 0 = silenced.
halt: boolEffective halt flag consulted by clock (also serves as
envelope-loop on pulse/noise; control on triangle). Updated from
new_halt in reload.
new_halt: boolLatched halt value from the most recent $4000/$4004/$4008/$400C
write, promoted to halt by reload
after the half-frame clock (the “halt change occurs after clocking
length” rule). See the module docs.
enabled: boolChannel-enable flag from $4015 write.
reload_val: u8Pending reload value from the most recent length load. 0 = no pending
reload (a real load never selects table entry 0 for index 0 → value 10,
so 0 is an unambiguous “empty” sentinel here; the table has no 0
entry). Consumed by reload.
previous_count: u8Snapshot of count captured at load time. If the
half-frame clock decremented the counter this cycle, the post-clock
count differs from this snapshot and the pending reload is dropped (the
“reload ignored during clocking when ctr > 0” rule). See the module docs.
Implementations§
Source§impl LengthCounter
impl LengthCounter
Sourcepub fn load(&mut self, raw: u8)
pub fn load(&mut self, raw: u8)
Load a new value from a $4003/$4007/$400B/$400F write.
Lookup index = top 5 bits of the value.
The reload is deferred: it latches reload_val
and snapshots the current count into
previous_count; reload
applies it (or drops it, if a same-cycle half-frame clock moved the
count). A disabled channel ignores the load entirely.
Sourcepub const fn set_halt(&mut self, halt: bool)
pub const fn set_halt(&mut self, halt: bool)
Latch a halt-flag change from a $4000/$4004/$4008/$400C write.
The value takes effect at the next reload (after the
half-frame clock), not immediately — see the module docs.
Sourcepub const fn set_enabled(&mut self, enabled: bool)
pub const fn set_enabled(&mut self, enabled: bool)
Channel-enable update from $4015 write. Clearing the bit forces
the count to 0 (silences the channel).
Sourcepub const fn reload(&mut self)
pub const fn reload(&mut self)
Apply the deferred halt and reload. Called by the owning APU once per CPU
cycle, after the half-frame clock and before the
mixer samples the channel:
- A pending reload is honoured only if the post-clock count still equals
the
previous_countsnapshot taken at load — i.e. a same-cycle half-frame clock did not decrement it (it was already zero). Otherwise the reload is dropped. - The effective
haltis refreshed fromnew_haltunconditionally, so a halt change becomes effective for the next clock.
On a cycle with no half-frame clock (the overwhelmingly common case),
the count is untouched between the write and this call, so count == previous_count holds and the reload applies in-cycle — byte-identical to
an immediate load.
Trait Implementations§
Source§impl Clone for LengthCounter
impl Clone for LengthCounter
Source§fn clone(&self) -> LengthCounter
fn clone(&self) -> LengthCounter
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more