Nuke.YKT's OPL3 protocol - DhrBaksteen/ArduinoOPL2 GitHub Wiki
Nuke.YKT's OPL3 protocol can be used to send OPL2 or OPL3 data over a serial line. The protocol encodes the address and data byte pairs in 3 bytes and adds a marker in bit 7 of the first byte to detect the start of a transfer.
The structure of a transfer is as follows:
Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|
Byte 0 | 1 | 0 | 0 | 0 | A9 | A8 | A7 | A6 |
Byte 1 | 0 | A5 | A4 | A3 | A2 | A1 | A0 | D7 |
Byte 2 | 0 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
- A8 determines the bank of the OPL3 chip. For OPL2 this bit is always 0.
- A9 determines the synth unit of the OPL3 Duo. 0 addresses the left chip, 1 addresses the right chip. For OPL2 this bit is left as 0.
Some example code on how a transfer can be encoded:
/**
* Encode a data write such as used by the OPL2 Audio Board and OPL3 Duo.
*
* @param bank - The synth unit (bit 1) and OPL3 bank (bit 0). Set to 0 for OPL2 Audio Board.
* @param address - The address to write to.
* @param data - The data we want to write.
*/
void encodeNukeYKT(byte bank, byte address, byte data) {
byte byte0 = 0x80 | ((bank & 0x03) << 2) | (address >> 6);
byte byte1 = ((address & 0x3F) << 1) | (data >> 7);
byte byte2 = data & 0x7F;
}
Following example can be used to decode the encoded bytes. Assume that we're already detected the marker bit in byte0.
/**
* Decode NukeYKT encoded bytes into bank, address and data bytes for the OPL2 Audio Board or OPL3 Duo.
*
* @param byte0 - First received byte with marker bit (7) set.
* @param byte1 - Second received byte.
* @param byte2 - Third received byte.
*/
void decodeNukeYKT(byte byte0, byte byte1, byte byte2) {
byte bank = (byte0 & 0x0C) >> 2;
byte address = ((byte0 & 0x03) << 6) | ((byte1 & 0x7E) >> 1);
byte data = ((byte1 & 0x01) << 7) | (byte2 & 0x7F);
}