APU Noise
The NES APU triangle channel generates a pseudo-triangle wave. It has no volume control; the waveform is either cycling or suspended. It includes a linear counter, an extra duration timer of higher accuracy than the length counter.
The triangle channel contains the following: timer, linear counter, length counter, halt flag, sequencer. The linear counter contains an internal halt flag and counter.
Linear Counter Length Counter | | v v Timer ---> Gate ----------> Gate ---> Sequencer ---> (to mixer)
$4008 | CRRR.RRRR | Linear counter setup (write) |
bit 7 | C---.---- | Control flag (this bit is also the length counter halt flag) |
bits 6-0 | -RRR RRRR | Counter reload value |
$400A | LLLL.LLLL | Timer low (write) |
bits 7-0 | LLLL LLLL | Timer low 8 bits |
$400B | llll.lHHH | Length counter load and timer high (write) |
bits 2-0 | ---- -HHH | Timer high 3 bits |
Side effects | Sets the halt flag |
The timer's period is the 11-bit value (%HHH.LLLLLLLL) formed by timer high and timer low, plus one.
When the frame counter generates a linear counter clock, the following actions occur in order:
- If the halt flag is set, the linear counter is reloaded with the counter reload value, otherwise if the linear counter is non-zero, it is decremented.
- If the control flag is clear, the halt flag is cleared.
The sequencer is clocked by the timer except when
- The linear counter is zero, or
- The length counter is zero
The sequencer sends the following looping 32-step sequence of values to the mixer:
15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
At the lowest two timer periods ($400B = 0 and $400A = 0 or 1), the resulting frequency is so high that the mixer effectively receives a value half way between 7 and 8.