Merge pull request #112 from TC1995/master
Implemented Sound Blaster MIDI through the DSP (was surprisingly miss…
This commit is contained in:
@@ -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
|
||||
|
@@ -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);
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -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)
|
||||
{
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user