Next Tuesday I’m spending an afternoon with Chris Huggett’s OSCar at PWM HQ, to find out how far I am from this prototype sounding and behaving like the original, so I can close that gap. I expect it to go about as well as any first technical rehearsal: the stated objective is to learn, but the real purpose is to instil fear.
A few features are still missing. As long as the LFOs, envelopes, filters, pitch, and VCAs are somewhat wired in, refinements can wait. Without my own fully-kosher OSCar to play, it’s surprisingly tiresome to work through two entire signal chains and prove something even as trivial as the fact that I’m sounding at the correct octave. If there’s any compensation to working blind, it’s obtaining a depth of understanding that probably surpasses Chris Huggett’s of the time. It’s anybody’s guess why I’d want or need that, though …
Anyway, Superbooth is looming. I never get to go myself, because I’m too busy sending products and features. I’ve promised some kind of playable demo, but it’s taken a lot longer than expected to make the modulation work. Such things always take time, incurring familiar long cycles of break-it-then-fix-it. But this work is also a grind: low-dopamine; high-effort; lots of carefully checking number ranges across two implementations. It breaks in funny ways in unexpected places. The code is a bit smelly, and reorganising it into something maintainable takes a lot of thought. But it’s essential, or why do this at all? Occasionally I lose half a day just moving blocks of it around, and confirming that it’s correct. All of which is making it hard to sleep, and one cannot do this kind of work during insomnia.
Knowing what to change and when is a constant problem, because old code involves a quantity of enquiry, and I find myself adding the comment ;BUG rather often: if it is broke, there has to be a reason not to fix it.
Sorry, where was I? Alex Ball makes some great videos featuring an original OSCar. And the comment thread below reveals that a couple of people at least do want to know how OSCar generates its sound. What follows is therefore a more-than-usually technical post about some of that.

Did I mention oscillators?
The short answer: OSCar’s got two wavetable oscillators. Each one scans its own table of 256 samples per period.
The long answer is that this was far harder to do in 1983 than you might expect. We end up with a circuit and implementation which is, to pull the apposite quote from @RegebroRepairs above:
SUPER weird.
Just one DAC
Remarkably, every analogue voltage that the OSCar generates — two oscillators and 7 control voltages — come out of the same mono 8-bit DAC. It gets switched a lot.

This is a slide from my still-unpublished ADC talk (and the AES talk before that: too expensive to use only once) which demonstrates what the DAC is outputting over time. I was measuring my own OSCar clone, which runs at half-speed so I can emulate the ROM and RAM using a cheap ARM chip. (That made debugging a lot easier and saved me needing to buy an EPROM programmer — more bloody stuff — but I couldn’t quite make it run reliably at 4MHz.)
The upper graph shows two sawtooth waves, of different frequencies, that the DAC is chopping between constantly: oscillators 1 and 2. The parts I’ve coloured red are where the interrupt service routine chucks out nine control voltages that OSCar also isolates and holds in separate op-amps:

The control voltages are updated via the DAC at the beginning and end of the interrupt. I think this doubling was to let Chris measure how long OSCar spent in that routine. The trace above shows it taking about 3.6 milliseconds (call it 1.8ms at full speed), in which it updates the LFO, glide, gating, PWM, filter and pitch control voltages, and checks the keybed, switches, and voice allocator. Considering that a single multiply takes about 80 microseconds, you can imagine the terseness of this code. The 244Hz control rate is a little low by modern standards: Mantis operates around 600Hz.
Why nine control voltages? OSCar uses 7 for internal amplifiers and filters; there’s an eighth (‘ANALOGUE REF’) that doesn’t connect to anything in practice. It was clearly intended for calibrating the VCA/VCF chips, but Chris found a more elegant solution to make them self-regulate. The ninth value is a nonsense one that’s pushed out to trigger fluctuations in logic levels so that the other eight go through correctly. One of many kludges.
Going synchronous
In most new digital synths, and certainly everything that Chris designed between OSCar and Peak, the output DAC is driven at a constant rate: often, in Chris’s work, a weird choice derived from the system clock. The relationship between this rate and the pitch of the notes being played is completely arbitrary, so any wave tables need to be interpolated. A lot of care needs to be taken to do this well: particularly in the transition where the phase wraps around. Naive oscillators suffer from aliasing, which sounds unpleasant.
(If you’ve listened to a few old computer game soundtracks, the older uploads would alias horrendously. People who wrote sound trackers and chip-synth emulators in the early days have now either brought in experts to handle this stuff, or have spent some time learning the theory. I was casting for some examples on YouTube, and they now all sound fine.)
Fast computation is essential: most of Chris’s synths, from the Supernova to the Mininova via the A- V- and X-Stations he did for Novation, used the Motorola 56000 series of DSPs. The kind of power those chips enabled is cheap and abundant today. Pretty much every modest microcontroller comes with a free synchronous audio interface — most use a standard called I²S — designed precisely for a wide, fast, synchronous DAC. The Z80 is nowhere near fast enough to do the computation for this approach: as I wrote in last week’s post, it’s about 5% of the way to making a digital volume control.
So we’re stuck with 8-bit arithmetic and an 8-bit DAC. The best-case performance of an 8-bit DAC is one part in 256: around 50dB of signal-to-noise ratio. The way to make that sound good is to vary its sample rate continually. In OSCar, it’s always a power-of-2 multiple of the pitch we’re playing.

