Merge pull request #112 from TC1995/master

Implemented Sound Blaster MIDI through the DSP (was surprisingly miss…
This commit is contained in:
OBattler
2017-05-10 18:36:15 +02:00
committed by GitHub
5 changed files with 93 additions and 34 deletions

View File

@@ -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

View File

@@ -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);

View File

@@ -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
}

View File

@@ -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)
{

View File

@@ -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;