custom firmware
PRO-8000 0.9.0 · technical tour

How the firmware works

The PRO-800 makes its sound with eight fully analog voices. This firmware is the brain that plays them: it reads your hands and your MIDI, does the maths, and sets the voltages that the analog circuits follow. Here's how, from the circuit board up.

Built on what Music Tribe, Behringer's parent company, published in PRO800-Firmware-Packer: the main-board schematic and the packer that turns a firmware into an update the synth's bootloader accepts.

Wildly experimental: use it at your own risk, with no liability if it harms your hardware. The disclaimer

STM32F446 · 168 MHzWritten from scratch in CNo operating systemAbout 69 kB
01

The big idea: a digital brain for analog voices

Nothing digital ever touches the PRO-800's audio. Sixteen oscillators, eight filters and eight amplifiers on the voice board make the sound. They're analog circuits, steered by control voltages: a higher voltage on an oscillator raises its pitch, a higher voltage on a filter opens it.

The firmware's whole job is to decide those voltages and keep setting them, hundreds of times a second. When you play a note with vibrato, the firmware doesn't make a wobbling sound. It nudges the oscillator's control voltage up and down, and the analog oscillator wobbles by itself.

Think of it like thisThe voice board is an orchestra of eight players who can only follow hand signals. The firmware is the conductor: it never plays a note itself, but every note, swell and vibrato happens because it signalled it at the right moment.
Inputs (MIDI, panel, patch memory) feed the brain, which sets voltages through DACs and sample-and-hold circuits on the analog voice board; a tuning comparator feeds back. MIDI: USB, 5-pinnotes, clock, editor Front panel26 knobs, buttons Patch memory128 kB EEPROM The brain STM32F446 microcontroller • reads MIDI and the panel • runs envelopes, LFOs and the mod matrix, per voice • turns it all into numbers • 400 to 1,000 full passes every second numbers DACs + sample &hold numbers become voltages 41 CVs 7 gates Voice board 8 analog voices OSC A, B FILTERVCA audio tuning comparator: the brain can listen to every oscillator and filter
digital: numbers and codethe bridge: numbers to voltagesanalog: voltages and sound
Figure 1. The firmware lives entirely on the left. Everything it does reaches the sound through voltages and a few on/off switches, and the only thing it hears back is a tuning signal.
41control voltages kept fresh: 32 per voice, 9 shared
≈ 0.6 msbetween updates of each voice's volume (VCA), with all eight sounding
±0.7 ¢tuning across C1–C8 after autotune
≈ 69 kBthe whole firmware, of the 128 kB the bootloader accepts
02

What's on the board

The firmware talks to the hardware directly, register by register, with no vendor libraries. Everything it knows about the board came from Behringer's published main-board schematic and from measuring the synth itself. The voice board's circuit isn't published, so its behaviour (how many DAC steps make an octave, where the amplifiers start to open) was measured with test firmware and recordings.

Block diagram: USB, front panel, display chip and EEPROM connect to the STM32F446; it drives three DACs, a sample-and-hold stage and gate lines to the voice board, and reads a tuning comparator. MIDI inUSB: notes, clock, editor, updates5-pin DIN (UART4): notes, clock Front panel (inputs) 26 knobs → 3 analogmultiplexers → the ADC 14 latching switches and the3-way switch → input pins VALUE encoder → input pins Display, LEDs, 21 buttonsone HT16K33 chip, over I²C(software-driven bus) EEPROM · 128 kBpatches, sequences, tuning STM32F446 ARM Cortex-M4F at 168 MHz 128 kB RAM firmware ≈ 69 kB of a 128 kB slot What it runs, in one loop: • MIDI (USB, 5-pin) and SysEx • panel scan and display • sequencer, internal clock • synth engine: 8 voices, 4 envelopes each, 4 LFOs, 16-route mod matrix • the CV refresh • autotune (on request) Interrupts: a 1 ms tick, USB, MIDI IN, the tuning comparator. DAC80501 · 16-bitpitch A, pitch B, cutoff (24 CVs) On-chip DAC 2 · 12-bitthe 8 VCA levels On-chip DAC 1 · 12-bit9 shared: mixer, PW, resonance… SPI Sample & hold6 multiplexers → 41 capacitors which Voice board (analog)16 VCOs · 8 filters · 8 VCAs → mono gates Tuning comparatorhears each voice before master volume edges
Figure 2. The main board as the firmware sees it. Inputs on the left, the microcontroller in the middle, and on the right the path that turns numbers into the voltages the voice board follows.

