Overview
Each of the SID’s three voices needs configuration before playing. Set the frequency (pitch), waveform (tone character), and ADSR envelope (volume shape over time). This pattern shows how to initialise a voice for typical game audio.
Code
; =============================================================================
; SID VOICE SETUP - COMMODORE 64
; Configure SID voice with frequency, waveform, and ADSR
; Taught: Game 1 (SID Symphony), Unit 3
; CPU: ~60 cycles per voice | Memory: ~40 bytes
; =============================================================================
; SID register base
SID = $D400
; Voice 1 registers
SID_V1_FREQ_LO = $D400
SID_V1_FREQ_HI = $D401
SID_V1_PWLO = $D402 ; Pulse width low
SID_V1_PWHI = $D403 ; Pulse width high
SID_V1_CTRL = $D404 ; Control (waveform + gate)
SID_V1_AD = $D405 ; Attack/Decay
SID_V1_SR = $D406 ; Sustain/Release
; Voice 2 registers (add 7 to voice 1 addresses)
SID_V2_FREQ_LO = $D407
SID_V2_CTRL = $D40B
SID_V2_AD = $D40C
SID_V2_SR = $D40D
; Voice 3 registers (add 14 to voice 1 addresses)
SID_V3_FREQ_LO = $D40E
SID_V3_CTRL = $D412
SID_V3_AD = $D413
SID_V3_SR = $D414
SID_VOLUME = $D418 ; Master volume
; Waveform values (for control register)
WAVE_TRIANGLE = $11 ; Soft, mellow tone
WAVE_SAWTOOTH = $21 ; Bright, buzzy tone
WAVE_PULSE = $41 ; Hollow, reedy tone (needs pulse width)
WAVE_NOISE = $81 ; White noise (drums, explosions)
; Initialize SID for audio
init_sid:
; Clear all SID registers
ldx #$18
lda #0
- sta SID,x
dex
bpl -
; Set master volume (0-15)
lda #$0F ; Maximum volume
sta SID_VOLUME
; === Configure Voice 1 ===
lda #$00
sta SID_V1_FREQ_LO
lda #$1C ; Frequency high byte (C5)
sta SID_V1_FREQ_HI
lda #$08 ; Pulse width (50% duty cycle)
sta SID_V1_PWHI
; ADSR: Attack=0 (instant), Decay=9 (medium)
; Sustain=0, Release=0 (instant)
lda #$09
sta SID_V1_AD
lda #$00
sta SID_V1_SR
rts
; Play voice 1 (call init_sid first)
play_voice1:
lda #WAVE_SAWTOOTH ; Waveform
ora #$01 ; Set gate bit (start note)
sta SID_V1_CTRL
rts
; Stop voice 1
stop_voice1:
lda #WAVE_SAWTOOTH ; Keep waveform
and #$FE ; Clear gate bit (release note)
sta SID_V1_CTRL
rts
Trade-offs
| Aspect | Cost |
|---|---|
| CPU | ~60 cycles per voice setup |
| Memory | ~40 bytes |
| Limitation | Must clear SID before init on some hardware |
When to use: Any game with SID audio. Always initialise before playing.
When to avoid: Never - uninitialised SID gives unpredictable results.
ADSR Envelope
The ADSR envelope shapes how volume changes over time:
Volume
│ ╱╲
│ ╱ ╲___________
│ ╱ ╲
│ ╱ ╲
└──┴─────────────────────▶ Time
A D S R
A = Attack - Time to reach peak volume
D = Decay - Time to fall to sustain level
S = Sustain - Volume level while held
R = Release - Time to silence after release
AD register format: $AD where A=attack (0-15), D=decay (0-15)
SR register format: $SR where S=sustain (0-15), R=release (0-15)
Common ADSR Values
| Sound Type | AD | SR | Description |
|---|---|---|---|
| Pluck | $09 | $00 | Instant attack, medium decay, no sustain |
| Organ | $00 | $F0 | Instant attack, full sustain |
| Pad | $88 | $84 | Slow attack/release, medium sustain |
| Drum | $09 | $00 | Quick hit, no sustain |
Frequency Reference
| Note | Freq Hi | Freq Lo |
|---|---|---|
| C3 | $07 | $00 |
| C4 | $0E | $00 |
| C5 | $1C | $00 |
| C6 | $38 | $00 |
Related
Patterns: SID Note Trigger
Vault: Commodore 64