SID file format (.sid)

aliases .sid, SID file, PSID, RSID, PSID v2NG
sources SID-Wizard 1.8 User Manual (summary) · Creating Chiptunes with SID-Wizard, Second Edition (summary) · GoatTracker v2.72 readme (summary) · HVSC — SID file format description (PSID v1–v4, RSID) · Lemon64: SID-Wizard instrument recommendations? (2021) · chipmusic.org — sid music hints'n'tips (2013) · SIDin #1 — Ripping a game: Dig Dug (Stefano Tognon, 2002) · SIDin #2 — David Whittaker's Lazy Jones music routine (Stefano Tognon, 2002) · SIDin #3 — Ripping BASIC based tune: Sheba and Testcard (Stefano Tognon, 2003) · SIDin #4 — Ripping a BASIC program into RSID: Telengard (Stefano Tognon, 2003) · SIDin #4 — Martin Galway's Arkanoid music routine, the explanation (Stefano Tognon, 2003) · SIDin #12 — Ripping Trivia Arcade (Stefano Tognon, 2008) · SIDin #1–15 — Editorials and News digest (Stefano Tognon, 2002–2015) · The CheeseCutter Guide — the recovered site manual (Wayback) · CheeseCutter — the repo, the man pages, and the release paper trail (2011–2026) · defMON wiki — using a defMON tune in your own program · chipmusic.org — the defMON megathread (2014–2026) · chipmusic.org — C64 Music for Dummies (ant1's SID-Wizard 1.0 tutorial, 2012) · SIDin #5 — Music Engines Pattern Searching, part 2: the Lostack database (Stefano Tognon, 2004) · SIDin #8 — Catweasel Mk4: a PCI card with two SID sockets (Stefano Tognon, 2005) · SIDin #14 — Inside Hunter's Moon (Martin Walker's sound-effects engine, reverse-engineered, 2015)
created 2026-08-30 · updated 2026-08-31

The distribution format for commodore-64 music: the tune's data plus its player routine, with metadata, playable in SID players and emulators. sid-wizard's SID-Maker exports it; the author-info field uses : as separator between author name and title for the export, the SID-type (old/new sid) and player type are auto-detected but can be set, and a relocation address can be chosen (source: s-sid-wizard-manual).

Calling convention of an exported SID-Wizard tune#

  • LoadAddress: init subroutine (subtune number in the accumulator).
  • LoadAddress + 3: play routine, call every frame.
  • LoadAddress + 6: multispeed call.
  • LoadAddress + 9: external volume setting (volume in A).
  • LoadAddress + 12: trigger a sound effect on channel 3 (X = note, Y = instrument, A = length in frames; SID-Maker-SFX build).
  • LoadAddress + 15: tape-slowdown effect (0–24 semitones in A; SWP-FX build).

SWP is the relocatable variant: load address lo/hi in X/Y, subtune in A.

Exporting (book details)#

