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:
@@ -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;
|
||||
|
@@ -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*/
|
||||
|
@@ -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;
|
||||
|
@@ -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
|
||||
};
|
||||
|
@@ -103,6 +103,7 @@ static netcard_t net_cards[] = {
|
||||
{ ðernext_mc_device, NULL },
|
||||
{ &wd8003eta_device, NULL },
|
||||
{ &wd8003ea_device, NULL },
|
||||
{ &wd8013epa_device, NULL },
|
||||
{ &pcnet_am79c973_device, NULL },
|
||||
{ &pcnet_am79c970a_device, NULL },
|
||||
{ &rtl8029as_device, NULL },
|
||||
|
@@ -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",
|
||||
|
@@ -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",
|
||||
|
@@ -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 },
|
||||
|
Reference in New Issue
Block a user