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:
@@ -81,6 +81,7 @@ static void
|
|||||||
MPU401_ReCalcClock(mpu_t *mpu)
|
MPU401_ReCalcClock(mpu_t *mpu)
|
||||||
{
|
{
|
||||||
int32_t maxtempo = 240, mintempo = 16;
|
int32_t maxtempo = 240, mintempo = 16;
|
||||||
|
int32_t freq;
|
||||||
|
|
||||||
if (mpu->clock.timebase >= 168)
|
if (mpu->clock.timebase >= 168)
|
||||||
maxtempo = 179;
|
maxtempo = 179;
|
||||||
@@ -94,12 +95,13 @@ MPU401_ReCalcClock(mpu_t *mpu)
|
|||||||
((mpu->clock.freq / 2) < maxtempo ? (mpu->clock.freq / 2) : maxtempo));
|
((mpu->clock.freq / 2) < maxtempo ? (mpu->clock.freq / 2) : maxtempo));
|
||||||
|
|
||||||
if (mpu->state.sync_in) {
|
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)))
|
if ((freq > (mpu->clock.timebase * mintempo)) && (freq < (mpu->clock.timebase * maxtempo)))
|
||||||
mpu->clock.freq = freq;
|
mpu->clock.freq = freq;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
MPU401_StartClock(mpu_t *mpu)
|
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);
|
timer_set_delay_u64(&mpu->mpu401_event_callback, (MPU401_TIMECONSTANT / mpu->clock.freq) * 1000 * TIMER_USEC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
MPU401_StopClock(mpu_t *mpu)
|
MPU401_StopClock(mpu_t *mpu)
|
||||||
{
|
{
|
||||||
@@ -121,6 +124,7 @@ MPU401_StopClock(mpu_t *mpu)
|
|||||||
timer_disable(&mpu->mpu401_event_callback);
|
timer_disable(&mpu->mpu401_event_callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
MPU401_RunClock(mpu_t *mpu)
|
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);
|
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
|
static void
|
||||||
MPU401_QueueByte(mpu_t *mpu, uint8_t data)
|
MPU401_QueueByte(mpu_t *mpu, uint8_t data)
|
||||||
{
|
{
|
||||||
@@ -140,10 +145,11 @@ MPU401_QueueByte(mpu_t *mpu, uint8_t data)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mpu->queue_used == 0) && (mpu->mode == M_INTELLIGENT)) {
|
if (mpu->queue_used == 0) {
|
||||||
mpu->state.irq_pending = 1;
|
mpu->state.irq_pending = 1;
|
||||||
picint(1 << mpu->irq);
|
picint(1 << mpu->irq);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mpu->queue_used < MPU401_QUEUE) {
|
if (mpu->queue_used < MPU401_QUEUE) {
|
||||||
int pos = mpu->queue_used+mpu->queue_pos;
|
int pos = mpu->queue_used+mpu->queue_pos;
|
||||||
|
|
||||||
@@ -157,20 +163,22 @@ MPU401_QueueByte(mpu_t *mpu, uint8_t data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
MPU401_RecQueueBuffer(mpu_t *mpu, uint8_t *buf, uint32_t len, int block)
|
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) {
|
while (cnt < len) {
|
||||||
if (mpu->rec_queue_used < MPU401_INPUT_QUEUE) {
|
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)
|
if (pos >= MPU401_INPUT_QUEUE)
|
||||||
pos -= MPU401_INPUT_QUEUE;
|
pos -= MPU401_INPUT_QUEUE;
|
||||||
mpu->rec_queue[pos] = buf[cnt];
|
mpu->rec_queue[pos] = buf[cnt];
|
||||||
mpu->rec_queue_used++;
|
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;
|
mpu->state.sysex_in_finished = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -195,6 +203,7 @@ MPU401_RecQueueBuffer(mpu_t *mpu, uint8_t *buf, uint32_t len, int block)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
MPU401_ClrQueue(mpu_t *mpu)
|
MPU401_ClrQueue(mpu_t *mpu)
|
||||||
{
|
{
|
||||||
@@ -255,7 +264,7 @@ MPU401_Reset(mpu_t *mpu)
|
|||||||
mpu->filter.midi_thru = 1;
|
mpu->filter.midi_thru = 1;
|
||||||
mpu->filter.commonmsgs_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++) {
|
for (i = 0; i < 4; i++) {
|
||||||
mpu->chanref[i].on = 1;
|
mpu->chanref[i].on = 1;
|
||||||
mpu->chanref[i].chan = i;
|
mpu->chanref[i].chan = i;
|
||||||
@@ -266,7 +275,7 @@ MPU401_Reset(mpu_t *mpu)
|
|||||||
mpu->inputref[i].on = 1;
|
mpu->inputref[i].on = 1;
|
||||||
mpu->inputref[i].chan = i;
|
mpu->inputref[i].chan = i;
|
||||||
if (i > 3)
|
if (i > 3)
|
||||||
mpu->ch_toref[i] = 4;/*dummy reftable*/
|
mpu->ch_toref[i] = 4; /* Dummy reftable. */
|
||||||
}
|
}
|
||||||
|
|
||||||
MPU401_ClrQueue(mpu);
|
MPU401_ClrQueue(mpu);
|
||||||
@@ -281,7 +290,7 @@ MPU401_Reset(mpu_t *mpu)
|
|||||||
mpu->playbuf[i].counter = 0;
|
mpu->playbuf[i].counter = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*clear MIDI buffers, terminate notes*/
|
/* Clear MIDI buffers, terminate notes. */
|
||||||
midi_clear_buffer();
|
midi_clear_buffer();
|
||||||
|
|
||||||
for (i = 0xb0; i <= 0xbf; i++) {
|
for (i = 0xb0; i <= 0xbf; i++) {
|
||||||
@@ -313,15 +322,20 @@ MPU401_ResetDone(void *priv)
|
|||||||
static void
|
static void
|
||||||
MPU401_WriteCommand(mpu_t *mpu, uint8_t val)
|
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)
|
if (mpu->state.reset)
|
||||||
mpu->state.cmd_pending = val + 1;
|
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)
|
if ((val != 0x3f) && (val != 0xff) && !mpu->intelligent)
|
||||||
return;
|
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;
|
mpu->midi_thru = 1;
|
||||||
|
|
||||||
if (val <= 0x2f) { /* Sequencer state */
|
if (val <= 0x2f) { /* Sequencer state */
|
||||||
@@ -393,6 +407,7 @@ MPU401_WriteCommand(mpu_t *mpu, uint8_t val)
|
|||||||
send_prchg = 1;
|
send_prchg = 1;
|
||||||
MPU401_StartClock(mpu);
|
MPU401_StartClock(mpu);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MPU401_QueueByte(mpu, MSG_MPU_ACK);
|
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))
|
if (((val == 0x20) || (val == 0x26)) && (mpu->state.rec == M_RECON))
|
||||||
MPU401_RecQueueBuffer(mpu, &rec_cnt, 1, 0);
|
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)) {
|
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);
|
MPU401_RecQueueBuffer(mpu, recmsg, 3, 0);
|
||||||
mpu->filter.prchg_mask &= ~(1 << i);
|
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);
|
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.old_track = mpu->state.track;
|
||||||
mpu->state.track= val & 7;
|
mpu->state.track= val & 7;
|
||||||
mpu->state.wsd = 1;
|
mpu->state.wsd = 1;
|
||||||
@@ -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
|
uint8_t
|
||||||
MPU401_ReadData(mpu_t *mpu)
|
MPU401_ReadData(mpu_t *mpu)
|
||||||
{
|
{
|
||||||
@@ -1045,11 +1080,7 @@ MPU401_ReadData(mpu_t *mpu)
|
|||||||
|
|
||||||
/* Shouldn't this check mpu->mode? */
|
/* Shouldn't this check mpu->mode? */
|
||||||
if (mpu->mode == M_UART) {
|
if (mpu->mode == M_UART) {
|
||||||
if (mpu->state.irq_pending) {
|
MPU401_ReadRaiseIRQ(mpu);
|
||||||
picintc(1 << mpu->irq);
|
|
||||||
mpu->state.irq_pending = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1059,7 +1090,7 @@ MPU401_ReadData(mpu_t *mpu)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*copy from recording buffer*/
|
/* Copy from recording buffer. */
|
||||||
if (!mpu->queue_used && mpu->rec_queue_used) {
|
if (!mpu->queue_used && mpu->rec_queue_used) {
|
||||||
mpu->state.rec_copy = 1;
|
mpu->state.rec_copy = 1;
|
||||||
if (mpu->rec_queue_pos >= MPU401_INPUT_QUEUE)
|
if (mpu->rec_queue_pos >= MPU401_INPUT_QUEUE)
|
||||||
@@ -1069,10 +1100,7 @@ MPU401_ReadData(mpu_t *mpu)
|
|||||||
mpu->rec_queue_used--;
|
mpu->rec_queue_used--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mpu->queue_used == 0) {
|
MPU401_ReadRaiseIRQ(mpu);
|
||||||
picintc(1 << mpu->irq);
|
|
||||||
mpu->state.irq_pending = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ret >= 0xf0) && (ret <= 0xf7)) {
|
if ((ret >= 0xf0) && (ret <= 0xf7)) {
|
||||||
/* MIDI data request */
|
/* 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);
|
MPU401_EOIHandlerDispatch(mpu);
|
||||||
}
|
|
||||||
|
|
||||||
return(ret);
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1135,8 +1162,10 @@ mpu401_read(uint16_t addr, void *priv)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 1: /* Read Status */
|
case 1: /* Read Status */
|
||||||
if (mpu->state.cmd_pending) ret=STATUS_OUTPUT_NOT_READY;
|
if (mpu->state.cmd_pending)
|
||||||
if (!mpu->queue_used) ret=STATUS_INPUT_NOT_READY;
|
ret = STATUS_OUTPUT_NOT_READY;
|
||||||
|
if (!mpu->queue_used)
|
||||||
|
ret = STATUS_INPUT_NOT_READY;
|
||||||
ret |= 0x3f;
|
ret |= 0x3f;
|
||||||
|
|
||||||
mpu401_log("Read Status (0x331) %x\n", ret);
|
mpu401_log("Read Status (0x331) %x\n", ret);
|
||||||
@@ -1153,6 +1182,7 @@ MPU401_Event(void *priv)
|
|||||||
{
|
{
|
||||||
mpu_t *mpu = (mpu_t *)priv;
|
mpu_t *mpu = (mpu_t *)priv;
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
|
int max_meascnt;
|
||||||
|
|
||||||
mpu401_log("MPU-401 event callback\n");
|
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.irq_pending) goto next_event;
|
||||||
|
|
||||||
if (mpu->state.playing) {
|
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)) {
|
if (mpu->state.amask & (1 << i)) {
|
||||||
mpu->playbuf[i].counter--;
|
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++;
|
mpu->clock.rec_counter++;
|
||||||
if (mpu->clock.rec_counter>=240) {
|
if (mpu->clock.rec_counter>=240) {
|
||||||
mpu->clock.rec_counter=0;
|
mpu->clock.rec_counter=0;
|
||||||
@@ -1198,8 +1231,9 @@ MPU401_Event(void *priv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mpu->state.playing || (mpu->state.rec == M_RECON)) {
|
if (mpu->state.playing || (mpu->state.rec == M_RECON)) {
|
||||||
int max_meascnt = (mpu->clock.timebase * mpu->clock.midimetro * mpu->clock.metromeas) / 24;
|
max_meascnt = (mpu->clock.timebase * mpu->clock.midimetro * mpu->clock.metromeas) / 24;
|
||||||
if (max_meascnt != 0) { /* measure end */
|
if (max_meascnt != 0) {
|
||||||
|
/* Measure end. */
|
||||||
if (++mpu->clock.measure_counter >= max_meascnt) {
|
if (++mpu->clock.measure_counter >= max_meascnt) {
|
||||||
if (mpu->filter.rt_out)
|
if (mpu->filter.rt_out)
|
||||||
midi_raw_out_rt_byte(0xf8);
|
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);
|
MPU401_EOIHandler(mpu);
|
||||||
}
|
|
||||||
|
|
||||||
next_event:
|
next_event:
|
||||||
MPU401_RunClock(mpu);
|
MPU401_RunClock(mpu);
|
||||||
@@ -1219,6 +1252,7 @@ next_event:
|
|||||||
mpu->clock.ticks_in++;
|
mpu->clock.ticks_in++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
MPU401_NotesOff(mpu_t *mpu, int i)
|
MPU401_NotesOff(mpu_t *mpu, int i)
|
||||||
{
|
{
|
||||||
@@ -1246,16 +1280,17 @@ MPU401_NotesOff(mpu_t *mpu, int i)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*Input handler for SysEx */
|
/*Input handler for SysEx */
|
||||||
static int
|
static int
|
||||||
MPU401_InputSysex(void *p, uint8_t *buffer, uint32_t len, int abort)
|
MPU401_InputSysex(void *p, uint8_t *buffer, uint32_t len, int abort)
|
||||||
{
|
{
|
||||||
mpu_t *mpu = (mpu_t *)p;
|
mpu_t *mpu = (mpu_t *)p;
|
||||||
|
int i;
|
||||||
|
uint8_t val_ff = 0xff;
|
||||||
|
|
||||||
mpu401_log("MPU401 Input Sysex\n");
|
mpu401_log("MPU401 Input Sysex\n");
|
||||||
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (mpu->filter.sysex_in) {
|
if (mpu->filter.sysex_in) {
|
||||||
if (abort) {
|
if (abort) {
|
||||||
mpu->state.sysex_in_finished=1;
|
mpu->state.sysex_in_finished=1;
|
||||||
@@ -1265,7 +1300,6 @@ MPU401_InputSysex(void *p, uint8_t *buffer, uint32_t len, int abort)
|
|||||||
if (mpu->state.sysex_in_finished) {
|
if (mpu->state.sysex_in_finished) {
|
||||||
if (mpu->rec_queue_used>=MPU401_INPUT_QUEUE)
|
if (mpu->rec_queue_used>=MPU401_INPUT_QUEUE)
|
||||||
return len;
|
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->state.sysex_in_finished=0;
|
||||||
mpu->clock.rec_counter=0;
|
mpu->clock.rec_counter=0;
|
||||||
@@ -1277,15 +1311,13 @@ MPU401_InputSysex(void *p, uint8_t *buffer, uint32_t len, int abort)
|
|||||||
if (available >= len) {
|
if (available >= len) {
|
||||||
MPU401_RecQueueBuffer(mpu, buffer, len, 1);
|
MPU401_RecQueueBuffer(mpu, buffer, len, 1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
MPU401_RecQueueBuffer(mpu,buffer, available, 1);
|
MPU401_RecQueueBuffer(mpu,buffer, available, 1);
|
||||||
if (mpu->state.sysex_in_finished)
|
if (mpu->state.sysex_in_finished)
|
||||||
return 0;
|
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);
|
midi_raw_out_byte(0xf0);
|
||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < len; i++)
|
||||||
midi_raw_out_byte(*(buffer+i));
|
midi_raw_out_byte(*(buffer+i));
|
||||||
@@ -1299,8 +1331,14 @@ static void
|
|||||||
MPU401_InputMsg(void *p, uint8_t *msg)
|
MPU401_InputMsg(void *p, uint8_t *msg)
|
||||||
{
|
{
|
||||||
mpu_t *mpu = (mpu_t *)p;
|
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) {
|
if (!mpu->state.sysex_in_finished) {
|
||||||
mpu401_log("SYSEX in progress\n");
|
mpu401_log("SYSEX in progress\n");
|
||||||
return;
|
return;
|
||||||
@@ -1308,29 +1346,26 @@ MPU401_InputMsg(void *p, uint8_t *msg)
|
|||||||
|
|
||||||
mpu401_log("MPU401 Input Msg\n");
|
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 (mpu->mode == M_INTELLIGENT) {
|
||||||
if (msg[0]<0x80) { /* Expand running status */
|
if (msg[0] < 0x80) {
|
||||||
|
/* Expand running status */
|
||||||
midistatus = 1;
|
midistatus = 1;
|
||||||
msg[2]=msg[1];msg[1]=msg[0];msg[0]=old_msg;
|
msg[2] = msg[1];
|
||||||
|
msg[1] = msg[0];
|
||||||
|
msg[0] = old_msg;
|
||||||
}
|
}
|
||||||
old_msg = msg[0];
|
old_msg = msg[0];
|
||||||
int chan=msg[0]&0xf;
|
chan = msg[0] & 0xf;
|
||||||
int chrefnum=mpu->ch_toref[chan];
|
chrefnum = mpu->ch_toref[chan];
|
||||||
uint8_t key=msg[1]&0x7f;
|
key = msg[1] & 0x7f;
|
||||||
if (msg[0]<0xf0) { //if non-system msg
|
if (msg[0] < 0xf0) {
|
||||||
|
/* If non-system msg. */
|
||||||
if (!(mpu->state.midi_mask & (1 << chan)) && mpu->filter.all_thru)
|
if (!(mpu->state.midi_mask & (1 << chan)) && mpu->filter.all_thru)
|
||||||
send_thru = 1;
|
send_thru = 1;
|
||||||
else if (mpu->filter.midi_thru)
|
else if (mpu->filter.midi_thru)
|
||||||
send_thru = 1;
|
send_thru = 1;
|
||||||
switch (msg[0] & 0xf0) {
|
switch (msg[0] & 0xf0) {
|
||||||
case 0x80: /*note off*/
|
case 0x80: /* Note off. */
|
||||||
if (send_thru) {
|
if (send_thru) {
|
||||||
if (mpu->chanref[chrefnum].on && (mpu->chanref[chrefnum].M_GETKEY))
|
if (mpu->chanref[chrefnum].on && (mpu->chanref[chrefnum].M_GETKEY))
|
||||||
send_thru = 0;
|
send_thru = 0;
|
||||||
@@ -1341,7 +1376,7 @@ MPU401_InputMsg(void *p, uint8_t *msg)
|
|||||||
mpu->inputref[chan].M_DELKEY;
|
mpu->inputref[chan].M_DELKEY;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x90: /*note on*/
|
case 0x90: /* Note on. */
|
||||||
if (send_thru) {
|
if (send_thru) {
|
||||||
if (mpu->chanref[chrefnum].on && (mpu->chanref[chrefnum].M_GETKEY))
|
if (mpu->chanref[chrefnum].on && (mpu->chanref[chrefnum].M_GETKEY))
|
||||||
retrigger_thru = 1;
|
retrigger_thru = 1;
|
||||||
@@ -1355,7 +1390,8 @@ MPU401_InputMsg(void *p, uint8_t *msg)
|
|||||||
case 0xb0:
|
case 0xb0:
|
||||||
if (msg[1] >= 120) {
|
if (msg[1] >= 120) {
|
||||||
send_thru = 0;
|
send_thru = 0;
|
||||||
if (msg[1]==123) { /* All notes off */
|
if (msg[1] == 123) {
|
||||||
|
/* All notes off. */
|
||||||
for (key = 0; key < 128; key++) {
|
for (key = 0; key < 128; key++) {
|
||||||
if (!(mpu->chanref[chrefnum].on && (mpu->chanref[chrefnum].M_GETKEY)))
|
if (!(mpu->chanref[chrefnum].on && (mpu->chanref[chrefnum].M_GETKEY)))
|
||||||
if (mpu->inputref[chan].on && mpu->inputref[chan].M_GETKEY) {
|
if (mpu->inputref[chan].on && mpu->inputref[chan].M_GETKEY) {
|
||||||
@@ -1370,39 +1406,40 @@ MPU401_InputMsg(void *p, uint8_t *msg)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (msg[0]>=0xf0 || (mpu->state.midi_mask&(1<<chan)))
|
}
|
||||||
|
if ((msg[0] >= 0xf0) || (mpu->state.midi_mask & (1 << chan))) {
|
||||||
switch (msg[0] & 0xf0) {
|
switch (msg[0] & 0xf0) {
|
||||||
case 0xa0: /*aftertouch*/
|
case 0xa0: /* Aftertouch. */
|
||||||
if (!mpu->filter.bender_in)
|
if (!mpu->filter.bender_in)
|
||||||
send = 0;
|
send = 0;
|
||||||
break;
|
break;
|
||||||
case 0xb0: /*control change*/
|
case 0xb0: /* Control change. */
|
||||||
if (!mpu->filter.bender_in && msg[1]<64)
|
if (!mpu->filter.bender_in && (msg[1] < 64))
|
||||||
send = 0;
|
send = 0;
|
||||||
if (msg[1] >= 120) {
|
if (msg[1] >= 120) {
|
||||||
if (mpu->filter.modemsgs_in)
|
if (mpu->filter.modemsgs_in)
|
||||||
send = 1;
|
send = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0xc0: /*program change*/
|
case 0xc0: /* Program change. */
|
||||||
if ((mpu->state.rec != M_RECON) && !mpu->filter.data_in_stop) {
|
if ((mpu->state.rec != M_RECON) && !mpu->filter.data_in_stop) {
|
||||||
mpu->filter.prchg_buf[chan] = msg[1];
|
mpu->filter.prchg_buf[chan] = msg[1];
|
||||||
mpu->filter.prchg_mask |= 1 << chan;
|
mpu->filter.prchg_mask |= 1 << chan;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0xd0: /*ch pressure*/
|
case 0xd0: /* Ch pressure. */
|
||||||
case 0xe0: /*pitch wheel*/
|
case 0xe0: /* Pitch wheel. */
|
||||||
if (!mpu->filter.bender_in)
|
if (!mpu->filter.bender_in)
|
||||||
send = 0;
|
send = 0;
|
||||||
break;
|
break;
|
||||||
case 0xf0: //system message
|
case 0xf0: /* System message. */
|
||||||
if (msg[0] == 0xf8) {
|
if (msg[0] == 0xf8) {
|
||||||
send = 0;
|
send = 0;
|
||||||
if (mpu->clock.active && mpu->state.sync_in) {
|
if (mpu->clock.active && mpu->state.sync_in) {
|
||||||
send = 0;/*don't pass to host in this mode?*/
|
send = 0; /* Don't pass to host in this mode? */
|
||||||
int tick=mpu->clock.timebase/24;
|
tick = mpu->clock.timebase / 24;
|
||||||
if (mpu->clock.ticks_in != tick) {
|
if (mpu->clock.ticks_in != tick) {
|
||||||
if (!mpu->clock.ticks_in || (mpu->clock.ticks_in>tick*2))
|
if (!mpu->clock.ticks_in || (mpu->clock.ticks_in > (tick * 2)))
|
||||||
mpu->clock.freq_mod *= 2.0;
|
mpu->clock.freq_mod *= 2.0;
|
||||||
else {
|
else {
|
||||||
if (ABS(mpu->clock.ticks_in-tick) == 1)
|
if (ABS(mpu->clock.ticks_in-tick) == 1)
|
||||||
@@ -1414,17 +1451,16 @@ MPU401_InputMsg(void *p, uint8_t *msg)
|
|||||||
}
|
}
|
||||||
mpu->clock.ticks_in = 0;
|
mpu->clock.ticks_in = 0;
|
||||||
}
|
}
|
||||||
}
|
} else if (msg[0] > 0xf8) { /* Realtime. */
|
||||||
else if (msg[0]>0xf8) { /*realtime*/
|
if (!(mpu->filter.rt_in && (msg[0] <= 0xfc) && (msg[0] >= 0xfa))) {
|
||||||
if (!(mpu->filter.rt_in && msg[0]<=0xfc && msg[0]>=0xfa)) {
|
recdata[0] = 0xff;
|
||||||
uint8_t recdata[2]={0xff,msg[0]};
|
recdata[1] = msg[0];
|
||||||
MPU401_RecQueueBuffer(mpu, recdata, 2, 1);
|
MPU401_RecQueueBuffer(mpu, recdata, 2, 1);
|
||||||
send = 0;
|
send = 0;
|
||||||
}
|
}
|
||||||
}
|
} else { /* Common or system. */
|
||||||
else { /*common or system*/
|
|
||||||
send = 0;
|
send = 0;
|
||||||
if (msg[0]==0xf2 || msg[0]==0xf3 || msg[0]==0xf6) {
|
if ((msg[0] == 0xf2) || (msg[0] == 0xf3) || (msg[0] == 0xf6)) {
|
||||||
if (mpu->filter.commonmsgs_in)
|
if (mpu->filter.commonmsgs_in)
|
||||||
send = 1;
|
send = 1;
|
||||||
if (mpu->filter.commonmsgs_thru)
|
if (mpu->filter.commonmsgs_thru)
|
||||||
@@ -1433,64 +1469,79 @@ MPU401_InputMsg(void *p, uint8_t *msg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (send) {
|
if (send) {
|
||||||
uint8_t recmsg[4]={0xff,msg[0],msg[1],msg[2]};
|
recmsg[0] = 0xff;
|
||||||
|
recmsg[1] = msg[0];
|
||||||
|
recmsg[2] = msg[1];
|
||||||
|
recmsg[3] = msg[2];
|
||||||
MPU401_RecQueueBuffer(mpu, recmsg, len + 1, 1);
|
MPU401_RecQueueBuffer(mpu, recmsg, len + 1, 1);
|
||||||
}
|
}
|
||||||
if (mpu->filter.rt_affection) switch(msg[0]) {
|
if (mpu->filter.rt_affection) {
|
||||||
|
switch(msg[0]) {
|
||||||
case 0xf2: case 0xf3:
|
case 0xf2: case 0xf3:
|
||||||
mpu->state.block_ack = 1;
|
mpu->state.block_ack = 1;
|
||||||
MPU401_WriteCommand(mpu,0xb8);/*clear play counters*/
|
MPU401_WriteCommand(mpu, 0xb8); /* Clear play counters. */
|
||||||
break;
|
break;
|
||||||
case 0xfa:
|
case 0xfa:
|
||||||
mpu->state.block_ack = 1;
|
mpu->state.block_ack = 1;
|
||||||
MPU401_WriteCommand(mpu,0xa);/*start,play*/
|
MPU401_WriteCommand(mpu, 0xa); /* Start, play. */
|
||||||
if (mpu->filter.rt_out)
|
if (mpu->filter.rt_out)
|
||||||
midi_raw_out_rt_byte(msg[0]);
|
midi_raw_out_rt_byte(msg[0]);
|
||||||
break;
|
break;
|
||||||
case 0xfb:
|
case 0xfb:
|
||||||
mpu->state.block_ack = 1;
|
mpu->state.block_ack = 1;
|
||||||
MPU401_WriteCommand(mpu,0xb);/*continue,play*/
|
MPU401_WriteCommand(mpu, 0xb); /* Continue, play. */
|
||||||
if (mpu->filter.rt_out)
|
if (mpu->filter.rt_out)
|
||||||
midi_raw_out_rt_byte(msg[0]);
|
midi_raw_out_rt_byte(msg[0]);
|
||||||
break;
|
break;
|
||||||
case 0xfc:
|
case 0xfc:
|
||||||
mpu->state.block_ack = 1;
|
mpu->state.block_ack = 1;
|
||||||
MPU401_WriteCommand(mpu,0xd);/*stop: play,rec,midi*/
|
MPU401_WriteCommand(mpu, 0xd) ;/* Stop: Play, rec, midi */
|
||||||
if (mpu->filter.rt_out)
|
if (mpu->filter.rt_out)
|
||||||
midi_raw_out_rt_byte(msg[0]);
|
midi_raw_out_rt_byte(msg[0]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (send_thru && mpu->midi_thru) {
|
if (send_thru && mpu->midi_thru) {
|
||||||
if (retrigger_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[1]);
|
||||||
midi_raw_out_byte(msg[2]);
|
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]);
|
midi_raw_out_byte(msg[i]);
|
||||||
}
|
}
|
||||||
if (send) {
|
if (send) {
|
||||||
if (mpu->state.rec == M_RECON) {
|
if (mpu->state.rec == M_RECON) {
|
||||||
uint8_t recmsg[4]={mpu->clock.rec_counter,msg[0],msg[1],msg[2]};
|
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);
|
MPU401_RecQueueBuffer(mpu, recmsg, len + 1, 1);
|
||||||
mpu->clock.rec_counter = 0;
|
mpu->clock.rec_counter = 0;
|
||||||
}
|
}
|
||||||
else if (mpu->filter.data_in_stop) {
|
else if (mpu->filter.data_in_stop) {
|
||||||
if (mpu->filter.timing_in_stop) {
|
if (mpu->filter.timing_in_stop) {
|
||||||
uint8_t recmsg[4]={0,msg[0],msg[1],msg[2]};
|
recmsg[0] = 0;
|
||||||
|
recmsg[1] = msg[0];
|
||||||
|
recmsg[2] = msg[1];
|
||||||
|
recmsg[3] = msg[2];
|
||||||
MPU401_RecQueueBuffer(mpu, recmsg, len + 1, 1);
|
MPU401_RecQueueBuffer(mpu, recmsg, len + 1, 1);
|
||||||
}
|
} else {
|
||||||
else {
|
recmsg[0] = msg[0];
|
||||||
uint8_t recmsg[4]={msg[0],msg[1],msg[2],0};
|
recmsg[1] = msg[1];
|
||||||
|
recmsg[2] = msg[2];
|
||||||
|
recmsg[3] = 0;
|
||||||
MPU401_RecQueueBuffer(mpu, recmsg, len, 1);
|
MPU401_RecQueueBuffer(mpu, recmsg, len, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/*UART mode input*/
|
|
||||||
|
/* UART mode input. */
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
MPU401_QueueByte(mpu, msg[i]);
|
MPU401_QueueByte(mpu, msg[i]);
|
||||||
picint(1 << mpu->irq);
|
picint(1 << mpu->irq);
|
||||||
@@ -1530,7 +1581,8 @@ mpu401_init(mpu_t *mpu, uint16_t addr, int irq, int mode)
|
|||||||
void
|
void
|
||||||
mpu401_device_add(void)
|
mpu401_device_add(void)
|
||||||
{
|
{
|
||||||
if (!mpu401_standalone_enable) return;
|
if (!mpu401_standalone_enable)
|
||||||
|
return;
|
||||||
|
|
||||||
if (machines[machine].flags & MACHINE_MCA)
|
if (machines[machine].flags & MACHINE_MCA)
|
||||||
device_add(&mpu401_mca_device);
|
device_add(&mpu401_mca_device);
|
||||||
|
Reference in New Issue
Block a user