summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/portmedia/pmmidi.c
diff options
context:
space:
mode:
author R. Belmont <rb6502@users.noreply.github.com>2013-02-03 21:26:37 +0000
committer R. Belmont <rb6502@users.noreply.github.com>2013-02-03 21:26:37 +0000
commit70a9d274aca683ae6a9a5522ac7162f931c76453 (patch)
tree28fa8c16db389ad17ad5f20731e6288b0e595227 /src/osd/portmedia/pmmidi.c
parent7731ec7923b1e365ccfc7c72b98aca4678757909 (diff)
MIDI: preliminary SysEx reception support [R. Belmont]
Diffstat (limited to 'src/osd/portmedia/pmmidi.c')
-rw-r--r--src/osd/portmedia/pmmidi.c113
1 files changed, 78 insertions, 35 deletions
diff --git a/src/osd/portmedia/pmmidi.c b/src/osd/portmedia/pmmidi.c
index 4321652dfaa..222941509d5 100644
--- a/src/osd/portmedia/pmmidi.c
+++ b/src/osd/portmedia/pmmidi.c
@@ -24,6 +24,7 @@ struct osd_midi_device
UINT8 xmit_in[4]; // Pm_Messages mean we can at most have 3 residue bytes
int xmit_cnt;
UINT8 last_status;
+ bool rx_sysex;
};
void osd_list_midi_devices(void)
@@ -192,46 +193,88 @@ int osd_read_midi_channel(osd_midi_device *dev, UINT8 *pOut)
for (int msg = 0; msg < msgsRead; msg++)
{
UINT8 status = Pm_MessageStatus(dev->rx_evBuf[msg].message);
- switch ((status>>4) & 0xf)
- {
- case 0xc: // 2-byte messages
- case 0xd:
- *pOut++ = status;
- *pOut++ = Pm_MessageData1(dev->rx_evBuf[msg].message);
- bytesOut += 2;
- break;
- case 0xf: // system common
- switch (status & 0xf)
+ if (dev->rx_sysex)
+ {
+ if (status & 0x80) // sys real-time imposing on us?
+ {
+ if ((status == 0xf2) || (status == 0xf3))
{
- case 0: // System Exclusive
- printf("No SEx please!\n");
- break;
-
- case 7: // End of System Exclusive
- *pOut++ = status;
- bytesOut += 1;
- break;
-
- case 2: // song pos
- case 3: // song select
- *pOut++ = status;
- *pOut++ = Pm_MessageData1(dev->rx_evBuf[msg].message);
- *pOut++ = Pm_MessageData2(dev->rx_evBuf[msg].message);
- bytesOut += 3;
- break;
-
- default: // all other defined Fx messages are 1 byte
+ *pOut++ = status;
+ *pOut++ = Pm_MessageData1(dev->rx_evBuf[msg].message);
+ *pOut++ = Pm_MessageData2(dev->rx_evBuf[msg].message);
+ bytesOut += 3;
+ }
+ else
+ {
+ *pOut++ = status;
+ bytesOut++;
+ }
+ }
+ else // shift out the sysex bytes
+ {
+ for (int i = 0; i < 4; i++)
+ {
+ UINT8 byte = dev->rx_evBuf[msg].message & 0xff;
+ *pOut++ = byte;
+ bytesOut++;
+ if (byte == MIDI_EOX)
+ {
+ dev->rx_sysex = false;
break;
+ }
+ dev->rx_evBuf[msg].message >>= 8;
}
- break;
+ }
+ }
+ else
+ {
+ switch ((status>>4) & 0xf)
+ {
+ case 0xc: // 2-byte messages
+ case 0xd:
+ *pOut++ = status;
+ *pOut++ = Pm_MessageData1(dev->rx_evBuf[msg].message);
+ bytesOut += 2;
+ break;
- default:
- *pOut++ = status;
- *pOut++ = Pm_MessageData1(dev->rx_evBuf[msg].message);
- *pOut++ = Pm_MessageData2(dev->rx_evBuf[msg].message);
- bytesOut += 3;
- break;
+ case 0xf: // system common
+ switch (status & 0xf)
+ {
+ case 0: // System Exclusive
+ *pOut++ = status; // this should be OK: the shortest legal sysex is F0 tt dd F7, I believe
+ *pOut++ = (dev->rx_evBuf[msg].message>>8) & 0xff;
+ *pOut++ = (dev->rx_evBuf[msg].message>>16) & 0xff;
+ *pOut++ = (dev->rx_evBuf[msg].message>>24) & 0xff;
+ bytesOut += 4;
+ dev->rx_sysex = true;
+ break;
+
+ case 7: // End of System Exclusive
+ *pOut++ = status;
+ bytesOut += 1;
+ break;
+
+ case 2: // song pos
+ case 3: // song select
+ *pOut++ = status;
+ *pOut++ = Pm_MessageData1(dev->rx_evBuf[msg].message);
+ *pOut++ = Pm_MessageData2(dev->rx_evBuf[msg].message);
+ bytesOut += 3;
+ break;
+
+ default: // all other defined Fx messages are 1 byte
+ break;
+ }
+ break;
+
+ default:
+ *pOut++ = status;
+ *pOut++ = Pm_MessageData1(dev->rx_evBuf[msg].message);
+ *pOut++ = Pm_MessageData2(dev->rx_evBuf[msg].message);
+ bytesOut += 3;
+ break;
+ }
}
}