Overhauled SB DSP IRQ's and masking and also how it attaches to the MPU-401, fixes IBM OS/2 2.11 among other things.
This commit is contained in:
@@ -72,8 +72,7 @@ typedef struct mpu_t
|
|||||||
{
|
{
|
||||||
uint16_t addr;
|
uint16_t addr;
|
||||||
int uart_mode, intelligent,
|
int uart_mode, intelligent,
|
||||||
irq, irq_mask,
|
irq, midi_thru,
|
||||||
midi_thru,
|
|
||||||
queue_pos, queue_used;
|
queue_pos, queue_used;
|
||||||
uint8_t rx_data, is_mca,
|
uint8_t rx_data, is_mca,
|
||||||
status,
|
status,
|
||||||
@@ -135,12 +134,15 @@ typedef struct mpu_t
|
|||||||
uint16_t prchg_mask;
|
uint16_t prchg_mask;
|
||||||
} filter;
|
} filter;
|
||||||
struct {
|
struct {
|
||||||
int on;
|
int on;
|
||||||
uint8_t chan, trmask;
|
uint8_t chan, trmask;
|
||||||
uint32_t key[4];
|
uint32_t key[4];
|
||||||
} chanref[5], inputref[16];
|
} chanref[5], inputref[16];
|
||||||
pc_timer_t mpu401_event_callback, mpu401_eoi_callback,
|
pc_timer_t mpu401_event_callback, mpu401_eoi_callback,
|
||||||
mpu401_reset_callback;
|
mpu401_reset_callback;
|
||||||
|
void (*ext_irq_update)(void *priv, int set);
|
||||||
|
int (*ext_irq_pending)(void *priv);
|
||||||
|
void *priv;
|
||||||
} mpu_t;
|
} mpu_t;
|
||||||
|
|
||||||
extern int mpu401_standalone_enable, mpu401_already_loaded;
|
extern int mpu401_standalone_enable, mpu401_already_loaded;
|
||||||
@@ -154,6 +156,7 @@ extern void mpu401_setirq(mpu_t *mpu, int irq);
|
|||||||
extern void mpu401_change_addr(mpu_t *mpu, uint16_t addr);
|
extern void mpu401_change_addr(mpu_t *mpu, uint16_t addr);
|
||||||
extern void mpu401_init(mpu_t *mpu, uint16_t addr, int irq, int mode, int receive_input);
|
extern void mpu401_init(mpu_t *mpu, uint16_t addr, int irq, int mode, int receive_input);
|
||||||
extern void mpu401_device_add(void);
|
extern void mpu401_device_add(void);
|
||||||
|
extern void mpu401_irq_attach(mpu_t *mpu, void (*ext_irq_update)(void *priv, int set), int (*ext_irq_pending)(void *priv), void *priv);
|
||||||
|
|
||||||
extern int MPU401_InputSysex(void *p, uint8_t *buffer, uint32_t len, int abort);
|
extern int MPU401_InputSysex(void *p, uint8_t *buffer, uint32_t len, int abort);
|
||||||
extern void MPU401_InputMsg(void *p, uint8_t *msg);
|
extern void MPU401_InputMsg(void *p, uint8_t *msg);
|
||||||
|
@@ -62,8 +62,8 @@ typedef struct sb_dsp_t
|
|||||||
uint8_t sb_test;
|
uint8_t sb_test;
|
||||||
int sb_timei, sb_timeo;
|
int sb_timei, sb_timeo;
|
||||||
|
|
||||||
int sb_irq8, sb_irq16;
|
int sb_irq8, sb_irq16, sb_irq401;
|
||||||
int sb_irqm8, sb_irqm16;
|
int sb_irqm8, sb_irqm16, sb_irqm401;
|
||||||
|
|
||||||
uint8_t sb_asp_regs[256];
|
uint8_t sb_asp_regs[256];
|
||||||
|
|
||||||
@@ -91,6 +91,8 @@ typedef struct sb_dsp_t
|
|||||||
int pos;
|
int pos;
|
||||||
|
|
||||||
uint8_t azt_eeprom[AZTECH_EEPROM_SIZE]; /* the eeprom in the Aztech cards is attached to the DSP */
|
uint8_t azt_eeprom[AZTECH_EEPROM_SIZE]; /* the eeprom in the Aztech cards is attached to the DSP */
|
||||||
|
|
||||||
|
mpu_t *mpu;
|
||||||
} sb_dsp_t;
|
} sb_dsp_t;
|
||||||
|
|
||||||
|
|
||||||
@@ -98,7 +100,7 @@ void sb_dsp_input_msg(void *p, uint8_t *msg);
|
|||||||
|
|
||||||
int sb_dsp_input_sysex(void *p, uint8_t *buffer, uint32_t len, int abort);
|
int sb_dsp_input_sysex(void *p, uint8_t *buffer, uint32_t len, int abort);
|
||||||
|
|
||||||
void sb_dsp_set_mpu(mpu_t *src_mpu);
|
void sb_dsp_set_mpu(sb_dsp_t *dsp, mpu_t *src_mpu);
|
||||||
|
|
||||||
void sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent);
|
void sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent);
|
||||||
void sb_dsp_close(sb_dsp_t *dsp);
|
void sb_dsp_close(sb_dsp_t *dsp);
|
||||||
@@ -115,5 +117,6 @@ void sb_dsp_poll(sb_dsp_t *dsp, int16_t *l, int16_t *r);
|
|||||||
void sb_dsp_set_stereo(sb_dsp_t *dsp, int stereo);
|
void sb_dsp_set_stereo(sb_dsp_t *dsp, int stereo);
|
||||||
|
|
||||||
void sb_dsp_update(sb_dsp_t *dsp);
|
void sb_dsp_update(sb_dsp_t *dsp);
|
||||||
|
void sb_update_irq(sb_dsp_t *dsp);
|
||||||
|
|
||||||
#endif /* SOUND_SND_SB_DSP_H */
|
#endif /* SOUND_SND_SB_DSP_H */
|
@@ -1179,7 +1179,7 @@ azt_init(const device_t *info)
|
|||||||
mpu401_init(azt2316a->mpu, azt2316a->cur_mpu401_addr, azt2316a->cur_mpu401_irq, M_UART, device_get_config_int("receive_input401"));
|
mpu401_init(azt2316a->mpu, azt2316a->cur_mpu401_addr, azt2316a->cur_mpu401_irq, M_UART, device_get_config_int("receive_input401"));
|
||||||
} else
|
} else
|
||||||
azt2316a->mpu = NULL;
|
azt2316a->mpu = NULL;
|
||||||
sb_dsp_set_mpu(azt2316a->mpu);
|
sb_dsp_set_mpu(&azt2316a->sb->dsp, azt2316a->mpu);
|
||||||
|
|
||||||
if (device_get_config_int("receive_input"))
|
if (device_get_config_int("receive_input"))
|
||||||
midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &azt2316a->sb->dsp);
|
midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &azt2316a->sb->dsp);
|
||||||
|
@@ -155,9 +155,13 @@ MPU401_QueueByteEx(mpu_t *mpu, uint8_t data, int irq)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mpu->queue_used == 0) && !mpu->irq_mask) {
|
if (mpu->queue_used == 0) {
|
||||||
mpu->state.irq_pending = 1;
|
if (mpu->ext_irq_update)
|
||||||
picint(1 << mpu->irq);
|
mpu->ext_irq_update(mpu->priv, 1);
|
||||||
|
else {
|
||||||
|
mpu->state.irq_pending = 1;
|
||||||
|
picint(1 << mpu->irq);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mpu->queue_used < MPU401_QUEUE) {
|
if (mpu->queue_used < MPU401_QUEUE) {
|
||||||
@@ -181,6 +185,20 @@ MPU401_QueueByte(mpu_t *mpu, uint8_t data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
MPU401_IRQPending(mpu_t *mpu)
|
||||||
|
{
|
||||||
|
int irq_pending;
|
||||||
|
|
||||||
|
if (mpu->ext_irq_pending)
|
||||||
|
irq_pending = mpu->ext_irq_pending(mpu->priv);
|
||||||
|
else
|
||||||
|
irq_pending = mpu->state.irq_pending;
|
||||||
|
|
||||||
|
return irq_pending;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
@@ -204,10 +222,14 @@ MPU401_RecQueueBuffer(mpu_t *mpu, uint8_t *buf, uint32_t len, int block)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mpu->queue_used == 0) {
|
if (mpu->queue_used == 0) {
|
||||||
if (mpu->state.rec_copy || mpu->state.irq_pending) {
|
if (mpu->state.rec_copy || MPU401_IRQPending(mpu)) {
|
||||||
if (mpu->state.irq_pending) {
|
if (MPU401_IRQPending(mpu)) {
|
||||||
picintc(1 << mpu->irq);
|
if (mpu->ext_irq_update)
|
||||||
mpu->state.irq_pending = 0;
|
mpu->ext_irq_update(mpu->priv, 0);
|
||||||
|
else {
|
||||||
|
mpu->state.irq_pending = 0;
|
||||||
|
picintc(1 << mpu->irq);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -229,7 +251,12 @@ MPU401_ClrQueue(mpu_t *mpu)
|
|||||||
mpu->rec_queue_used = 0;
|
mpu->rec_queue_used = 0;
|
||||||
mpu->rec_queue_pos = 0;
|
mpu->rec_queue_pos = 0;
|
||||||
mpu->state.sysex_in_finished = 1;
|
mpu->state.sysex_in_finished = 1;
|
||||||
mpu->state.irq_pending = 0;
|
if (mpu->ext_irq_update)
|
||||||
|
mpu->ext_irq_update(mpu->priv, 0);
|
||||||
|
else {
|
||||||
|
mpu->state.irq_pending = 0;
|
||||||
|
picintc(1 << mpu->irq);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -240,12 +267,20 @@ MPU401_Reset(mpu_t *mpu)
|
|||||||
|
|
||||||
#ifdef DOSBOX_CODE
|
#ifdef DOSBOX_CODE
|
||||||
if (mpu->mode == M_INTELLIGENT) {
|
if (mpu->mode == M_INTELLIGENT) {
|
||||||
picintc(1 << mpu->irq);
|
if (mpu->ext_irq_update)
|
||||||
mpu->state.irq_pending = 0;
|
mpu->ext_irq_update(mpu->priv, 0);
|
||||||
|
else {
|
||||||
|
mpu->state.irq_pending = 0;
|
||||||
|
picintc(1 << mpu->irq);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
picintc(1 << mpu->irq);
|
if (mpu->ext_irq_update)
|
||||||
mpu->state.irq_pending = 0;
|
mpu->ext_irq_update(mpu->priv, 0);
|
||||||
|
else {
|
||||||
|
mpu->state.irq_pending = 0;
|
||||||
|
picintc(1 << mpu->irq);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mpu->mode = M_INTELLIGENT;
|
mpu->mode = M_INTELLIGENT;
|
||||||
@@ -1037,10 +1072,15 @@ MPU401_EOIHandler(void *priv)
|
|||||||
} else UpdateTrack(mpu, mpu->state.track);
|
} else UpdateTrack(mpu, mpu->state.track);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mpu->state.rec_copy || !mpu->state.sysex_in_finished)
|
if (mpu->state.rec_copy || !mpu->state.sysex_in_finished)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mpu->state.irq_pending = 0;
|
if (mpu->ext_irq_update)
|
||||||
|
mpu->ext_irq_update(mpu->priv, 0);
|
||||||
|
else {
|
||||||
|
mpu->state.irq_pending = 0;
|
||||||
|
picintc(1 << mpu->irq);
|
||||||
|
}
|
||||||
|
|
||||||
if (!(mpu->state.req_mask && mpu->clock.active))
|
if (!(mpu->state.req_mask && mpu->clock.active))
|
||||||
return;
|
return;
|
||||||
@@ -1081,13 +1121,21 @@ void
|
|||||||
MPU401_ReadRaiseIRQ(mpu_t *mpu)
|
MPU401_ReadRaiseIRQ(mpu_t *mpu)
|
||||||
{
|
{
|
||||||
/* Clear IRQ. */
|
/* Clear IRQ. */
|
||||||
picintc(1 << mpu->irq);
|
if (mpu->ext_irq_update)
|
||||||
mpu->state.irq_pending = 0;
|
mpu->ext_irq_update(mpu->priv, 0);
|
||||||
|
else {
|
||||||
|
mpu->state.irq_pending = 0;
|
||||||
|
picintc(1 << mpu->irq);
|
||||||
|
}
|
||||||
|
|
||||||
if (mpu->queue_used && !mpu->irq_mask) {
|
if (mpu->queue_used) {
|
||||||
/* Bytes remaining in queue, raise IRQ again. */
|
/* Bytes remaining in queue, raise IRQ again. */
|
||||||
mpu->state.irq_pending = 1;
|
if (mpu->ext_irq_update)
|
||||||
picint(1 << mpu->irq);
|
mpu->ext_irq_update(mpu->priv, 1);
|
||||||
|
else {
|
||||||
|
mpu->state.irq_pending = 1;
|
||||||
|
picint(1 << mpu->irq);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1234,7 +1282,8 @@ MPU401_Event(void *priv)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (mpu->state.irq_pending) goto next_event;
|
if (MPU401_IRQPending(mpu))
|
||||||
|
goto next_event;
|
||||||
|
|
||||||
if (mpu->state.playing) {
|
if (mpu->state.playing) {
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < 8; i++) {
|
||||||
@@ -1287,7 +1336,8 @@ MPU401_Event(void *priv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!mpu->state.irq_pending && mpu->state.req_mask)
|
|
||||||
|
if (MPU401_IRQPending(mpu) && mpu->state.req_mask)
|
||||||
MPU401_EOIHandler(mpu);
|
MPU401_EOIHandler(mpu);
|
||||||
|
|
||||||
next_event:
|
next_event:
|
||||||
@@ -1703,6 +1753,15 @@ mpu401_mca_feedb(void *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
mpu401_irq_attach(mpu_t *mpu, void (*ext_irq_update)(void *priv, int set), int (*ext_irq_pending)(void *priv), void *priv)
|
||||||
|
{
|
||||||
|
mpu->ext_irq_update = ext_irq_update;
|
||||||
|
mpu->ext_irq_pending = ext_irq_pending;
|
||||||
|
mpu->priv = priv;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
mpu401_standalone_init(const device_t *info)
|
mpu401_standalone_init(const device_t *info)
|
||||||
{
|
{
|
||||||
|
@@ -624,8 +624,7 @@ void sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *p)
|
|||||||
mixer->regs[0x83] = 0xff;
|
mixer->regs[0x83] = 0xff;
|
||||||
sb->dsp.sb_irqm8 = 0;
|
sb->dsp.sb_irqm8 = 0;
|
||||||
sb->dsp.sb_irqm16 = 0;
|
sb->dsp.sb_irqm16 = 0;
|
||||||
if (sb->mpu != NULL)
|
sb->dsp.sb_irqm401 = 0;
|
||||||
sb->mpu->irq_mask = 0;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -697,18 +696,9 @@ void sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *p)
|
|||||||
case 0x83:
|
case 0x83:
|
||||||
/* Interrupt mask. */
|
/* Interrupt mask. */
|
||||||
sb->dsp.sb_irqm8 = !(val & 0x01);
|
sb->dsp.sb_irqm8 = !(val & 0x01);
|
||||||
if (sb->dsp.sb_irqm8)
|
|
||||||
sb_irqc(&sb->dsp, 1);
|
|
||||||
sb->dsp.sb_irqm16 = !(val & 0x02);
|
sb->dsp.sb_irqm16 = !(val & 0x02);
|
||||||
if (sb->dsp.sb_irqm16)
|
sb->dsp.sb_irqm401 = !(val & 0x04);
|
||||||
sb_irqc(&sb->dsp, 0);
|
sb_update_irq(&sb->dsp);
|
||||||
if (sb->mpu != NULL) {
|
|
||||||
sb->mpu->irq_mask = !(val & 0x04);
|
|
||||||
if (sb->mpu->irq_mask) {
|
|
||||||
picintc(1 << sb->mpu->irq);
|
|
||||||
sb->mpu->state.irq_pending = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x84:
|
case 0x84:
|
||||||
@@ -721,6 +711,7 @@ void sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *p)
|
|||||||
else if ((val & 0x06) == 0x02)
|
else if ((val & 0x06) == 0x02)
|
||||||
mpu401_change_addr(sb->mpu, 0);
|
mpu401_change_addr(sb->mpu, 0);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
mixer->output_selector = mixer->regs[0x3C];
|
mixer->output_selector = mixer->regs[0x3C];
|
||||||
@@ -854,9 +845,8 @@ uint8_t sb_ct1745_mixer_read(uint16_t addr, void *p)
|
|||||||
case 0x82:
|
case 0x82:
|
||||||
/* 0 = none, 1 = digital 8bit or SBMIDI, 2 = digital 16bit, 4 = MPU-401 */
|
/* 0 = none, 1 = digital 8bit or SBMIDI, 2 = digital 16bit, 4 = MPU-401 */
|
||||||
/* 0x02000 DSP v4.04, 0x4000 DSP v4.05 0x8000 DSP v4.12. I haven't seen this making any difference, but I'm keeping it for now. */
|
/* 0x02000 DSP v4.04, 0x4000 DSP v4.05 0x8000 DSP v4.12. I haven't seen this making any difference, but I'm keeping it for now. */
|
||||||
temp = ((sb->dsp.sb_irq8) ? 1 : 0) | ((sb->dsp.sb_irq16) ? 2 : 0) | 0x4000;
|
temp = ((sb->dsp.sb_irq8) ? 1 : 0) | ((sb->dsp.sb_irq16) ? 2 : 0) |
|
||||||
if (sb->mpu)
|
((sb->dsp.sb_irq401) ? 4 : 0) | 0x4000;
|
||||||
temp |= ((sb->mpu->state.irq_pending) ? 4 : 0);
|
|
||||||
ret = temp;
|
ret = temp;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -1278,7 +1268,7 @@ void *sb_16_init(const device_t *info)
|
|||||||
mpu401_init(sb->mpu, device_get_config_hex16("base401"), device_get_config_int("irq"), M_UART, device_get_config_int("receive_input401"));
|
mpu401_init(sb->mpu, device_get_config_hex16("base401"), device_get_config_int("irq"), M_UART, device_get_config_int("receive_input401"));
|
||||||
} else
|
} else
|
||||||
sb->mpu = NULL;
|
sb->mpu = NULL;
|
||||||
sb_dsp_set_mpu(sb->mpu);
|
sb_dsp_set_mpu(&sb->dsp, sb->mpu);
|
||||||
|
|
||||||
if (device_get_config_int("receive_input"))
|
if (device_get_config_int("receive_input"))
|
||||||
midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp);
|
midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp);
|
||||||
@@ -1322,7 +1312,7 @@ void *sb_awe32_init(const device_t *info)
|
|||||||
sb->mpu = (mpu_t *) malloc(sizeof(mpu_t));
|
sb->mpu = (mpu_t *) malloc(sizeof(mpu_t));
|
||||||
memset(sb->mpu, 0, sizeof(mpu_t));
|
memset(sb->mpu, 0, sizeof(mpu_t));
|
||||||
mpu401_init(sb->mpu, device_get_config_hex16("base401"), device_get_config_int("irq"), M_UART, device_get_config_int("receive_input401"));
|
mpu401_init(sb->mpu, device_get_config_hex16("base401"), device_get_config_int("irq"), M_UART, device_get_config_int("receive_input401"));
|
||||||
sb_dsp_set_mpu(sb->mpu);
|
sb_dsp_set_mpu(&sb->dsp, sb->mpu);
|
||||||
} else
|
} else
|
||||||
sb->mpu = NULL;
|
sb->mpu = NULL;
|
||||||
emu8k_init(&sb->emu8k, emu_addr, onboard_ram);
|
emu8k_init(&sb->emu8k, emu_addr, onboard_ram);
|
||||||
|
@@ -44,8 +44,6 @@ static int sbe2dat[4][9] = {
|
|||||||
{ 0x01, -0x02, 0x04, -0x08, -0x10, 0x20, -0x40, 0x80, 90 }
|
{ 0x01, -0x02, 0x04, -0x08, -0x10, 0x20, -0x40, 0x80, 90 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static mpu_t *mpu;
|
|
||||||
|
|
||||||
static int sb_commands[256]=
|
static int sb_commands[256]=
|
||||||
{
|
{
|
||||||
-1, 2,-1,-1, 1, 2,-1, 0, 1,-1,-1,-1,-1,-1, 2, 1,
|
-1, 2,-1,-1, 1, 2,-1, 0, 1,-1,-1,-1,-1,-1, 2, 1,
|
||||||
@@ -179,28 +177,81 @@ recalc_sb16_filter(int playback_freq)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
sb_update_irq(sb_dsp_t *dsp)
|
||||||
|
{
|
||||||
|
int irq_pending;
|
||||||
|
|
||||||
|
irq_pending = (dsp->sb_irq8 && !dsp->sb_irqm8) ||
|
||||||
|
(dsp->sb_irq16 && !dsp->sb_irqm16) ||
|
||||||
|
(dsp->sb_irq401 && !dsp->sb_irq401);
|
||||||
|
|
||||||
|
if (irq_pending)
|
||||||
|
picint(1 << dsp->sb_irqnum);
|
||||||
|
else
|
||||||
|
picintc(1 << dsp->sb_irqnum);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
sb_update_status(sb_dsp_t *dsp, int bit, int set)
|
||||||
|
{
|
||||||
|
switch (bit) {
|
||||||
|
case 0:
|
||||||
|
default:
|
||||||
|
dsp->sb_irq8 = set;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
dsp->sb_irq16 = set;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
dsp->sb_irq401 = set;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
sb_update_irq(dsp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
sb_irq(sb_dsp_t *dsp, int irq8)
|
sb_irq(sb_dsp_t *dsp, int irq8)
|
||||||
{
|
{
|
||||||
sb_dsp_log("IRQ %i %02X\n", irq8, pic.mask);
|
sb_update_status(dsp, !irq8, 1);
|
||||||
if (irq8 && !dsp->sb_irqm8)
|
|
||||||
dsp->sb_irq8 = 1;
|
|
||||||
else if (!irq8 && !dsp->sb_irqm16)
|
|
||||||
dsp->sb_irq16 = 1;
|
|
||||||
|
|
||||||
picint(1 << dsp->sb_irqnum);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
sb_irqc(sb_dsp_t *dsp, int irq8)
|
sb_irqc(sb_dsp_t *dsp, int irq8)
|
||||||
{
|
{
|
||||||
if (irq8)
|
sb_update_status(dsp, !irq8, 0);
|
||||||
dsp->sb_irq8 = 0;
|
}
|
||||||
else
|
|
||||||
dsp->sb_irq16 = 0;
|
|
||||||
|
|
||||||
picintc(1 << dsp->sb_irqnum);
|
|
||||||
|
static void
|
||||||
|
sb_dsp_irq_update(void *priv, int set)
|
||||||
|
{
|
||||||
|
sb_dsp_t *dsp = (sb_dsp_t *) priv;
|
||||||
|
|
||||||
|
sb_update_status(dsp, 2, set);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
sb_dsp_irq_pending(void *priv)
|
||||||
|
{
|
||||||
|
sb_dsp_t *dsp = (sb_dsp_t *) priv;
|
||||||
|
|
||||||
|
return dsp->sb_irq401;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
sb_dsp_set_mpu(sb_dsp_t *dsp, mpu_t *mpu)
|
||||||
|
{
|
||||||
|
dsp->mpu = mpu;
|
||||||
|
|
||||||
|
if (mpu != NULL)
|
||||||
|
mpu401_irq_attach(mpu, sb_dsp_irq_update, sb_dsp_irq_pending, dsp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -217,8 +268,10 @@ sb_dsp_reset(sb_dsp_t *dsp)
|
|||||||
dsp->sb_8_length = 0xffff;
|
dsp->sb_8_length = 0xffff;
|
||||||
dsp->sb_8_autolen = 0xffff;
|
dsp->sb_8_autolen = 0xffff;
|
||||||
|
|
||||||
sb_irqc(dsp, 0);
|
dsp->sb_irq8 = 0;
|
||||||
sb_irqc(dsp, 1);
|
dsp->sb_irq16 = 0;
|
||||||
|
dsp->sb_irq401 = 0;
|
||||||
|
sb_update_irq(dsp);
|
||||||
dsp->sb_16_pause = 0;
|
dsp->sb_16_pause = 0;
|
||||||
dsp->sb_read_wp = dsp->sb_read_rp = 0;
|
dsp->sb_read_wp = dsp->sb_read_rp = 0;
|
||||||
dsp->sb_data_stat = -1;
|
dsp->sb_data_stat = -1;
|
||||||
@@ -853,8 +906,8 @@ sb_read(uint16_t a, void *priv)
|
|||||||
|
|
||||||
switch (a & 0xf) {
|
switch (a & 0xf) {
|
||||||
case 0xA: /* Read data */
|
case 0xA: /* Read data */
|
||||||
if (mpu && dsp->uart_midi) {
|
if (dsp->mpu && dsp->uart_midi) {
|
||||||
ret = MPU401_ReadData(mpu);
|
ret = MPU401_ReadData(dsp->mpu);
|
||||||
} else {
|
} else {
|
||||||
dsp->sbreaddat = dsp->sb_read_data[dsp->sb_read_rp];
|
dsp->sbreaddat = dsp->sb_read_data[dsp->sb_read_rp];
|
||||||
if (dsp->sb_read_rp != dsp->sb_read_wp) {
|
if (dsp->sb_read_rp != dsp->sb_read_wp) {
|
||||||
@@ -912,69 +965,64 @@ sb_read(uint16_t a, void *priv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This should not even be needed. */
|
|
||||||
void
|
|
||||||
sb_dsp_set_mpu(mpu_t *src_mpu)
|
|
||||||
{
|
|
||||||
mpu = src_mpu;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
sb_dsp_input_msg(void *p, uint8_t *msg)
|
sb_dsp_input_msg(void *p, uint8_t *msg)
|
||||||
{
|
{
|
||||||
sb_dsp_t *dsp = (sb_dsp_t *) p;
|
sb_dsp_t *dsp = (sb_dsp_t *) p;
|
||||||
|
uint8_t len = msg[3], i = 0;
|
||||||
|
|
||||||
sb_dsp_log("MIDI in sysex = %d, uart irq = %d, msg = %d\n", dsp->midi_in_sysex, dsp->uart_irq, msg[3]);
|
sb_dsp_log("MIDI in sysex = %d, uart irq = %d, msg = %d\n", dsp->midi_in_sysex, dsp->uart_irq, msg[3]);
|
||||||
|
|
||||||
if (!dsp->uart_irq && !dsp->midi_in_poll && (mpu != NULL)) {
|
if (!dsp->uart_irq && !dsp->midi_in_poll && (dsp->mpu != NULL)) {
|
||||||
MPU401_InputMsg(mpu, msg);
|
MPU401_InputMsg(dsp->mpu, msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dsp->midi_in_sysex) {
|
if (dsp->midi_in_sysex)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t len = msg[3];
|
if (dsp->uart_irq) {
|
||||||
uint8_t i = 0;
|
for (i = 0; i < len; i++)
|
||||||
if (dsp->uart_irq) {
|
sb_add_data(dsp, msg[i]);
|
||||||
for (i=0;i<len;i++)
|
sb_irq(dsp, 1);
|
||||||
sb_add_data(dsp, msg[i]);
|
} else if (dsp->midi_in_poll) {
|
||||||
sb_dsp_log("SB IRQ8 = %d\n", dsp->sb_irq8);
|
for (i = 0; i < len; i++)
|
||||||
if (!dsp->sb_irq8)
|
sb_add_data(dsp, msg[i]);
|
||||||
picint(1 << dsp->sb_irqnum);
|
}
|
||||||
} else if (dsp->midi_in_poll) {
|
|
||||||
for (i=0;i<len;i++)
|
|
||||||
sb_add_data(dsp, msg[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
sb_dsp_input_sysex(void *p, uint8_t *buffer, uint32_t len, int abort)
|
sb_dsp_input_sysex(void *p, uint8_t *buffer, uint32_t len, int abort)
|
||||||
{
|
{
|
||||||
sb_dsp_t *dsp = (sb_dsp_t *) p;
|
sb_dsp_t *dsp = (sb_dsp_t *) p;
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
uint32_t i;
|
if (!dsp->uart_irq && !dsp->midi_in_poll && (dsp->mpu != NULL))
|
||||||
|
return MPU401_InputSysex(dsp->mpu, buffer, len, abort);
|
||||||
|
|
||||||
if (!dsp->uart_irq && !dsp->midi_in_poll && (mpu != NULL))
|
if (abort) {
|
||||||
return MPU401_InputSysex(mpu, buffer, len, abort);
|
|
||||||
|
|
||||||
if (abort) {
|
|
||||||
dsp->midi_in_sysex = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
dsp->midi_in_sysex = 1;
|
|
||||||
for (i=0;i<len;i++) {
|
|
||||||
if (dsp->sb_read_rp == dsp->sb_read_wp) {
|
|
||||||
sb_dsp_log("Length sysex SB = %d\n", len-i);
|
|
||||||
return (len-i);
|
|
||||||
}
|
|
||||||
sb_add_data(dsp, buffer[i]);
|
|
||||||
}
|
|
||||||
dsp->midi_in_sysex = 0;
|
dsp->midi_in_sysex = 0;
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
dsp->midi_in_sysex = 1;
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
if (dsp->sb_read_rp == dsp->sb_read_wp) {
|
||||||
|
sb_dsp_log("Length sysex SB = %d\n", len - i);
|
||||||
|
return (len - i);
|
||||||
|
}
|
||||||
|
|
||||||
|
sb_add_data(dsp, buffer[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
dsp->midi_in_sysex = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent)
|
sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent)
|
||||||
{
|
{
|
||||||
@@ -986,7 +1034,7 @@ sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent)
|
|||||||
dsp->sb_irqnum = 7;
|
dsp->sb_irqnum = 7;
|
||||||
dsp->sb_8_dmanum = 1;
|
dsp->sb_8_dmanum = 1;
|
||||||
dsp->sb_16_dmanum = 5;
|
dsp->sb_16_dmanum = 5;
|
||||||
mpu = NULL;
|
dsp->mpu = NULL;
|
||||||
|
|
||||||
sb_doreset(dsp);
|
sb_doreset(dsp);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user