amiga-bootcamp/01_hardware/ocs_a500/paula_audio.md
Ilia Sharin 21751c0025 docs(amiga): complete AmigaOS 3.1/3.2 developer reference — 172 files across 17 sections
Comprehensive technical documentation covering:
- Hardware: OCS/ECS/AGA custom chip registers, Copper & Blitter deep dives
- Boot sequence: cold boot through startup-sequence
- Binary format: HUNK executable spec, relocation, debug info
- Linking & ABI: .fd files, LVO tables, register calling conventions
- Exec kernel: tasks, interrupts, memory, signals, semaphores
- AmigaDOS: file I/O, FFS/OFS layout, CLI/Shell scripting
- Graphics: planar bitmaps, Copper programming, HAM/EHB modes
- Intuition: screens, windows, IDCMP, BOOPSI
- Devices: trackdisk, SCSI, serial, timer, audio, keyboard
- Libraries: utility, expansion, IFFParse, locale, ARexx
- Networking: bsdsocket API, SANA-II, TCP/IP stack comparison
- Toolchain: GCC, vasm/vlink, SAS/C, NDK, debugging
- Reverse engineering: IDA/Ghidra setup, compiler fingerprints, case studies
- CPU & MMU: 68040/060 emulation libs, PMMU, cache management
- Driver development: SANA-II, Picasso96/RTG, AHI audio

All files include breadcrumb navigation. No local paths or proprietary content.
2026-04-23 12:17:35 -04:00

4.4 KiB
Raw Permalink Blame History

← Home · Hardware · OCS

Paula — Audio DMA

Overview

Paula (MOS 8364) provides four independent audio DMA channels (03), corresponding to the four hardware voice outputs:

Channel Stereo Output
0 Left
1 Right
2 Right
3 Left

Each channel has its own DMA pointer, length, period (pitch), and volume registers. Paula fetches sample data from Chip RAM automatically at the rate set by the period register.

Audio Registers Per Channel

Channel n (n = 03) registers at $DFF0A0 + n×$10:

Offset Name Description
+$00/$01 AUDnLCH/AUDnLCL Sample pointer high/low (Chip RAM address)
+$04 AUDnLEN Sample length in words (not bytes)
+$06 AUDnPER Period — clock divider for playback rate
+$08 AUDnVOL Volume: 064 (0 = silent, 64 = full)
+$0A AUDnDAT Current sample word (direct, for non-DMA mode)

Sample Playback Rate

Paula derives playback rate from the system clock divided by the period register:

Sample rate (Hz) = System clock / Period
System Clock Period for 8363 Hz Period for 22050 Hz
PAL 3,546,895 Hz 428 ~161
NTSC 3,579,545 Hz 428 ~162

8363 Hz is the standard MOD tracker reference — period 428 on PAL plays middle-A at exactly 8363 Hz.

Period range: 12465535 (minimum period = maximum frequency ≈ 28 kHz PAL).

Starting Audio DMA

; Load channel 0 with sample at SampleData, length 256 words
move.l  #SampleData, d0
move.w  d0, AUD0LCL+custom
swap    d0
move.w  d0, AUD0LCH+custom
move.w  #256, AUD0LEN+custom    ; 256 words = 512 bytes
move.w  #428, AUD0PER+custom    ; period 428 = 8287 Hz PAL
move.w  #64,  AUD0VOL+custom    ; full volume

; Enable audio DMA for channel 0
move.w  #$8201, DMACON+custom   ; SET + MASTER + AUD0EN

; Enable audio interrupt (optional)
move.w  #$A080, INTENA+custom   ; SET + INTEN + AUD0

ADKCON — Audio/Disk Control

Bit Name Description
15 SET/CLR Write: 1=set, 0=clear bits
11 PRECOMP1 Disk precompensation
10 PRECOMP0 Disk precompensation
9 MFMPREC MFM precompensation
7 MSBSYNC Audio sync from MSB
6 WORDSYNC Disk word sync enable
4 ATPER Channel 3 period from channel 2 data
3 ATVOL Channel 3 volume from channel 2 data
2 ATPER2 Channel 1 period from channel 0 data
1 ATVOL2 Channel 1 volume from channel 0 data
0 (unused)

ATPER/ATVOL bits enable audio modulation — channel N's period/volume is modulated by the sample data of channel N-1. Used for AM synthesis effects (e.g., in many MOD players for 8-channel soft mixing).

Interrupt Handling

Audio channels raise interrupts when their DMA pointer wraps to the beginning of the next buffer:

INTENA/INTREQ bits:
AUD0 = bit 7  (IPL 4)
AUD1 = bit 8  (IPL 4)
AUD2 = bit 9  (IPL 4)
AUD3 = bit 10 (IPL 4)

The interrupt fires when the channel has consumed its buffer and reloaded the pointer from the DMA registers. At this point, software can update AUDnLCH/L and AUDnLEN with the next buffer.

Double-Buffering Pattern

/* In interrupt handler (IPL 4 server for AUD0): */
void audio_interrupt(void)
{
    /* Swap buffers */
    UWORD *next = (active_buf == buf_a) ? buf_b : buf_a;
    active_buf = next;

    /* Load next buffer address */
    custom.aud[0].ac_ptr = (UWORD *)next;
    custom.aud[0].ac_len = BUF_WORDS;
}

Direct (Non-DMA) Audio

For simple sound effects without DMA overhead, write directly to AUDnDAT:

move.w  #$0080, AUD0VOL+custom   ; volume 64 (approx)
move.w  #$7FFF, AUD0DAT+custom   ; max positive sample

This only produces a single sample word — not practical for continuous audio but useful for one-shot clicks/beeps.

audio.device

AmigaOS provides audio.device for arbitrated, multi-application audio access:

  • Allocates channels (bitmask: {1,2,4,8})
  • Creates IOAudio request, uses standard device I/O (BeginIO/WaitIO)
  • Handles period, volume, sample pointer, cycle count
  • See 10_devices/audio_device.md for full API reference

References