Merge pull request #2503 from 86Box/batchfixp1

DMA: Implemented autoinit mode in the PS/2 MCA side (although the bit…
This commit is contained in:
Miran Grča
2022-07-23 23:59:51 +02:00
committed by GitHub
8 changed files with 414 additions and 32 deletions

View File

@@ -62,6 +62,7 @@ static struct {
#define DMA_PS2_IOA (1 << 0)
#define DMA_PS2_AUTOINIT (1 << 1)
#define DMA_PS2_XFER_MEM_TO_IO (1 << 2)
#define DMA_PS2_XFER_IO_TO_MEM (3 << 2)
#define DMA_PS2_XFER_MASK (3 << 2)
@@ -729,6 +730,8 @@ dma_ps2_write(uint16_t addr, uint8_t val, void *priv)
else if ((val & DMA_PS2_XFER_MASK) == DMA_PS2_XFER_IO_TO_MEM)
mode |= 4;
dma_c->mode = (dma_c->mode & ~0x2c) | mode;
if (val & DMA_PS2_AUTOINIT)
dma_c->mode |= 0x10;
dma_c->ps2_mode = val;
dma_c->size = val & DMA_PS2_SIZE16;
break;

View File

@@ -50,7 +50,8 @@ enum {
WD8003EB, /* WD8003EB : 8-bit ISA, 5x3 interface chip */
WD8013EBT, /* WD8013EBT : 16-bit ISA, no interface chip */
WD8003ETA, /* WD8003ET/A: 16-bit MCA, no interface chip */
WD8003EA /* WD8003E/A : 16-bit MCA, 5x3 interface chip */
WD8003EA, /* WD8003E/A : 16-bit MCA, 5x3 interface chip */
WD8013EPA
};
extern const device_t wd8003e_device;
@@ -58,5 +59,6 @@ extern const device_t wd8003eb_device;
extern const device_t wd8013ebt_device;
extern const device_t wd8003eta_device;
extern const device_t wd8003ea_device;
extern const device_t wd8013epa_device;
#endif /*NET_WD8003_H*/

View File

@@ -120,6 +120,7 @@ extern const device_t sb_16_device;
extern const device_t sb_16_pnp_device;
extern const device_t sb_16_compat_device;
extern const device_t sb_16_compat_nompu_device;
extern const device_t sb_16_reply_mca_device;
extern const device_t sb_32_pnp_device;
extern const device_t sb_awe32_device;
extern const device_t sb_awe32_pnp_device;

View File

@@ -540,7 +540,6 @@ wd_mca_read(int port, void *priv)
#define MCA_6FC0_IRQS { 3, 4, 10, 15 }
static void
wd_mca_write(int port, uint8_t val, void *priv)
{
@@ -582,6 +581,68 @@ wd_mca_write(int port, uint8_t val, void *priv)
dev->base_address, dev->irq, dev->ram_addr);
}
static void
wd_8013epa_mca_write(int port, uint8_t val, void *priv)
{
wd_t *dev = (wd_t *)priv;
/* MCA does not write registers below 0x0100. */
if (port < 0x0102) return;
/* Save the MCA register value. */
dev->pos_regs[port & 7] = val;
/*
* The PS/2 Model 80 BIOS always enables a card if it finds one,
* even if no resources were assigned yet (because we only added
* the card, but have not run AutoConfig yet...)
*
* So, remove current address, if any.
*/
if (dev->base_address)
wd_io_remove(dev, dev->base_address);
dev->base_address = 0x800 + ((dev->pos_regs[2] & 0xf0) << 8);
switch (dev->pos_regs[5] & 0x0c) {
case 0:
dev->irq = 3;
break;
case 4:
dev->irq = 4;
break;
case 8:
dev->irq = 10;
break;
case 0x0c:
dev->irq = 14;
break;
}
if (dev->pos_regs[3] & 0x10)
dev->ram_size = 0x4000;
else
dev->ram_size = 0x2000;
dev->ram_addr = ((dev->pos_regs[3] & 0x0f) << 13) + 0xc0000;
if (dev->pos_regs[3] & 0x80)
dev->ram_addr += 0xf00000;
/* Initialize the device if fully configured. */
/* Register (new) I/O handler. */
if (dev->pos_regs[2] & 0x01)
wd_io_set(dev, dev->base_address);
mem_mapping_set_addr(&dev->ram_mapping, dev->ram_addr, dev->ram_size);
mem_mapping_disable(&dev->ram_mapping);
if ((dev->msr & WE_MSR_ENABLE_RAM) && (dev->pos_regs[2] & 0x01))
mem_mapping_enable(&dev->ram_mapping);
wdlog("%s: attached IO=0x%X IRQ=%d, RAM addr=0x%06x\n", dev->name,
dev->base_address, dev->irq, dev->ram_addr);
}
static uint8_t
wd_mca_feedb(void *priv)
@@ -624,9 +685,12 @@ wd_init(const device_t *info)
dev->maclocal[5] = (mac & 0xff);
}
if ((dev->board == WD8003ETA) || (dev->board == WD8003EA))
mca_add(wd_mca_read, wd_mca_write, wd_mca_feedb, NULL, dev);
else {
if ((dev->board == WD8003ETA) || (dev->board == WD8003EA) || dev->board == WD8013EPA) {
if (dev->board == WD8013EPA)
mca_add(wd_mca_read, wd_8013epa_mca_write, wd_mca_feedb, NULL, dev);
else
mca_add(wd_mca_read, wd_mca_write, wd_mca_feedb, NULL, dev);
} else {
dev->base_address = device_get_config_hex16("base");
dev->irq = device_get_config_int("irq");
dev->ram_addr = device_get_config_hex20("ram_addr");
@@ -679,12 +743,20 @@ wd_init(const device_t *info)
dev->board_chip = WE_ID_SOFT_CONFIG;
/* Ethernet, MCA, no interface chip, RAM 16k */
case WD8003ETA:
dev->board_chip |= 0x05 | WE_ID_BUS_MCA;
dev->board_chip |= WE_TYPE_WD8013EBT | WE_ID_BUS_MCA;
dev->ram_size = 0x4000;
dev->pos_regs[0] = 0xC0;
dev->pos_regs[1] = 0x6F;
dev->bit16 = 3;
break;
case WD8013EPA:
dev->board_chip = WE_TYPE_WD8013EP | WE_ID_BUS_MCA;
dev->ram_size = device_get_config_int("ram_size");
dev->pos_regs[0] = 0xC8;
dev->pos_regs[1] = 0x61;
dev->bit16 = 3;
break;
}
dev->irr |= WE_IRR_ENABLE_IRQ;
@@ -969,6 +1041,31 @@ static const device_config_t wd8013_config[] = {
{ .name = "", .description = "", .type = CONFIG_END }
};
static const device_config_t wd8013epa_config[] = {
{
.name = "ram_size",
.description = "Initial RAM size",
.type = CONFIG_SELECTION,
.default_string = "",
.default_int = 16384,
.file_filter = "",
.spinner = { 0 },
.selection = {
{ .description = "8 kB", .value = 8192 },
{ .description = "16 kB", .value = 16384 },
{ .description = "" }
},
},
{
.name = "mac",
.description = "MAC Address",
.type = CONFIG_MAC,
.default_string = "",
.default_int = -1
},
{ .name = "", .description = "", .type = CONFIG_END }
};
static const device_config_t mca_mac_config[] = {
{
.name = "mac",
@@ -1050,3 +1147,17 @@ const device_t wd8003ea_device = {
.force_redraw = NULL,
.config = mca_mac_config
};
const device_t wd8013epa_device = {
.name = "Western Digital WD8013EP/A",
.internal_name = "wd8013epa",
.flags = DEVICE_MCA,
.local = WD8013EPA,
.init = wd_init,
.close = wd_close,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = wd8013epa_config
};

View File

@@ -103,6 +103,7 @@ static netcard_t net_cards[] = {
{ &ethernext_mc_device, NULL },
{ &wd8003eta_device, NULL },
{ &wd8003ea_device, NULL },
{ &wd8013epa_device, NULL },
{ &pcnet_am79c973_device, NULL },
{ &pcnet_am79c970a_device, NULL },
{ &rtl8029as_device, NULL },

View File

@@ -20,6 +20,7 @@
typedef struct adgold_t {
int adgold_irq_status;
int irq, dma, hdma;
uint8_t adgold_eeprom[0x1a];
@@ -157,7 +158,7 @@ adgold_update_irq_status(adgold_t *adgold)
adgold->adgold_status = temp;
if ((adgold->adgold_status ^ 0xf) && !adgold->adgold_irq_status) {
picint(0x80);
picint(1 << adgold->irq);
}
adgold->adgold_irq_status = adgold->adgold_status ^ 0xf;
@@ -167,23 +168,26 @@ void
adgold_getsamp_dma(adgold_t *adgold, int channel)
{
int temp;
dma_set_drq(adgold->dma, 1);
if ((adgold->adgold_mma_regs[channel][0xc] & 0x60) && (((adgold->adgold_mma_fifo_end[channel] - adgold->adgold_mma_fifo_start[channel]) & 255) >= 127))
return;
temp = dma_channel_read(1);
if (temp == DMA_NODATA)
temp = dma_channel_read(adgold->dma);
if (temp == DMA_NODATA) {
return;
}
adgold->adgold_mma_fifo[channel][adgold->adgold_mma_fifo_end[channel]] = temp;
adgold->adgold_mma_fifo_end[channel] = (adgold->adgold_mma_fifo_end[channel] + 1) & 255;
adgold->adgold_mma_fifo_end[channel] = (adgold->adgold_mma_fifo_end[channel] + 1) & 255;
if (adgold->adgold_mma_regs[channel][0xc] & 0x60) {
temp = dma_channel_read(1);
temp = dma_channel_read(adgold->dma);
adgold->adgold_mma_fifo[channel][adgold->adgold_mma_fifo_end[channel]] = temp;
adgold->adgold_mma_fifo_end[channel] = (adgold->adgold_mma_fifo_end[channel] + 1) & 255;
adgold->adgold_mma_fifo_end[channel] = (adgold->adgold_mma_fifo_end[channel] + 1) & 255;
}
if (((adgold->adgold_mma_fifo_end[channel] - adgold->adgold_mma_fifo_start[channel]) & 255) >= adgold->adgold_mma_intpos[channel]) {
adgold->adgold_mma_status &= ~(0x01 << channel);
adgold_update_irq_status(adgold);
dma_set_drq(adgold->dma, 0);
}
}
@@ -335,10 +339,11 @@ adgold_write(uint16_t addr, uint8_t val, void *p)
break; /* 7350 Hz*/
}
if (val & 0x80) {
adgold->adgold_mma_enable[0] = 0;
adgold->adgold_mma_enable[0] = 0;
adgold->adgold_mma_fifo_end[0] = adgold->adgold_mma_fifo_start[0] = 0;
adgold->adgold_mma_status &= ~0x01;
adgold_update_irq_status(adgold);
dma_set_drq(adgold->dma, 0);
}
if ((val & 0x01)) /*Start playback*/
{
@@ -347,7 +352,7 @@ adgold_write(uint16_t addr, uint8_t val, void *p)
if (adgold->adgold_mma_regs[0][0xc] & 1) {
if (adgold->adgold_mma_regs[0][0xc] & 0x80) {
adgold->adgold_mma_enable[1] = 1;
adgold->adgold_mma_enable[1] = 1;
adgold->adgold_mma.voice_count[1] = adgold->adgold_mma.voice_latch[1];
while (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) < 128) {
@@ -357,10 +362,12 @@ adgold_write(uint16_t addr, uint8_t val, void *p)
if (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) >= adgold->adgold_mma_intpos[0]) {
adgold->adgold_mma_status &= ~0x01;
adgold_update_irq_status(adgold);
dma_set_drq(adgold->dma, 0);
}
if (((adgold->adgold_mma_fifo_end[1] - adgold->adgold_mma_fifo_start[1]) & 255) >= adgold->adgold_mma_intpos[1]) {
adgold->adgold_mma_status &= ~0x02;
adgold_update_irq_status(adgold);
dma_set_drq(adgold->dma, 0);
}
} else {
while (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) < 128) {
@@ -369,6 +376,7 @@ adgold_write(uint16_t addr, uint8_t val, void *p)
if (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) >= adgold->adgold_mma_intpos[0]) {
adgold->adgold_mma_status &= ~0x01;
adgold_update_irq_status(adgold);
dma_set_drq(adgold->dma, 0);
}
}
}
@@ -379,10 +387,11 @@ adgold_write(uint16_t addr, uint8_t val, void *p)
case 0xb:
if (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) < 128) {
adgold->adgold_mma_fifo[0][adgold->adgold_mma_fifo_end[0]] = val;
adgold->adgold_mma_fifo_end[0] = (adgold->adgold_mma_fifo_end[0] + 1) & 255;
adgold->adgold_mma_fifo_end[0] = (adgold->adgold_mma_fifo_end[0] + 1) & 255;
if (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) >= adgold->adgold_mma_intpos[0]) {
adgold->adgold_mma_status &= ~0x01;
adgold_update_irq_status(adgold);
dma_set_drq(adgold->dma, 0);
}
}
break;
@@ -457,6 +466,7 @@ adgold_write(uint16_t addr, uint8_t val, void *p)
adgold->adgold_mma_fifo_end[1] = adgold->adgold_mma_fifo_start[1] = 0;
adgold->adgold_mma_status &= ~0x02;
adgold_update_irq_status(adgold);
dma_set_drq(adgold->dma, 0);
}
if ((val & 0x01)) /*Start playback*/
{
@@ -479,6 +489,7 @@ adgold_write(uint16_t addr, uint8_t val, void *p)
if (((adgold->adgold_mma_fifo_end[1] - adgold->adgold_mma_fifo_start[1]) & 255) >= adgold->adgold_mma_intpos[1]) {
adgold->adgold_mma_status &= ~0x02;
adgold_update_irq_status(adgold);
dma_set_drq(adgold->dma, 0);
}
}
break;
@@ -525,6 +536,7 @@ adgold_read(uint16_t addr, void *p)
default:
temp = adgold->adgold_38x_regs[adgold->adgold_38x_addr];
break;
}
} else
temp = opl3_read(addr, &adgold->opl);
@@ -877,8 +889,9 @@ adgold_init(const device_t *info)
adgold_t *adgold = malloc(sizeof(adgold_t));
memset(adgold, 0, sizeof(adgold_t));
adgold->dma = device_get_config_int("dma");
adgold->irq = device_get_config_int("irq");
adgold->surround_enabled = device_get_config_int("surround");
adgold->gameport_enabled = device_get_config_int("gameport");
opl3_init(&adgold->opl);
@@ -912,9 +925,9 @@ adgold_init(const device_t *info)
adgold->adgold_eeprom[0x10] = 0xff;
adgold->adgold_eeprom[0x11] = 0x20;
adgold->adgold_eeprom[0x12] = 0x00;
adgold->adgold_eeprom[0x13] = 0x0b; /* IRQ 1, DMA1 */
adgold->adgold_eeprom[0x14] = 0x00; /* DMA2 */
adgold->adgold_eeprom[0x15] = 0x71; /* Port */
adgold->adgold_eeprom[0x13] = 0xa0;
adgold->adgold_eeprom[0x14] = 0x00;
adgold->adgold_eeprom[0x15] = 0x388 / 8; /*Present at 388-38f*/
adgold->adgold_eeprom[0x16] = 0x00;
adgold->adgold_eeprom[0x17] = 0x68;
adgold->adgold_eeprom[0x18] = 0x00; /* Surround */
@@ -927,25 +940,36 @@ adgold_init(const device_t *info)
fclose(f);
}
adgold->adgold_status = 0xf;
adgold->adgold_38x_addr = 0;
adgold->adgold_eeprom[0x13] = 3 | (1 << 3); /*IRQ 7, DMA 1*/
// adgold->adgold_eeprom[0x14] = 3 << 4; /*DMA 3 - Double check this */
adgold->adgold_eeprom[0x14] = 0x00; /*DMA ?*/
adgold->adgold_eeprom[0x15] = 0x388 / 8; /*Present at 388-38f*/
adgold->adgold_status = 0xf;
adgold->adgold_38x_addr = 0;
switch (adgold->irq) {
case 3:
adgold->adgold_eeprom[0x13] |= 0x00;
break;
case 4:
adgold->adgold_eeprom[0x13] |= 0x01;
break;
case 5:
adgold->adgold_eeprom[0x13] |= 0x02;
break;
case 7:
adgold->adgold_eeprom[0x13] |= 0x03;
break;
}
adgold->adgold_eeprom[0x13] |= (adgold->dma << 3);
memcpy(adgold->adgold_38x_regs, adgold->adgold_eeprom, 0x19);
adgold->vol_l = attenuation[adgold->adgold_eeprom[0x04] & 0x3f];
adgold->vol_r = attenuation[adgold->adgold_eeprom[0x05] & 0x3f];
adgold->bass = adgold->adgold_eeprom[0x06] & 0xf;
adgold->treble = adgold->adgold_eeprom[0x07] & 0xf;
adgold->fm_vol_l = (int) (int8_t) (adgold->adgold_eeprom[0x09] - 128);
adgold->fm_vol_r = (int) (int8_t) (adgold->adgold_eeprom[0x0a] - 128);
adgold->vol_l = attenuation[adgold->adgold_eeprom[0x04] & 0x3f];
adgold->vol_r = attenuation[adgold->adgold_eeprom[0x05] & 0x3f];
adgold->bass = adgold->adgold_eeprom[0x06] & 0xf;
adgold->treble = adgold->adgold_eeprom[0x07] & 0xf;
adgold->fm_vol_l = (int) (int8_t) (adgold->adgold_eeprom[0x09] - 128);
adgold->fm_vol_r = (int) (int8_t) (adgold->adgold_eeprom[0x0a] - 128);
adgold->samp_vol_l = (int) (int8_t) (adgold->adgold_eeprom[0x0b] - 128);
adgold->samp_vol_r = (int) (int8_t) (adgold->adgold_eeprom[0x0c] - 128);
adgold->aux_vol_l = (int) (int8_t) (adgold->adgold_eeprom[0x0d] - 128);
adgold->aux_vol_r = (int) (int8_t) (adgold->adgold_eeprom[0x0e] - 128);
adgold->adgold_mma_enable[0] = 0;
adgold->adgold_mma_enable[0] = 0;
adgold->adgold_mma_fifo_start[0] = adgold->adgold_mma_fifo_end[0] = 0;
/*388/389 are handled by adlib_init*/
@@ -982,6 +1006,54 @@ adgold_close(void *p)
static const device_config_t adgold_config[] = {
// clang-format off
{
.name = "irq",
.description = "IRQ",
.type = CONFIG_SELECTION,
.default_string = "",
.default_int = 7,
.file_filter = "",
.spinner = { 0 },
.selection = {
{
.description = "IRQ 3",
.value = 3
},
{
.description = "IRQ 4",
.value = 4
},
{
.description = "IRQ 5",
.value = 5
},
{
.description = "IRQ 7",
.value = 7
},
{ .description = "" }
}
},
{
.name = "dma",
.description = "Low DMA channel",
.type = CONFIG_SELECTION,
.default_string = "",
.default_int = 1,
.file_filter = "",
.spinner = { 0 },
.selection = {
{
.description = "DMA 1",
.value = 1
},
{
.description = "DMA 3",
.value = 3
},
{ .description = "" }
}
},
{
.name = "gameport",
.description = "Enable Game port",

View File

@@ -1198,6 +1198,148 @@ sb_pro_mcv_write(int port, uint8_t val, void *p)
sb_dsp_setdma8(&sb->dsp, sb->pos_regs[4] & 3);
}
static uint8_t
sb_16_reply_mca_read(int port, void *p)
{
sb_t *sb = (sb_t *) p;
uint8_t ret = sb->pos_regs[port & 7];
sb_log("sb_16_reply_mca_read: port=%04x ret=%02x\n", port, ret);
return ret;
}
static void
sb_16_reply_mca_write(int port, uint8_t val, void *p)
{
uint16_t addr, mpu401_addr;
int low_dma, high_dma;
sb_t *sb = (sb_t *) p;
if (port < 0x102)
return;
sb_log("sb_16_reply_mca_write: port=%04x val=%02x\n", port, val);
switch (sb->pos_regs[2] & 0xc4) {
case 4:
addr = 0x220;
break;
case 0x44:
addr = 0x240;
break;
case 0x84:
addr = 0x260;
break;
case 0xc4:
addr = 0x280;
break;
case 0:
addr = 0;
break;
}
if (addr) {
io_removehandler(addr, 0x0004,
opl3_read, NULL, NULL,
opl3_write, NULL, NULL,
&sb->opl);
io_removehandler(addr + 8, 0x0002,
opl3_read, NULL, NULL,
opl3_write, NULL, NULL,
&sb->opl);
io_removehandler(0x0388, 0x0004,
opl3_read, NULL, NULL,
opl3_write, NULL, NULL,
&sb->opl);
io_removehandler(addr + 4, 0x0002,
sb_ct1745_mixer_read, NULL, NULL,
sb_ct1745_mixer_write, NULL, NULL,
sb);
}
/* DSP I/O handler is activated in sb_dsp_setaddr */
sb_dsp_setaddr(&sb->dsp, 0);
mpu401_change_addr(sb->mpu, 0);
gameport_remap(sb->gameport, 0);
sb->pos_regs[port & 7] = val;
if (sb->pos_regs[2] & 1) {
switch (sb->pos_regs[2] & 0xc4) {
case 4:
addr = 0x220;
break;
case 0x44:
addr = 0x240;
break;
case 0x84:
addr = 0x260;
break;
case 0xc4:
addr = 0x280;
break;
case 0:
addr = 0;
break;
}
switch (sb->pos_regs[2] & 0x18) {
case 8:
mpu401_addr = 0x330;
break;
case 0x18:
mpu401_addr = 0x300;
break;
case 0:
mpu401_addr = 0;
break;
}
if (addr) {
io_sethandler(addr, 0x0004,
opl3_read, NULL, NULL,
opl3_write, NULL, NULL,
&sb->opl);
io_sethandler(addr + 8, 0x0002,
opl3_read, NULL, NULL,
opl3_write, NULL, NULL,
&sb->opl);
io_sethandler(0x0388, 0x0004,
opl3_read, NULL, NULL,
opl3_write, NULL, NULL, &sb->opl);
io_sethandler(addr + 4, 0x0002,
sb_ct1745_mixer_read, NULL, NULL,
sb_ct1745_mixer_write, NULL, NULL,
sb);
}
/* DSP I/O handler is activated in sb_dsp_setaddr */
sb_dsp_setaddr(&sb->dsp, addr);
mpu401_change_addr(sb->mpu, mpu401_addr);
gameport_remap(sb->gameport, (sb->pos_regs[2] & 0x20) ? 0x200 : 0);
}
switch (sb->pos_regs[4] & 0x60) {
case 0x20:
sb_dsp_setirq(&sb->dsp, 5);
break;
case 0x40:
sb_dsp_setirq(&sb->dsp, 7);
break;
case 0x60:
sb_dsp_setirq(&sb->dsp, 10);
break;
}
low_dma = sb->pos_regs[3] & 3;
high_dma = (sb->pos_regs[3] >> 4) & 7;
if (!high_dma)
high_dma = low_dma;
sb_dsp_setdma8(&sb->dsp, low_dma);
sb_dsp_setdma16(&sb->dsp, high_dma);
}
static void
sb_16_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv)
{
@@ -1785,6 +1927,41 @@ sb_16_init(const device_t *info)
return sb;
}
static void *
sb_16_reply_mca_init(const device_t *info)
{
sb_t *sb = malloc(sizeof(sb_t));
memset(sb, 0x00, sizeof(sb_t));
sb->opl_enabled = 1;
opl3_init(&sb->opl);
sb_dsp_init(&sb->dsp, SB16, SB_SUBTYPE_DEFAULT, sb);
sb_ct1745_mixer_reset(sb);
sb->mixer_enabled = 1;
sb->mixer_sb16.output_filter = 1;
sound_add_handler(sb_get_buffer_sb16_awe32, sb);
sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb);
sb->mpu = (mpu_t *) malloc(sizeof(mpu_t));
memset(sb->mpu, 0, sizeof(mpu_t));
mpu401_init(sb->mpu, 0, 0, M_UART, device_get_config_int("receive_input401"));
sb_dsp_set_mpu(&sb->dsp, sb->mpu);
if (device_get_config_int("receive_input"))
midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp);
sb->gameport = gameport_add(&gameport_device);
/* I/O handlers activated in sb_pro_mcv_write */
mca_add(sb_16_reply_mca_read, sb_16_reply_mca_write, sb_mcv_feedb, NULL, sb);
sb->pos_regs[0] = 0x38;
sb->pos_regs[1] = 0x51;
return sb;
}
static void *
sb_16_pnp_init(const device_t *info)
{
@@ -3371,6 +3548,20 @@ const device_t sb_16_device = {
.config = sb_16_config
};
const device_t sb_16_reply_mca_device = {
.name = "Sound Blaster 16 Reply MCA",
.internal_name = "sb16_reply_mca",
.flags = DEVICE_MCA,
.local = 0,
.init = sb_16_reply_mca_init,
.close = sb_close,
.reset = NULL,
{ .available = NULL },
.speed_changed = sb_speed_changed,
.force_redraw = NULL,
.config = sb_16_pnp_config
};
const device_t sb_16_pnp_device = {
.name = "Sound Blaster 16 PnP",
.internal_name = "sb16_pnp",

View File

@@ -140,6 +140,7 @@ static const SOUND_CARD sound_cards[] = {
{ &ncr_business_audio_device },
{ &sb_mcv_device },
{ &sb_pro_mcv_device },
{ &sb_16_reply_mca_device },
{ &cmi8338_device },
{ &cmi8738_device },
{ &es1371_device },