APU Frame Counter
The NES APU frame counter (or frame sequencer) generates low-frequency clocks for the channels and an optional 60 Hz interrupt. Despite the name being “frame counter”, the clocks have nothing to do with the Vsync signal from the PPU.
The sequencer is clocked on every other CPU cycle, so 2 CPU cycles = 1 APU cycle. The sequencer keeps track of how many APU cycles have elapsed in total, and each step of the sequence will occur once that total has reached the indicated amount (with an additional delay of one CPU cycle for the quarter and half frame signals). Once the last step has executed, the count resets to 0 on the next APU cycle.
7 bit 0
---- ----
MI.. ....
||
|+-------- Interrupt inhibit flag
+--------- External synchronization mode
0: Freerun
1: Expect external synchronization
Writing to this register resets the counter to 0. If the write occurs during an APU cycle, the effects occur 3 CPU cycles after the write cycle, and if the write occurs between APU cycles, the effects occurs 4 CPU cycles after the write cycle.
When the write occurs with the bit 7 (M bit) set, both Quarter frame and Half frame clocks are also generated.
The external synchronization mode (M bit) exists to provide a way for synchronization with the external timing source; in NES’ case, it’s the Vblank NMI. When the mode is disabled, the frame counter counts it own ≈60Hz (or ≈50Hz in 2A07) cycle that is not synchronized with the Vsync signal from PPU. When it’s enabled, it expects the CPU to manually synchronize the internal counter with the external timing source that the CPU uses. (See below)
| Step | APU cycles | Envelopes & triangle's linear counter (Quarter frame) | Length counters & sweep units (Half frame) | Interrupt flag | |
|---|---|---|---|---|---|
| NTSC | PAL | ||||
| 1 | 3728, PUT | 4156, PUT | Clock | ||
| 2 | 7456, PUT | 8313, PUT | Clock | Clock | |
| 3 | 11185, PUT | 12469, PUT | Clock | ||
| 4 | 14914, GET | 16626, GET | Set if interrupt inhibit flag (I bit) is clear | ||
| 14914, PUT | 16626, PUT | Clock | Clock | Set if interrupt inhibit flag (I bit) is clear | |
| 0 (14915), GET | 0 (16627), GET | Set if interrupt inhibit flag (I bit) is clear | |||
| NTSC: 240 Hz (approx.) PAL: 200 Hz (approx) | NTSC: 120 Hz (approx.) PAL: 100 Hz (approx) | NTSC: 60 Hz (approx.) PAL: 50 Hz (approx) | |||
- In this mode, the interrupt flag is set every 29830 CPU cycles, which is slightly (0.166%) slower than the 29780.5 CPU cycles per NTSC PPU frame.
- On the PAL RP2A07, this is every 33254 CPU cycles, still slower than the 33247.5 CPU cycles per PAL PPU frame but much closer (only off by 0.0196%).
- The interrupt is intended to have the software sound player synchronized with those hardware envelopes.
- The interrupt flag is connected to the CPU’s IRQ line, and can be acknowledged (cleared) by writing to $4017 with interrupt inhibit flag set (
Ibit), or reading $4015 also clears the flag.
| Step | APU cycles | Envelopes & triangle's linear counter (Quarter frame) | Length counters & sweep units (Half frame) | Interrupt flag | |
|---|---|---|---|---|---|
| NTSC | PAL | ||||
| 1 | 3728, PUT | 4156, PUT | Clock | ||
| 2 | 7456, PUT | 8313, PUT | Clock | Clock | |
| 3 | 11185, PUT | 12469, PUT | Clock | ||
| 4 | 14914, PUT | 16626, PUT | |||
| 5 | 18640, PUT | 20782, PUT | Clock | Clock | |
| 0 (18641), GET | 0 (20783), GET | ||||
| NTSC: 192 Hz (approx.), uneven timing PAL: 160 Hz (approx.), uneven timing | NTSC: 96 Hz (approx.), uneven timing PAL: 80 Hz (approx.), uneven timing | NTSC: none PAL: none | |||
- In this mode, the interrupt flag is never set.
- This mode essentially gives the software about 7,454 CPU cycles (8,314 in 2A07) of gap to reset the sequencer manually before the counter wraps around to 0.
- The synchronization is done by writing to $4017 with the bit 7 (
Mbit) set at the (beginning of the) external timing source, which will reset the counter and also generate the both Quarter frame and Half frame clock.
- The synchronization is done by writing to $4017 with the bit 7 (
| V | | |
|---|---|
| Concepts | Registers | Basics | Period table |
| Channels | Pulse 1 and Pulse 2 | Triangle | Noise | DMC |
| Components | Envelope | Sweep | Frame Counter | Length Counter | DMA | Mixer |
| Expansion audio | 2C33 (Disk System) | MMC5 | VRC6 | VRC7 | Namco 163 | Sunsoft 5B | µPD7756 |