A few details are worth knowing because they shape everything else:

  • Three converters for 41 voltages. One precise 16-bit DAC handles everything that must be in tune (both oscillators and the filter of each voice). Two 12-bit DACs built into the chip handle the volume of each voice and the nine controls all voices share.
  • Seven plain switches. Saw and triangle on each oscillator, hard sync, and the two poly-mod routings are on/off lines. Square waves are switched by moving the pulse-width voltage to its very end.
  • An ear on the voices. A comparator chip turns the voice signal into clean on/off edges the firmware can time. That's what makes autotune possible.
03

Three DACs, forty-one voltages

A DAC (digital-to-analog converter) turns a number into a voltage. But there are only three of them and 41 places that need a voltage. The trick is sample and hold: every destination has its own small capacitor (10 nF) that remembers a voltage, followed by a buffer amplifier so the voice board can read it without draining it.

To set one destination, the firmware:

  1. Puts the value on a DAC. For the 16-bit DAC80501 that means clocking out 24 bits, one at a time: exactly 48 µs, each bit timed from the chip's cycle counter.
  2. Picks the capacitor. Three address lines choose one of eight outputs on a multiplexer chip (a 74HC4051, an electronic rotary switch).
  3. Connects the DAC to the capacitor, and leaves it connected. The capacitor needs about 9 µs to settle and charge to 16-bit accuracy, but it isn't disconnected until something it's sampling is about to change, usually two bits before the end of the next value's frame. So the sampling hides inside the next write and costs no time of its own.
  4. Writes neighbours alongside. The three DACs feed different multiplexers, so while a pitch or cutoff samples at a voice's address, that voice's VCA (from an on-chip DAC) samples at the same address for free, and so does a shared control that happens to be due.
Two DAC80501 frames of 48 microseconds back to back; the channel written by the first keeps sampling through almost all of the second. An on-chip DAC write alone takes about 18 microseconds. Through the DAC80501 (pitch, cutoff): a 48 µs frame, and the sampling hides inside the next one frame n: 24 bits at 500 kHz · 48 µs frame n + 1: the next voltage channel n samples until 2 bits before frame n + 1 ends … and the VCA at the same address samples alongside, for free Through an on-chip DAC alone (a VCA, a shared control): about 18 µs write sample
Figure 3. Writes to scale. A pitch or cutoff value is a 48 µs frame on the DAC80501's serial link. Instead of waiting for the capacitor afterwards, the firmware leaves it connected while the next frame clocks in, so the sampling costs nothing. The DAC is rated far faster, but pro800 dac-test showed that on this board anything above about 0.6 MHz, about 1.65 µs per bit, garbles it, whatever drives the bus.
MultiplexerFed byHolds
U25DAC80501 (16-bit)Oscillator A pitch, voices 1–8
U32DAC80501Oscillator B pitch, voices 1–8
U43DAC80501Filter cutoff, voices 1–8
U24On-chip DAC 2 (12-bit)VCA level, voices 1–8
U23On-chip DAC 1 (12-bit)Poly-mod osc B amount, osc A and B level, noise, master volume, external filter
U15On-chip DAC 1Pulse width A and B, resonance

The catch: capacitors leak. A held voltage slowly sags (droops), so the firmware can never stop. It visits every capacitor again and again, forever. Below is that refresh in slow motion, in the firmware's real order.

 

