Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Length Counters and Power Cycling

The length counters are the APU's third counter family — and the one with no reset path at all. That single fact, plus the polarity of their 256 Hz gate, generates the DMG power-cycle behaviour and the NRx4-write extra-clock quirk.

At a glance

  • The counter cells (tffnl) have no reset pin — power-off preserves the value and merely stops the clocking.
  • The counter advances on bufy_256hz's falling edge (frame-sequencer even steps).
  • Enabling length via NRx4 is itself a clock opportunity: extra clock ⟺ CARU.q = 0 ∧ not stopped — a plain level test at the enable edge.

The counter cells

CH2's counter (CH1/CH3/CH4 mirror cell-for-cell; CH3's is 8-bit) is a 6-bit ripple up-counter loaded from NR21[5:0] on an NRx1 write and counting on the gated 256 Hz tick:

BitCellLoad valueLoad enableCount clockNotes
0ERYCNR21[0]bymoDYRO (= NOT(DEME), the gated 256 Hz tick)First stage
1CERANR21[1]bymoERYC ripple
2CONUNR21[2]bymoCERA ripple
3CAMENR21[3]bymoCONU ripple
4BUVANR21[4]agetCAME ripple (via BUKO)Upper bits load via aget — a fan-out split of the same NRx1 strobe
5AKYDNR21[5]agetBUVA rippleq_n = the channel's length-stop flag

tffnl has no reset pin. Compare the duty counters (CH1/CH2), which are dffr cells reset by apu_reset: the two counter families sit on opposite sides of the reset tree, and that is the entire DMG-vs-power-cycle story below.

The length clock and its gate

The tick is bufy_256hz — the CARU tap of the frame-sequencer ripple (APU clocks) — gated per channel by a NOR3:

CH2: deme = NOR(cyre, bufy_256hz, NOT(NR24[6]))

(CH1/CH3/CH4: CAPY/DODA/GEPY with their NRx4 bits.) The counter's clock pulses only with length-enable set and bufy_256hz low.

Measured: polarity

bufy_256hz equals CARU.q exactly — verified at 1,266/1,266 sampled points (dmg-sim measurement) — and the counter advances on bufy_256hz's falling edge (CARU 1→0, i.e. the frame-sequencer ripple reaching an even step: the conventional "length clocks on even steps"). To keep the two edge roles straight: the rising edge is the re-lock step marker in the power-cycle closed form; the falling edge is the counting edge.

The NRx4-write extra length clock

Because the gate is a plain NOR, enabling length is itself a clock opportunity. An NRx4 write taking bit 6 from 0→1 drives the gate's enable input low. The gate output then rises iff bufy_256hz is LOW at that instant (and the channel isn't already length-stopped). That rise is one extra count, identical to a 256 Hz tick.

Rule: the extra clock is a level test

extra clock ⟺ CARU.q = 0 (frame-sequencer step even) ∧ not stopped — evaluated at the enable edge, nothing more.

After an in-game power-cycle the ripple holds its reset value until the first 512 Hz edge. An enabling write landing in that window therefore fires (or not) according to the power-on sub-step. That sub-step is the a bit of the re-lock closed form. Measured on the hardware-pinned gambatte div_write_reset_length_counter_timing ROM (dmg-sim measurement): power-on at sub-step 14 leaves CARU high, the enabling NR24 write produces no extra clock, the counter holds its value across the write, and the ROM's NR52 expectation follows. The same level test predicts that the opposite sub-step case fires.

Across an NR52 power cycle (DMG)

Power-off does two things to a length counter, neither of which is a reset:

  1. No clear — the cells have no reset path; the value holds.
  2. No clocking — power-off clears the register bank, so length-enable drops and the gate pins the clock; the counter cannot advance.

Preserved and frozen — exactly the behaviour blargg's 08-len ctr during power pins for DMG ("unaffected, and not clocked"). The phase of the length clock after power-on re-locks per the frame-sequencer rule in APU clocks; the value is governed entirely by the two points above.