On a home computer of the 1980s, sound was a list of numbers. A program played a note by writing a pitch, a volume and perhaps a waveform into the registers of a sound chip, and the chip kept making that sound until the program wrote something else. There was no library to call and no operating system to mix voices. A tune was a small program, usually run fifty or sixty times a second, that kept rewriting those registers; a sound effect was the same thing, interrupting the tune. And on the cheapest machines there was no chip at all, only a speaker the processor had to switch on and off for every cycle of every note.
Every machine drew the lines in a different place. The same tune had to be rethought for three square waves on one machine, three synthesiser voices on another and four channels of recorded sound on a third, and the people who did it well became known by name.
Fast facts
- The method: write values to the sound hardware’s registers; nothing else stands in between.
- The timing: usually a music routine called from an interrupt fifty or sixty times a second (see Interrupt-Driven Music); beeper music on the 48K Spectrum had to count out every cycle instead.
- The software: a sound driver that reads the composer’s music data and feeds the chip.
- The tricks: arpeggios for chords, software envelopes and vibrato, pulse-width modulation, filter sweeps, sampled sound.
- The budget: a few kilobytes of memory and a slice of every frame’s processor time.
What each machine offered
| Machine | Sound hardware | What the program controls |
|---|---|---|
| ZX Spectrum 16K/48K | None: one bit of port 254 drives the speaker | The processor flips the bit at the note’s frequency; see Beeper Music |
| Commodore 64 | SID 6581, later 8580 | Three voices, each with triangle, sawtooth, pulse and noise waveforms and its own ADSR envelope; ring modulation and sync; one programmable filter |
| Spectrum 128, Amstrad CPC, MSX | AY-3-8910 family (AY-3-8912 in the Spectrum and CPC) | Three square-wave tone channels and one noise generator; 16 volume levels per channel, or one hardware envelope shared by all three |
| Atari ST | Yamaha YM2149, compatible with the AY-3-8910 | As the AY, with a finer envelope |
| Atari 2600 | TIA | Two channels, each with a 4-bit control choosing a tone or noise type, a 5-bit frequency divider and 16 volume levels |
| Atari 400/800 | POKEY | Four channels with 8-bit frequency dividers and “distortion” from polynomial counters; pairs can be joined into 16-bit channels, and a high-pass filter can be switched in |
| NES | 2A03 APU | Two pulse channels with four duty settings and sweep units, a triangle channel, a noise channel and a delta-modulation channel for samples |
| Amiga | Paula | Four channels that fetch 8-bit samples from memory by DMA, each with its own period (playback rate) and volume from 0 to 64; two channels on each stereo side |
| Mega Drive | YM2612 and a Texas Instruments 76489 PSG | Six four-operator FM channels, the sixth replaceable by an 8-bit sample DAC; three tone channels and a noise channel on the PSG |
| Super NES | Sony SPC700 sound processor with its own DSP and 64K of RAM | Eight voices of compressed 4-bit samples, run by a program on the sound processor itself |
The clock behind the chip mattered as much as the chip. The Spectrum 128 runs its AY-3-8912 at 1.7734 MHz and the Amstrad CPC runs the same part at 1.00 MHz, so the same period value plays two different notes. A C64 note table written for an American machine plays flat on a European one.
On the Commodore 64
Commodore’s own manual made no secret that the programmer was on their own. The Programmer’s Reference Guide introduces the SID as “one of the most sophisticated electronic music synthesizers available on any computer”, with “three voices, totally addressable, ATTACK/DECAY/SUSTAIN/RELEASE (ADSR), filtering, modulation, and ‘white noise’”, and then explains how to reach it: “You get to the sound generator by POKEing into specified memory locations.” The 25 registers a program writes run from 54272 ($D400) to 54296. “The workhorse of your sound programs is the POKE statement.”
This program plays one note, the A above middle C, on voice 1:
10 S=54272
20 FOR R=S TO S+24:POKE R,0:NEXT
30 POKE S+24,15
40 POKE S+5,0:POKE S+6,240
50 POKE S+1,29:POKE S,69
60 POKE S+4,17
70 FOR T=1 TO 2000:NEXT
80 POKE S+4,16Line 20 clears every register. Line 30 sets the master volume to 15. Line 40 gives voice 1 an instant attack and decay and a full sustain level. Line 50 writes the 16-bit frequency value 7493 ($1D45) as a high byte, 29, and a low byte, 69. Line 60 selects the triangle wave and sets the gate bit, which starts the note; line 80 clears the gate, which starts the release. The data sheet’s formula turns the frequency value into a pitch, value × clock ÷ 16,777,216, so the right value depends on the machine’s clock: 7493 is A at 440 Hz on a European (PAL) C64, as the SID chip entry’s frequency tables show. The Programmer’s Reference Guide’s own value for that note is 7217, which plays at about 424 Hz on a PAL machine. Commodore’s table was worked out for the faster American NTSC clock, so a European program that copied it played about two-thirds of a semitone flat.
The music was also a memory budget, and on a commercial game the composer’s share was argued over. Chris Butler, who wrote Elite’s C64 conversion of Commando in about eight weeks for Christmas 1985, told ZZAP!64 what happened to its third level: “the game was completely finished — but when Rob Hubbard came down he said that he needed about 6K for the music, and there wasn’t room. So Steve Wilcox, the man, said, ‘Right — hack out level three.’” Butler, “not a musical person at all”, still rated the machine: “considering it’s probably got the best music capabilities of any home computer, excluding the 16 bit stuff… it’s not bad at all.”
The music routine
Most music on these machines came from the same shape of program, called from an interrupt once a frame. Trace this:
each interrupt (50 times a second on a PAL machine):
count down to the next row of the tune
when a row is due: read the next notes from the music data
for each channel:
update the volume envelope
update the pitch (vibrato, slides, arpeggio)
write the new values to the chip's registers
let any sound effect overwrite the channel it has takenEach pass is a “tick”, and the tempo is a count of ticks per row of the tune. The trackers made the arithmetic visible. In the documentation of the ProTracker module format, the default is 6 ticks a row and 125 beats a minute, with four rows to a beat: at 50 ticks a second that is a row about every eighth of a second.
The 48K Spectrum is the exception that shows why the interrupt mattered. Its ROM’s BEEP routine switches interrupts off while it plays, and the processor does nothing else until the note ends. A game with continuous music had to slot the notes in between everything else. Matthew Smith told Sinclair User in 1984 that the music in Jet Set Willy “does not use an interrupt”: “It’s just move-a-tiny-little-bit, BEEP-a-tiny-little-bit.” Beeper Music tells that story.
Tricks the hardware did not provide
Programmers filled the gaps in the hardware with software, and many of the best-known sounds of the period are those workarounds:
| Technique | What it does | Where it mattered |
|---|---|---|
| Arpeggio | Cycles one channel through the notes of a chord every frame or two | Everywhere there were too few channels |
| Software envelopes | The driver rewrites the volume every frame to shape each note | The AY, whose one hardware envelope is shared by all three channels; the TIA, POKEY and Paula, which have none |
| Vibrato and slides | The driver nudges the pitch every frame | Every chip |
| Pulse-width modulation | Changes a pulse wave’s shape while it plays | The SID’s 12-bit pulse width; the NES’s four duty settings; the Spectrum beeper, where it acts as a volume control |
| Filter sweeps | Moves a filter’s cutoff while a note plays | The SID, the only chip here with a programmable filter of this kind |
| Sampled sound | Plays recorded sound | Paula, the NES’s delta-modulation channel, the Mega Drive’s DAC and the SNES by design; the C64 by writing 4-bit values to its volume register |
| Software mixing | Adds several voices together before they reach one output | Three-voice music on the Spectrum beeper; eight-channel music on the Amiga’s four |
| The AY envelope as a waveform | Runs a repeating envelope fast enough to hear as a tone | The AY-3-8910 family |
Some of these cost a great deal. Sega’s own manual warned Mega Drive programmers that with the sample DAC “all timing must be done by software”, and that unless the program was very carefully built it could not use the FM channels at the same time. The SID’s sample trick took a large share of the C64’s processor time too. On the Amiga, OctaMED, which Amiga Format described in 1992 as “the 8-channel version of MED”, could only play eight voices on Paula’s four channels by mixing them in software.
The AY’s envelope trick comes straight from the data sheet. General Instrument’s manual explains that the envelope’s frequency is the input clock divided by 256 and then by the 16-bit envelope period, and that the generator then steps through “a 16-state per cycle envelope pattern”. With a repeating shape, a sawtooth or a triangle, and a small period, that cycle falls in the audible range, and the envelope becomes a buzzing waveform the tone channels cannot make.
Writing the music down
Composers worked in three main ways.
Straight into the program. Early composers wrote their notes as data for a routine they had written themselves. Rob Hubbard started that way: after hearing Activision’s Master of the Lamps he connected his monitor to his hi-fi and wrote his own music utility, because he found the commercial ones “very limited with the sounds you can create” (ZZAP!64, 1985).
Music Macro Language. Some BASICs played tunes written as text. MSX BASIC’s PLAY statement “plays music according to the music macro language”, taking up to three strings, one for each of the AY’s voices: letters A to G for notes, O for the octave, L for the note length and T for the tempo, with M and S setting the period and shape of the chip’s hardware envelope. PLAY "T120O4L4CDEFGABO5C" plays a C major scale. Microsoft’s GW-BASIC for the IBM PC has a PLAY statement built on the same idea.
The tracker. On the Amiga, music was written in a tracker, a grid of notes, sample numbers and effect commands that scrolls up the screen, one column per channel. Karsten Obarski’s SoundTracker began it at the end of 1987, and ProTracker became the standard; its files are the MOD format. The same way of working later spread to other machines, including newer trackers for older chips, such as SID-Wizard for the C64 and FamiTracker for the NES.
Sources
- Commodore 64 Programmer’s Reference Guide (Commodore, 1982), chapter 4, “Programming Sound and Music”: introduction and register locations; Appendix E, music note values (A-4 = 7217).
- MOS Technology, 6581 Sound Interface Device (SID) data sheet: the frequency formula and the voice registers.
- ZZAP!64 issue 17, September 1986, p. 104: Gary Penn’s interview with Chris Butler (“The Butler Did It”).
- ZZAP!64 issue 6, October 1985, p. 16: Rob Hubbard and his music utility.
- Sinclair User issue 33, December 1984, pp. 89–90: Matthew Smith on the music in Jet Set Willy.
- Sinclair ZX Spectrum BASIC Programming (Sinclair Research, 1982), chapters 19 and 23:
BEEP, one note at a time, and port 254 driving the loudspeaker. - General Instrument, AY-3-8910/8912/8913 Programmable Sound Generator data sheet: the tone, noise and envelope generators, “Envelope Period Control” and “Envelope Shape/Cycle Control”.
- Sinclair ZX Spectrum +2 manual (Amstrad), Part 29, and CPC464 Firmware (AMSOFT, 1984), appendix XII: the AY-3-8912’s clock on each machine.
- Atari, Stella Programmer’s Guide (1979), section 11: the TIA’s two audio channels and their control, frequency and volume registers.
- Ian Chadwick, Mapping the Atari (COMPUTE! Books), POKEY, locations 53760–53775: frequency and control registers, polynomial counters, AUDCTL’s 16-bit and high-pass options.
- Sega, Genesis Software Manual, sound section (1992): the Texas Instruments 76489 PSG and its four channels; the YM2612’s DAC on channel 6, “all timing must be done by software”.
- Nintendo, Super NES Development Manual, Book I, “SNES Sound Source Outline” and “BRR (Bit Rate Reduction)”: the SPC700, its 64K of memory, eight voices of 4-bit ADPCM sound.
- MSX Technical Data Book (ASCII Corporation), MSX BASIC reference,
PLAY: the music macro language commands. - GW-BASIC Interpreter User’s Guide,
PLAYstatement. - “Noisetracker/Soundtracker/Protracker Module Format”, 4th revision, by Lars Hamre and others (web): the default 6 ticks a row and 125 beats a minute. https://www.aes.id.au/modformat.html
- Amiga Format issue 35, June 1992: “OctaMED is the 8-channel version of MED”.