C64 Programmer's Reference Guide, ch. 4 — Programming Sound and Music on Your Commodore 64 (1982)
The official 1982 introduction to the sid from the BASIC programmer's side: ten example programs that POKE the chip's registers, each with a line-by-line explanation, plus a short "technical explanation" of frequency, waveforms, harmonics, ADSR, the filter, the oscillator-3 readback and sync/ring modulation. Appendix O (the chip specification with the register map) and Appendix E (the note table) are referenced but not part of this chapter — see s-mos-6581-datasheet for what Appendix O reprints.
Key claims#
- The register model: the sound registers are memory locations 54272–54296 (
$D400+ 0–24); "remember only location 54272 and then add a number from 0 through 24"; values 0–255;PEEKreads back the two read-only registers. Register 24 = volume 0–15 in the low nybble, "the other four bits are used for purposes we'll get into later" (filter modes and voice-3-off). - Frequency: two bytes per voice;
Fn = Fout / .06097, thenFhi = INT(Fn/256),Flo = Fn − 256·Fhi; the note table in Appendix E covers eight octaves. (The datasheet givesFout = Fn × Fclk / 16777216, i.e. the constant depends on the system clock — 0.0596 at 1.0 MHz; the PRG's 0.06097 corresponds to a clock of about 1.023 MHz, the NTSC C64 — a derived observation, not stated in either text.) - Gating: a note is started by writing the waveform byte with bit 0 set and stopped by writing it with bit 0 clear — sawtooth
33/32, triangle17/16, pulse65/64, noise129/128($21/$20…$81/$80). - Multi-voice sequencing (Example 2): a measure is divided into sixteenths, each voice has an "activity array" of high byte, low byte and control byte per sixteenth; a note is packed into one number
((D×8)+O)×16+N(D = duration in sixteenths, O = octave 0–7, N = note 0–11), a rest is the negative duration; lower octaves are derived from the top-octave frequencies by halving. - Pulse width: register 2 = low byte, register 3 = high 4 bits;
PWn = Hpw×256 + Lpw;PWout = (PWn/40.95) %; 2048 (Hpw = 8) = square wave; changingHpwfrom 8 to 1 makes a "dramatic" timbre change. - Harmonics: triangle = odd harmonics at 1/n²; sawtooth = all harmonics at 1/n; square = odd harmonics at 1/n; other pulse widths vary the content "tremendously".
- ADSR: register 5 = attack (high nybble) × 16 + decay (low nybble); register 6 = sustain level (high nybble) × 16 + release rate (low nybble); the rate table (attack 2 ms … 8 s; decay/release 6 ms … 24 s) is printed on page 198 — identical to the datasheet's Table 2.
- Filter: cutoff in registers 21 (low 3 bits, 0–7) and 22 (8 bits, 0–255); register 23 routes voices into the filter (
POKE S+23,1= voice 1); register 24 bit 6 = high-pass, bit 5 = band-pass, bit 4 = low-pass, so79= high-pass + volume 15; high- and low-pass together form a "notch reject" filter; "changing the filtering of a sound as it goes through the ADSR phases of its life can produce interesting effects". - Advanced techniques: register 27 reads oscillator 3's output (sawtooth = 0…255 ramp, triangle = up and down, pulse = jumps, noise = random numbers) unaffected by its envelope; register 28 reads envelope 3 (the oscillator must be gated); bit 7 of register 24 mutes voice 3's audio so it can modulate silently. Example 6 makes vibrato by adding
PEEK(S+27)/2(voice 3 on a low-frequency triangle) to voice 1's frequency inside the note loop; Example 7 a siren (×3.5); Example 8 a hand clap from noise through the high-pass filter, gated fifteen times. - Sync and ring modulation: sync is described as "basically a logical ANDing of two wave forms" (the datasheet says the fundamental of one oscillator is synchronised to the other's); Example 9 ("mosquito") writes
19= bits 0, 1 and 4 (gate, sync, triangle) with voice 1 high byte 100 and voice 3 high byte 28; "bit 1 enables the syncing function between voice 1 and voice 3". Example 10 (a clock chime) writes21= bits 0, 2 and 4 (gate, ring mod, triangle) with voice 1 high byte 130, voice 3 high byte 30 and attack 0 / decay 9 — ring modulation "replaces the triangular output of oscillator 1 with a 'ring modulated' combination of oscillators 1 and 3" for "bell or gong sounds". The prose calls it "bit 3 of register 4", but the value 21 sets bit 2 — the datasheet confirms ring mod = bit 2 and test = bit 3, so the PRG's "bit 3" is a slip. - Closes by announcing the book Making Music on Your Commodore Computer.
Practical takeaways#
- Official ADSR presets, as
A D S Rnybbles: violin5 8 5 9(POKE S+5,88 : POKE S+6,89); xylophone (triangle)0 9 0 9; piano (square, width 2048)0 9 0 0; "unique to the synthesizer"9 0 15 3(144,243). - The hand-clap recipe: noise waveform, attack 0 / decay 8, high-pass with cutoff high byte 104, voice routed through the filter, 15 short gates.
- Hardware vibrato/siren: run voice 3 silently (3OFF) on a triangle and add its readback to another voice's frequency every loop — the same idea trackers implement as a calculated vibrato.
- The packed-note trick
((D×8)+O)×16+Nand per-sixteenth activity arrays are a 1982 "pattern" data model — a BASIC sid-player-routine in miniature.
Notable quotes#
"The most exciting sounds are those unique to the music synthesizer itself, ones that do not attempt to mimic acoustic instruments."
"When oscillator 3 is used for modulation, you usually do NOT want to hear its output."
Relevance#
The composer's-side official description of every SID feature the wiki's C64 techniques use, with register numbers and decimal POKE values that translate directly to the hex the trackers show; a second, official source for the ADSR timing table and the filter/waveform bit layout.
Pages touched#
sid · adsr-envelope · ring-modulation-and-sync · filter-programming · pulse-width-modulation · vibrato · sid-player-routine · commodore-64 · instrument-design · c64-programmers-reference-guide