Skip to content

Commit

Permalink
Allow SysEx to pass through to mGB
Browse files Browse the repository at this point in the history
Allows SysEx messages of type 0x70 to pass through to mGB
  • Loading branch information
tstirrat committed Sep 27, 2024
1 parent 5bb05a9 commit ac30761
Showing 1 changed file with 71 additions and 1 deletion.
72 changes: 71 additions & 1 deletion Arduinoboy/Mode_MidiGb.ino
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ void modeMidiGb()

if(!checkForProgrammerSysex(incomingMidiByte) && !usbMode) serial->write(incomingMidiByte); //Echo the Byte to MIDI Output

if(incomingMidiByte & 0x80) {
if(incomingMidiByte & 0xF0) {
switch (incomingMidiByte & 0xF0) {
case 0xF0:
midiValueMode = false;
Expand Down Expand Up @@ -119,6 +119,9 @@ void sendByteToGameboy(byte send_byte)
}
}

// Are we capturing SysEx bytes?
bool isSysexMessage = false;

void modeMidiGbUsbMidiReceive()
{
#ifdef USE_TEENSY
Expand Down Expand Up @@ -195,6 +198,13 @@ void modeMidiGbUsbMidiReceive()
do
{
rx = MidiUSB.read();

maybePassThroughSysex(rx.byte1);
maybePassThroughSysex(rx.byte2);
maybePassThroughSysex(rx.byte3);

if (isSysexMessage) continue;

uint8_t ch = rx.byte1 & 0x0F;
boolean send = false;
if(ch == memory[MEM_MGB_CH]) {
Expand Down Expand Up @@ -264,3 +274,63 @@ void modeMidiGbUsbMidiReceive()
} while (rx.header != 0);
#endif
}

#define MIDI_SYSEX_BYTE 0xF0
#define MIDI_SYSEX_EOF 0xF7

#define SYSEX_ID_NON_COMMERCIAL 0x7D

// What MFG id did we find, if we find the mGB one, we'll pass through all the bits
byte capturedSysexId = 0x00;

// Passes through sysex messages to the GB if they are of the form:
// `0xF0 0x7D ..... 0xF7`
void maybePassThroughSysex(byte incomingMidiByte) {
// byte 1 - Check for SysEx status byte
if (!isSysexMessage && incomingMidiByte == MIDI_SYSEX_BYTE) {
isSysexMessage = true;
capturedSysexId = 0x00; // prompt check for mfg_id
blinkLight(0x90+2, 1);
return;
}

if (!isSysexMessage) return;

// byte 2 (mfg_id)
if (capturedSysexId == 0x00) {
capturedSysexId = incomingMidiByte;

// only if it's the right id
if (capturedSysexId == SYSEX_ID_NON_COMMERCIAL) {
// replay Sysex status byte, since we skipped it
sendByteToGameboy(MIDI_SYSEX_BYTE);
delayMicroseconds(GB_MIDI_DELAY);
blinkLight(0x90+2, 1);

// forward current byte (mfg id)
sendByteToGameboy(capturedSysexId);
delayMicroseconds(GB_MIDI_DELAY);
blinkLight(0x90+2, 1);
}
return;
}

// stop passthrough, wrong id
if (capturedSysexId != SYSEX_ID_NON_COMMERCIAL) {
isSysexMessage = false;
capturedSysexId = 0x00;
return;
}

// stop passing through, EOF
if (incomingMidiByte == MIDI_SYSEX_EOF) {
isSysexMessage = false;
capturedSysexId = 0x00;
}

// send bytes (incl EOF)
sendByteToGameboy(incomingMidiByte);
delayMicroseconds(GB_MIDI_DELAY);
blinkLight(0x90+2, 1);

}

0 comments on commit ac30761

Please sign in to comment.