APU Pulse: Difference between revisions
m (→APU: only cosmetic changes.) |
(Sweep registers are conspicuous by absence. IMO the least astonishing thing is to link to the page describing them.) |
||
Line 25: | Line 25: | ||
|- | |- | ||
|colspan=2| Side effects || The duty cycle is changed (see table below), but the sequencer's current position isn't affected. | |colspan=2| Side effects || The duty cycle is changed (see table below), but the sequencer's current position isn't affected. | ||
|- | |||
|colspan=3| | |||
|- | |||
| '''$4001''' || <tt>EPPP.NSSS</tt> || See [[APU Sweep]] | |||
|- | |||
| '''$4005''' || <tt>EPPP.NSSS</tt> || See [[APU Sweep]] | |||
|- | |- | ||
|colspan=3| | |colspan=3| |
Revision as of 15:58, 28 December 2016
Each of the two NES APU pulse (square) wave channels generate a pulse wave with variable duty.
Each pulse channel contains the following: envelope generator, sweep unit, timer, 8-step sequencer, length counter. Note: the addresses below are write-only!
Sweep -----> Timer | | | | | v | Sequencer Length Counter | | | | | | v v v Envelope -------> Gate -----> Gate -------> Gate --->(to mixer)
Address | Bitfield | Description |
---|---|---|
$4000 | DDlc.vvvv | Pulse 1 Duty cycle, length counter halt, constant volume/envelope flag, and volume/envelope divider period |
$4004 | DDlc.vvvv | Pulse 2 Duty cycle, length counter halt, constant volume/envelope flag, and volume/envelope divider period |
Side effects | The duty cycle is changed (see table below), but the sequencer's current position isn't affected. | |
$4001 | EPPP.NSSS | See APU Sweep |
$4005 | EPPP.NSSS | See APU Sweep |
$4002 | LLLL.LLLL | Pulse 1 timer Low 8 bits |
$4006 | LLLL.LLLL | Pulse 2 timer Low 8 bits |
$4003 | llll.lHHH | Pulse 1 length counter load and timer High 3 bits |
$4007 | llll.lHHH | Pulse 2 length counter load and timer High 3 bits |
Side effects | The sequencer is immediately restarted at the first value of the current sequence. The envelope is also restarted. |
Duty Cycle Sequences
Duty | Waveform sequence |
---|---|
0 | 0 1 0 0 0 0 0 0 (12.5%) |
1 | 0 1 1 0 0 0 0 0 (25%) |
2 | 0 1 1 1 1 0 0 0 (50%) |
3 | 1 0 0 1 1 1 1 1 (25% negated) |
- The reason for these odd sequences is that the sequence counter is initialized to zero but counts downward rather than upward
The sequencer is clocked by an 11-bit timer. Given the timer value t = HHHLLLLLLLL formed by timer high and timer low, this timer is updated every APU cycle (i.e., every second CPU cycle), and counts t, t-1, ..., 0, t, t-1, ..., clocking the waveform generator when it goes from 0 to t. Since the period of the timer is t+1 APU cycles and the sequencer has 8 steps, the period of the waveform is 8*(t+1) APU cycles, or equivalently 16*(t+1) CPU cycles.
Hence
- fpulse = fCPU/(16*(t+1)) (where fCPU is 1.789773 MHz for NTSC, 1.662607 MHz for PAL, and 1.773448 MHz for Dendy)
- t = fCPU/(16*fpulse) - 1
A period of t < 8, either set explicitly or via a sweep period update, silences the corresponding pulse channel. The highest frequency a pulse channel can output is hence about 12.4 kHz for NTSC. (TODO: PAL behavior?)
The mixer receives the current envelope volume except when
- The sequencer output is zero, or
- overflow from the sweep unit's adder is silencing the channel, or
- the length counter is zero, or
- the timer has a value less than eight.
The behavior of the two pulse channels differs only in the effect of the negate mode of their sweep units.
Notice that a few Famiclone units have swapped APU duty cycles, as 12.5, 50, 25 and 25 negated instead.