We don’t need to do any interpolation if we work like this: we’re essentially doing it in the time domain. Naive-looking waveforms like the ones above — OSCar’s actual tables — work just fine.
Making the audio frequency and the sampling frequency harmonically related is a special case of aliasing: all the quantising distortion occurs at harmonics of the note frequency, so it sounds intentional. That’s how OSCar gets away with it.
Counters, counters everywhere
When we scan a 256-word wave table to reproduce, say, middle C, the sampling frequency will be 256 times 261.63Hz: about 67.0kHz. Two conclusions follow from this simple calculation:
- That’s higher than the Compact Disc sampling frequency. OSCar can produce this kind of rate, just. We hit a performance ceiling somewhere around 70kHz where the data cannot be output quickly enough, and we compromise by skipping alternate samples in the wave table.
- To generate that sort of frequency directly from a 4MHz clock means dividing by about 59.7. We can only divide by integers, so if we accepted the worst-case performance for a divider of that level, it’d be about 1 part in 200, which is 8 cents. An octave higher, it would be 16 cents.
A couple of cents of pitch error (1/600th of an octave) is about the acceptable accuracy for a modern synth, which requires a clock accuracy of about one part in a thousand (2^(1/600) = 0.11%). To achieve that, we could start with a clock about a thousand times the speed of the highest frequency we’re trying to generate. If we’re maxing out around 70kHz, we’d need to start around 70MHz.
Circuit boards and chips of this era, built in the way OSCar is, aren’t going to handle 70MHz waves without upsetting the whole street’s FM radio reception. Rather than divide from a fast clock, Chris generated a slower clock at 8 times the audio frequency (261.63 x 8 = 2093Hz), and then added circuitry to multiply that frequency by 64x to bring it up to 134.0kHz. A couple of counters then divide that: one divides by two to make the 67.0kHz clock that drives the audio circuitry; another continually counts down from 256 to produce the wave table cursor.

All this ensures that the division factor is somewhat more than 1000 (4MHz / 2093Hz = 1911) which exceeds our pitch accuracy target. To manage all this, OSCar needs a few more components: a phase-locked loop surrounded by dividers to multiply the 2093Hz signal up, then divide it back down again to close the control loop, and a ton of counters to perform administration.
Suddenly the timer architecture gets complicated. There are seven separate counter/dividers in OSCar, spread across two chips:
- Intel 8253 counter 0. Sets the 244Hz time base for the Z80’s interrupt so all the control-rate logic happens regularly.
- Intel 8253 counters 1 and 2. These divide the 4MHz system clock into a simple multiple of the note frequency. Oscillator 1 and 2 respectively.
- Z80 CTC counters 0 and 2. For oscillators 1 and 2 respectively, these divide the 512x note frequency into the sample rate used by the system: usually it’s a divide-by-2 but higher pitches divide by as much as 16.
- Z80 CTC counters 1 and 3. For oscillators 1 and 2 respectively, these count down from (usually) 256, clocked at 256x the note frequency. These hold the indexes of the samples we’re currently reading out from memory.
All kinds of refinement are built into this, including two separate mechanisms for skipping samples in the wave tables as the frequency increases.
The clock multiplier also contains a complication: a mixed-signal hack that had me staring for days at the schematic in bewilderment, trying to understand why sections of the 4MHz clock were being chopped into the PLL control signal. Long story short: it improves the phase synchronisation between the processor and the multiplied-up signals.
We’re trying to replicate the sound and feel, not the component-level technology. But my duty here doesn’t stop at being a keyboard technician, or even just a synthesiser designer. Rather, there’s an unusual responsibility to create something new that sounds old. So it’s important to understand this stuff in a way that few people ever will.
The system clock on our new OSCar is 72MHz instead of 4MHz, which just about allows us to do away with the multiplier without losing the required precision. But I kept the external phase-locked loop in the new design for character: it’s nice to have a free-running VCO controlling the sample clock. My compromise was to change it from 64x to 8x.
All those counters are built into the microcontroller, which simplifies the rest of the circuit. And a lot of the firmware kludges to deal with high notes can be simplified because we now have the ability to decide where to put our play-head before we output each sample.
For very low pitches, the sample rate begins to enter the audio spectrum. This is a problem because you can hear that pitch clearly if you have reasonable high-frequency hearing. OSCar actually won’t play beneath the F two and a half octaves below middle C, which has a 11.8kHz sample rate. The new OSCar goes right down to MIDI note 0, more than two octaves beneath this, and we achieve that quietly by choosing a higher rate and repeating samples, which the old OSCar couldn’t do.
The RFSH hijack
The Z80A takes a microsecond, best case, to execute an instruction. If it were outputting 130,000 samples a second under its own control, the processor wouldn’t be able to do much else.
Chris circumvented this limit by making surreptitious use of a feature that the original Z80 was (to the best of my knowledge) the only microprocessor ever to include: refresh logic.
There’s two types of RAM, broadly speaking: static RAM, which is the bistable architecture with crossed gates that you’d remember if you took GCSE electronics:

