I've wondered for a while how exactly the CPU of the DR-220 controls its gate array. The CPU handles the screen, buttons, and triggers. The MB670120 gate array controls ROM, RAM, and the DAC + multiplexer for playing sounds. Interestingly, the two are separated onto different boards that are joined by a pin header. This makes it very easy to separate them and experiment.
Pinout
The service manual tells us the connections on the header, but it lists the pins in no particular order. Here they are laid out in the order they appear on the board. The signals of interest are underlined, while the others are in grey.
General Communication
The manual also explains the mechanics of communication, but not the significance of it. The gate array determines what sounds to play based on the contents of RAM, and the CPU accesses RAM/ROM through the gate array.
The CPU can't directly tell the gate array to do anything besides access memory for it. This means there's no instruction to "play a sound right now". Instead, it simply tells the gate array to store a specific value in a specific range of memory. A split second later, the gate array reads back the value, and plays the corresponding sound.
Timing
The timing is provided by the manual. We're also told what signals are involved. I've redrawn the diagram here.
We have a parallel bus, but no dedicated address lines. Instead the bus is multiplexed, similar to some CPUs like the 8085. We specify a 16 bit address, one byte at a time. First the high byte is put on the bus, then the ALEH signal is brought low. This latches our values into an internal address buffer. The same is done for the low byte of that address and ALEL. The data is then put on the bus, and finally we strobe the write line. This stores a value into RAM.
Curiously, the CPU can't read from RAM; Only the gate array can. This helps show that the RAM access is really just a way to communicate with the gate array.
Addresses
The last bit of info that the manual gives us is the range of addresses (0-5), though it doesn't exactly say what they do. It turns out these 6 addresses correspond to 6 outputs(channels) of the multiplexer. Different samples(instruments) are hardcoded to these channels. Since we have 11 instruments, some have to strategically share channels.
Data
So, what values do we put in the addresses to play sounds? The manual has no more answers.
By connecting a logic analyzer to our header, we can see the values sent to the gate array. With a little experimentation, it becomes obvious what the different values correspond to.
A single byte per address specifies the volume, pause/play status, and instrument for the channel. That's really all we really need.
- The most significant bit appears to have no impact
- The next 3 MSBs set the volume (The range is greater than what the CPU actually uses)
- The next bit says if the channels should be playing or not
- The last 3 bits specify the instrument
Wrapping up
Now that we have the pinout, protocol, memory map, and packet structure, we can play some drums! The bus is parallel, the speed is relatively slow, and the timing is forgiving, so most old CPUs should have no problem talking to the gate array. Newer microcontrollers should have it easy too, besides coming up with a dozen outputs. Since we're using the bus in only one direction, we can use a shift register to get extra outputs.
Now we can interface anything an arduino can be connected to. This opens up the machine immensely, given that it started with only a trigger in/out. MIDI would be an easy choice, but the sky is the limit.