APU Length Counter: Difference between revisions
Rainwarrior (talk | contribs) m (→Clocking: more clarification of immediate effects of enabled) |
mNo edit summary |
||
(25 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
The length counter provides automatic duration control for the [[APU|NES APU]] waveform channels. Once loaded with a value, it can optionally count down | [[Category:APU]] | ||
The length counter provides automatic duration control for the [[APU|NES APU]] waveform channels. Once loaded with a value, it can optionally count down (when the length counter halt flag is clear). Once it reaches zero, the corresponding channel is silenced. | |||
{| class="tabular" | {| class="tabular" | ||
Line 8: | Line 9: | ||
|colspan=3| | |colspan=3| | ||
|- | |- | ||
| '''$4000''' || <tt> | | '''$4000''' || <tt>ssHc.vvvv</tt> || '''[[APU Pulse|Pulse channel 1]] duty cycle, length counter halt, constant volume flag, and volume/[[APU Envelope|envelope]]''' (write) | ||
|- | |- | ||
| '''$4004''' || <tt> | | '''$4004''' || <tt>ssHc.vvvv</tt> || '''[[APU Pulse|Pulse channel 2]] duty cycle, length counter halt, constant volume flag, and volume/[[APU Envelope|envelope]]''' (write) | ||
|- | |- | ||
| '''$400C''' || <tt>-- | | '''$400C''' || <tt>--Hc.vvvv</tt> || '''[[APU Noise|Noise channel]] length counter halt, constant volume flag, and volume/[[APU Envelope|envelope]]''' (write) | ||
|- | |- | ||
| bit 5 || <tt>--H- ----</tt> || Halt length counter (this bit is also the [[APU Envelope|envelope's loop flag]]) | | bit 5 || <tt>--H- ----</tt> || Halt length counter (this bit is also the [[APU Envelope|envelope's loop flag]]) | ||
Line 40: | Line 41: | ||
</pre> | </pre> | ||
|- | |- | ||
|colspan=2| Side effects || The [[APU Envelope|envelope is restarted]] | |colspan=2| Side effects || The [[APU Envelope|envelope is restarted]], for pulse channels phase is reset, for triangle the linear counter reload flag is set. | ||
|} | |} | ||
Line 49: | Line 50: | ||
* The length counter is 0, or | * The length counter is 0, or | ||
* The halt flag is set | * The halt flag is set | ||
==Table structure== | |||
The structure of the length table becomes clearer when rearranged like in the following index to length map (which corresponds to the order in which the values appear in the [[Visual_circuit_tutorial#Decoders_and_mask_ROMs|internal APU lookup table]]): | |||
<pre> | |||
Legend: | |||
<bit pattern> (<value of bit pattern>) => <note length> | |||
Linear length values: | |||
1 1111 (1F) => 30 | |||
1 1101 (1D) => 28 | |||
1 1011 (1B) => 26 | |||
1 1001 (19) => 24 | |||
1 0111 (17) => 22 | |||
1 0101 (15) => 20 | |||
1 0011 (13) => 18 | |||
1 0001 (11) => 16 | |||
0 1111 (0F) => 14 | |||
0 1101 (0D) => 12 | |||
0 1011 (0B) => 10 | |||
0 1001 (09) => 8 | |||
0 0111 (07) => 6 | |||
0 0101 (05) => 4 | |||
0 0011 (03) => 2 | |||
0 0001 (01) => 254 | |||
Notes with base length 12 (4/4 at 75 bpm): | |||
1 1110 (1E) => 32 (96 times 1/3, quarter note triplet) | |||
1 1100 (1C) => 16 (48 times 1/3, eighth note triplet) | |||
1 1010 (1A) => 72 (48 times 1 1/2, dotted quarter) | |||
1 1000 (18) => 192 (Whole note) | |||
1 0110 (16) => 96 (Half note) | |||
1 0100 (14) => 48 (Quarter note) | |||
1 0010 (12) => 24 (Eighth note) | |||
1 0000 (10) => 12 (Sixteenth) | |||
Notes with base length 10 (4/4 at 90 bpm, with relative durations being the same as above): | |||
0 1110 (0E) => 26 (Approx. 80 times 1/3, quarter note triplet) | |||
0 1100 (0C) => 14 (Approx. 40 times 1/3, eighth note triplet) | |||
0 1010 (0A) => 60 (40 times 1 1/2, dotted quarter) | |||
0 1000 (08) => 160 (Whole note) | |||
0 0110 (06) => 80 (Half note) | |||
0 0100 (04) => 40 (Quarter note) | |||
0 0010 (02) => 20 (Eighth note) | |||
0 0000 (00) => 10 (Sixteenth) | |||
</pre> | |||
With the least significant bit set, the remaining bits select a linear length (with the exception of the 0 entry). Otherwise, we get note lengths based on a base length of 10 (MSB clear) or 12 (MSB set). | |||
==Length counter internals== | |||
In the actual APU, the length counter silences the channel when clocked ''while already zero'' (provided the length counter halt flag isn't set). The values in the above table are the actual values the length counter gets loaded with ''plus one'', to allow us to use a model where the channel is silenced when the length counter ''becomes'' zero. | |||
The triangle's linear counter works differently, and does silence the channel when it ''reaches'' zero. |
Latest revision as of 00:35, 12 June 2013
The length counter provides automatic duration control for the NES APU waveform channels. Once loaded with a value, it can optionally count down (when the length counter halt flag is clear). Once it reaches zero, the corresponding channel is silenced.
Address | Bitfield | Description |
---|---|---|
$4015 | ---d.nt21 | DMC control and length counter enabled flags (write) |
$4000 | ssHc.vvvv | Pulse channel 1 duty cycle, length counter halt, constant volume flag, and volume/envelope (write) |
$4004 | ssHc.vvvv | Pulse channel 2 duty cycle, length counter halt, constant volume flag, and volume/envelope (write) |
$400C | --Hc.vvvv | Noise channel length counter halt, constant volume flag, and volume/envelope (write) |
bit 5 | --H- ---- | Halt length counter (this bit is also the envelope's loop flag) |
$4008 | Hlll.llll | Triangle channel length counter halt and linear counter load (write) |
bit 7 | H--- ---- | Halt length counter (this bit is also the linear counter's control flag) |
$4003 | LLLL.Lttt | Pulse channel 1 length counter load and timer (write) |
$4007 | LLLL.Lttt | Pulse channel 2 length counter load and timer (write) |
$400B | LLLL.Lttt | Triangle channel length counter load and timer (write) |
$400F | LLLL.L--- | Noise channel length counter load (write) |
bits 7-3 | LLLL L--- | If the enabled flag is set, the length counter is loaded with entry L of the length table:
| 0 1 2 3 4 5 6 7 8 9 A B C D E F -----+---------------------------------------------------------------- 00-0F 10,254, 20, 2, 40, 4, 80, 6, 160, 8, 60, 10, 14, 12, 26, 14, 10-1F 12, 16, 24, 18, 48, 20, 96, 22, 192, 24, 72, 26, 16, 28, 32, 30 |
Side effects | The envelope is restarted, for pulse channels phase is reset, for triangle the linear counter reload flag is set. |
Clocking
When the enabled bit is cleared (via $4015), the length counter is forced to 0 and cannot be changed until enabled is set again (the length counter's previous value is lost). There is no immediate effect when enabled is set.
When clocked by the frame counter, the length counter is decremented except when:
- The length counter is 0, or
- The halt flag is set
Table structure
The structure of the length table becomes clearer when rearranged like in the following index to length map (which corresponds to the order in which the values appear in the internal APU lookup table):
Legend: <bit pattern> (<value of bit pattern>) => <note length> Linear length values: 1 1111 (1F) => 30 1 1101 (1D) => 28 1 1011 (1B) => 26 1 1001 (19) => 24 1 0111 (17) => 22 1 0101 (15) => 20 1 0011 (13) => 18 1 0001 (11) => 16 0 1111 (0F) => 14 0 1101 (0D) => 12 0 1011 (0B) => 10 0 1001 (09) => 8 0 0111 (07) => 6 0 0101 (05) => 4 0 0011 (03) => 2 0 0001 (01) => 254 Notes with base length 12 (4/4 at 75 bpm): 1 1110 (1E) => 32 (96 times 1/3, quarter note triplet) 1 1100 (1C) => 16 (48 times 1/3, eighth note triplet) 1 1010 (1A) => 72 (48 times 1 1/2, dotted quarter) 1 1000 (18) => 192 (Whole note) 1 0110 (16) => 96 (Half note) 1 0100 (14) => 48 (Quarter note) 1 0010 (12) => 24 (Eighth note) 1 0000 (10) => 12 (Sixteenth) Notes with base length 10 (4/4 at 90 bpm, with relative durations being the same as above): 0 1110 (0E) => 26 (Approx. 80 times 1/3, quarter note triplet) 0 1100 (0C) => 14 (Approx. 40 times 1/3, eighth note triplet) 0 1010 (0A) => 60 (40 times 1 1/2, dotted quarter) 0 1000 (08) => 160 (Whole note) 0 0110 (06) => 80 (Half note) 0 0100 (04) => 40 (Quarter note) 0 0010 (02) => 20 (Eighth note) 0 0000 (00) => 10 (Sixteenth)
With the least significant bit set, the remaining bits select a linear length (with the exception of the 0 entry). Otherwise, we get note lengths based on a base length of 10 (MSB clear) or 12 (MSB set).
Length counter internals
In the actual APU, the length counter silences the channel when clocked while already zero (provided the length counter halt flag isn't set). The values in the above table are the actual values the length counter gets loaded with plus one, to allow us to use a model where the channel is silenced when the length counter becomes zero.
The triangle's linear counter works differently, and does silence the channel when it reaches zero.