Skip to content

SID Voice Setup

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

Code status: illustrative code. Adapt the listing to your program and check it on your target machine. This page links no assembly or execution record for the listing itself.

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

Assembly
; =============================================================================
; SID VOICE SETUP - COMMODORE 64
; Configure SID voice with frequency, waveform, and ADSR
; Taught: Game 6 (SID Symphony), Unit 3
; =============================================================================

; 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 ===
    ; C5 on PAL: 523.25 Hz × 16777216 / 985248 = 8910 = $22CE
    lda #$CE
    sta SID_V1_FREQ_LO
    lda #$22                    ; Frequency high byte (C5 PAL)
    sta SID_V1_FREQ_HI

    lda #$08                    ; Pulse width (50% duty cycle)
    sta SID_V1_PWHI

    ; ADSR: Attack=0 (2 ms), Decay=9 (750 ms from peak)
    ;       Sustain=0, Release=0 (6 ms from peak)
    lda #$09
    sta SID_V1_AD
    lda #$00
    sta SID_V1_SR

    rts

; Play voice 1 (call init_sid first)
; The waveform constants above already include the gate bit, so writing one
; of them directly starts the note.
play_voice1:
    lda #WAVE_SAWTOOTH          ; Waveform + gate (gate bit already set)
    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 Note
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:

Code
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)

Rate 0 is the fastest setting, but it is not instant. The 6581 data sheet’s Table 2 gives 2 ms for attack and 6 ms for decay and release at rate 0, rising to 8 s and 24 s at rate 15. Attack times run from zero to peak; decay and release times run from peak to zero. The table assumes a 1 MHz clock, so on a PAL C64 (about 0.985 MHz) each time is about 1.5% longer.

Common ADSR Values

Sound Type AD SR Description
Pluck $09 $00 2 ms attack, 750 ms decay, no sustain
Organ $00 $F0 2 ms attack, full sustain
Pad $88 $84 Slow attack/release, medium sustain
Drum $09 $00 Quick hit, no sustain

Frequency Reference (PAL)

The 16-bit SID frequency value is FREQ = Hz × 16777216 / clock, with PAL clock = 985,248 Hz and NTSC clock = 1,022,727 Hz. Values double per octave:

Note Hz PAL ($Hi $Lo) NTSC ($Hi $Lo)
C3 130.81 $08 $B3 $08 $50
C4 (middle C) 261.63 $11 $67 $10 $A1
C5 523.25 $22 $CE $20 $5C
C6 1046.5 $45 $9C $42 $1B

For a complete chromatic scale, see the frequency tables in the SID vault entry.

Multi-voice setup

The SID has three independent voices. Setup is identical for each — the same code with different base addresses. The simplest way to handle all three is to parameterise on the voice’s base register:

Assembly
; Configure all three voices with the same envelope and waveform
init_all_voices:
    ldx #0                      ; Voice 0
    jsr setup_voice
    ldx #7                      ; Voice 1 base offset
    jsr setup_voice
    ldx #14                     ; Voice 2 base offset
    jsr setup_voice
    rts

; X = voice base offset (0, 7, or 14)
setup_voice:
    lda #$09
    sta SID_V1_AD,x             ; AD register at base+5 (V1=$D405, V2=$D40C, V3=$D413)
    lda #$00
    sta SID_V1_SR,x             ; SR register at base+6
    rts

Voice 1 ($D400-$D406), Voice 2 ($D407-$D40D), and Voice 3 ($D40E-$D414) are evenly spaced at 7-byte intervals.

Patterns: SID Note Trigger, SID Multi-Voice

Vault: The SID Chip | Commodore 64

Sources

MOS Technology, 6581 Sound Interface Device (SID) data sheet: Table 2’s envelope rates and the note scaling them to other clock speeds.