Skip to content

SID Voice Setup

Configure a SID voice with frequency, waveform, and ADSR envelope. Foundation for all SID audio programming.

Taught in Game 1, Unit 3 sidaudioadsrwaveform

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

AspectCost
CPU~60 cycles per voice setup
Memory~40 bytes
LimitationMust 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 TypeADSRDescription
Pluck$09$00Instant attack, medium decay, no sustain
Organ$00$F0Instant attack, full sustain
Pad$88$84Slow attack/release, medium sustain
Drum$09$00Quick hit, no sustain

Frequency Reference

NoteFreq HiFreq Lo
C3$07$00
C4$0E$00
C5$1C$00
C6$38$00

Patterns: SID Note Trigger

Vault: Commodore 64