Figure 4. Each bar is one held voltage; the small tick is the value the firmware wants. The write head (outlined bar) visits the capacitors one at a time, about a thousand times slower than real life. The droop is exaggerated enormously so you can see it: turn off Keep refreshing and watch every voltage sag. The VCAs are visited four times per pass because envelopes move fastest, mostly for free, alongside a pitch or cutoff at the same address.
Safety firstThe very first thing the firmware does after power-up, before even setting the clock, is disconnect every multiplexer. Otherwise a capacitor could sample a random voltage and a voice could scream before the firmware is ready.
Healing a bad bootOnce, after a flash, the synth came up with every oscillator and filter wrong while the VCAs were fine: one of the DAC80501's two setup frames had been garbled on this marginal bus, leaving the DAC at the wrong gain. It can't be read back to check, so since 0.8.5 the firmware re-sends its setup every 128th pass, about eight times a second, at a moment when no capacitor is sampling it. A bad boot now heals itself within a tenth of a second.
04

One loop, no operating system

There's no operating system and no task scheduler. The firmware is one loop that runs forever, doing the same jobs in the same order. Each trip around it is a pass:

  1. Read any MIDI that arrived over USB or the 5-pin MIDI IN (notes, controllers, and SysEx over USB), run the internal clock if that's the source, and advance the sequencer. MIDI clock doesn't wait for this: the interrupts handle it the moment it arrives.
  2. Scan the panel: the next step of the knob scan, the switches, the buttons, the VALUE encoder, Shift.
  3. Run the slow half of the engine: read the knobs, work out glide, drift, the macros and every route that doesn't need to be fast, and each voice's pitch and cutoff apart from what the envelopes and LFOs add.
  4. Update the display.
  5. Refresh the voltages, the long part, with four ticks inside it. Each tick reads MIDI again, advances the sequencer, moves every envelope and LFO one step, applies the routes from them, and writes the voltages that changed.

Only four things interrupt the loop: a 1 ms clock tick, the USB hardware and the MIDI IN socket's serial port (both timestamp each MIDI clock tick the moment it arrives), and the tuning comparator's edges (used only while tuning). Everything that touches the voices happens in the loop, so nothing can change a voice halfway through being worked out.

One pass of about 2.3 ms with eight voices sounding: a short engine part, then four ticks, each reading MIDI and stepping the envelopes and LFOs before writing two voices' pitches, the VCAs and every other tick the cutoffs, then the shared voltages.
engine and panelcutoffsVCAspitchesshared CVs
Figure 5. One pass to scale with all eight voices sounding, from the timing measured on the synth. The slow engine takes about 0.18 ms; the rest is writing voltages. Each tick (▼) reads MIDI, steps every envelope and LFO, and writes what moved, so the fastest-moving voltages are written most often. Fewer voices sounding means a shorter pass.

Why split the refresh like that? A pass takes about 2.4 ms with eight voices. If envelopes only moved once per pass, a snappy attack would be a staircase of 2.4 ms steps. So every envelope and LFO advances four times per pass, in the ticks, and the routes from them into pitch, cutoff and volume are applied there too:

VoltageWrittenUpdates about every (8 voices)(1 voice)
VCA (each voice's volume)at every tick0.6 ms0.3 ms
Filter cutoffevery other tick1.2 ms0.6 ms
Pitch A and Btwo voices per tick2.4 ms1.2 ms
Shared CVs (mixer, PW, resonance…)once per pass2.4 ms1.2 ms

Silent voices only need their capacitors topped up, so one of them is refreshed each pass, in turn, and passes get shorter when fewer notes sound. MIDI is read before every tick, so a note starts within a tick of its message rather than a pass, and when a voice starts a new note its pitch is written first, before its VCA opens, so you never hear a blip of the previous note.

The bus is the limitGliGli's Prophet-600 firmware, which this project used as a reference, updates everything in a 2 kHz timer interrupt. That's cheap there because the Prophet-600's DAC has a parallel bus. Here 32 of the 41 voltages go through one serial link to the DAC80501, and pro800 dac-test showed why it can't go faster: above about 0.6 MHz, about 1.65 µs per bit however the clock is split, the DAC receives wrong data. Something on the board, not in the code. So the firmware squeezes the frame to exactly 48 µs, hides the sampling inside the next frame and spreads the rest; a faster path would need a scope on the board.
05

From a key press to a voltage

Let's follow one note: you press A4 (MIDI note 69) on a keyboard plugged into the MIDI IN socket, with a little vibrato going. (Over USB the note comes from a computer instead; the path from step 2 on is the same.)

A note travels from MIDI through the sequencer, voice allocation, pitch maths in semitones and a per-oscillator tuning table to a sample-and-hold voltage.
Figure 6. Top: the path of a note. Bottom: the pitch maths for oscillator A at one moment. Every ingredient is in semitones, so combining them is plain addition. The CV is approximate: each oscillator's own tuning table gives a slightly different number.
  1. MIDI arrives. The chip's serial port (UART4) receives the three bytes at MIDI's 31,250 baud and queues them; the loop puts them back together into one message, including running status, where a keyboard leaves out repeated status bytes. Notes from USB arrive already packaged, and both go through the same code from here on.
  2. The sequencer looks first. If the patch's sequence is switched on for that key's layer, the key starts or transposes the sequence instead of playing a note directly.
  3. A voice is chosen. The layer mode decides which layer (or both) gets the note; that layer's voice mode (poly, mono or legato) and note priority decide which voice. In the per-channel modes (eight mono channels, MPE) the MIDI channel picks the voice directly. The voice records the note, its velocity and a fresh random value, and its four envelopes start.
  4. The engine works out pitch in semitones. For every voice it adds up the gliding note, pitch bend, LFOs, mod routes, unison spread and drift; the slow parts once a pass, the envelope and LFO parts in every tick. If a scale is set, the result snaps to it. Then each oscillator adds its own FREQ setting, and oscillator A adds the poly-mod envelope.
  5. The tuning table turns semitones into a number. Each of the 16 oscillators and 8 filters has its own measured table (next section).
  6. Sample and hold. The number goes onto the right capacitor, and the analog oscillator follows it.

Filter cutoff works the same way: the cutoff knob, keyboard tracking, LFOs, routes and drift are added in semitones, the filter envelope is added on the fast path, and the filter's own table turns the sum into a voltage. Because the filters are measured the same way as the oscillators, a cutoff can follow the keyboard exactly, and a self-oscillating filter plays in tune.

06

Autotune: measuring every oscillator

No two analog oscillators are alike. Send the same voltage to all sixteen and you get sixteen different pitches. Measured on this synth before tuning, they spread from 77 cents flat to 63 cents sharp, more than a semitone end to end:

Figure 7. Measured on this PRO-800: all 16 oscillators at the same CV (0x8000), in cents from their average (about 339 Hz). After autotune every oscillator is within ±0.7 cents from C1 to C8, a band thinner than the zero line drawn here.

So the firmware measures each one. Press Tune (or let it run by itself the first time) and, for each oscillator in turn, it:

  1. opens only that voice's VCA and plays a sawtooth on just that oscillator;
  2. sets its CV to one of 14 measuring points (0x2000, 0x3000 … 0xF000);
  3. listens through the tuning comparator: every falling edge of the saw is timestamped with the chip's 168 MHz cycle counter, about 6 ns resolution;
  4. takes the median interval between edges as the period, which ignores the odd stray edge from a noisy comparator.

The filters are measured the same way, self-oscillating at full resonance with both oscillators muted, and since 0.8.4 pro800 check verifies them too: on this synth the eight filters match each other within about 6 cents across the keyboard. The tuning signal is taken after each voice's VCA but before the master volume, so tuning is silent: you can turn the volume down and it still works. All of it takes about 25 seconds.

Figure 8. An illustration of one oscillator's table. The firmware stores the measured pitch at each point. To play a note it finds the two points either side and draws a straight line between them in log frequency (octaves), which matches how an exponential oscillator responds. Points that look wrong are thrown out while measuring, sweeping down from the top.
The resultUntuned, oscillators were up to ±120 cents off across the keyboard. After autotune, all 16 are within ±0.7 cents from C1 to C8. For comparison, the stock firmware measured on the same synth was off by 2–8 cents at C2, C4, C6 and C7. The tables are saved in the EEPROM, so they survive firmware updates; an update that changes how the voltages are written re-tunes once, by itself.
07

Inside the sound engine

Voices, layers and shared wires

The engine keeps two complete sets of the per-voice settings, called layers. Layer 1 plays voices 1–4 and layer 2 plays voices 5–8 (layer 1 gets all eight when layers are off, and a mono layer takes one voice and leaves the other seven to its partner). Some controls, though, are a single wire for all eight voices on the hardware. Those can't differ between layers, so they're shared.

Layer 1 settings drive voices 1 to 4, layer 2 settings drive voices 5 to 8, and a set of shared wires reaches all eight voices. Layer 1 FREQ A/B, FINE, CUTOFF,ENV AMT, four ADSRs, GLIDE,two LFOs, PMOD FIL ENV,Macro 1 knob, 16 mod routes Layer 2 its own copy of everyper-layer setting, its ownLFOs, shapes and routes Shared wires waveform switches, sync mixer: A, B, noise levels resonance pulse width A and B poly-mod osc B amount poly-mod routing buttons master volume One voltage or switch for all eight voices, so one value.
Figure 9. Per-layer settings reach their own four voices; the shared wires reach all eight. When a mod route targets a shared wire, it takes its value from the layer's most recently played voice.

The layer modes only change how notes are given out: off (layer 1 on all eight voices), split (layer 1 below a split note, layer 2 from it up), stack (every note on both layers) and channel (MIDI channel 2 plays layer 2, every other channel layer 1). Two more give one sound a voice per MIDI channel: 8CH (channels 1–8 each own one voice, mono, with their own bend, pressure and CC 74) and MPE (channel 1 is the master, channels 2–9 each play one voice with 48 semitones of bend).

Envelopes with an analog shape

Every voice has four ADSR envelopes: filter, amp, Env 3 and Env 4. By default they're shaped like the envelope chips in classic polysynths: the attack charges towards 1.5 and stops when it reaches 1, so it shoots up and eases into the top. Decay and release fall exponentially, and their times are measured to −60 dB, so a release that says 2 s really is gone at 2 s. Each envelope can also take a linear curve or a swell, add a delay and a hold (DAHDSR), start from key up instead of key down, or cycle; those are the same formulas with different stage orders.

Curve:
Figure 10. One envelope, drawn by the same formulas the firmware uses. Analog: the dashed curve is where the attack is heading, and cutting it off at 1 gives the punchy analog shape. Linear: every stage is a straight line that covers full scale in its time. Swell: the attack grows by a factor of 32 over its time, so it starts slowly and accelerates, like a bowed note.

Each time knob follows t = min + (max − min) · (212k − 1) / 4095 for a knob position k from 0 to 1. That puts the useful short times in the lower half of the knob instead of crushing them at the bottom: attack 0–10 s with 150 ms in the middle, decay and release 3 ms–20 s with 310 ms in the middle.

One more measured detail: the voice VCAs stay silent until their control voltage reaches about 7–9 % of its range. If the envelope were sent straight through, every release tail would cut off early. So the firmware maps the envelope onto the range from 7 % to full, and gives a silent voice exactly zero.

LFOs that follow a clock

MIDI clock sends 24 ticks per quarter note, and real clocks jitter. Jumping the LFO at every tick would make it step; ignoring the ticks would let it drift off the beat. So the USB and MIDI IN interrupts count and timestamp every tick the moment it arrives, the firmware averages the time between ticks to know the tempo, and between ticks it works out the position from the tick count plus the time since the last one. The LFO moves smoothly and stays on the grid. After MIDI Start, the next tick is the downbeat, so the LFO lines up with the bar; Continue and Song Position are honoured, and if the clock stops the LFO carries on at the last tempo. When the clock is the firmware's own (tap the tempo on Sync Clock) or the SYNC IN jack, a generator feeds the same tick counter, stamped from the cycle counter, so LFOs, looping envelopes and the sequencer always see one steady clock, and the Sync Clock LED blinks on its beat.

Jittery MIDI clock ticks above, and a smooth LFO locked to the beat below.
Figure 11. Top: one beat of MIDI clock, slightly uneven, as it really arrives. Bottom: an LFO at 1/8, smooth, and still landing on the beat. Measured on the synth at 1/4 triplets and 120 BPM: 27 flips averaged 0.1667 s apart, exactly the expected value.

Each LFO keeps a phase, a position through its cycle from 0 to 1. In the per-voice retrigger mode, every voice keeps its own phase, started at its own note-on. That's cheap, because LFOs are added in software to each voice's pitch and cutoff. Pulse width is one shared wire, so LFO → PW always uses the shared phase. Each LFO also has a delay and a fade-in: a gain per voice that stays at zero after the note starts and then rises to 1, so vibrato can arrive late without a route.

The mod matrix: adding things up per voice

Each layer has 16 routes. A route is just three numbers: a source (one of 27), a destination (one of 46), and a depth from −99 to +99. For every voice, the engine evaluates each route and adds source × depth to the destination: routes from envelopes and LFOs into pitch, cutoff and the VCA in every tick, the rest once a pass. Because the sources are per voice too (that voice's velocity, its envelopes, its random value, its pressure, its place in the layer), one route gives every note its own amount.

A velocity to cutoff route at depth 40 gives four notes four different cutoff offsets, while a velocity to resonance route can only follow the most recently played note.
Figure 12. Left: one route, velocity → cutoff at +40, opens each note's filter by its own amount (up to 96 semitones × 40/99 at full velocity). Right: resonance is a single wire, so a route to it follows the newest note only.

A few destinations get special treatment so they're musical:

  • Pitch routes use a squared depth curve: depth 10 is a quarter of a semitone, fine enough for vibrato, while 99 is still two octaves.
  • VCA routes multiply the amp envelope instead of adding to it, so a route can never open a voice that isn't playing. Velocity → VCA at 99 is plain velocity sensitivity.
  • LFO rate routes are per voice in per-voice mode (harder notes can have faster vibrato), and on a clock-synced LFO they sweep smoothly off the grid, then the LFO slides back onto the beat when the modulation stops.
  • Envelope stages and glide are destinations too: a route scales that time by up to 16× either way, per voice, so velocity → attack time makes hard notes snap while soft ones swell.
  • Macros are a source and a destination at once. Everything routed into Macro 1 is summed with a hand-set offset and the M TUNE knob, which is Macro 1's own knob now (master tune is gone; autotune keeps the voices in tune), and the macro fans out to any number of destinations. Macros are worked out once a pass.
  • Morph fades every knob of the layer towards a second patch before the engine reads the knobs at all.
08

The panel: knobs, pickup and four digits

24 of the 26 knobs sit behind three 8-way multiplexers. Each knob has a 100 nF capacitor at the multiplexer, so after switching address the reading needs about 4 ms to settle. The scan doesn't wait for it: it steps to the next address every 4 ms, between passes, and reads all three multiplexers at once, so every knob is read every 32 ms. A small dead band ignores the last bit of jitter, and values are smoothed over 10 ms so a turn never zips.

Two sets of settings (layers), two LFOs and four envelopes all share the same physical knobs. So when a knob's job changes (you load a patch, switch layer, or hold Shift), it goes into pickup: the sound keeps the stored value until you turn the knob onto it or past it. Try it:

Display: 70.  

Figure 13. The dot after the number means the knob hasn't picked up the stored value yet. Within 1.5 % of it, or once you sweep past it, the knob takes over.

Shift is the Sync Source button, held or latched with two quick presses. Under Shift the filter ADSR knobs edit Env 3 and the amp ADSR knobs Env 4, with pickup, and every other knob nudges a secondary value (LFO delay and fade, drift, unison detune, bend range, the macro offsets) by how far it moves, so nothing jumps and nothing needs picking up. The buttons get second jobs too: compare the edit with the stored patch, undo a load, save to the current slot, copy a layer, open a settings page, panic.

The four-digit, seven-segment display shows real units while you turn a knob: 737 Hz of cutoff, 1.25 seconds of attack, -12 semitones, or a clock division like 1-16. Several buttons have new jobs, since the stock arpeggiator and sequencer are gone:

ButtonNow does
Seq 1 / Seq 2Choose the layer the knobs edit
Arp Up-DnChoose LFO 1 or LFO 2 for the LFO knobs and buttons
Arp AssignMOD ASSIGN: build mod routes from the panel; hold it to browse them
Sync SourceShift: hold, or double-press to latch
Sync ClockTap the internal clock's tempo; hold to restart the bar; Shift + press cycles the clock source. Its LED blinks on the beat
Rec + Seq 1Record sequence steps from the notes you play
LFO ShapeStep through nine shapes
SettingsA menu on the number keys: sync, retrigger, layers, envelope modes and curves, bend range, detune, voice mode, drift
PerfLoad a plain init sound
09

Where things are stored

There are two memories. The chip's own flash holds code. A separate EEPROM chip holds your sounds, and it's the only memory that survives a firmware update untouched.

Flash map: a write-protected bootloader, then up to 128 kB for this firmware across sector 4 and half of sector 5, about 69 kB used. EEPROM map: 128 patch records with their sequences, the stock factory bank, global settings and tuning tables. Microcontroller flash · 256 kB Bootloader64 kB · write-protected This firmwareup to 128 kB: sector 4 and half of 5 · ≈ 69 kB used (shaded) Rest of sector 5erased with every update EEPROM · 128 kB 128 patch records768 bytes each: the patch ("P8P2", 512 bytes) and its step sequence ("P8S2", 256 bytes), each with its own checksum Factory bank100 stock sounds global block (last patch, clock, CC numbers) + autotune tables (last 3 kB) 0x000000x180000x190000x1FFFF
Figure 14. Both maps to scale. The bootloader erases flash sectors 4 and 5 on every update, which is why the tuning tables moved to the EEPROM; the firmware may use the first half of sector 5, which 0.8.4 tested, so it has room to grow.

A patch record holds both layers' knobs, Env 3 and 4, LFO 2, the latching buttons, all the settings (layer mode, LFO sync, retrigger, shapes, step patterns, delays and fades, envelope modes, curves, delays and holds, voice modes, drift, scale, morph target, macro offsets), both layers' 16 mod routes and a 16-character name, and in its second half the step sequence, with its own checksum so it can be written on its own. New fields take reserved bytes, and an older record reads them as zero, which always means "what older firmware did". The one break was 0.8.0, which went from 200 patches of 256 bytes to 128 records of 768: the first start of 0.8.0 wiped the old records (the EEPROM backups keep them).

The stock factory bank is left exactly where the stock firmware put it, and any factory sound can be converted into a slot. Before this firmware first wrote to the EEPROM, a full image of it was saved: writing that image back is the way home to stock.

10

MIDI in: USB, SysEx and the 5-pin socket

The USB driver is written from scratch for the chip's USB hardware and shows up as a standard class-compliant MIDI device. It reports Behringer's own IDs, the name "PRO 800" and the same serial number the stock firmware used, so a Mac treats it as the device it already knows. Notes play on any channel.

Everything beyond notes and controllers travels as SysEx, MIDI's "system exclusive" messages. They start with Behringer's header F0 00 20 32 00 01 24 00, then a command byte. For example, 08 00 asks for the firmware version, and the synth answers 09 00 00 09 00 (0.9.0). The firmware understands dozens of commands: read or set any parameter or setting, read the panel, list, load, save and rename patches, import factory sounds, read and write mod routes and the sequence, run autotune, report timing, and the two DAC probes.

The 5-pin MIDI IN socket works too, from 0.7.6. Its opto-isolator feeds the chip's UART4 serial port, which receives at MIDI's 31,250 baud and interrupts on every byte. Clock ticks go straight to the clock, timestamped like USB's; everything else is queued and turned into the same packets USB delivers. It carries notes, controllers, pressure, bend, program changes and clock, so a keyboard with a MIDI out plays the synth with no computer. SysEx stays on USB.

The USB socket itself is a device port, like a printer's: the synth waits for a computer to talk to it, and it can't power or host a USB keyboard. A USB-only controller needs a computer, or a small USB MIDI host box, in between.

The command-line tool, the web editor and MIDI apps talk to the firmware over one USB MIDI port; a keyboard with a MIDI out plays it through the 5-pin MIDI IN socket. pro800 tool (macOS) Web editor (Chrome, WebMIDI) DAW, Ableton Move, apps USB MIDI port"PRO 800" This firmware notes, bend, CCs, pressure, clock SysEx: parameters, patches, routes, sequences, tuning, timing, updates answers on the same port 5-pin: notes, bend, CCs, pressure, program change, clock Keyboard with a MIDI out MIDI IN socket5-pin DIN, UART4
Figure 15. Two ways in. The USB port serves three kinds of client, and the web editor can forward another MIDI input (such as the Move) to the synth. The 5-pin socket takes a keyboard directly, and both can be used at once.
11

Updating safely

The PRO-800 has a small bootloader at the start of its flash. It's write-protected and nothing here ever touches it, so the synth can always be recovered. It accepts an image of up to 128 kB and erases flash sectors 4 and 5 before programming it. Installing a firmware goes like this:

Update sequence between the pro800 tool, this firmware and the bootloader.
Figure 16. pro800 install does all of this in one command. The erase runs from RAM, because code can't run from the flash sector it's erasing.
If anything goes wrongHold buttons 0 and 7 while switching on. That starts the bootloader directly, and any firmware file can be flashed again: this one, or the stock firmware through Behringer's SynthTribe. Never connect a debugger to unlock the flash: that would erase the bootloader too.
12

What happens at power-on

The bootloader jumps into the firmware with its own clocks, interrupts and peripherals still running, so the first job is to put the chip back into a known state. Then, in order:

  1. Disconnect every sample-and-hold. All multiplexer enables go high so no capacitor can sample garbage.
  2. Clocks. The 8 MHz crystal is multiplied up to 168 MHz, with the 48 MHz USB needs.
  3. Timers and memory. The 1 ms tick and tuning timer start; master volume is set to zero; the EEPROM, panel and patch store come up.
  4. Patch store and tuning tables. If the EEPROM is still in an older layout of ours, the patch area is formatted first (ForM, about 2 s). The tuning tables are loaded, and the engine starts.
  5. Charge every capacitor. The whole refresh runs 20 times.
  6. Display and LEDs. The power LED lights, and the version shows for a moment.
  7. No tuning tables, or tables from a firmware that wrote the voltages differently? Then it tunes now, silently, showing tUnE, before anything else.
  8. Load the last patch, and the clock source and tempo. First comes one full knob scan, so pickup starts from the real knob positions.
  9. MIDI IN and USB start. Then the main loop runs forever, refreshing the watchdog on every pass.
13

What firmware can't change

Firmware decides voltages and switches; it can't rewire the voice board. These limits are set by the hardware:

Can'tBecauseWhat works instead
A different waveform, pulse width or resonance per voice or per layerEach is one wire or switch for all eight voicesPitch, cutoff and volume are per voice, and a route to a shared control follows the newest note
Mix two waveforms of one oscillator at different levelsWaveform buttons are on/off linesPut the second waveform on the other oscillator and use its level
Host a USB keyboard plugged straight into the synthThe USB socket is a device port, and the chip runs its USB in device modeThe 5-pin MIDI IN socket, or a computer or USB MIDI host box in between
Send the layers to separate outputsThe voice board sums all voices into one mono signalPer-layer volume with the VCAs; a hardware mod would be needed for more
Digital FM or effects at audio rateThe firmware never sees the audio, and voltages update every 0.3–2.4 msThe analog poly-mod path (osc B and the filter envelope to osc A and the filter) is audio rate

Within those walls there's a lot of room. Most of what makes a sound move (pitch, cutoff and volume, per voice, from any combination of sources) is pure software. The companion page, New territory for sound design, is about what to do with that room.