SID-Maker is a separate program (relocation cannot happen inside the editor's memory) writing .C64.PRG, .BIN.SEQ, executable .EXE.PRG and .SID.SEQ — rename the last to .sid after copying it off the disk; under VICE's folder integration the result is a .S00 that SWMconvert file.S00 file.sid converts. Steps: pick the tune, format, player type (match the one used while composing), machine type/tuning, relocation address (leave the default), SID model, filename. SAVE ERROR on non-1541 drives falls back to a compatible save at $1000 ($0F82 for SID) with the code still relocated. SWMconvert also converts to/from XM and MID (three monophonic tracks; chords expand to extra tracks) and .swm.sws; SIDEdit edits the SID header metadata (source: s-witchmaster-creating-chiptunes-with-sid-wizard). GoatTracker's F9 packer writes PRG, BIN or SID directly with a chosen start address (source: s-goattracker-readme).

Export troubleshooting (Lemon64, 2021)#

SID-Maker-2sid is for 2SID / stereo tunes only — use plain SID-Maker for a single-SID tune; a "SAVING ERROR" that appeared every time under VICE 3.1 disappeared with VICE 3.5; the binary/sequential export produces a binary file with a sequential extension that CBM prg Studio cannot load; chapter 13 of the SID-Wizard book explains which format a given program needs (source: s-lemon64-sid-wizard-instrument-recommendations). Reading a .sid back: siddump emulates the 6502 init and play calls and prints the register writes per frame; multispeed tunes need "the full CPU + CIA timer + IRQ environment", which it handles only partially since version 1.05 (source: s-chipmusic-sid-music-hints-n-tips).

What the other C64 editors export#

Not every editor writes a .sid, and two of the wiki's four write none from the editor itself:

  • CheeseCutter exports through its command-line companion ct2util: prg and sid for the two output formats, plus dump ("Dump song data to assembler source (BETA)"), import ("Copy data from another song without overwriting the player" — how a tune is moved between player versions) and init ("Create a fresh .ct from player binary", the door for custom players). Export options are -r to relocate, -zp to relocate the zero page, and -d/-s for the default and single subtune, 1–32 (sources: s-cheesecutter-repo-and-releases, s-cheesecutter-guide). In the 0.5.x era the route was the JCH editor's NP-Packer from CSDb instead.
  • defMON exports no .sid at all. SHIFT+P packs the tune to a PRG, executable or raw ("SAVE AS EXECUTABLE OR RAW? E/R", added within days of the support thread opening in June 2014); for a .sid frantic points at external PRG→PSID tools and the PSID header specification. Linking a packed tune into your own program means stripping the two leading .prg load-address bytes ($00,$10) — "An ugly 'trick' is otherwise to include the file at * = $0ffe" — then lda #$00 / jsr $1000 to init and jsr $1003 per frame; the init detects the SID model and temporarily disables interrupts while it does, the classic integration trap. 2SID tunes cannot be packed at all: only SID 1's data goes into the file, so stereo stays an editor-and-live format (sources: s-defmon-wiki-calling-the-player, s-chipmusic-defmon-thread; sid-player-routine).

One warning applies to every packer: the exported file is not the editor's playback. Frantic on defMON's — "the timing simply won't be the same … sometimes enough to trigger … the ADSR bug" (hard-restart) — so audition the export, not only the editor (source: s-chipmusic-defmon-thread). A beginner hit the same class of surprise from the SID-Wizard side, where an exported .sid detuned some arpeggios until a "noob arp error" in the instrument was found (source: s-chipmusic-c64-music-for-dummies).

The PSID / RSID container (HVSC's format description)#

The reference document lives in hvsc's DOCUMENTS folder, written by LaLa from Michael Schwendt's PSID v1/v2 description with Simon White's and Dag Lem's v2NG/RSID extensions and Wilfred Bos's v3/v4 additions (source: s-hvsc-sid-file-format). A .sid file is a big-endian header followed by the C64 binary:

fieldmeaning
magicIDPSID — runs on PlaySID/libsidplay1-style emulators — or RSID, "Real SID": the tune "strictly requires a true Commodore-64 environment" (multispeed, samples, extra interrupt sources, busy loops) and old players must reject it
version1–4; v2 adds the flags below, v3 a second SID, v4 a third
dataOffset$76 (v1) or $7C (v2+) — where the C64 data begins
loadAddress0 = the data starts with its own little-endian load address like a normal C64 file (always so in RSID, and the real address must be ≥ $07E8); the document warns about accidentally doubling the load address
initAddressthe init routine, called with the song number in the accumulator (0 = the load address; RSID: never in the ROM/I/O areas $A000–$BFFF, $D000–$FFFF)
playAddressthe routine "called frequently to produce a continuous sound"; 0 = init installs its own interrupt handler (always so in RSID)
songs, startSong1–256 subtunes and the default one
speedone bit per song: 0 = vertical-blank interrupt (50 Hz PAL, 60 Hz NTSC), 1 = CIA 1 timer (default 60 Hz); RSID: 0
name, author, releasedthree 32-byte Windows-1252 strings (released was once copyright)
flags (v2+)bit 0 = Compute!'s Sidplayer MUS data needing an external player; bit 1 = PlaySID-specific (Amiga-era "PlaySID samples", no longer C64-playable) or, in RSID, the C64 BASIC flag; bits 2–3 clock (unknown / PAL / NTSC / both); bits 4–5 SID model (unknown / 6581 / 8580 / both); bits 6–7 and 8–9 the models of the second and third SID
startPage, pageLength (v2NG)the largest free page range for relocating a player driver (0 = the file is clean, $FF = no free page)
secondSIDAddress, thirdSIDAddress (v3, v4)the middle byte of $Dxx0, even values $42–$7F or $E0–$FE only ($D420–$D7F0, $DE00–$DFE0) — the container for 2SID/3SID tunes

The environment a player must provide: $02A6 = 1 for PAL, 0 for NTSC; CIA 1 timer A at 60 Hz ($4025 PAL, $4295 NTSC); CIA values $3FFB / $5021 to play an NTSC tune on PAL or a PAL tune on NTSC at the right speed; for PSID the bank register is chosen per call address ($37 below $A000, $36 below $D000, $35 from $E000, $34 otherwise), for RSID it is the power-on state ($37, VIC raster IRQ set but disabled, CIA 1 IRQs active); with the BASIC flag the song number goes to $030C. The clock field exists because the NTSC refresh (17045 cycles) and the CIA latch (17095 cycles) differ enough that converting a VBI tune to CIA timing "can cause severe problems, as the SID ADSR bugs can actually break the tune"; the SID-model bits because the two chips differ in combined-waveform loudness, DC levels (volume-register samples) and filter (sid) (source: s-hvsc-sid-file-format).

So SID-Maker's export questions — player type, machine type, SID model, relocation address, author/title — are the header fields above, and a tune that uses multispeed through a CIA timer or plays samples belongs in an RSID.

Who else reads those fields. The SID-model bits are what a two-socket catweasel card uses to pick between the 6581 and the 8580 it carries — the reason to want two sockets in the first place (source: s-sidin08-catweasel-mk4). And because the container carries the player code, a .sid can be asked which player it is: once tunes lived as PSID/RSID files, engine identification moved off the C64 entirely — "there are no needed of use this database in the real C64" — and Tognon wanted the engine name shown in the SID player itself, computed by PSID64 while converting or by an emulator scanning its memory. Signature offsets survive because tunes are relocated in $100 steps, so the low byte of an absolute operand stays put (source: s-sidin05-pattern-searching-2; player-identification, sidid).

A rip as a PSID: SIDin's hand-written headers (2002)#

Two sidin rips show the container written as assembler directives around a reverse-engineered player — how a game rip became an hvsc file (sources: s-sidin01-dig-dug-rip, s-sidin02-whittaker-lazy-jones):

  • Dig Dug: .ifdef sid wraps .byte "PSID", .word $0200 (version 2), .word $7C00 (data offset $7C), .word $0000 (load address 0, "in cbm format" — the data starts with its own $01,$08), >initmusic/<initmusic and >play/<play (the fields are big-endian, so each is written high byte first), .word $0800 = 8 songs, .word $0700 = start song 7, four zero speed bytes (every song from the vertical-blank interrupt), the three 32-byte strings "Dig Dug", "<?>" (composer unknown) and "1984 Datasoft", and three zero words for the v2 flags and reserved bytes. Without sid defined the same source assembles to a .prg with a BASIC stub (SYS 2061), a raster IRQ that calls play between sta $D020 and dec $D020 (the border colour as a rastertime meter) and jmp $ea31 — one source, two builds (dig-dug).
  • Lazy Jones: org 1921, .word $1500 = 21 songs (tune 1 chains two pieces, the other twenty are one piece each), .word $0100 = start song 1, the strings "lazy Jones", "David Whittaker", "1984 Terminal Software"; load and init addresses are the listing's init label, play its IRQ label, which ends in jmp $EA31 (whittaker-player).
  • What the ripper checks first: which interrupt drives the music (Dig Dug: the raster at line $20 through $0314/$0315$9DE1; stop a suspected source in the emulator's monitor and listen), whether the image is cracked (Lazy Jones carries a faulty unused track from its cracked source), and that the result plays alike in several players and on a real machine.

BASIC-driven tunes: what the ripper must add (SIDin #3, 2003)#

  • A PSID needs an init routine and a play routine that the player calls from an interrupt; a tune driven by a BASIC program has neither. Tognon's examples are Commodore's Introduction to BASIC pieces — Andrew Colin's The Arrival of the Queen of Sheba (machine code for pitch and duration; BASIC only POKEs the SID registers, generates a frequency table and decodes the note data) and Testcard (machine code for pitch only, durations timed by BASIC's TI clock). His 2003 rip: disassemble the routine in an emulator's monitor, save the memory blocks BASIC wrote, move BASIC's SID initialisation into initMusic, and give the tune an IRQ-driven player (for Testcard the Sheba routine with its speed byte "set as a TI timing", after a hint from "Warren P."). The header he writes by hand: PSID, version $0200, data offset $7C, load address $0000 (CBM format — the two-byte load address stays in the data), init and play addresses, one or four songs, $FFFF speed words and the three 32-byte strings; under .ifdef sid, so the same source also builds a .prg with a SYS 2061 stub (source: s-sidin03-ripping-basic-tune). The RSID BASIC flag above is the later alternative for programs that cannot be rewritten; the magazine's next issue continues with "Ripping BASIC program into RSID" (#4, pp. 12–22, per its contents page).

RSID in practice: two SIDin #4 cases (2003)#

  • A BASIC game's music as RSID: Telengard (Avalon Hill, 1983) plays its sound from BASIC without interrupts, so Ninja's BASIC-only rip could not run in a SID player. Tognon translated every statement into 6502 followed by a call to a cycle-wasting routine sized from emulator measurements (about 5 200 cycles per POKE, 138 000 for a ten-step FOR loop with RND, 1 548 000 for a TI wait of 90 jiffies), corrected by ear, and packed it as an RSID v2 (load address 0, init $0801, play $0000, three songs) — RSID being the format in which the init routine may never return and busy-loop in the foreground. He called it "a temporary work" until "the sidplayers will manage Basic and Kernal roms"; the RSID BASIC flag above is that feature (sources: s-sidin04-ripping-basic-rsid, s-hvsc-sid-file-format).
  • Why Arkanoid is an RSID: Galway's "samples" are foreground code stepping the volume register (arkanoid, galway-player); the PSID "extended SID register" sample emulation "try to emulated this kind of sound generation", so the tune "will play so different into a sidplayer (with extended sid register) instead of the real machine (or today RSID rip)" (source: s-sidin04-galway-arkanoid).

Making a .sid from a game rip (SIDin #12)#

  • Tognon's Trivia Arcade rip shows the other route into the format: extract the music file with c1541 (list, extract), inspect load address and entry points in LaLa's SIDedit, find the init/play calls and their rate with vice monitor breakpoints (break 5000, m 314 for the IRQ vector), locate the subtune variable by reading the play code, then wrap the binary in a tiny raster-interrupt driver (A = subtune; four $D012 positions per frame) placed just below the data, drop the BASIC stub and let SIDedit write "a standard sidplay header … Real C64 tune, init address, 4 subtunes" — an RSID, because the wrapper installs its own interrupt chain (source: s-sidin12-ripping-trivia-arcade).

Subtunes as a sound-effect bank#

The songs field does not have to mean songs. Tognon's study of Hunter's Moon (Martin Walker, 1987 Thalamus) wraps the game's sound-effect player in a PSID v2 with 16 "songs" — explosion, star cell, choose system, bell, short tick, long drill, plonk, fire, bonus, launching, stage start, enemy explosion and the rest — so the subtune number selects an effect routine rather than a tune and every effect can be auditioned in an ordinary SID player (code at $0900, "extracted from original TAP") (source: s-sidin14-hunters-moon; sound-effects).

Format milestones and PSID64 (from the SIDin news)#

  • Dates for the container's history: PSIDv2NG arrived with hvsc 5.0 (2002-08-17); RSID with update 33 (2002-10-26) — "RSID is just a PSID (with the new PSIDv2NG extension) that require a real C64 environment to run (Real SID)", and Sidplay2/w (2002-10-20) and PSID64 0.5 (2002-11-07) supported it within weeks; the "C64 BASIC" RSID flag in SIDedit 4.00 / Audio::SID 3.03 (February 2004), with real BASIC rips (_BASIC suffix) in HVSC 39 (May 2004); PSID v3 for stereo/2SID tunes with HVSC 55 (2011-06-25), which also relaxed the text fields to 32 characters; 3SID files playable in XSidPlay2 2.1.7 via libsidplayfp 1.8.1 (September 2015) (source: s-sidin-news-digest).
  • PSID64 (Roland Hermans) turns a .sid into "a C64 self extracting executable" with a pre-relocated player and, if memory allows, an info screen: 0.4 (2002), 0.5 RSID (2002-11-07), 0.6 (2003), 0.7 (2005: INST/DEL screen toggle, +/- subtune keys, an NMI bank-register fix); SIDPLAY for Mac OS X used it for PRG export (source: s-sidin-news-digest).
  • PlaySID-only files: HVSC removed the _PSID digi hacks that had RSID equivalents in update 50 (2009-05-01) and replaced the last PlaySID/Sidplay1-specific files with RSID rips in update 56 (2011-12-23) (source: s-sidin-news-digest).

sid-wizard · sid · sid-player-routine · vice · hvsc · commodore-64 · siddump · cheesecutter · defmon · player-identification · sidid · sound-effects

Sources#

s-sid-wizard-manual · s-witchmaster-creating-chiptunes-with-sid-wizard · s-goattracker-readme · s-hvsc-sid-file-format · s-lemon64-sid-wizard-instrument-recommendations · s-chipmusic-sid-music-hints-n-tips · s-sidin01-dig-dug-rip · s-sidin02-whittaker-lazy-jones · s-sidin03-ripping-basic-tune · s-sidin04-ripping-basic-rsid · s-sidin04-galway-arkanoid · s-sidin12-ripping-trivia-arcade · s-sidin-news-digest · s-cheesecutter-guide · s-cheesecutter-repo-and-releases · s-defmon-wiki-calling-the-player · s-chipmusic-defmon-thread · s-chipmusic-c64-music-for-dummies · s-sidin05-pattern-searching-2 · s-sidin08-catweasel-mk4 · s-sidin14-hunters-moon

source file wiki/entities/sid-format.md · graph