sd:appendix_5_sound_system
This is an old revision of the document!
Table of Contents
Appendix 5 Sound System
This is Appendix 5 of the SD-8516 Programmer's Reference Guide.
Introduction
The SD-8516 is paired with the SD-450 sound subsystem; named for featuring 4 independent voices with 5 waveforms available, each with a programmable ADSR envelope. Let's dive in with an overview of the architecture and a quick look at INT 11h, the sound services library.
Voice Architecture
Each voice occupies 16 bytes of memory in Bank 1:
| Offset | Register | Description |
|---|---|---|
| +$00 | FREQ_LO | Frequency low byte |
| +$01 | FREQ_MID | Frequency mid byte |
| +$02 | FREQ_HI | Frequency high byte |
| +$03 | GATE | Waveform/gate control |
| +$04 | VOLUME | Volume (0-255) |
| +$05 | ATTACK | Attack time |
| +$06 | DECAY | Decay time |
| +$07 | SUSTAIN | Sustain level |
| +$08 | RELEASE | Release time |
| +$09 | DATA1 | Pulse width / noise type |
| +$09-$0F | DATA2-7 | Reserved - Future expansion |
Voice base addresses:
- Voice 0:
$1EF80 - Voice 1:
$1EF90 - Voice 2:
$1EFA0 - Voice 3:
$1EFB0
Waveforms
Gate register values:
- 0: Silent (gate off)
- 1: Square wave
- 2: Triangle wave
- 3: Sawtooth wave
- 4: Sine wave
- 5: Pulse wave (variable width via DATA1)
- 6: White/pink/brown noise (type via DATA1)
ADSR Envelope
The Attack-Decay-Sustain-Release envelope shapes each note:
- Attack: Time to reach peak volume (0-255 × 10ms)
- Decay: Time to decay to sustain level (0-255 × 10ms)
- Sustain: Held volume level (0.0-1.0 of peak)
- Release: Time to fade to silence after gate off (0-255 × 10ms)
Example:
; Play middle C on voice 0
LDA $112B ; C4 frequency (262 Hz / 0.0596)
STA [$1ED00] ; $01ED00 = FREQ_LO/MID
LDA #0
STA [$1ED02] ; $01ED02 = FREQ_HI
LDAL $4D ; Initialize volume to ~30%
STAL [$1ED03] ; $1ED03 = VOLUME
LDAL $01 ; Square wave
STAL [$1ED02] ; set GATE to square wave (i.e. turn on)
You can also use the sound services library (I
Sound System Memory Map
Also see Appendix 3 Memory Map.
Sound System Memory Map
The sound system memory map occupies ($01EF80–$01EFBF) – 64 bytes total
| Address Range | Size | Symbol / Register | Description |
|---|---|---|---|
| $01EF80–$01EF8F | 16 bytes | SOUND0_BASE | Voice 0 |
| $01EF80 | 1 byte | SOUND0_FREQ_LO | Frequency low byte (bits 7–0) |
| $01EF81 | 1 byte | SOUND0_FREQ_HI | Frequency high byte (bits 15–8) |
| $01EF82 | 1 byte | SOUND0_GATE | Gate / Waveform select (gate bit + waveform type: noise, pulse, saw, triangle, etc.) |
| $01EF83 | 1 byte | SOUND0_VOLUME | Master volume for voice 0 (usually 0–15, may include global volume in some implementations) |
| $01EF84 | 1 byte | SOUND0_ATTACK | Attack rate (0–15) |
| $01EF85 | 1 byte | SOUND0_DECAY | Decay rate (0–15) |
| $01EF86 | 1 byte | SOUND0_SUSTAIN | Sustain level (0–15) |
| $01EF87 | 1 byte | SOUND0_RELEASE | Release rate (0–15) |
| $01EF88 | 1 byte | SOUND0_DATA1 | Voice-specific control / extra parameter 1 (e.g. pulse width low, filter routing, etc.) |
| $01EF89 | 1 byte | SOUND0_DATA2 | Voice-specific control / extra parameter 2 (e.g. pulse width high, ring/mod flags, etc.) |
| $01EF8A–$01EF8F | 6 bytes | — | Reserved / unused / future expansion for Voice 0 |
| Address Range | Size | Symbol / Register | Description |
|---|---|---|---|
| $01EF90–$01EF9F | 16 bytes | SOUND1_BASE | Voice 1 |
| $01EF90 | 1 byte | SOUND1_FREQ_LO | Frequency low byte |
| $01EF91 | 1 byte | SOUND1_FREQ_HI | Frequency high byte |
| $01EF92 | 1 byte | SOUND1_GATE | Gate / Waveform select |
| $01EF93 | 1 byte | SOUND1_VOLUME | Volume for voice 1 |
| $01EF94 | 1 byte | SOUND1_ATTACK | Attack rate |
| $01EF95 | 1 byte | SOUND1_DECAY | Decay rate |
| $01EF96 | 1 byte | SOUND1_SUSTAIN | Sustain level |
| $01EF97 | 1 byte | SOUND1_RELEASE | Release rate |
| $01EF98 | 1 byte | SOUND1_DATA1 | Extra control 1 |
| $01EF99 | 1 byte | SOUND1_DATA2 | Extra control 2 |
| $01EF9A–$01EF9F | 6 bytes | — | Reserved / unused / future expansion for Voice 1 |
| Address Range | Size | Symbol / Register | Description |
|---|---|---|---|
| $01EFA0–$01EFAF | 16 bytes | SOUND2_BASE | Voice 2 |
| $01EFA0 | 1 byte | SOUND2_FREQ_LO | Frequency low byte |
| $01EFA1 | 1 byte | SOUND2_FREQ_HI | Frequency high byte |
| $01EFA2 | 1 byte | SOUND2_GATE | Gate / Waveform select |
| $01EFA3 | 1 byte | SOUND2_VOLUME | Volume for voice 2 |
| $01EFA4 | 1 byte | SOUND2_ATTACK | Attack rate |
| $01EFA5 | 1 byte | SOUND2_DECAY | Decay rate |
| $01EFA6 | 1 byte | SOUND2_SUSTAIN | Sustain level |
| $01EFA7 | 1 byte | SOUND2_RELEASE | Release rate |
| $01EFA8 | 1 byte | SOUND2_DATA1 | Extra control 1 |
| $01EFA9 | 1 byte | SOUND2_DATA2 | Extra control 2 |
| $01EFAA–$01EFAF | 6 bytes | — | Reserved / unused / future expansion for Voice 2 |
| Address Range | Size | Symbol / Register | Description |
|---|---|---|---|
| $01EFB0–$01EFBF | 16 bytes | SOUND3_BASE | Voice 3 |
| $01EFB0 | 1 byte | SOUND3_FREQ_LO | Frequency low byte |
| $01EFB1 | 1 byte | SOUND3_FREQ_HI | Frequency high byte |
| $01EFB2 | 1 byte | SOUND3_GATE | Gate / Waveform select |
| $01EFB3 | 1 byte | SOUND3_VOLUME | Volume for voice 3 |
| $01EFB4 | 1 byte | SOUND3_ATTACK | Attack rate |
| $01EFB5 | 1 byte | SOUND3_DECAY | Decay rate |
| $01EFB6 | 1 byte | SOUND3_SUSTAIN | Sustain level |
| $01EFB7 | 1 byte | SOUND3_RELEASE | Release rate |
| $01EFB8 | 1 byte | SOUND3_DATA1 | Extra control 1 |
| $01EFB9 | 1 byte | SOUND3_DATA2 | Extra control 2 |
| $01EFBA–$01EFBF | 6 bytes | — | Reserved / unused / future expansion for Voice 3 |
INT 11h Sound Services
; ============================================================================
; INT 11h - SOUND & MUSIC SERVICES
; SD-450 Sound Interface Device + Music Player
; ============================================================================
;
; REGISTER CONVENTION:
; AH = command
; AL = voice (1-4 for music commands, 0-3 for hardware channel)
; B = data (BL=low, BH=high; or BL=single byte)
; C = additional data
; D, E, F = extended data (for AH=30h "new instrument")
;
; FUNCTION MAP:
; --- Music Player Control ---
; AH=00h: Poll music player (check tick timer, advance if ready)
; AH=01h: Execute next note group from song data
; AH=02h: Set clock for next note group
; AH=03h: Execute a single music command
; AH=04h: Reset music player (stop + rewind to start)
; AH=05h: Start / continue music player
; AH=06h: Pause / unpause (AL=00 pause, AL=01+ unpause)
; AH=07h: Load new song (pointer, tempo, calc tick length)
; AH=08h: Insert note data by index
; AH=09h: Delete note data by index
; AH=0Ah: Ask JavaScript to LOAD a music file
; AH=0Bh: Ask JavaScript to SAVE a music file
;
; --- Direct Sound Commands (also used by music file data) ---
; AH=10h: Turn off voice
; AH=11h: Turn on as square (+3 bytes freq: BL, BH, CL)
; AH=12h: Turn on as triangle (+3 bytes freq)
; AH=13h: Turn on as sawtooth (+3 bytes freq)
; AH=14h: Turn on as sine (+3 bytes freq)
; AH=15h: Turn on as PWM (+3 bytes freq)
; AH=16h: Turn on as noise (+3 bytes freq)
; AH=17h: Turn on as waveform byte + note index
; (BL=note index 1-88, BH=waveform 01-06)
; AH=21h: Set GATE (BL = gate byte)
; AH=22h: Set FREQ (BL=lo, BH=mid, CL=hi)
; AH=23h: Set ATTACK (BL = attack byte)
; AH=24h: Set SUSTAIN (BL = sustain byte)
; AH=25h: Set RELEASE (BL = release byte)
; AH=26h: Set DATA1 (BL = data1 byte)
; AH=27h: Set DATA2 (BL = data2 byte)
; AH=28h: Set VOLUME (BL = volume byte)
; AH=29h: Set DECAY (BL = decay byte)
; AH=30h: Set new voice data at-once (10 bytes: BCDEF)
;
; --- Legacy / Utility ---
; AH=40h: Initialize sound system
; AH=41h: Play note (blocking, with duration)
; AH=42h: Stop channel
; AH=43h: Stop all channels
; AH=44h: Set master volume
; AH=45h: Get channel status
; AH=46h: Sound effect (bell, beep, buzz, etc.)
; AH=47h: Play startup sound (GECF)
; AH=48h: Wait milliseconds (C = ms)
; AH=49h: Note index to frequency lookup (BH=index, returns B:CL)
;
; ============================================================================
sd/appendix_5_sound_system.1772759678.txt.gz · Last modified: by appledog