Then there’s dynamic RAM, which is a single capacitor that stores whatever charge it’s told to (high or low), until it’s needed again.

Normally you’d use dynamic RAM in a project. It’s simpler and therefore cheaper. It uses less power when it’s working. But that convenience isn’t free. That capacitor needs to be read and rewritten fairly frequently or it’ll discharge and forget its data. During the time it’s being refreshed, of course, the processor cannot access it.
Fortunately, there’s a bit of time during each instruction fetch where the Z80 is not using the memory bus. As the timing diagram below shows, two clock cycles are spent fetching an instruction from memory; two more are spent decoding and executing it.
During the two cycles where the bus is idle, the Z80 puts its RFSH pin low, which signals to any connected logic that it has 500 nanoseconds to do some capacitor refreshing without having to halt the processor. It also chucks a number onto the address bus, which is a counter that increments on every instruction fetch and wraps at 127. The idea is that the designer might use this counter to simplify their refresh circuitry.

This cadence isn’t guaranteed, by the way: the hungriest regular instructions take around 20 clock cycles to execute. That’s five microseconds between RFSH events. With the need to keep two oscillators and the control voltages up-to-date, it explains the 70kHz sample rate limit.
OSCar uses static RAM. There are two reasons for this. The first is that, as long as we supply it with a voltage, it takes only a tiny amount of current to remember its contents indefinitely. With the aid of a rechargeable nickel-cadmium battery, the static RAM in OSCar holds its presets, waveforms, and sequences permanently even with the power off. The second reason to use static RAM is that we can hijack the RFSH signal and use it for another purpose.
In a crowded field, this is probably the most ingenious feature of OSCar, because it makes the two oscillators possible. The Z80 CTC chip, containing four of the counters we use, has its data pins wired to the address bus, not the data bus. We communicate with it by writing to specific addresses. Any data we put on the bus is ignored, and the Z80 cannot read back from it.

The reason for this peculiar wiring is that, during RFSH, a few logic chips wake up, one of which isolates eight bits of the address bus from the Z80 processor (which otherwise is the only device allowed to write to it). They also request the current value from the wavetable counter.
The count value finds its way, because of the novel wiring, onto bits A8 to A1 of the address bus. We let the Z80 control A0 as it toggles every time there’s a refresh cycle: the two wave tables are interpolated in memory. A15 to A9 are also set by the Z80, by some of the very first instructions the processor executes when it’s turned on:
0002 : LD A,6
0004 : LD I,A
This ensures that the upper byte of the address that appears during refresh is 0x06, which matches the place where we keep the wave tables, at addresses 0x600 to 0x7FF on that chip. Because the counters count towards zero, the waves are stored backwards in time. Which gets a lot more confusing than you think it would.
With the correct sample address on the address bus, more logic forces the RAM chip to output its data. The RAM puts this on the data bus a few nanoseconds later, whereupon the DAC is instructed to convert it.

A short interval later still, a delayed clock pulse goes high to load the converted voltage into the output amplifier.
TL;DR: There’s absolutely no code for reading out the wave tables. This was the high point of an era when a lot of firmware was essentially embodied in hardware. A small number of logic chips run the wave table readout in half-microsecond snatches while the Z80 is busy running its program.
When I’m asked, as I am occasionally, why we couldn’t build our new OSCar using one of the modern in-production variants of the Z80, and simply modernise the old code and fix the bugs, this is the most consequential of many answers. As Zilog refined the Z80, its architecture changed. Instruction fetches are now pipelined, which means that they happen while the previous instruction is being executed: four clock cycles become two. The newer chips also have 16-bit logic units, so most instructions will run in only one clock cycle: two cycles become one. The idle time was thrown away to speed up the chip, and the RFSH feature was the first thing to go. No chips, Z80 successors or otherwise, have it today. But they do, fortunately, all feature a single-instruction multiply.
It would be nice to summarise such a long post with a little audio demo. One day, I’ll revisit this and tail it off nicely. Unfortunately, the most important contextual difference between a blog post and a book chapter is that right now, I am in thrall to the exigencies of the day, and I’m excused from ending it well. Let’s reconvene after my deadlines.






