SID-Wizard cheat sheet

From SID-Wizard · print · built 2026-08-31

Reference

Cheat sheet#

Most-used keys#

keyaction
F1 / F2 / F3 / F4play from start / from play-mark / selected patterns / stop-continue (C=+F1..F4 = same with follow-play)
fast-forward 6×
Shift+F / Shift+Gframespeed up / down
< > (Shift+,/.)subtune tempo up/down; [ ] second FunkTempo; C=+T toggle FunkTempo
C=+, / C=+.select subtune
RETURN / Shift+RETURNnote-on / note-off; go to instrument/chord
Shift+1..9/0mute/solo tracks
C=+1..8, C= +/-octave
C=+Z/X/C/Vundo / cut / copy / paste; Shift+C marks end of block
Shift+Q/W, C=+Q/Wtranspose from cursor by semitone / octave
Shift+V, Shift+P, Shift/C=+R, Shift/C=+Svibrato, portamento, ring-mod on/off, sync on/off in the note column
Shift+A/Z, Shift+H/Jauto-advance step, highlight step
C=+E (orderlist)find first empty pattern
Shift+N (instrument)name instrument; C=+P / C=+F toggle PW / filter reset; = negate table value
C=+N (chord table)toggle note-mode / number-mode

Instrument-column effects#

