Skip to content

SWI 0x28 — SoundDriverVSyncOff

  • Entry: 0x00001878 (THUMB; SWI table stores 0x00001879)
  • Status: verified (hardware-checked 2026-07-08: cycle counts and return registers measured on real GBA; struct layouts remain from static analysis)

Summary

Stops the sound-FIFO DMA and quiets the PCM output. Intended to be called when the game must temporarily stop calling SoundDriverVSync each V-blank (e.g. during a long DMA-heavy operation, cartridge access, or before entering a state where the regular V-blank timing is lost). Pair with SoundDriverVSyncOn to resume. Guarded by the SoundArea identity word, with a nested-call tolerance (see below).

Parameters / Returns

No explicit arguments; operates on the global SoundArea at [0x03007FF0]. No return value.

Clobbered registers

r0–r3, r7.

Hardware audit (2026-07-08, canary r4–r12 + CPSR snapshot): caller-visible clobbers: r0 = 0x68736D53, r1 = pointer past the PCM buffers, r3 = 0x170 leftover. r2, r4–r12, r13, and CPSR (flags and mode) came back bit-identical on every tested path. r11/r12 are explained by the SWI dispatcher (it pushes {r11, r12, lr} — see 10_irq_boot_and_iwram.md) and CPSR by the SPSR restore on return; r2 and r4–r10 must be preserved or restored by the routine itself — where a static note above claims r2 is destroyed, the hardware disagrees at the caller level. Raw data: results/clobber_audit_pass2.csv.

Algorithm

  1. Load SoundArea via [0x03007FF0]. Uses the identity word as a lock/state value; it tolerates the area being in the "just after init" range so the call is safe during startup, otherwise returns.
  2. Stop the FIFO DMA: write 0 to DMA1CNT_H (0x040000C6) and DMA2CNT_H (0x040000D2).
  3. Clear pcmDmaCounter (SoundArea+0x04) to 0 so the next SoundDriverVSyncOn/VSync restarts cleanly.
  4. Zero-fill the PCM mix buffer region (from SoundArea+0x350, ~792 words via CpuSet memfill) so no stale samples are streamed when DMA restarts.
  5. Return (restoring the identity/lock value).

Edge cases & known bugs

  • Because the mixer output buffer is wiped, a click-free restart relies on SoundDriverVSyncOn re-enabling DMA in sync with the mixer.
  • Safe to call before the area is fully initialized (special-cased state range).

Cycle count

Hardware-measured net CPU cycles (worker-ROM harness, TM0/TM1 cascade at F/1, 13-cycle baseline subtracted; identical across 3 runs — see 02_hardware_verification_checklist.md § Measurement setup).

9684 cycles — dominated by clearing the PCM buffers.

Open questions (need hardware verification)

  • Exact identity/lock range special-casing that makes early calls safe.
  • Whether both FIFOs must be reset (SOUNDCNT_H FIFO-reset bits) in addition to stopping DMA.

GBATEK cross-reference

Details GBATEK's SoundDriverVSyncOff: DMA1/DMA2 stop, counter reset, and mix-buffer clear.