Skip to content

One-Shot Samples

Queue a silent reload after a sample starts, so it finishes once. Understand DMA ownership, interrupt latency and safe reuse.

Code status: illustrative interrupt adapter. The maintained sample player executes the reload-to-silence protocol in a polling caller. This interrupt adapter has no separate execution record.

Queue silence after the sound starts

Paula can keep repeating a sample without further CPU work. A one-shot needs a different next block: silence. Once the initial location and length have been latched, write a one-word zero block as the next location and length. The current sound finishes and the next reload becomes silence.

Do not use “turn DMA off on the second interrupt” as an exact end-of-sample guarantee. Interrupt delivery and DMA pipelining make that a poor boundary for a reusable one-shot.

Interrupt ownership comes first

This adapter requires an exclusive, already installed level-4 handler for AUD0, with other level-4 audio sources disabled or dispatched elsewhere. The caller enables the master interrupt bit, sets the CPU interrupt mask appropriately, and owns channel 0, its DMA, interrupt and modulation settings. Before starting, disable channel DMA and let it settle using the maintained player’s stop/start protocol. An immediate off/on pair is insufficient. Point at an even, non-empty signed-byte sample in Chip RAM, set length in words, period and volume, clear stale AUD0 requests, then enable AUD0 interrupts and DMA.

68000 assembly
; First AUD0 request after starting DMA: queue silence for the next reload.
; Exclusive AUD0 level-4 handler; absolute symbols, no general IRQ dispatcher.
; No data/address registers change. CCR changes are restored by RTE.
audio_irq:
    move.l #silence,$dff0a0
    move.w #1,$dff0a4
    move.w #$0080,$dff09a       ; disable this interrupt, retain other enable bits
    move.w #$0080,$dff09c       ; acknowledge AUD0
    rte
    section data,data_c
    even
silence: dc.w 0

The handler must run and publish both reload values before the current block needs its next reload. A very short sound, long interrupt mask or busy higher-priority handler can miss that deadline. Use the complete polling sample as the initial working integration, then measure the interrupt version with your actual sample lengths and interrupt workload.

DMA remains enabled while looping silence. Stop and settle it before reusing the channel; do not free or overwrite either sample allocation while DMA can still read it. This is a useful building block for effects, but a tracker also needs instrument state, timing, pattern interpretation and ownership across voices. The four-channel sequencer deliberately teaches a smaller step.