Fixed coding style and IRQ handling per the spec.

Also made commands other than 0xFF ignored in UART mode, also per the spec.
This commit is contained in:
OBattler
2020-01-04 03:32:20 +01:00
committed by GitHub
parent e8dd8c3774
commit f7ffe8a247

View File

@@ -81,6 +81,7 @@ static void
MPU401_ReCalcClock(mpu_t *mpu)
{
int32_t maxtempo = 240, mintempo = 16;
int32_t freq;
if (mpu->clock.timebase >= 168)
maxtempo = 179;
@@ -94,12 +95,13 @@ MPU401_ReCalcClock(mpu_t *mpu)
((mpu->clock.freq / 2) < maxtempo ? (mpu->clock.freq / 2) : maxtempo));
if (mpu->state.sync_in) {
int32_t freq = (int32_t)((float)(mpu->clock.freq) * mpu->clock.freq_mod);
freq = (int32_t)((float)(mpu->clock.freq) * mpu->clock.freq_mod);
if ((freq > (mpu->clock.timebase * mintempo)) && (freq < (mpu->clock.timebase * maxtempo)))
mpu->clock.freq = freq;
}
}
static void
MPU401_StartClock(mpu_t *mpu)
{
@@ -112,6 +114,7 @@ MPU401_StartClock(mpu_t *mpu)
timer_set_delay_u64(&mpu->mpu401_event_callback, (MPU401_TIMECONSTANT / mpu->clock.freq) * 1000 * TIMER_USEC);
}
static void
MPU401_StopClock(mpu_t *mpu)
{
@@ -121,6 +124,7 @@ MPU401_StopClock(mpu_t *mpu)
timer_disable(&mpu->mpu401_event_callback);
}
static void
MPU401_RunClock(mpu_t *mpu)
{
@@ -132,6 +136,7 @@ MPU401_RunClock(mpu_t *mpu)
mpu401_log("Next event after %i us (time constant: %i)\n", (uint64_t) ((MPU401_TIMECONSTANT/mpu->clock.freq) * 1000 * TIMER_USEC), (int) MPU401_TIMECONSTANT);
}
static void
MPU401_QueueByte(mpu_t *mpu, uint8_t data)
{
@@ -140,10 +145,11 @@ MPU401_QueueByte(mpu_t *mpu, uint8_t data)
return;
}
if ((mpu->queue_used == 0) && (mpu->mode == M_INTELLIGENT)) {
if (mpu->queue_used == 0) {
mpu->state.irq_pending = 1;
picint(1 << mpu->irq);
}
if (mpu->queue_used < MPU401_QUEUE) {
int pos = mpu->queue_used+mpu->queue_pos;
@@ -157,20 +163,22 @@ MPU401_QueueByte(mpu_t *mpu, uint8_t data)
}
}
static void
MPU401_RecQueueBuffer(mpu_t *mpu, uint8_t *buf, uint32_t len, int block)
{
uint32_t cnt;
uint32_t cnt = 0;
int pos;
cnt = 0;
while (cnt < len) {
if (mpu->rec_queue_used < MPU401_INPUT_QUEUE) {
int pos = mpu->rec_queue_used + mpu->rec_queue_pos;
pos = mpu->rec_queue_used + mpu->rec_queue_pos;
if (pos >= MPU401_INPUT_QUEUE)
pos -= MPU401_INPUT_QUEUE;
mpu->rec_queue[pos] = buf[cnt];
mpu->rec_queue_used++;
if ((!mpu->state.sysex_in_finished) && (buf[cnt] == MSG_EOX)) { /*finish sysex*/
if ((!mpu->state.sysex_in_finished) && (buf[cnt] == MSG_EOX)) {
/* finish sysex */
mpu->state.sysex_in_finished = 1;
break;
}
@@ -195,6 +203,7 @@ MPU401_RecQueueBuffer(mpu_t *mpu, uint8_t *buf, uint32_t len, int block)
}
}
static void
MPU401_ClrQueue(mpu_t *mpu)
{
@@ -255,7 +264,7 @@ MPU401_Reset(mpu_t *mpu)
mpu->filter.midi_thru = 1;
mpu->filter.commonmsgs_thru = 1;
/*reset channel reference and input tables*/
/* Reset channel reference and input tables. */
for (i = 0; i < 4; i++) {
mpu->chanref[i].on = 1;
mpu->chanref[i].chan = i;
@@ -266,7 +275,7 @@ MPU401_Reset(mpu_t *mpu)
mpu->inputref[i].on = 1;
mpu->inputref[i].chan = i;
if (i > 3)
mpu->ch_toref[i] = 4;/*dummy reftable*/
mpu->ch_toref[i] = 4; /* Dummy reftable. */
}
MPU401_ClrQueue(mpu);
@@ -276,12 +285,12 @@ MPU401_Reset(mpu_t *mpu)
mpu->condbuf.counter = 0;
mpu->condbuf.type = T_OVERFLOW;
for (i=0;i<8;i++) {
for (i = 0; i < 8; i++) {
mpu->playbuf[i].type = T_OVERFLOW;
mpu->playbuf[i].counter = 0;
}
/*clear MIDI buffers, terminate notes*/
/* Clear MIDI buffers, terminate notes. */
midi_clear_buffer();
for (i = 0xb0; i <= 0xbf; i++) {
@@ -313,15 +322,20 @@ MPU401_ResetDone(void *priv)
static void
MPU401_WriteCommand(mpu_t *mpu, uint8_t val)
{
uint8_t i, j, was_uart;
uint8_t i, j, was_uart, recmsg[3];
if (mpu->state.reset)
mpu->state.cmd_pending = val + 1;
/* The only command recognized in UART mode is 0xFF: Reset and return to Intelligent mode. */
if ((val != 0xff) && (mpu->mode == M_UART))
return;
/* In Intelligent mode, UART-only variants of the MPU-401 only support commands 0x3F and 0xFF. */
if ((val != 0x3f) && (val != 0xff) && !mpu->intelligent)
return;
/*hack:enable midi through after the first mpu401 command is written*/
/* Hack: Enable midi through after the first mpu401 command is written. */
mpu->midi_thru = 1;
if (val <= 0x2f) { /* Sequencer state */
@@ -393,6 +407,7 @@ MPU401_WriteCommand(mpu_t *mpu, uint8_t val)
send_prchg = 1;
MPU401_StartClock(mpu);
}
break;
}
}
MPU401_QueueByte(mpu, MSG_MPU_ACK);
@@ -401,15 +416,20 @@ MPU401_WriteCommand(mpu_t *mpu, uint8_t val)
if (((val == 0x20) || (val == 0x26)) && (mpu->state.rec == M_RECON))
MPU401_RecQueueBuffer(mpu, &rec_cnt, 1, 0);
if (send_prchg) for (i = 0; i < 16; i++)
if (send_prchg) {
for (i = 0; i < 16; i++) {
if (mpu->filter.prchg_mask & (1 << i)) {
uint8_t recmsg[3] = {mpu->clock.rec_counter, 0xc0 | i, mpu->filter.prchg_buf[i]};
recmsg[0] = mpu->clock.rec_counter;
recmsg[1] = 0xc0 | i;
recmsg[2] = mpu->filter.prchg_buf[i];
MPU401_RecQueueBuffer(mpu, recmsg, 3, 0);
mpu->filter.prchg_mask &= ~(1 << i);
}
} else if ((val >= 0xa0) && (val <= 0xa7)) { /* Request play counter */
}
}
} else if ((val >= 0xa0) && (val <= 0xa7)) /* Request play counter */
MPU401_QueueByte(mpu, mpu->playbuf[val & 7].counter);
} else if ((val >= 0xd0) && (val <= 0xd7)) { /* Send data */
else if ((val >= 0xd0) && (val <= 0xd7)) { /* Send data */
mpu->state.old_track = mpu->state.track;
mpu->state.track= val & 7;
mpu->state.wsd = 1;
@@ -459,7 +479,7 @@ MPU401_WriteCommand(mpu_t *mpu, uint8_t val)
mpu->filter.rt_in = 1;
break;
case 0x3f: /* UART mode */
mpu401_log("MPU-401:Set UART mode %X\n",val);
mpu401_log("MPU-401: Set UART mode %X\n",val);
MPU401_QueueByte(mpu, MSG_MPU_ACK);
mpu->mode = M_UART;
return;
@@ -581,7 +601,7 @@ MPU401_WriteCommand(mpu_t *mpu, uint8_t val)
mpu->state.command_byte = val;
break;
case 0xff: /* Reset MPU-401 */
mpu401_log("MPU-401:Reset %X\n",val);
mpu401_log("MPU-401: Reset %X\n", val);
timer_set_delay_u64(&mpu->mpu401_reset_callback, MPU401_RESETBUSY * 33LL * TIMER_USEC);
mpu->state.reset = 1;
was_uart = (mpu->mode == M_UART);
@@ -1028,6 +1048,21 @@ imf_write(uint16_t addr, uint8_t val, void *priv)
}
void
MPU401_ReadRaiseIRQ(mpu_t *mpu)
{
/* Clear IRQ. */
picintc(1 << mpu->irq);
mpu->state.irq_pending = 0;
if (mpu->queue_used) {
/* Bytes remaining in queue, raise IRQ again. */
mpu->state.irq_pending = 1;
picint(1 << mpu->irq);
}
}
uint8_t
MPU401_ReadData(mpu_t *mpu)
{
@@ -1045,11 +1080,7 @@ MPU401_ReadData(mpu_t *mpu)
/* Shouldn't this check mpu->mode? */
if (mpu->mode == M_UART) {
if (mpu->state.irq_pending) {
picintc(1 << mpu->irq);
mpu->state.irq_pending = 0;
}
MPU401_ReadRaiseIRQ(mpu);
return ret;
}
@@ -1059,7 +1090,7 @@ MPU401_ReadData(mpu_t *mpu)
return ret;
}
/*copy from recording buffer*/
/* Copy from recording buffer. */
if (!mpu->queue_used && mpu->rec_queue_used) {
mpu->state.rec_copy = 1;
if (mpu->rec_queue_pos >= MPU401_INPUT_QUEUE)
@@ -1069,10 +1100,7 @@ MPU401_ReadData(mpu_t *mpu)
mpu->rec_queue_used--;
}
if (mpu->queue_used == 0) {
picintc(1 << mpu->irq);
mpu->state.irq_pending = 0;
}
MPU401_ReadRaiseIRQ(mpu);
if ((ret >= 0xf0) && (ret <= 0xf7)) {
/* MIDI data request */
@@ -1094,11 +1122,10 @@ MPU401_ReadData(mpu_t *mpu)
}
}
if ((ret == MSG_MPU_END) || (ret == MSG_MPU_CLOCK) || (ret == MSG_MPU_ACK) || (ret == MSG_MPU_OVERFLOW)) {
if ((ret == MSG_MPU_END) || (ret == MSG_MPU_CLOCK) || (ret == MSG_MPU_ACK) || (ret == MSG_MPU_OVERFLOW))
MPU401_EOIHandlerDispatch(mpu);
}
return(ret);
return ret;
}
@@ -1135,8 +1162,10 @@ mpu401_read(uint16_t addr, void *priv)
break;
case 1: /* Read Status */
if (mpu->state.cmd_pending) ret=STATUS_OUTPUT_NOT_READY;
if (!mpu->queue_used) ret=STATUS_INPUT_NOT_READY;
if (mpu->state.cmd_pending)
ret = STATUS_OUTPUT_NOT_READY;
if (!mpu->queue_used)
ret = STATUS_INPUT_NOT_READY;
ret |= 0x3f;
mpu401_log("Read Status (0x331) %x\n", ret);
@@ -1153,6 +1182,7 @@ MPU401_Event(void *priv)
{
mpu_t *mpu = (mpu_t *)priv;
uint8_t i;
int max_meascnt;
mpu401_log("MPU-401 event callback\n");
@@ -1164,10 +1194,12 @@ MPU401_Event(void *priv)
if (mpu->state.irq_pending) goto next_event;
if (mpu->state.playing) {
for (i = 0; i < 8; i++) { /* Decrease counters */
for (i = 0; i < 8; i++) {
/* Decrease counters. */
if (mpu->state.amask & (1 << i)) {
mpu->playbuf[i].counter--;
if (mpu->playbuf[i].counter <= 0) UpdateTrack(mpu, i);
if (mpu->playbuf[i].counter <= 0)
UpdateTrack(mpu, i);
}
}
@@ -1189,7 +1221,8 @@ MPU401_Event(void *priv)
}
}
if (mpu->state.rec==M_RECON) { /* recording */
if (mpu->state.rec == M_RECON) {
/* Recording. */
mpu->clock.rec_counter++;
if (mpu->clock.rec_counter>=240) {
mpu->clock.rec_counter=0;
@@ -1198,8 +1231,9 @@ MPU401_Event(void *priv)
}
if (mpu->state.playing || (mpu->state.rec == M_RECON)) {
int max_meascnt = (mpu->clock.timebase * mpu->clock.midimetro * mpu->clock.metromeas) / 24;
if (max_meascnt != 0) { /* measure end */
max_meascnt = (mpu->clock.timebase * mpu->clock.midimetro * mpu->clock.metromeas) / 24;
if (max_meascnt != 0) {
/* Measure end. */
if (++mpu->clock.measure_counter >= max_meascnt) {
if (mpu->filter.rt_out)
midi_raw_out_rt_byte(0xf8);
@@ -1209,9 +1243,8 @@ MPU401_Event(void *priv)
}
}
}
if (!mpu->state.irq_pending && mpu->state.req_mask) {
if (!mpu->state.irq_pending && mpu->state.req_mask)
MPU401_EOIHandler(mpu);
}
next_event:
MPU401_RunClock(mpu);
@@ -1219,6 +1252,7 @@ next_event:
mpu->clock.ticks_in++;
}
static void
MPU401_NotesOff(mpu_t *mpu, int i)
{
@@ -1226,15 +1260,15 @@ MPU401_NotesOff(mpu_t *mpu, int i)
uint8_t key;
if (mpu->filter.allnotesoff_out && !(mpu->inputref[i].on &&
(mpu->inputref[i].key[0]|mpu->inputref[i].key[1]|
mpu->inputref[i].key[2]|mpu->inputref[i].key[3]))) {
(mpu->inputref[i].key[0] | mpu->inputref[i].key[1] |
mpu->inputref[i].key[2] | mpu->inputref[i].key[3]))) {
for (j=0;j<4;j++)
mpu->chanref[mpu->ch_toref[i]].key[j]=0;
midi_raw_out_byte(0xb0|i);
midi_raw_out_byte(0xb0 | i);
midi_raw_out_byte(123);
midi_raw_out_byte(0);
} else if (mpu->chanref[mpu->ch_toref[i]].on) {
for (key=0;key<128;key++) {
for (key = 0; key < 128; key++) {
if ((mpu->chanref[mpu->ch_toref[i]].M_GETKEY) &&
!(mpu->inputref[i].on && (mpu->inputref[i].M_GETKEY))) {
midi_raw_out_byte(0x80|i);
@@ -1246,16 +1280,17 @@ MPU401_NotesOff(mpu_t *mpu, int i)
}
}
/*Input handler for SysEx */
static int
MPU401_InputSysex(void *p, uint8_t *buffer, uint32_t len, int abort)
{
mpu_t *mpu = (mpu_t *)p;
int i;
uint8_t val_ff = 0xff;
mpu401_log("MPU401 Input Sysex\n");
int i;
if (mpu->filter.sysex_in) {
if (abort) {
mpu->state.sysex_in_finished=1;
@@ -1265,29 +1300,26 @@ MPU401_InputSysex(void *p, uint8_t *buffer, uint32_t len, int abort)
if (mpu->state.sysex_in_finished) {
if (mpu->rec_queue_used>=MPU401_INPUT_QUEUE)
return len;
uint8_t val_ff=0xff;
MPU401_RecQueueBuffer(mpu,&val_ff,1,1);
MPU401_RecQueueBuffer(mpu, &val_ff, 1, 1);
mpu->state.sysex_in_finished=0;
mpu->clock.rec_counter=0;
}
if (mpu->rec_queue_used>=MPU401_INPUT_QUEUE)
return len;
int available=MPU401_INPUT_QUEUE-mpu->rec_queue_used;
int available = MPU401_INPUT_QUEUE - mpu->rec_queue_used;
if (available>=len) {
MPU401_RecQueueBuffer(mpu,buffer,len,1);
if (available >= len) {
MPU401_RecQueueBuffer(mpu, buffer, len, 1);
return 0;
}
else {
MPU401_RecQueueBuffer(mpu,buffer,available,1);
} else {
MPU401_RecQueueBuffer(mpu,buffer, available, 1);
if (mpu->state.sysex_in_finished)
return 0;
return (len-available);
return (len - available);
}
}
else if (mpu->filter.sysex_thru && mpu->midi_thru) {
} else if (mpu->filter.sysex_thru && mpu->midi_thru) {
midi_raw_out_byte(0xf0);
for (i=0;i<len;i++)
for (i = 0; i < len; i++)
midi_raw_out_byte(*(buffer+i));
}
return 0;
@@ -1299,8 +1331,14 @@ static void
MPU401_InputMsg(void *p, uint8_t *msg)
{
mpu_t *mpu = (mpu_t *)p;
int i, tick;
static uint8_t old_msg = 0;
uint8_t len = msg[3], key;
uint8_t recdata[2], recmsg[4];
int send = 1, send_thru = 0;
int retrigger_thru = 0, midistatus = 0, chan, chrefnum;
/*abort if sysex transfer is in progress*/
/* Abort if sysex transfer is in progress. */
if (!mpu->state.sysex_in_finished) {
mpu401_log("SYSEX in progress\n");
return;
@@ -1308,58 +1346,56 @@ MPU401_InputMsg(void *p, uint8_t *msg)
mpu401_log("MPU401 Input Msg\n");
int i;
static uint8_t old_msg=0;
uint8_t len=msg[3];
int send=1;
int send_thru=0;
int retrigger_thru=0;
int midistatus=0;
if (mpu->mode==M_INTELLIGENT) {
if (msg[0]<0x80) { /* Expand running status */
midistatus=1;
msg[2]=msg[1];msg[1]=msg[0];msg[0]=old_msg;
if (mpu->mode == M_INTELLIGENT) {
if (msg[0] < 0x80) {
/* Expand running status */
midistatus = 1;
msg[2] = msg[1];
msg[1] = msg[0];
msg[0] = old_msg;
}
old_msg=msg[0];
int chan=msg[0]&0xf;
int chrefnum=mpu->ch_toref[chan];
uint8_t key=msg[1]&0x7f;
if (msg[0]<0xf0) { //if non-system msg
if (!(mpu->state.midi_mask&(1<<chan)) && mpu->filter.all_thru)
send_thru=1;
old_msg = msg[0];
chan = msg[0] & 0xf;
chrefnum = mpu->ch_toref[chan];
key = msg[1] & 0x7f;
if (msg[0] < 0xf0) {
/* If non-system msg. */
if (!(mpu->state.midi_mask & (1 << chan)) && mpu->filter.all_thru)
send_thru = 1;
else if (mpu->filter.midi_thru)
send_thru=1;
switch (msg[0]&0xf0) {
case 0x80: /*note off*/
send_thru = 1;
switch (msg[0] & 0xf0) {
case 0x80: /* Note off. */
if (send_thru) {
if (mpu->chanref[chrefnum].on && (mpu->chanref[chrefnum].M_GETKEY))
send_thru=0;
send_thru = 0;
if (!mpu->filter.midi_thru)
break;
if (!(mpu->inputref[chan].M_GETKEY))
send_thru=0;
send_thru = 0;
mpu->inputref[chan].M_DELKEY;
}
break;
case 0x90: /*note on*/
case 0x90: /* Note on. */
if (send_thru) {
if (mpu->chanref[chrefnum].on && (mpu->chanref[chrefnum].M_GETKEY))
retrigger_thru=1;
retrigger_thru = 1;
if (!mpu->filter.midi_thru)
break;
if (mpu->inputref[chan].M_GETKEY)
retrigger_thru=1;
retrigger_thru = 1;
mpu->inputref[chan].M_SETKEY;
}
break;
case 0xb0:
if (msg[1]>=120) {
send_thru=0;
if (msg[1]==123) { /* All notes off */
for (key=0;key<128;key++) {
if (msg[1] >= 120) {
send_thru = 0;
if (msg[1] == 123) {
/* All notes off. */
for (key = 0; key < 128; key++) {
if (!(mpu->chanref[chrefnum].on && (mpu->chanref[chrefnum].M_GETKEY)))
if (mpu->inputref[chan].on && mpu->inputref[chan].M_GETKEY) {
midi_raw_out_byte(0x80|chan);
midi_raw_out_byte(0x80 | chan);
midi_raw_out_byte(key);
midi_raw_out_byte(0);
}
@@ -1370,128 +1406,143 @@ MPU401_InputMsg(void *p, uint8_t *msg)
break;
}
}
if (msg[0]>=0xf0 || (mpu->state.midi_mask&(1<<chan)))
switch (msg[0]&0xf0) {
case 0xa0: /*aftertouch*/
}
if ((msg[0] >= 0xf0) || (mpu->state.midi_mask & (1 << chan))) {
switch (msg[0] & 0xf0) {
case 0xa0: /* Aftertouch. */
if (!mpu->filter.bender_in)
send=0;
send = 0;
break;
case 0xb0: /*control change*/
if (!mpu->filter.bender_in && msg[1]<64)
send=0;
if (msg[1]>=120) {
case 0xb0: /* Control change. */
if (!mpu->filter.bender_in && (msg[1] < 64))
send = 0;
if (msg[1] >= 120) {
if (mpu->filter.modemsgs_in)
send=1;
send = 1;
}
break;
case 0xc0: /*program change*/
if ((mpu->state.rec!=M_RECON) && !mpu->filter.data_in_stop) {
mpu->filter.prchg_buf[chan]=msg[1];
mpu->filter.prchg_mask|=1<<chan;
case 0xc0: /* Program change. */
if ((mpu->state.rec != M_RECON) && !mpu->filter.data_in_stop) {
mpu->filter.prchg_buf[chan] = msg[1];
mpu->filter.prchg_mask |= 1 << chan;
}
break;
case 0xd0: /*ch pressure*/
case 0xe0: /*pitch wheel*/
case 0xd0: /* Ch pressure. */
case 0xe0: /* Pitch wheel. */
if (!mpu->filter.bender_in)
send=0;
send = 0;
break;
case 0xf0: //system message
if (msg[0]==0xf8) {
send=0;
case 0xf0: /* System message. */
if (msg[0] == 0xf8) {
send = 0;
if (mpu->clock.active && mpu->state.sync_in) {
send = 0;/*don't pass to host in this mode?*/
int tick=mpu->clock.timebase/24;
if (mpu->clock.ticks_in!=tick) {
if (!mpu->clock.ticks_in || (mpu->clock.ticks_in>tick*2))
mpu->clock.freq_mod*=2.0;
send = 0; /* Don't pass to host in this mode? */
tick = mpu->clock.timebase / 24;
if (mpu->clock.ticks_in != tick) {
if (!mpu->clock.ticks_in || (mpu->clock.ticks_in > (tick * 2)))
mpu->clock.freq_mod *= 2.0;
else {
if (ABS(mpu->clock.ticks_in-tick)==1)
mpu->clock.freq_mod/=mpu->clock.ticks_in/(float)(tick*2);
if (ABS(mpu->clock.ticks_in-tick) == 1)
mpu->clock.freq_mod /= mpu->clock.ticks_in / (float) (tick * 2);
else
mpu->clock.freq_mod/=mpu->clock.ticks_in/(float)(tick);
mpu->clock.freq_mod /= mpu->clock.ticks_in / (float) (tick);
}
MPU401_ReCalcClock(mpu);
}
mpu->clock.ticks_in=0;
mpu->clock.ticks_in = 0;
}
} else if (msg[0] > 0xf8) { /* Realtime. */
if (!(mpu->filter.rt_in && (msg[0] <= 0xfc) && (msg[0] >= 0xfa))) {
recdata[0] = 0xff;
recdata[1] = msg[0];
MPU401_RecQueueBuffer(mpu, recdata, 2, 1);
send = 0;
}
else if (msg[0]>0xf8) { /*realtime*/
if (!(mpu->filter.rt_in && msg[0]<=0xfc && msg[0]>=0xfa)) {
uint8_t recdata[2]={0xff,msg[0]};
MPU401_RecQueueBuffer(mpu,recdata,2,1);
send=0;
}
}
else { /*common or system*/
send=0;
if (msg[0]==0xf2 || msg[0]==0xf3 || msg[0]==0xf6) {
} else { /* Common or system. */
send = 0;
if ((msg[0] == 0xf2) || (msg[0] == 0xf3) || (msg[0] == 0xf6)) {
if (mpu->filter.commonmsgs_in)
send=1;
send = 1;
if (mpu->filter.commonmsgs_thru)
for (i=0;i<len;i++)
for (i = 0; i < len; i++)
midi_raw_out_byte(msg[i]);
}
}
if (send) {
uint8_t recmsg[4]={0xff,msg[0],msg[1],msg[2]};
MPU401_RecQueueBuffer(mpu,recmsg,len+1,1);
recmsg[0] = 0xff;
recmsg[1] = msg[0];
recmsg[2] = msg[1];
recmsg[3] = msg[2];
MPU401_RecQueueBuffer(mpu, recmsg, len + 1, 1);
}
if (mpu->filter.rt_affection) switch(msg[0]) {
case 0xf2:case 0xf3:
mpu->state.block_ack=1;
MPU401_WriteCommand(mpu,0xb8);/*clear play counters*/
if (mpu->filter.rt_affection) {
switch(msg[0]) {
case 0xf2: case 0xf3:
mpu->state.block_ack = 1;
MPU401_WriteCommand(mpu, 0xb8); /* Clear play counters. */
break;
case 0xfa:
mpu->state.block_ack=1;
MPU401_WriteCommand(mpu,0xa);/*start,play*/
mpu->state.block_ack = 1;
MPU401_WriteCommand(mpu, 0xa); /* Start, play. */
if (mpu->filter.rt_out)
midi_raw_out_rt_byte(msg[0]);
break;
case 0xfb:
mpu->state.block_ack=1;
MPU401_WriteCommand(mpu,0xb);/*continue,play*/
mpu->state.block_ack = 1;
MPU401_WriteCommand(mpu, 0xb); /* Continue, play. */
if (mpu->filter.rt_out)
midi_raw_out_rt_byte(msg[0]);
break;
case 0xfc:
mpu->state.block_ack=1;
MPU401_WriteCommand(mpu,0xd);/*stop: play,rec,midi*/
mpu->state.block_ack = 1;
MPU401_WriteCommand(mpu, 0xd) ;/* Stop: Play, rec, midi */
if (mpu->filter.rt_out)
midi_raw_out_rt_byte(msg[0]);
break;
}
return;
}
}
}
if (send_thru && mpu->midi_thru) {
if (retrigger_thru) {
midi_raw_out_byte(0x80|(msg[0]&0xf));
midi_raw_out_byte(0x80 | (msg[0] & 0xf));
midi_raw_out_byte(msg[1]);
midi_raw_out_byte(msg[2]);
}
for (i=0/*((midistatus && !retrigger_thru)? 1:0)*/;i<len;i++)
for (i = 0; i < len; i++)
midi_raw_out_byte(msg[i]);
}
if (send) {
if (mpu->state.rec==M_RECON) {
uint8_t recmsg[4]={mpu->clock.rec_counter,msg[0],msg[1],msg[2]};
MPU401_RecQueueBuffer(mpu,recmsg,len+1,1);
mpu->clock.rec_counter=0;
if (mpu->state.rec == M_RECON) {
recmsg[0] = mpu->clock.rec_counter;
recmsg[1] = msg[0];
recmsg[2] = msg[1];
recmsg[3] = msg[2];
MPU401_RecQueueBuffer(mpu, recmsg, len + 1, 1);
mpu->clock.rec_counter = 0;
}
else if (mpu->filter.data_in_stop) {
if (mpu->filter.timing_in_stop) {
uint8_t recmsg[4]={0,msg[0],msg[1],msg[2]};
MPU401_RecQueueBuffer(mpu,recmsg,len+1,1);
}
else {
uint8_t recmsg[4]={msg[0],msg[1],msg[2],0};
MPU401_RecQueueBuffer(mpu,recmsg,len,1);
recmsg[0] = 0;
recmsg[1] = msg[0];
recmsg[2] = msg[1];
recmsg[3] = msg[2];
MPU401_RecQueueBuffer(mpu, recmsg, len + 1, 1);
} else {
recmsg[0] = msg[0];
recmsg[1] = msg[1];
recmsg[2] = msg[2];
recmsg[3] = 0;
MPU401_RecQueueBuffer(mpu, recmsg, len, 1);
}
}
}
return;
}
/*UART mode input*/
for (i=0;i<len;i++) {
/* UART mode input. */
for (i = 0; i < len; i++) {
MPU401_QueueByte(mpu, msg[i]);
picint(1 << mpu->irq);
}
@@ -1530,7 +1581,8 @@ mpu401_init(mpu_t *mpu, uint16_t addr, int irq, int mode)
void
mpu401_device_add(void)
{
if (!mpu401_standalone_enable) return;
if (!mpu401_standalone_enable)
return;
if (machines[machine].flags & MACHINE_MCA)
device_add(&mpu401_mca_device);