
It's alive! PicoFaceD5 — Roland D-50 LA synthesis on an RP2350, built from the machine's own firmware
Hey everyone,
The tenth instrument in my RP2350 collection is running: PicoFaceD5, a Roland D-50. Bare metal, 32 kHz, no OS, same board and same core as the other nine.
What it actually is
Not a chip emulation. It is a native LA engine over the D-50's own PCM data: sampled attacks dovetailed with synthesized sustains, the seven structures with their ring modulator, three tone-global LFOs, the pitch envelope, and the common block's EQ, chorus and reverb. Sixteen voices on one tone, eight and eight when both play.
The part I did not expect to get
I disassembled the machine. The program EPROM and the internal ROM of its uPD78312 went through MAME's 78K/III debugger, and once that worked, measuring things by ear stopped being the method. Out of the ROM and into the engine, byte for byte:
- the envelope arithmetic — a rate index per segment, and a time law that compensates the level distance so the inner segments come out time-constant
- the release, which is rate-constant, not time-constant: the distance lookup is computed and then overwritten. Dead code in a 1987 ROM.
- the pitch constant, the keyfollow and depth tables, the LFO rate law and its two-phase delay, portamento, aftertouch, the bender modes, the TVA level basis
- the voice allocator: one pool of sixteen slots, all sixteen to the upper tone in whole mode, and a free list that makes the machine drop a new note when it is empty rather than steal a held one. I had it stealing, like everyone does. The firmware says otherwise.
Two things the firmware settled that I had wrong
The sawtooth is an octave up. The LA32 builds a saw as square ⊗ cosine, so the ring comb only carries even harmonics of the base — the MT-32 compensates for that in its control ROM, and I copied that. The D-50's pitch path never reads the waveform. Captures of a real machine confirm it: same key, square at 262 Hz, saw at 524. And the factory bank is written around it — the squares sit an octave above the saws in every unison layer.
Pulse width 0 is an honest square, not a needle pulse. I had the law inverted, which put the fundamental 22 dB down on every patch that used it. Pipe Solo was the giveaway.
The samples
100 PCM waves, 512 KB total. Every loop turns out to be a power-of-two number of words holding a power-of-two number of cycles, so every root frequency lands exactly on 32000/2^k — 15.625, 31.25, 62.5, 125, 250, 500, 1000 Hz, nothing else. Their geometry is in the program ROM too: a start page and a length class per wave, which also resolved the 24 combination waves that had been silent.
What it will not do
The reverb is not the D-50's. That chip holds 32 types of coefficients in silicon and the firmware says nothing about them, so the 32 panel types stand on the MT-32's Boss RRV-10 topology, which the munt project read out — same era, same Roland department. Right character, not the original impulse response. Chorus and EQ are the same deal.
Practical
- MIDI: the D-50's own CC list, read out of its dispatch table (1, 5, 6, 7, 38, 64, 65, 98-101), plus the hold pedal and Roland exclusive — DT1 in, RQ1 answered, so an editor can program it and a librarian can pull a bank back out
- 884 KB of flash, 264 KB of RAM. It is the one sample-based instrument in the collection that fits a 4 MB board.
- Hardware is the same as the rest: I2S DAC, 128x64 SH1106 OLED over I2C, three encoders, USB and DIN MIDI. Board target is sparkfun_promicro_rp2350.
One catch, and it is the reason there is no download. It needs a D-50 ROM set, which is not mine to distribute, so this one is not in the release binaries — the eight that are unaffected still build and flash as before. Put your own dumps in roms/ and it builds; without them the configure step skips it and says so. GPL-3, like the rest.
https://github.com/Michi71/PicoVintageSynthCollection
Happy to go into any of it. The disassembly notes are in the repo.