An NES APU sweep unit can be made to periodically adjust a pulse channel's period up or down.
Each sweep unit contains the following:
$4001 | EPPP.NSSS | Pulse channel 1 sweep setup (write) |
$4005 | EPPP.NSSS | Pulse channel 2 sweep setup (write) |
bit 7 | E--- ---- | Enabled flag |
bits 6-4 | -PPP ---- | The divider's period is P + 1 half-frames |
bit 3 | ---- N--- | Negate flag 0: add to period, sweeping toward lower frequencies 1: subtract from period, sweeping toward higher frequencies |
bits 2-0 | ---- -SSS | Shift count (number of bits). If SSS is 0, then behaves like E=0. |
Side effects | Sets the reload flag |
The sweep unit continuously calculates each pulse channel's target period in this way:
For example, if the negate flag is false and the shift amount is zero, the change amount equals the current period, making the target period equal to twice the current period.
The two pulse channels have their adders' carry inputs wired differently, which produces different results when each channel's change amount is made negative:
Whenever the current period or sweep setting changes, whether by $400x writes or by sweep updating the period, the target period also changes.
Muting means that the pulse channel sends 0 to the mixer instead of the current volume. Muting happens regardless of whether the sweep unit is disabled (because either the Enabled flag or the Shift count are zero) and regardless of whether the sweep divider is outputting a clock signal.
Two conditions cause the sweep unit to mute the channel:
In particular, if the negate flag is false, the shift count is zero, and the current period is at least $400, the target period will be large enough to mute the channel. (This is why several publishers' NES games never seem to use the bottom octave of the pulse waves.)
Because the target period is computed continuously, a target period overflow from the sweep unit's adder can silence a channel even when the sweep unit is disabled and even when the sweep divider is not outputting a clock signal. Thus to fully disable the sweep unit, a program must additionally turn on the Negate flag, such as by writing $08. This ensures that the target period is not greater than the current period and therefore not greater than $7FF.
When the frame counter sends a half-frame clock (at 120 or 96 Hz), two things happen:
If the sweep unit is disabled including because the shift count is zero, the pulse channel's period is never updated, but muting logic still applies.
Categories: APU