valueeffect
$01–$3Eselect instrument
$3Flegato / tied note (pitch only, no retrigger)
$40–$4Fset waveform (small fx)
$50–$5Fset sustain level (note volume)
$60–$6Fset release time
$70–$7Fset chord (overrides the instrument's default chord)

Effect-column "small" effects ($xy, y = value)#

rangeeffect
$2x / $3xattack / decay time of the note
$4x$7xsame as the instrument-column effects above
$8x / $9xvibrato amplitude / rate
$Axmain volume ($D418 low nybble)
$Bxfilter band nybble
$Cxchord (arpeggio) speed
$Dxdetune current note
$Excontrol nybble (test / ring / sync)
$Fxfilter resonance

Effect-column "big" effects ($xx + value byte)#

fxeffectfxeffect
$01pitch slide up$0Eset pulse width
$02pitch slide down$0Fset filter cutoff hi-byte
$03tone portamento (auto-portamento)$10set main single tempo
$04waveform/control register$11set main FunkTempo
$05attack/decay register$12launch main tempo program
$06sustain/release register$13set track's single tempo
$07select chord (overrides default)$14set track's FunkTempo
$08vibrato amplitude & rate$15launch tempo program for track
$09go to WF-ARP table position$16vibrato type (00/10/20/30)
$0Ago to pulse-width table position$1Cshift cutoff hi-byte (permanent)
$0Bgo to filter table position$1Ddelay track by $00–$FF frames
$0Cset chord / arpeggio speed$1Edelay note (max = tempo − 3 frames)
$0Ddetune current note upwards$1Fset filter-switch/resonance register ($D417)

Orderlist values#

$01–$7F pattern · $80–$8F transpose down ($8F = −1) · $90–$9F transpose up ($90 = original) · $A0–$AF main volume · $B0–$EF single track tempo · $F0–$FD separator NOP with section id (shown as ---D) · $FE end of tune · $FF xx jump to position xx (above $80: jump to subtune). The orderlist must not begin with $FE/$FF.

Chord table#

$00–$7D relative pitch up (semitones) · $80–$FF relative pitch down · $7E return from chord to the arp table · $7F loop the chord infinitely. Note-mode lets you set a root note outside the table and type the chord's notes as notes.

Tempo table#

$00–$7F = tempo (frames) for one pattern row; tempo programs can vary the tempo per row.

Table value schemes#

See instrument-tables for the WF-ARP-Detune, pulse-width and filter tables ($8x..$Fx = set, $00..$7F = add n times, $FE = jump).

Techniques

Chord arpeggio (the 0 3 7 trick) › SID-Wizard #

  • Chord table (C=+F5 or C=+K): entries $00–$7D = semitones up, $80–$FF = semitones down, $7F = loop the chord forever, $7E = return from the chord to the instrument's arp table. C=+N toggles note-mode, where you set the root note outside the table and type the chord's notes as notes (select editing mode with Space). Shift+K/L selects a chord from anywhere, +/- inside the table.
  • Assign it: each instrument has a default chord number; override per note with $70–$7F in the instrument column or $07 xx in the effect column.
  • Speed: $0C xx (big effect) or $Cx (small effect) sets the chord/arpeggio speed.
  • Arps in the instrument instead: the Arp column of the WF-ARP-Detune table ($01–$5F up, $E0–$FF down, $81–$DF absolute pitch, $7F jump to the chord) — see instrument-tables. Note: an arp entry cancels a running slide or vibrato.
  • The chord table is not available in the Light, Bare and Demo player types (sid-player-routine).

(source: s-sid-wizard-manual)

The SID-Wizard book's arpeggio instrument: WF-ARP 11 7F (triangle, jump to the default chord), chord table 00 03 07 0C 07 03 ending in 7F (loop) — "it runs quite fast", so set chord speed 02 in the instrument or in the WF column left of the 7F; attack 8, release B. Chords "are essentially arpeggios in SID-Wizard, but they don't depend on instruments"; 7E returns to the wave table's next row; note-mode (default since 1.5, C=+N toggles) lets you type or play chord notes from a MIDI keyboard with the root shown above the table (source: s-witchmaster-creating-chiptunes-with-sid-wizard).

A player author's confirmation of the idiom: in linus-walleij's SID player the arpeggio macro is a table of bytes that "represents the number of halftones to transpose the current note UPWARDS. For example macro 0x00 0x03 0x07 creates a minor chord"; the table "can loop or end", and the arpeggio step is skipped while the instrument's vibrato runs (source: s-walleij-sid-player-routine).

What the player actually does (SW 1.97 player.asm)#

The exact stepping rules, from m64's duet research (WFARPTB, player.asm 2396–2537; source: s-duet-research-sidwizard-deep):

  • The arp-speed counter is decremented on every player call that reaches the table; a step happens only on underflow, so a row is held (speed+1) calls and speed 0 steps every call. In a multispeed tune the unit is player calls, not frames — arps speed up with the framespeed. Small-FX $Cx sets the speed and forces an instant step on the next call.
  • A WF-column value $00–$0F is a one-shot speed override for that row only (held value+1 calls); no waveform is written for such a row. On ordinary rows the waveform is written only on the step entering the row; on chord rows it is re-read and re-masked every step.
  • On a chord row (arp $7F) the table does not advance; each step reads the chord table: $7E returns — and the next WF-table row executes immediately in the same step; $7F wraps to the chord's first entry; anything else is a note-relative offset. Chord speed is the arp speed — same counter.
  • Chord entries are relative to the pattern note, and every chord step stores the row's detune column unconditionally$FF, elsewhere "keep previous", becomes a literal +255 detune on a chord row (quirk; keep the detune column at $00 on $7F rows).
  • A pitch-yielding arp step is a plain frequency-table lookup written over the accumulator — this overwrite is the "arp cancels slide/vibrato" rule; $80 (NOP) leaves even the accumulated vibrato displacement untouched.

Detune › SID-Wizard #

  • Per instrument: the Detune column of the WF-ARP-Detune table ($00–$FE detune upwards per row, $FF keep) — so a "lead B" instrument can be a detuned copy of "lead A".
  • Per note: $Dx small effect detunes the current note; $0D xx (big effect) detunes upwards with finer range.
  • Not available in the Light and Bare players (sid-player-routine).

(source: s-sid-wizard-manual)

What the player actually does (SW 1.97 player.asm)#

From m64's duet research (player.asm 2445–2448, 2539–2541, 3399–3404; source: s-duet-research-sidwizard-deep):

  • The detune value is added at the output stage every frame, never into the pitch accumulator — so vibrato, slides and arps cannot destroy it, and it detunes upward only (0..254 frequency LSBs; small-FX $Dx sets x×8, big-FX $0D the raw value).
  • It is never reset — not by note start, not by player init: a pattern detune stays on the channel until a table row or another FX changes it. The table column's $FF means "keep previous" — except on chord rows, where it is stored unconditionally and becomes a literal +255 (quirk: keep $00 in the detune column of $7F chord rows).
  • The addition has a path-dependent carry-in (no CLC), giving a deterministic ±1 LSB jitter tied to the table state — part of the SW sound a bit-exact reimplementation must reproduce.

Fake echo / delay › SID-Wizard #

Per-note volume is the instrument-column effect $5x (sustain level = note volume), so an echo note is the same note with a lower $5x, or a separate quieter echo instrument. $1D xx (Extra player) delays a whole track by $00–$FF frames and $1E xx delays a single note by up to tempo−3 frames — (unverified suggestion) a duplicated track with $1D gives a delay finer than one row (source of the commands: s-sid-wizard-manual).

Filter programming on the SID › SID-Wizard #

The instrument's filter-program table:

entrymeaning
$8r..$Fr xxset resonance r and cutoff xx; the high nybble picks the band: 9 low-pass, A band-pass, C high-pass
$00..$7F xxadd xx to the cutoff, this many times
$FE xxjump to table position xx

Third column: $00–$7F / $FF–$90 keyboard tracking (cutoff follows the note pitch), $8x filter-switch override. Behaviour: filters are switched on automatically for channels using a filtered instrument; if several tracks try to control the filter, the leftmost channel wins; an instrument with an empty first table row is filtered but does not control the filter. C=+F toggles filter reset on instrument selection.

Pattern effects: $0B xx go to filter table position · $0F xx set cutoff hi-byte · $1C xx shift the cutoff hi-byte permanently · $1F xx write the filter-switch/resonance register · $Bx filter band nybble · $Fx resonance. The Extra player adds a filter-switch/resonance effect and keeps program tables from being skipped; Light lacks keyboard tracking and the 11-bit filter; Bare/Demo lack the filter small effects and filter shift (sid-player-routine). The cutoff bar in the top border shows what the filter does. With a table speed above $80 the filter table runs at multispeed rate (source: s-sid-wizard-manual).

More from the SID-Wizard book: the band nibble also allows combinations — $8 filter off, $9 low-pass, $B low+band, $C high-pass, $D low+high, $E band+high, $F all three (then resonance cannot be $F); the cutoff byte spans roughly 30 Hz–10 kHz; keyboard tracking is a signed exponential strength ($00–$7F brighter for higher notes, $FF–$90 weaker); $80–$8F in the third column is a filter-switch override kept for GoatTracker imports ($81 channel 1, $82 channel 2, $84 channel 3 — printed "channel 4" in the book — $88 external input, combinable). "The latest instrument always takes over the control over the common filter" ("like with polyphonic jamming in JCH's editor"); C=+F toggles whether the program restarts on every note (bright FILT. header) or only on instrument selection. The book's bass filter: 9B 45 (low-pass, resonance B, cutoff $45 — "quite dark") followed by 40 05, which opens the cutoff by $05 sixty-four times (source: s-witchmaster-creating-chiptunes-with-sid-wizard). The 1.6 charts print the same band list but skip $A (band-pass alone), which the beginners' tutorial confirms as "A (band pass)"; the tutorial's first filter row is 9F 30 — low-pass, resonance F, cutoff $30 — and it repeats the rule that an instrument with a blank first row is "filtered, but not to control the filter" (sources: s-sid-wizard-charts-and-tables, s-chipmusic-c64-music-for-dummies).

What the player actually does (SW 1.97 player.asm)#

The mechanism behind "the leftmost channel wins", from m64's duet research (flprog/STRTSND, player.asm 2175–2328, 1931–2009; source: s-duet-research-sidwizard-deep):

  • There is one filter program per SID, and only the current controller track executes it. At init the controller is a $0F "nobody" sentinel — no filter program runs until an instrument takes over.
  • Arbitration happens at note start, by the FIRST byte of the starting instrument's filter table: $00passive (the channel's routing bit is switched on, controller untouched); $FFunfiltered (own routing bit off; if this track was the controller, the program parks on the $FF row); anything else → take over: this track becomes controller and the table starts from its pointer next tick. Leftmost priority is emergent: channels are processed 3→2→1, so on simultaneous starts channel 1 writes last and wins. An instrument with filter-reset disabled (ctrl bit 7) and no re-typed instrument number skips arbitration entirely — including its routing-bit update.
  • The table position is per SID but interpreted against whatever instrument currently sits on the controller track — switch instruments there without a reset and the offset points into the wrong table (a real quirk, reproduced by DUET).
  • The sweep works on the true 11-bit cutoff ((hi<<3)|low3), the "fine filter sweep" of the Normal/Extra players; the sweep counter is not reset by a take-over.
  • Column 3's $80–$8F override replaces the entire $D417 routing nibble (all three channel bits plus external-in) and zeroes the keyboard-track value.
  • Write-out each frame: $D416 = kb-track curve value (indexed by the controller track's pitch) + cutoff-hi + the permanent $1C shift, carries chained; $D415 gets the raw low 3 bits, un-tracked. Big-FX $0B (filter-table jump) skips the controller check — it moves the shared position from any track (quirk).

Hard restart › SID-Wizard #

Instrument main settings (F7):

settingmeaning
ADHRthe ADSR loaded "1-2 frames before a new note is triggered"; common values 0F00 and F800
HardRestart timer0..2 frames before the note
HardRestart typenormal, or staccato / aggregated: the test bit is also reset at hard restart, "adds 1-2 frames of gap between consequent notes"
Frame-1 waveformwaveform/control byte for the note's first frame (enable with RETURN, on by default); Hermit: its purpose "is the same as in Goattracker, to test / reset the oscillators with waveform $09 (test-bit set) before the sound starts and get a short 'sexy' start of the sound"

In SID-Wizard 1.0 the beginners' tutorial had every instrument set HRTY to 2 (a square symbol appears next to the number) "so that the gate bit is reset between each note, which is important because otherwise notes will not sound if they come after another note rather than a note off" — later versions do this by default (source: s-chipmusic-c64-music-for-dummies). The Medium player drops the HR type and frame-1 setting; the Demo player has no hard-restart/frame-1 settings (sid-player-routine) (sources: s-sid-wizard-manual, s-witchmaster-creating-chiptunes-with-sid-wizard).

What the player actually does (SW 1.97 player.asm)#

The exact schedule behind the HR timer, from m64's duet research (player.asm 1517–1592, 1726–1728, 1820–2054; source: s-duet-research-sidwizard-deep):

  • A row is fetched at tick 0 but its note starts at tick 2 — uniformly 2 frames later. That lookahead is what makes hard restart possible: the control byte's bit 1 fires the HR phase at tick 0, bit 0 at tick 1 (both bits = both ticks), so "HR timer 0..2" is literally which of the two pre-note frames get the treatment.
  • An HR phase sets the ghost ADSR to the instrument's HR values (ADHR), masks the gate off, and clears the gate bit in the waveform ghost. The staccato type (ctrl bit 2) additionally writes waveform $18 (test bit + triangle) and skips the rest of the channel's processing that tick — the audible 1–2 frame gap.
  • During HR ticks the Normal player pauses vibrato, filter and pulse tables but keeps the WF table running (even for HR-timer-0 instruments); the Extra player pauses nothing. Because tick 2 must exist, the Normal player needs tempo ≥ 3 for notes; only Extra's fast-speed binding folds the ticks for tempo 1–2.
  • Hard restart is suppressed when the incoming row is legato ($3F), tone portamento ($03), or follows a $78 portamento flag — glides never restart.
  • The 1st-frame waveform mechanism at tick 2: the player writes the frequency hi byte only (the low byte still holds the previous note) plus the frame-1 waveform — default $09, whose test bit freezes the oscillator so the stale low byte is inaudible; the WF table's row 0 then executes on the next call, releasing the test bit and setting the true 16-bit pitch in the same write-out. ADSR order at note start: SR is written first, then AD.

Instrument design beats note count › SID-Wizard #

An instrument (F7 panel, up to 36 per tune in 1.8, Shift+N to name) = adsr-envelope + hard-restart settings + vibrato settings + default chord + octave shift + the three instrument-tables (wave/arp/detune, pulse, filter). Instruments are saved separately as .swi files, travel between tunes through the clipboard (C=+C … load … C=+V), and the distribution includes 324 example instruments. C=+X/C/V cut/copy/paste whole instruments; C=+P/C=+F decide whether pulse/filter tables restart on every note or only on instrument change (sources: s-sid-wizard-manual, s-witchmaster-creating-chiptunes-with-sid-wizard). The examples are the usual starting point in practice — "A lot of excellent example instruments are included in the Zip file" — and a tweaked one gave a Lemon64 poster a TR-808-like bass drum with a long decay, though he posted its WF-ARP table only as an image, so the values are lost (source: s-lemon64-sid-wizard-instrument-recommendations).

Three worked recipes from the SID-Wizard book (source: s-witchmaster-creating-chiptunes-with-sid-wizard):

instrumentWF-ARP tablepulse tableADSR / vibrato / filter
Bazz ("a standard SID bass")41 (pulse, gate on); octave transpose −382 (width $200), then 40 20 (add $20 sixty-four times — watch the pulse bar); keyboard tracking 10 on both rowsADSR 089A; vibrato 3720, delayed up-down; filter 9B 45 (low-pass, resonance B, cutoff $45) then 40 05 (opens the cutoff by $05 sixty-four times)
Snare81 CE (noise at F-7) · 41 AD · 41 AC (pulse at G#4, G-4) · 80 C4 · 80 C5 (noise, gate off)88 ($800)decay D, sustain E, release 9 — "the release parameter makes the biggest difference"
Arpeggio11 7F (triangle, jump to the default chord); chord 00 03 07 0C 07 03 + 7F loopchord speed 02 (instrument or WF column); attack 8, release B "for a smooth attack and longer release"

Because the snare uses only absolute pitches "all notes will sound the same". The 037-lab-style pitch drop for kicks and the "tiny downward pitch envelope" for bass go in the Arp column of the wave table ($01–$5F up on the first rows, then $00); hi-hat = a short noise row with a fast decay (wavetable-programming); lead = pulse with a slow pulse-width-modulation sweep and delayed vibrato.

A beginner's set from the 2012 chipmusic.org tutorial for SID-Wizard 1.0 (source: s-chipmusic-c64-music-for-dummies):

instrumentADSRWF-ARP tablepulse tablenotes
saw lead00F021 .."no dynamics", but a sound; 11 .. for triangle
octave flick00F021 0C · 21 ..starts an octave up and "quickly flicks back down" — one table row is 1/50 s (1/60 on NTSC)
pulse kick080041 30 · 41 20 · 41 10 · 41 0C · 41 ..88 .. (square; 80 10 for "a very thin sound")play it in octave 1; a pulse instrument is silent until the pulse table sets a width
hi-hat0400 closed, 0800 open81 .. (noise; a pitch in the arp digits makes it "slightly tonal")"a short blast of white noise"

Multispeed (framespeed) › SID-Wizard #

  • Shift+F / Shift+G increase / decrease the framespeed (SDI layout: ? sets speed calls 1..8).
  • Instrument tables can follow the higher rate selectively: a WF-Arp table speed above $40 runs the pulse table at multispeed, above $80 the filter table too.
  • Exported tunes expose the multispeed call at LoadAddress + 6, which the host program must call the extra times per frame (sid-format, sid-player-routine).
  • The Bare player does not support multispeed.

(source: s-sid-wizard-manual)

Design note from the book: in SID-Wizard (as in X-SID) only the tables (waveform / pulse / filter) run at the multiplied rate; tempo, vibrato and slides are handled once per frame — "you can't set tune-tempo in a finer scale, but on the other hand in multispeed the tempo / hard restart / vibrato / slide settings can stay the same". GoatTracker calls the whole player. "The 2x speed (100Hz) can be quite enough for some nice effects. (E.g. Rubicon's title music by Jeroen Tel is 2x, and has drums that are not possible in 1x single-speed at 50Hz)" (source: s-witchmaster-creating-chiptunes-with-sid-wizard).

What the player actually does (SW 1.97 player.asm)#

The exact split between the main call and the extra calls, from m64's duet research (MULPLY/MULCNTP, player.asm 1240–1327; source: s-duet-research-sidwizard-deep):

  • The framespeed−1 extra calls are spaced evenly across the 312 PAL rasterlines by the exporter. Row fetch, orderlist, hard restart, note start, tempo, vibrato and slides happen only in the main call; the extra calls run tables and re-write the registers.
  • Per channel each extra call enters the chain by the instrument's table-speed byte: the WF-arp table always runs at the multiplied rate; bit 6 ($40) adds the pulse table, bit 7 ($80) the filter table (which falls through pulse and WF). The filter/volume registers (COMMONREGS) are rewritten every subframe.
  • Table counters therefore tick per player call: an arp speed or sweep length means calls, not video frames — the same instrument runs its tables N× faster in an N× tune (the design the book describes as "only the tables run at the multiplied rate").
  • A channel is skipped by the extra calls on its note's first frame (the note-start marker), so the frame-1 waveform trick survives multispeed: the WF table's row 0 lands on the next frame's first call.

Octave bass › SID-Wizard #

25 % pulse = pulse width $400 (set with $8x..$Fx in the pulse table or $0E); triangle is a plain waveform entry in the wave table. A short downward pitch envelope in the wave table's Arp column makes the octave hits punchier (instrument-design; source for the table mechanics: s-sid-wizard-manual).

Pitch slides and tone portamento › SID-Wizard #

commandeffect
$01 xxpitch slide up
$02 xxpitch slide down
$03 xxtone portamento (auto-portamento to the new note)
Shift+Pportamento flag directly in the note column
$3F in the instrument columnlegato / tied note: sets the pitch only, no envelope retrigger

Slides are calculated: a slide of N semitones takes about the same time at any pitch. Practical ranges from s-037-lab: $30–$60 is the everyday portamento zone (a semitone in ~140–40 ms), $08–$20 a slow dramatic slide, $80 and up a one-frame snap; every +$18 doubles the speed. The Light and Bare players lack calculated slides / note-column portamento; an arp table entry cancels a slide; in the Extra player vibrato survives a pitch slide (source: s-sid-wizard-manual).

The book's pattern tutorial: 03 25 on a G#5 for a slow portamento, 02 20 slide down near the end, then a note-off; "when using slow portamento … you may have to adjust the note to play a bit earlier so it doesn't sound as if the note starts late" — they move it from row $10 to $0C (source: s-witchmaster-creating-chiptunes-with-sid-wizard).

What the player actually does (SW 1.97 player.asm)#

From m64's duet research (player.asm 2085–2171, 3094–3099, 1803–1816; source: s-duet-research-sidwizard-deep):

  • A slide's per-frame step is freq16(speed/2 + note − 107) through the exponential table — the "calculated" slide: equal semitones per second at any pitch. Slides $01/$02 never self-terminate (no clamp; the 16-bit frequency can wrap) — they end only when something rewrites the slide state: a note start, $03/$08/$16, a $6x note-FX or legato.
  • Tone portamento $03 steps FREQMOD+1 per frame (a carry quirk — plain slides step exactly FREQMOD, so $03 00 still creeps 1 LSB/frame), detects overshoot by borrow and snaps to the exact target, then stays pinned re-asserting the target each frame. The note on a $03 row sets the target pitch but skips the sound init, and hard-restart is suppressed for it.
  • The note-column portamento flag ($78, Shift+P) uses a fixed speed of 110 (≈ note frequency / 20 per frame) with no parameter; the next real note then converts into a glide without retrigger — hard restart and note start are both suppressed.
  • Legato ($3F) is implemented as a maximum-speed portamento: slide speed is forced to the ceiling so the pitch snaps within a frame or two, while envelope, tables and vibrato state are left completely untouched.

Pulse width modulation (PWM) › SID-Wizard #

The SID pulse width is a 12-bit value (low byte + high nybble), so 50 % = $800, 25 % = $400, 12.5 % = $200. The instrument's pulse-width table (Shift+P) programs it frame by frame:

entrymeaning
$8x..$Fx xxset the pulse width to xxx
$00..$7F xxadd xx to the pulse width, this many times (one step per frame)
$FE xxjump to table position xx

A sweep is therefore: set a start value, add a small positive step for n frames, add a negative step (= negates a value) for n frames, jump back. The third column is a keyboard-tracking curve ($00 off; $01 upward = more pitch dependence, $FF downward = less), so the width can follow the note. C=+P toggles whether the table restarts when the instrument is selected; $0E xx sets the pulse width from the pattern; $0A xx jumps to a table position. The current width is shown as a bar in the top border. With a table speed above $40 the pulse table runs at multispeed rate for smoother sweeps (source: s-sid-wizard-manual).

Details from the SID-Wizard book: $000 and $FFF give "a constant DC output (silence)", $800 a square wave; the first nibble of a set-row must be $8–$F but does not affect the width (true for the immediate output — but the player keeps seven bits of it in its ghost register, and a later sweep runs from the full value; see "What the player actually does" below). Keyboard tracking is "a signed value in exponential scale" — $00–$7F widens the pulse for higher notes, $FF–$80 does the same more weakly. C=+P toggles the header: bright PULSE = the program restarts on every note, dark = only when an instrument is (re)selected. The book's bass recipe: 82 (width $200) then 40 20 (add $20 sixty-four times) with keyboard tracking 10 on both rows — "look at the pulse width bar … while you try the instrument" (instrument-design; source: s-witchmaster-creating-chiptunes-with-sid-wizard).

The beginners' tutorial for SID-Wizard 1.0 puts it in two numbers: 80 10 is "a very thin pulse width", 88 .. the square wave, and past it the pulse gets "thinner again"; a pulse instrument with an empty pulse table is silent ("there is no default pulse width in this tracker"); a sweep row is 01–7F (frames) followed by the speed and direction — FF "a slow downward sweep", 81 "a very fast downward sweep" — and the purple KT column makes "the pulse width follow the pitch of the note being played" (source: s-chipmusic-c64-music-for-dummies).

What the player actually does (SW 1.97 player.asm)#

From m64's duet research (SETPWID, player.asm 2332–2394; source: s-duet-research-sidwizard-deep):

  • A set row stores seven bits into the pulse-hi ghost (cmd & $7F), not just the nibble: the SID ignores bits 4–7 of $D403, so $9x and $8x sound identical now, but a following sweep runs from the full 7-bit ghost value and wraps at a different point.
  • A sweep row [N, xx] makes N signed 16-bit additions over N+1 ticks (the last tick advances the row without adding). The ghost can run through the whole 16-bit space; the SID sees bits 0–11. The sweep counter is reset on row advance but not at note start — leftover residue can shorten an instrument's first sweep row.
  • Keyboard tracking is applied at the output stage only, every tick: the player adds the first difference EXPTABH[kb+pitch] − EXPTABH[kb+pitch−1] to the written hi byte, never to the ghost. 6502 borrow semantics leak through: a flat region of the curve yields a −1 artifact, an index wrap a +1.
  • The pattern gate does not touch the pulse program — it keeps stepping and writing through the release phase; gate-off merely redirects the position to the instrument's PW gate-off pointer.
  • A $FE jump landing on a set row executes it the same tick (set+jump in one tick); landing on a sweep row starts it the next tick. Big-FX $0A (table jump) also zeroes the sweep counter; big-FX $0E vv writes only PW bits 8–11 (vv & $0F), keeping the low 8 bits.

Ring modulation and oscillator sync › SID-Wizard #

  • In the note column: Shift+R / C=+R switch ring modulation on/off, Shift+S / C=+S switch sync on/off — shown as small symbols after the note.
  • As effects: $Ex sets the control nybble (test / ring / sync / gate) as a small effect; $04 xx writes the whole waveform/control register.
  • In the instrument's wave table any $10–$FD entry is a full waveform/control byte, so ring/sync/test can be switched per frame (wavetable-programming): control nibble 1 gate + 4 ring = 5, e.g. $15 for a gated ring-modulated triangle; the 1.6 charts and the beginners' tutorial spell the nybble out — 1 gate, 2 sync, 4 ring, 8 test; 3 = sync + gate, 5 = ring + gate, 7 = both with gate, and "you need to keep the gate bit turned on" (sources: s-sid-wizard-charts-and-tables, s-chipmusic-c64-music-for-dummies).
  • The Bare and Demo players drop the waveform/ring/sync small effects (sid-player-routine).

(sources: s-sid-wizard-manual, s-witchmaster-creating-chiptunes-with-sid-wizard)

What the player actually does (SW 1.97 player.asm)#

From m64's duet research (player.asm 3101–3108; source: s-duet-research-sidwizard-deep):

  • The note-column flags flip single bits in the channel's waveform ghost: $79/$7A set/clear the sync bit, $7B/$7C the ring bit — and they persist only until a WF-table waveform row replaces the whole byte or the next note starts. An instrument whose wave table keeps writing waveform values will silently erase a pattern's ring/sync flag on its next table step; the flags survive only over table rows that hold ($00–$0F repeats, $FF end).
  • Small-FX $Ex replaces the ghost's entire low nibble (gate/sync/ring/test at once), $4x the high nibble; big-FX $04 the whole byte, raw.

Shuffle, swing and FunkTempo › SID-Wizard #

Tempo is frames per row. Besides a single tempo there is FunkTempo — "two tempos are alternated every pattern step so with funktempo activated the first tempo is for even rows in the pattern and the second tempo is for odd rows" (source: s-witchmaster-creating-chiptunes-with-sid-wizard):

controleffect
< > (Shift+,/.)subtune tempo up/down; [ ] (Shift+:/;) second FunkTempo; C=+T toggle subtune FunkTempo
$10 xx / $11 xxset main single tempo / main FunkTempo
$13 xx / $14 xxset this track's single tempo / FunkTempo
$12 xx / $15 xxlaunch a tempo program for the tune / for this track
orderlist $B0–$EFsingle track tempo

Tempo programs (C=+F7/C=+F8 table, Shift+T/Y to select) hold one tempo value $00–$7F per pattern row, so any repeating groove — not just two-value swing — can be written. Different tracks may run at different tempos. The Light player has no tempo programs; the Extra player allows "fast tempo" 0..2 (source: s-sid-wizard-manual).

The book adds the BPM arithmetic: at 4 lines per beat, BPM ≈ 3007.47 / (tempo × 4) on PAL, and a funktempo counts as the mean of its two values (0604 → 5). Tempo programs (C=+F7) take values up to $7F and roll over automatically; a tempo program selected from a pattern effect maps its rows onto the rows of that pattern (source: s-witchmaster-creating-chiptunes-with-sid-wizard).

The 1.6 charts print the arithmetic as lookup tables for tempos $01–$14 against 1–32 lines per beat, which is how you pick a tempo/row-height pair for a target BPM: on PAL, tempo 06 at 4 lines, tempo 08 at 3 lines and tempo 04 at 6 lines all give 125.31 BPM, tempo 05 at 5 lines gives 120.30, and the same tempo 06 at 5 lines on NTSC gives 119.65 (source: s-sid-wizard-charts-and-tables). The charts also name two effects that shift timing without touching tempo at all — $1D delays the whole track by a number of frames (20 ms each) and $1E delays a single note — a per-track or per-note nudge where FunkTempo would move every row (same source; compare defMON's per-channel speed column below).

Inside the tempo machinery (SW 1.97 player.asm)#

From m64's duet research (player.asm 1341–1384, 3586–3696, packdepack.inc; sources: s-duet-research-sidwizard, s-duet-research-sidwizard-deep):

  • The runtime tempo table starts with the main tempo/funktempo pair (loaded from the subtune's funktempo bytes at init), then one pair per track, then the tempo programs. A plain byte = tempo for one row then advance; a byte with bit 7 = tempo (& $7F) then loop — so a single tempo is just a one-byte looping program, and funktempo is a nibble pair written as two entries (hi plain, lo | $80) alternating for ever. A row lasts tempo & $7F frames; the Normal player needs tempo ≥ 3.
  • Every subtune owns a funktempo pair at the module's tail; an untouched subtune carries $86/$83 — bit 7 on the left byte means single tempo, so that reads "tempo 6, with 3 parked for the day C=+T toggles funktempo on".
  • Tempo programs are a saved thing with tight caps: the file stores only the programs (an empty tune saves zero tempo bytes); at most 62 programs, 32 bytes per program, and a total table of 119/113/107/101 bytes for the 1–4-SID formats. In the editor bit 7 is never typable (the loop marker is set by the packer), INS inserts a $00 row and DEL cannot remove a terminator.
  • The tempo-program effects $12/$15 treat operand 00 as a no-op ("NO TEMPOPROGRAM 0") — program numbering starts at 1.

Sound effects and game audio › SID-Wizard #

The exported tune is an API with an effects entry point. Call LoadAddress + 12 with X = note, Y = instrument, A = length; SFX plays on channel 3 (sources: s-witchmaster-creating-chiptunes-with-sid-wizard, s-sid-wizard-manual). That is the same instrument-plus-pitch triple the 1980s drivers used, exposed as three registers — so any of the tune's 36 instruments can be a sound effect, and designing effects becomes ordinary instrument-design and wavetable-programming.

Vibrato and delayed vibrato › SID-Wizard #

  • Per instrument: four hex digits — amplitude, frequency (speed), and a two-digit delay (or increment speed); the four vibrato types are delayed up-down, delayed downwards, delayed upwards and incremental "violin style" (source: s-witchmaster-creating-chiptunes-with-sid-wizard; note the traced 1.97 player arithmetic runs $20/$30 the other way round — see "What the player actually does" below). Vibrato is "calculated", i.e. its depth is pitch-independent. The book's bass uses 3720 with delayed up-down.
  • In the note column: Shift+V puts a vibrato flag on the note (amplitude 1..F), shown as a tiny graph symbol.
  • Effects: $08 xy set amplitude and rate; $8x amplitude only; $9x rate only; $16 xx select vibrato type (00/10/20/30).
  • Caveats: an arp entry in the instrument's table cancels vibrato; a pitch slide cancels it too except in the Extra player; the Light player has no calculated vibrato; Bare and Demo drop the vibrato-rate/frequency effects (sid-player-routine).

(source: s-sid-wizard-manual)

What the player actually does (SW 1.97 player.asm)#

The "calculated" arithmetic, from m64's duet research (VIBSLIDE/SETVIB0, player.asm 2085–2171, 2890–2941; source: s-duet-research-sidwizard-deep):

  • Vibrato is a triangle added directly to the 16-bit frequency accumulator: period = 2×rate frames, per-frame step FREQMOD = freq16(4×amplitude + note − 107) looked up through the exponential table — which is why the depth is a constant musical interval at any pitch.
  • The four types differ only in phase seed and the role of instrument byte 6: type $00 "increasing" has no delay — byte 6 is a per-frame amplitude increment, and the ramp is unbounded (it never clamps); type $10 "normal" waits byte 6+1 frames then oscillates symmetrically; type $20 seeds at the full rate and, as traced, oscillates above the note; type $30 seeds at zero and oscillates below. The source comments name $20 "down-oriented" and $30 "up-oriented" — the opposite of the traced arithmetic (open question in the research; the traced behaviour is what DUET implements).
  • Note-column $6x and small-FX $8x set the amplitude only — the rate stays the instrument's, the phase resets, and the delay counter is not reloaded; they also cancel a running slide/portamento by restoring the instrument's vibrato type. $9x sets the rate only, touching nothing else; big-FX $16 the type only.
  • "Arp cancels vibrato" is an overwrite, not a flag: a pitch-yielding WF-table step writes a fresh table lookup over the accumulator, discarding the displacement; on hold/end ticks the displacement survives and keeps accumulating. On ticks 0/1 before a new note the vibrato stage is skipped altogether (Normal player).

Wavetable programming (waveform / arp tables) › SID-Wizard #

The Waveform-Arpeggio-Detune table (Shift+W in the instrument panel; at least one row is required), three columns per row, one row per frame:

columnvalues
WF$00–$0F repeat only the arp/detune columns for 1–16 frames (no waveform change) · $10–$FD waveform/control byte written to the SID (waveform bits + test/ring/sync/gate) · $FE xx jump to row xx (≥ $40 jumps to itself = hold) · $FF END (shown, not typed)
Arp$00 original pitch · $01–$5F semitones up · $E0–$FF semitones down · $81–$DF absolute pitch ($81 = C-1, $8D = C-2, $99 = C-3, $A5 = C-4, $B1 = C-5, $BD = C-6, $C9 = C-7, $D5 = C-8) · $80 NOP · $7F jump to the chord (chord speed override in the WF column)
Detune$00–$FE detune up · $FF keep

Waveform nibble: 1 triangle, 2 saw, 4 pulse, 8 noise (add to combine, noise excluded; pulse needs a pulse-table row); control nibble: 1 gate, 2 sync, 4 ring, 8 test. Shift+SPACE marks a row to be executed on note-off — "more control on the release phase … reverb-like effects by changing the waveform". Related instrument settings: Frame-1 waveform (the byte for the note's first frame, normally $09 = test + gate), WF-Arp table execution speed (run the table slower than 1 row/frame; >$40 also runs the pulse table at multispeed, >$80 the filter table), = negates a value. $09 xx in the pattern jumps to a table row; $04 xx writes the waveform/control register directly (above $F0 jumps to a table position); $4x sets the waveform as a small effect. An arp entry cancels slides and vibrato. In the Extra player program tables are never skipped even at fast tempos (sources: s-sid-wizard-manual, s-witchmaster-creating-chiptunes-with-sid-wizard).

The book's snare (all absolute pitches, so every key sounds the same): 81 CE (noise at F-7), 41 AD, 41 AC (two frames of pulse at G#4 and G-4 — "a tone to the snare"), 80 C4, 80 C5 (noise with the gate off, so the release starts even while the key is held); pulse table 88; ADSR decay D, sustain E, release 9 (source: s-witchmaster-creating-chiptunes-with-sid-wizard).