diff --git a/src/SOUND/snd_mpu401.c b/src/SOUND/snd_mpu401.c index 526eecf84..5fcb15484 100644 --- a/src/SOUND/snd_mpu401.c +++ b/src/SOUND/snd_mpu401.c @@ -528,6 +528,47 @@ static void MPU401_EOIHandlerDispatch(void *p) MPU401_EOIHandler(mpu, 0); } +uint8_t MPU401_ReadData(mpu_t *mpu) +{ + uint8_t ret; + + ret = MSG_MPU_ACK; + if (mpu->queue_used) + { + if (mpu->queue_pos>=MPU401_QUEUE) mpu->queue_pos-=MPU401_QUEUE; + ret=mpu->queue[mpu->queue_pos]; + mpu->queue_pos++;mpu->queue_used--; + } + if (!mpu->intelligent) return ret; + + if (mpu->queue_used == 0) picintc(1 << mpu->irq); + + if (ret>=0xf0 && ret<=0xf7) + { /* MIDI data request */ + mpu->state.channel=ret&7; + mpu->state.data_onoff=0; + mpu->state.cond_req=0; + } + if (ret==MSG_MPU_COMMAND_REQ) + { + mpu->state.data_onoff=0; + mpu->state.cond_req=1; + if (mpu->condbuf.type!=T_OVERFLOW) + { + mpu->state.block_ack=1; + MPU401_WriteCommand(mpu, mpu->condbuf.value[0]); + if (mpu->state.command_byte) MPU401_WriteData(mpu, mpu->condbuf.value[1]); + } + mpu->condbuf.type=T_OVERFLOW; + } + if (ret==MSG_MPU_END || ret==MSG_MPU_CLOCK || ret==MSG_MPU_ACK) { + mpu->state.data_onoff=-1; + MPU401_EOIHandlerDispatch(mpu); + } + + return ret; +} + static void mpu401_write(uint16_t addr, uint8_t val, void *p) { mpu_t *mpu = (mpu_t *)p; @@ -554,39 +595,7 @@ static uint8_t mpu401_read(uint16_t addr, void *p) switch (addr & 1) { case 0: //Read Data - ret = MSG_MPU_ACK; - if (mpu->queue_used) - { - if (mpu->queue_pos>=MPU401_QUEUE) mpu->queue_pos-=MPU401_QUEUE; - ret=mpu->queue[mpu->queue_pos]; - mpu->queue_pos++;mpu->queue_used--; - } - if (!mpu->intelligent) return ret; - - if (mpu->queue_used == 0) picintc(1 << mpu->irq); - - if (ret>=0xf0 && ret<=0xf7) - { /* MIDI data request */ - mpu->state.channel=ret&7; - mpu->state.data_onoff=0; - mpu->state.cond_req=0; - } - if (ret==MSG_MPU_COMMAND_REQ) - { - mpu->state.data_onoff=0; - mpu->state.cond_req=1; - if (mpu->condbuf.type!=T_OVERFLOW) - { - mpu->state.block_ack=1; - MPU401_WriteCommand(mpu, mpu->condbuf.value[0]); - if (mpu->state.command_byte) MPU401_WriteData(mpu, mpu->condbuf.value[1]); - } - mpu->condbuf.type=T_OVERFLOW; - } - if (ret==MSG_MPU_END || ret==MSG_MPU_CLOCK || ret==MSG_MPU_ACK) { - mpu->state.data_onoff=-1; - MPU401_EOIHandlerDispatch(mpu); - } + ret = MPU401_ReadData(mpu); break; case 1: //Read Status diff --git a/src/SOUND/snd_mpu401.h b/src/SOUND/snd_mpu401.h index d8eedc25b..8cb721883 100644 --- a/src/SOUND/snd_mpu401.h +++ b/src/SOUND/snd_mpu401.h @@ -58,4 +58,6 @@ typedef struct mpu_t } clock; } mpu_t; +uint8_t MPU401_ReadData(mpu_t *mpu); + void mpu401_init(mpu_t *mpu, uint16_t addr, int irq, int mode); diff --git a/src/SOUND/snd_sb.c b/src/SOUND/snd_sb.c index 0308fa632..d5dee73d0 100644 --- a/src/SOUND/snd_sb.c +++ b/src/SOUND/snd_sb.c @@ -780,6 +780,9 @@ static device_config_t sb_config[] = } } }, + { + "midi", "MIDI out device", CONFIG_MIDI, "", 0 + }, { "", "", -1 } @@ -818,6 +821,9 @@ static device_config_t sb_mcv_config[] = } } }, + { + "midi", "MIDI out device", CONFIG_MIDI, "", 0 + }, { "", "", -1 } @@ -873,6 +879,9 @@ static device_config_t sb_pro_config[] = } } }, + { + "midi", "MIDI out device", CONFIG_MIDI, "", 0 + }, { "", "", -1 } diff --git a/src/SOUND/snd_sb_dsp.c b/src/SOUND/snd_sb_dsp.c index 16215d05e..f078cede9 100644 --- a/src/SOUND/snd_sb_dsp.c +++ b/src/SOUND/snd_sb_dsp.c @@ -11,8 +11,10 @@ #include "../dma.h" #include "../timer.h" #include "sound.h" +#include "snd_mpu401.h" #include "snd_sb_dsp.h" +mpu_t mpu; void pollsb(void *p); void sb_poll_i(void *p); @@ -321,6 +323,29 @@ void sb_exec_command(sb_dsp_t *dsp) temp = 1000000 / temp; dsp->sb_freq = temp; break; + + case 0x30: + case 0x31: + break; + + case 0x34: + dsp->uart_midi = 1; + dsp->uart_irq = 0; + break; + + case 0x35: + dsp->uart_midi = 1; + dsp->uart_irq = 1; + break; + + case 0x36: + case 0x37: + break; + + case 0x38: + dsp->onebyte_midi = 1; + break; + case 0x41: /*Set output sampling rate*/ case 0x42: /*Set input sampling rate*/ if (dsp->sb_type < SB16) break; @@ -514,6 +539,12 @@ void sb_write(uint16_t a, uint8_t v, void *priv) dsp->sbreset = v; return; case 0xC: /*Command/data write*/ + if (dsp->uart_midi || dsp->onebyte_midi) + { + midi_write(v); + dsp->onebyte_midi = 0; + return; + } timer_process(); dsp->wb_time = TIMER_USEC * 1; dsp->wb_full = 1; @@ -549,6 +580,10 @@ uint8_t sb_read(uint16_t a, void *priv) switch (a & 0xf) { case 0xA: /*Read data*/ + if (dsp->uart_midi) + { + return MPU401_ReadData(&mpu); + } dsp->sbreaddat = dsp->sb_read_data[dsp->sb_read_rp]; if (dsp->sb_read_rp != dsp->sb_read_wp) { diff --git a/src/SOUND/snd_sb_dsp.h b/src/SOUND/snd_sb_dsp.h index 9d4dee133..fb14284fa 100644 --- a/src/SOUND/snd_sb_dsp.h +++ b/src/SOUND/snd_sb_dsp.h @@ -1,5 +1,9 @@ typedef struct sb_dsp_t -{ +{ + int uart_midi; + int uart_irq; + int onebyte_midi; + int sb_type; int sb_8_length, sb_8_format, sb_8_autoinit, sb_8_pause, sb_8_enable, sb_8_autolen, sb_8_output;