APU Pulse: Difference between revisions

From NESdev Wiki
Jump to navigationJump to search
(clarify - duty cycle sequencer is *immediately* restarted)
m (→‎APU: only cosmetic changes.)
Line 3: Line 3:


Each pulse channel contains the following: [[APU Envelope|envelope generator]], [[APU Sweep|sweep unit]], [[APU Misc|timer]], 8-step [[APU Misc|sequencer]], [[APU Length Counter|length counter]].
Each pulse channel contains the following: [[APU Envelope|envelope generator]], [[APU Sweep|sweep unit]], [[APU Misc|timer]], 8-step [[APU Misc|sequencer]], [[APU Length Counter|length counter]].
'''Note''': the addresses below are write-only''!''


<pre>
<pre>
Line 19: Line 20:
! Address || Bitfield || Description
! Address || Bitfield || Description
|-
|-
| '''$4000''' || <tt>DDlc.vvvv</tt> || '''Pulse 1''' duty, [[APU Length Counter|length counter halt]], constant volume/[[APU Envelope|envelope]] flag, and volume/envelope divider period (write)
| '''$4000''' || <tt>DDlc.vvvv</tt> || '''Pulse 1''' '''D'''uty cycle, [[APU Length Counter|length counter halt]], '''c'''onstant volume/[[APU Envelope|envelope]] flag, and '''v'''olume/envelope divider period
|-
|-
| '''$4004''' || <tt>DDlc.vvvv</tt> || '''Pulse 2''' duty, [[APU Length Counter|length counter halt]], constant volume/[[APU Envelope|envelope]] flag, and volume/envelope divider period (write)
| '''$4004''' || <tt>DDlc.vvvv</tt> || '''Pulse 2''' '''D'''uty cycle, [[APU Length Counter|length counter halt]], '''c'''onstant volume/[[APU Envelope|envelope]] flag, and '''v'''olume/envelope divider period
|-
|-
| bits 7-6 || <tt>DD-- ----</tt> || The duty cycle is set (see table below). The sequencer's current position is not changed.
|colspan=2| Side effects || The duty cycle is changed (see table below), but the sequencer's current position isn't affected.
|-
|-
|colspan=3| &nbsp;
|colspan=3| &nbsp;
|-
|-
| '''$4002''' || <tt>LLLL.LLLL</tt> || '''Pulse 1''' timer low (write)
| '''$4002''' || <tt>LLLL.LLLL</tt> || '''Pulse 1''' timer '''L'''ow 8 bits
|-
|-
| '''$4006''' || <tt>LLLL.LLLL</tt> || '''Pulse 2''' timer low (write)
| '''$4006''' || <tt>LLLL.LLLL</tt> || '''Pulse 2''' timer '''L'''ow 8 bits
|-
| bits 7-0 || <tt>LLLL LLLL</tt> || Timer low 8 bits
|-
|-
|colspan=3| &nbsp;
|colspan=3| &nbsp;
|-
|-
| '''$4003''' || <tt>llll.lHHH</tt> || '''Pulse 1''' [[APU Length Counter|length counter load]] and timer high (write)
| '''$4003''' || <tt>llll.lHHH</tt> || '''Pulse 1''' [[APU Length Counter|length counter load]] and timer '''H'''igh 3 bits
|-
| '''$4007''' || <tt>llll.lHHH</tt> || '''Pulse 2''' [[APU Length Counter|length counter load]] and timer high (write)
|-
|-
| bits 2-0 || <tt>---- -HHH</tt> || Timer high 3 bits
| '''$4007''' || <tt>llll.lHHH</tt> || '''Pulse 2''' [[APU Length Counter|length counter load]] and timer '''H'''igh 3 bits
|-
|-
|colspan=2| Side effects || The sequencer is immediately restarted at the first value of the current sequence. The [[APU Envelope|envelope]] is also restarted.
|colspan=2| Side effects || The sequencer is immediately restarted at the first value of the current sequence. The [[APU Envelope|envelope]] is also restarted.

Revision as of 15:26, 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.
 
$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.