Implement ESS activity flags and improve the timed IRQ triggering via SB DSP commands F2 and F3, fixes ESSCFG 2.01C and the LBA 2 ES(1)688 driver.
This commit is contained in:
@@ -187,6 +187,8 @@ typedef struct sb_t {
|
|||||||
uint8_t pnp_rom[512];
|
uint8_t pnp_rom[512];
|
||||||
|
|
||||||
uint16_t opl_pnp_addr;
|
uint16_t opl_pnp_addr;
|
||||||
|
|
||||||
|
uint16_t midi_addr;
|
||||||
uint16_t gameport_addr;
|
uint16_t gameport_addr;
|
||||||
|
|
||||||
void *opl_mixer;
|
void *opl_mixer;
|
||||||
|
@@ -91,6 +91,8 @@ typedef struct sb_dsp_t {
|
|||||||
uint8_t sbref;
|
uint8_t sbref;
|
||||||
int8_t sbstep;
|
int8_t sbstep;
|
||||||
|
|
||||||
|
uint8_t activity;
|
||||||
|
|
||||||
int sbdacpos;
|
int sbdacpos;
|
||||||
|
|
||||||
int sbleftright;
|
int sbleftright;
|
||||||
|
@@ -1374,6 +1374,70 @@ sb_ct1745_mixer_reset(sb_t *sb)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ess_base_write(uint16_t addr, uint8_t val, void *priv)
|
||||||
|
{
|
||||||
|
sb_t * ess = (sb_t *) priv;
|
||||||
|
|
||||||
|
switch (addr & 0x000f) {
|
||||||
|
case 0x0002:
|
||||||
|
case 0x0003:
|
||||||
|
case 0x0006:
|
||||||
|
case 0x000c:
|
||||||
|
ess->dsp.activity &= 0xdf;
|
||||||
|
break;
|
||||||
|
case 0x0008:
|
||||||
|
case 0x0009:
|
||||||
|
ess->dsp.activity &= 0x7f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t
|
||||||
|
ess_base_read(uint16_t addr, void *priv)
|
||||||
|
{
|
||||||
|
sb_t * ess = (sb_t *) priv;
|
||||||
|
|
||||||
|
switch (addr & 0x000f) {
|
||||||
|
case 0x0002:
|
||||||
|
case 0x0003:
|
||||||
|
case 0x0004: /* Undocumented but tested by the LBA 2 ES688 driver. */
|
||||||
|
case 0x000a:
|
||||||
|
ess->dsp.activity &= 0xdf;
|
||||||
|
break;
|
||||||
|
case 0x0008:
|
||||||
|
case 0x0009:
|
||||||
|
ess->dsp.activity &= 0x7f;
|
||||||
|
break;
|
||||||
|
case 0x000c:
|
||||||
|
case 0x000e:
|
||||||
|
ess->dsp.activity &= 0xbf;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
sb_log("ess_base_read(%04X): %04X, activity now: %02X\n", addr, addr & 0x000f, ess->dsp.activity);
|
||||||
|
|
||||||
|
return 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ess_fm_midi_write(uint16_t addr, uint8_t val, void *priv)
|
||||||
|
{
|
||||||
|
sb_t * ess = (sb_t *) priv;
|
||||||
|
|
||||||
|
ess->dsp.activity &= 0x7f;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t
|
||||||
|
ess_fm_midi_read(uint16_t addr, void *priv)
|
||||||
|
{
|
||||||
|
sb_t * ess = (sb_t *) priv;
|
||||||
|
|
||||||
|
ess->dsp.activity &= 0x7f;
|
||||||
|
|
||||||
|
return 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ess_mixer_write(uint16_t addr, uint8_t val, void *priv)
|
ess_mixer_write(uint16_t addr, uint8_t val, void *priv)
|
||||||
{
|
{
|
||||||
@@ -1500,6 +1564,12 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv)
|
|||||||
{
|
{
|
||||||
uint16_t mpu401_base_addr = 0x300 | ((mixer->regs[0x40] << 1) & 0x30);
|
uint16_t mpu401_base_addr = 0x300 | ((mixer->regs[0x40] << 1) & 0x30);
|
||||||
sb_log("mpu401_base_addr = %04X\n", mpu401_base_addr);
|
sb_log("mpu401_base_addr = %04X\n", mpu401_base_addr);
|
||||||
|
|
||||||
|
io_removehandler(ess->midi_addr, 0x0002,
|
||||||
|
ess_fm_midi_read, NULL, NULL,
|
||||||
|
ess_fm_midi_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
|
|
||||||
gameport_remap(ess->gameport, !(mixer->regs[0x40] & 0x2) ? 0x00 : 0x200);
|
gameport_remap(ess->gameport, !(mixer->regs[0x40] & 0x2) ? 0x00 : 0x200);
|
||||||
|
|
||||||
if (ess->dsp.sb_subtype != SB_SUBTYPE_ESS_ES1688) {
|
if (ess->dsp.sb_subtype != SB_SUBTYPE_ESS_ES1688) {
|
||||||
@@ -1519,7 +1589,8 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
case 0:
|
case 0:
|
||||||
mpu401_change_addr(ess->mpu, 0x00);
|
mpu401_base_addr = 0x0000;
|
||||||
|
mpu401_change_addr(ess->mpu, mpu401_base_addr);
|
||||||
mpu401_setirq(ess->mpu, -1);
|
mpu401_setirq(ess->mpu, -1);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
@@ -1551,6 +1622,11 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv)
|
|||||||
mpu401_setirq(ess->mpu, 10);
|
mpu401_setirq(ess->mpu, 10);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
ess->midi_addr = mpu401_base_addr;
|
||||||
|
io_sethandler(addr, 0x0002,
|
||||||
|
ess_fm_midi_read, NULL, NULL,
|
||||||
|
ess_fm_midi_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2166,15 +2242,36 @@ ess_x688_pnp_config_changed(UNUSED(const uint8_t ld), isapnp_device_config_t *co
|
|||||||
ess->opl.read, NULL, NULL,
|
ess->opl.read, NULL, NULL,
|
||||||
ess->opl.write, NULL, NULL,
|
ess->opl.write, NULL, NULL,
|
||||||
ess->opl.priv);
|
ess->opl.priv);
|
||||||
|
io_removehandler(addr, 0x0004,
|
||||||
|
ess_fm_midi_read, NULL, NULL,
|
||||||
|
ess_fm_midi_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
io_removehandler(addr + 8, 0x0002,
|
io_removehandler(addr + 8, 0x0002,
|
||||||
ess->opl.read, NULL, NULL,
|
ess->opl.read, NULL, NULL,
|
||||||
ess->opl.write, NULL, NULL,
|
ess->opl.write, NULL, NULL,
|
||||||
ess->opl.priv);
|
ess->opl.priv);
|
||||||
|
io_removehandler(addr + 8, 0x0002,
|
||||||
|
ess_fm_midi_read, NULL, NULL,
|
||||||
|
ess_fm_midi_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
io_removehandler(addr + 4, 0x0002,
|
io_removehandler(addr + 4, 0x0002,
|
||||||
ess_mixer_read, NULL, NULL,
|
ess_mixer_read, NULL, NULL,
|
||||||
ess_mixer_write, NULL, NULL,
|
ess_mixer_write, NULL, NULL,
|
||||||
ess);
|
ess);
|
||||||
|
|
||||||
|
io_removehandler(addr + 2, 0x0004,
|
||||||
|
ess_base_read, NULL, NULL,
|
||||||
|
ess_base_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
|
io_removehandler(addr + 6, 0x0001,
|
||||||
|
ess_base_read, NULL, NULL,
|
||||||
|
ess_base_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
|
io_removehandler(addr + 0x0a, 0x0006,
|
||||||
|
ess_base_read, NULL, NULL,
|
||||||
|
ess_base_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
|
|
||||||
ess->mixer_ess.ess_id_str[2] = 0x00;
|
ess->mixer_ess.ess_id_str[2] = 0x00;
|
||||||
ess->mixer_ess.ess_id_str[3] = 0x00;
|
ess->mixer_ess.ess_id_str[3] = 0x00;
|
||||||
|
|
||||||
@@ -2185,10 +2282,23 @@ ess_x688_pnp_config_changed(UNUSED(const uint8_t ld), isapnp_device_config_t *co
|
|||||||
ess->opl.read, NULL, NULL,
|
ess->opl.read, NULL, NULL,
|
||||||
ess->opl.write, NULL, NULL,
|
ess->opl.write, NULL, NULL,
|
||||||
ess->opl.priv);
|
ess->opl.priv);
|
||||||
|
io_removehandler(addr, 0x0004,
|
||||||
|
ess_fm_midi_read, NULL, NULL,
|
||||||
|
ess_fm_midi_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ess->pnp == 3)
|
if (ess->pnp == 3) {
|
||||||
|
addr = ess->midi_addr;
|
||||||
|
if (addr) {
|
||||||
|
ess->midi_addr = 0;
|
||||||
mpu401_change_addr(ess->mpu, 0);
|
mpu401_change_addr(ess->mpu, 0);
|
||||||
|
io_removehandler(addr, 0x0002,
|
||||||
|
ess_fm_midi_read, NULL, NULL,
|
||||||
|
ess_fm_midi_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sb_dsp_setaddr(&ess->dsp, 0);
|
sb_dsp_setaddr(&ess->dsp, 0);
|
||||||
sb_dsp_setirq(&ess->dsp, 0);
|
sb_dsp_setirq(&ess->dsp, 0);
|
||||||
@@ -2204,16 +2314,36 @@ ess_x688_pnp_config_changed(UNUSED(const uint8_t ld), isapnp_device_config_t *co
|
|||||||
ess->opl.read, NULL, NULL,
|
ess->opl.read, NULL, NULL,
|
||||||
ess->opl.write, NULL, NULL,
|
ess->opl.write, NULL, NULL,
|
||||||
ess->opl.priv);
|
ess->opl.priv);
|
||||||
|
io_sethandler(addr, 0x0004,
|
||||||
|
ess_fm_midi_read, NULL, NULL,
|
||||||
|
ess_fm_midi_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
io_sethandler(addr + 8, 0x0002,
|
io_sethandler(addr + 8, 0x0002,
|
||||||
ess->opl.read, NULL, NULL,
|
ess->opl.read, NULL, NULL,
|
||||||
ess->opl.write, NULL, NULL,
|
ess->opl.write, NULL, NULL,
|
||||||
ess->opl.priv);
|
ess->opl.priv);
|
||||||
|
io_sethandler(addr + 8, 0x0002,
|
||||||
|
ess_fm_midi_read, NULL, NULL,
|
||||||
|
ess_fm_midi_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
io_sethandler(addr + 4, 0x0002,
|
io_sethandler(addr + 4, 0x0002,
|
||||||
ess_mixer_read, NULL, NULL,
|
ess_mixer_read, NULL, NULL,
|
||||||
ess_mixer_write, NULL, NULL,
|
ess_mixer_write, NULL, NULL,
|
||||||
ess);
|
ess);
|
||||||
|
|
||||||
sb_dsp_setaddr(&ess->dsp, addr);
|
sb_dsp_setaddr(&ess->dsp, addr);
|
||||||
|
io_sethandler(addr + 2, 0x0004,
|
||||||
|
ess_base_read, NULL, NULL,
|
||||||
|
ess_base_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
|
io_sethandler(addr + 6, 0x0001,
|
||||||
|
ess_base_read, NULL, NULL,
|
||||||
|
ess_base_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
|
io_sethandler(addr + 0x0a, 0x0006,
|
||||||
|
ess_base_read, NULL, NULL,
|
||||||
|
ess_base_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
|
|
||||||
ess->mixer_ess.ess_id_str[2] = (addr >> 8) & 0xff;
|
ess->mixer_ess.ess_id_str[2] = (addr >> 8) & 0xff;
|
||||||
ess->mixer_ess.ess_id_str[3] = addr & 0xff;
|
ess->mixer_ess.ess_id_str[3] = addr & 0xff;
|
||||||
@@ -2226,12 +2356,21 @@ ess_x688_pnp_config_changed(UNUSED(const uint8_t ld), isapnp_device_config_t *co
|
|||||||
ess->opl.read, NULL, NULL,
|
ess->opl.read, NULL, NULL,
|
||||||
ess->opl.write, NULL, NULL,
|
ess->opl.write, NULL, NULL,
|
||||||
ess->opl.priv);
|
ess->opl.priv);
|
||||||
|
io_sethandler(addr, 0x0004,
|
||||||
|
ess_fm_midi_read, NULL, NULL,
|
||||||
|
ess_fm_midi_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ess->pnp == 3) {
|
if (ess->pnp == 3) {
|
||||||
addr = config->io[2].base;
|
addr = config->io[2].base;
|
||||||
if (addr != ISAPNP_IO_DISABLED)
|
if (addr != ISAPNP_IO_DISABLED) {
|
||||||
mpu401_change_addr(ess->mpu, addr);
|
mpu401_change_addr(ess->mpu, addr);
|
||||||
|
io_sethandler(addr, 0x0002,
|
||||||
|
ess_fm_midi_read, NULL, NULL,
|
||||||
|
ess_fm_midi_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val = config->irq[0].irq;
|
val = config->irq[0].irq;
|
||||||
@@ -2312,27 +2451,58 @@ ess_soundpiper_mca_write(const int port, const uint8_t val, void *priv)
|
|||||||
ess->opl.read, NULL, NULL,
|
ess->opl.read, NULL, NULL,
|
||||||
ess->opl.write, NULL, NULL,
|
ess->opl.write, NULL, NULL,
|
||||||
ess->opl.priv);
|
ess->opl.priv);
|
||||||
|
io_removehandler(ess->dsp.sb_addr, 0x0004,
|
||||||
|
ess_fm_midi_read, NULL, NULL,
|
||||||
|
ess_fm_midi_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
io_removehandler(ess->dsp.sb_addr + 8, 0x0002,
|
io_removehandler(ess->dsp.sb_addr + 8, 0x0002,
|
||||||
ess->opl.read, NULL, NULL,
|
ess->opl.read, NULL, NULL,
|
||||||
ess->opl.write, NULL, NULL,
|
ess->opl.write, NULL, NULL,
|
||||||
ess->opl.priv);
|
ess->opl.priv);
|
||||||
|
io_removehandler(ess->dsp.sb_addr + 8, 0x0002,
|
||||||
|
ess_fm_midi_read, NULL, NULL,
|
||||||
|
ess_fm_midi_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
io_removehandler(0x0388, 0x0004,
|
io_removehandler(0x0388, 0x0004,
|
||||||
ess->opl.read, NULL, NULL,
|
ess->opl.read, NULL, NULL,
|
||||||
ess->opl.write, NULL, NULL,
|
ess->opl.write, NULL, NULL,
|
||||||
ess->opl.priv);
|
ess->opl.priv);
|
||||||
|
io_removehandler(0x0388, 0x0004,
|
||||||
|
ess_fm_midi_read, NULL, NULL,
|
||||||
|
ess_fm_midi_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
io_removehandler(ess->dsp.sb_addr + 4, 0x0002,
|
io_removehandler(ess->dsp.sb_addr + 4, 0x0002,
|
||||||
ess_mixer_read, NULL, NULL,
|
ess_mixer_read, NULL, NULL,
|
||||||
ess_mixer_write, NULL, NULL,
|
ess_mixer_write, NULL, NULL,
|
||||||
ess);
|
ess);
|
||||||
|
|
||||||
|
io_removehandler(ess->dsp.sb_addr + 2, 0x0004,
|
||||||
|
ess_base_read, NULL, NULL,
|
||||||
|
ess_base_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
|
io_removehandler(ess->dsp.sb_addr + 6, 0x0001,
|
||||||
|
ess_base_read, NULL, NULL,
|
||||||
|
ess_base_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
|
io_removehandler(ess->dsp.sb_addr + 0x0a, 0x0006,
|
||||||
|
ess_base_read, NULL, NULL,
|
||||||
|
ess_base_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* DSP I/O handler is activated in sb_dsp_setaddr */
|
/* DSP I/O handler is activated in sb_dsp_setaddr */
|
||||||
sb_dsp_setaddr(&ess->dsp, 0);
|
sb_dsp_setaddr(&ess->dsp, 0);
|
||||||
gameport_remap(ess->gameport, 0);
|
gameport_remap(ess->gameport, 0);
|
||||||
|
|
||||||
if (ess->dsp.sb_subtype == SB_SUBTYPE_ESS_ES1688)
|
if (ess->dsp.sb_subtype == SB_SUBTYPE_ESS_ES1688) {
|
||||||
mpu401_change_addr(ess->mpu, 0);
|
mpu401_change_addr(ess->mpu, 0);
|
||||||
|
|
||||||
|
io_removehandler(0x0330, 0x0002,
|
||||||
|
ess_fm_midi_read, NULL, NULL,
|
||||||
|
ess_fm_midi_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
|
}
|
||||||
|
|
||||||
ess->pos_regs[port & 7] = val;
|
ess->pos_regs[port & 7] = val;
|
||||||
|
|
||||||
if (ess->pos_regs[2] & 1) {
|
if (ess->pos_regs[2] & 1) {
|
||||||
@@ -2353,20 +2523,52 @@ ess_soundpiper_mca_write(const int port, const uint8_t val, void *priv)
|
|||||||
ess->opl.read, NULL, NULL,
|
ess->opl.read, NULL, NULL,
|
||||||
ess->opl.write, NULL, NULL,
|
ess->opl.write, NULL, NULL,
|
||||||
ess->opl.priv);
|
ess->opl.priv);
|
||||||
|
io_sethandler(ess->dsp.sb_addr, 0x0004,
|
||||||
|
ess_fm_midi_read, NULL, NULL,
|
||||||
|
ess_fm_midi_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
io_sethandler(ess->dsp.sb_addr + 8, 0x0002,
|
io_sethandler(ess->dsp.sb_addr + 8, 0x0002,
|
||||||
ess->opl.read, NULL, NULL,
|
ess->opl.read, NULL, NULL,
|
||||||
ess->opl.write, NULL, NULL,
|
ess->opl.write, NULL, NULL,
|
||||||
ess->opl.priv);
|
ess->opl.priv);
|
||||||
|
io_sethandler(ess->dsp.sb_addr + 8, 0x0002,
|
||||||
|
ess_fm_midi_read, NULL, NULL,
|
||||||
|
ess_fm_midi_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
io_sethandler(0x0388, 0x0004,
|
io_sethandler(0x0388, 0x0004,
|
||||||
ess->opl.read, NULL, NULL,
|
ess->opl.read, NULL, NULL,
|
||||||
ess->opl.write, NULL, NULL, ess->opl.priv);
|
ess->opl.write, NULL, NULL, ess->opl.priv);
|
||||||
|
io_sethandler(0x0388, 0x0004,
|
||||||
|
ess_fm_midi_read, NULL, NULL,
|
||||||
|
ess_fm_midi_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
io_sethandler(ess->dsp.sb_addr + 4, 0x0002,
|
io_sethandler(ess->dsp.sb_addr + 4, 0x0002,
|
||||||
ess_mixer_read, NULL, NULL,
|
ess_mixer_read, NULL, NULL,
|
||||||
ess_mixer_write, NULL, NULL,
|
ess_mixer_write, NULL, NULL,
|
||||||
ess);
|
ess);
|
||||||
|
|
||||||
if (ess->dsp.sb_subtype == SB_SUBTYPE_ESS_ES1688)
|
io_sethandler(ess->dsp.sb_addr + 2, 0x0004,
|
||||||
|
ess_base_read, NULL, NULL,
|
||||||
|
ess_base_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
|
io_sethandler(ess->dsp.sb_addr + 6, 0x0001,
|
||||||
|
ess_base_read, NULL, NULL,
|
||||||
|
ess_base_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
|
io_sethandler(ess->dsp.sb_addr + 0x0a, 0x0006,
|
||||||
|
ess_base_read, NULL, NULL,
|
||||||
|
ess_base_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
|
|
||||||
|
if (ess->dsp.sb_subtype == SB_SUBTYPE_ESS_ES1688) {
|
||||||
mpu401_change_addr(ess->mpu, ess->pos_regs[3] & 0x02 ? 0x0330 : 0);
|
mpu401_change_addr(ess->mpu, ess->pos_regs[3] & 0x02 ? 0x0330 : 0);
|
||||||
|
|
||||||
|
if (ess->pos_regs[3] & 0x02)
|
||||||
|
io_sethandler(0x0330, 0x0002,
|
||||||
|
ess_fm_midi_read, NULL, NULL,
|
||||||
|
ess_fm_midi_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* DSP I/O handler is activated in sb_dsp_setaddr */
|
/* DSP I/O handler is activated in sb_dsp_setaddr */
|
||||||
@@ -2420,26 +2622,58 @@ ess_chipchat_mca_write(int port, uint8_t val, void *priv)
|
|||||||
ess->opl.read, NULL, NULL,
|
ess->opl.read, NULL, NULL,
|
||||||
ess->opl.write, NULL, NULL,
|
ess->opl.write, NULL, NULL,
|
||||||
ess->opl.priv);
|
ess->opl.priv);
|
||||||
|
io_removehandler(ess->dsp.sb_addr, 0x0004,
|
||||||
|
ess_fm_midi_read, NULL, NULL,
|
||||||
|
ess_fm_midi_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
io_removehandler(ess->dsp.sb_addr + 8, 0x0002,
|
io_removehandler(ess->dsp.sb_addr + 8, 0x0002,
|
||||||
ess->opl.read, NULL, NULL,
|
ess->opl.read, NULL, NULL,
|
||||||
ess->opl.write, NULL, NULL,
|
ess->opl.write, NULL, NULL,
|
||||||
ess->opl.priv);
|
ess->opl.priv);
|
||||||
|
io_removehandler(ess->dsp.sb_addr + 8, 0x0002,
|
||||||
|
ess_fm_midi_read, NULL, NULL,
|
||||||
|
ess_fm_midi_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
io_removehandler(0x0388, 0x0004,
|
io_removehandler(0x0388, 0x0004,
|
||||||
ess->opl.read, NULL, NULL,
|
ess->opl.read, NULL, NULL,
|
||||||
ess->opl.write, NULL, NULL,
|
ess->opl.write, NULL, NULL,
|
||||||
ess->opl.priv);
|
ess->opl.priv);
|
||||||
|
io_removehandler(0x0388, 0x0004,
|
||||||
|
ess_fm_midi_read, NULL, NULL,
|
||||||
|
ess_fm_midi_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
io_removehandler(ess->dsp.sb_addr + 4, 0x0002,
|
io_removehandler(ess->dsp.sb_addr + 4, 0x0002,
|
||||||
ess_mixer_read, NULL, NULL,
|
ess_mixer_read, NULL, NULL,
|
||||||
ess_mixer_write, NULL, NULL,
|
ess_mixer_write, NULL, NULL,
|
||||||
ess);
|
ess);
|
||||||
|
|
||||||
|
io_removehandler(ess->dsp.sb_addr + 2, 0x0004,
|
||||||
|
ess_base_read, NULL, NULL,
|
||||||
|
ess_base_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
|
io_removehandler(ess->dsp.sb_addr + 6, 0x0001,
|
||||||
|
ess_base_read, NULL, NULL,
|
||||||
|
ess_base_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
|
io_removehandler(ess->dsp.sb_addr + 0x0a, 0x0006,
|
||||||
|
ess_base_read, NULL, NULL,
|
||||||
|
ess_base_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* DSP I/O handler is activated in sb_dsp_setaddr */
|
/* DSP I/O handler is activated in sb_dsp_setaddr */
|
||||||
sb_dsp_setaddr(&ess->dsp, 0);
|
sb_dsp_setaddr(&ess->dsp, 0);
|
||||||
gameport_remap(ess->gameport, 0);
|
gameport_remap(ess->gameport, 0);
|
||||||
|
|
||||||
|
if (ess->dsp.sb_subtype == SB_SUBTYPE_ESS_ES1688) {
|
||||||
mpu401_change_addr(ess->mpu, 0);
|
mpu401_change_addr(ess->mpu, 0);
|
||||||
|
|
||||||
|
io_removehandler(0x0330, 0x0002,
|
||||||
|
ess_fm_midi_read, NULL, NULL,
|
||||||
|
ess_fm_midi_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
|
}
|
||||||
|
|
||||||
ess->pos_regs[port & 7] = val;
|
ess->pos_regs[port & 7] = val;
|
||||||
|
|
||||||
if (ess->pos_regs[2] & 1) {
|
if (ess->pos_regs[2] & 1) {
|
||||||
@@ -2450,20 +2684,52 @@ ess_chipchat_mca_write(int port, uint8_t val, void *priv)
|
|||||||
ess->opl.read, NULL, NULL,
|
ess->opl.read, NULL, NULL,
|
||||||
ess->opl.write, NULL, NULL,
|
ess->opl.write, NULL, NULL,
|
||||||
ess->opl.priv);
|
ess->opl.priv);
|
||||||
|
io_sethandler(ess->dsp.sb_addr, 0x0004,
|
||||||
|
ess_fm_midi_read, NULL, NULL,
|
||||||
|
ess_fm_midi_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
io_sethandler(ess->dsp.sb_addr + 8, 0x0002,
|
io_sethandler(ess->dsp.sb_addr + 8, 0x0002,
|
||||||
ess->opl.read, NULL, NULL,
|
ess->opl.read, NULL, NULL,
|
||||||
ess->opl.write, NULL, NULL,
|
ess->opl.write, NULL, NULL,
|
||||||
ess->opl.priv);
|
ess->opl.priv);
|
||||||
|
io_sethandler(ess->dsp.sb_addr + 8, 0x0002,
|
||||||
|
ess_fm_midi_read, NULL, NULL,
|
||||||
|
ess_fm_midi_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
io_sethandler(0x0388, 0x0004,
|
io_sethandler(0x0388, 0x0004,
|
||||||
ess->opl.read, NULL, NULL,
|
ess->opl.read, NULL, NULL,
|
||||||
ess->opl.write, NULL, NULL, ess->opl.priv);
|
ess->opl.write, NULL, NULL, ess->opl.priv);
|
||||||
|
io_sethandler(0x0388, 0x0004,
|
||||||
|
ess_fm_midi_read, NULL, NULL,
|
||||||
|
ess_fm_midi_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
io_sethandler(ess->dsp.sb_addr + 4, 0x0002,
|
io_sethandler(ess->dsp.sb_addr + 4, 0x0002,
|
||||||
ess_mixer_read, NULL, NULL,
|
ess_mixer_read, NULL, NULL,
|
||||||
ess_mixer_write, NULL, NULL,
|
ess_mixer_write, NULL, NULL,
|
||||||
ess);
|
ess);
|
||||||
|
|
||||||
if (ess->dsp.sb_subtype == SB_SUBTYPE_ESS_ES1688)
|
io_sethandler(ess->dsp.sb_addr + 2, 0x0004,
|
||||||
|
ess_base_read, NULL, NULL,
|
||||||
|
ess_base_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
|
io_sethandler(ess->dsp.sb_addr + 6, 0x0001,
|
||||||
|
ess_base_read, NULL, NULL,
|
||||||
|
ess_base_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
|
io_sethandler(ess->dsp.sb_addr + 0x0a, 0x0006,
|
||||||
|
ess_base_read, NULL, NULL,
|
||||||
|
ess_base_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
|
|
||||||
|
if (ess->dsp.sb_subtype == SB_SUBTYPE_ESS_ES1688) {
|
||||||
mpu401_change_addr(ess->mpu, (ess->pos_regs[2] == 0x51) ? 0x0330 : 0);
|
mpu401_change_addr(ess->mpu, (ess->pos_regs[2] == 0x51) ? 0x0330 : 0);
|
||||||
|
|
||||||
|
if (ess->pos_regs[2] == 0x51)
|
||||||
|
io_sethandler(0x0330, 0x0002,
|
||||||
|
ess_fm_midi_read, NULL, NULL,
|
||||||
|
ess_fm_midi_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* DSP I/O handler is activated in sb_dsp_setaddr */
|
/* DSP I/O handler is activated in sb_dsp_setaddr */
|
||||||
@@ -3452,20 +3718,43 @@ ess_x688_init(UNUSED(const device_t *info))
|
|||||||
ess_mixer_reset(ess);
|
ess_mixer_reset(ess);
|
||||||
|
|
||||||
/* DSP I/O handler is activated in sb_dsp_setaddr */
|
/* DSP I/O handler is activated in sb_dsp_setaddr */
|
||||||
{
|
|
||||||
io_sethandler(addr, 0x0004,
|
io_sethandler(addr, 0x0004,
|
||||||
ess->opl.read, NULL, NULL,
|
ess->opl.read, NULL, NULL,
|
||||||
ess->opl.write, NULL, NULL,
|
ess->opl.write, NULL, NULL,
|
||||||
ess->opl.priv);
|
ess->opl.priv);
|
||||||
|
io_sethandler(addr, 0x0004,
|
||||||
|
ess_fm_midi_read, NULL, NULL,
|
||||||
|
ess_fm_midi_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
io_sethandler(addr + 8, 0x0002,
|
io_sethandler(addr + 8, 0x0002,
|
||||||
ess->opl.read, NULL, NULL,
|
ess->opl.read, NULL, NULL,
|
||||||
ess->opl.write, NULL, NULL,
|
ess->opl.write, NULL, NULL,
|
||||||
ess->opl.priv);
|
ess->opl.priv);
|
||||||
|
io_sethandler(addr + 8, 0x0002,
|
||||||
|
ess_fm_midi_read, NULL, NULL,
|
||||||
|
ess_fm_midi_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
io_sethandler(0x0388, 0x0004,
|
io_sethandler(0x0388, 0x0004,
|
||||||
ess->opl.read, NULL, NULL,
|
ess->opl.read, NULL, NULL,
|
||||||
ess->opl.write, NULL, NULL,
|
ess->opl.write, NULL, NULL,
|
||||||
ess->opl.priv);
|
ess->opl.priv);
|
||||||
}
|
io_sethandler(0x0388, 0x0004,
|
||||||
|
ess_fm_midi_read, NULL, NULL,
|
||||||
|
ess_fm_midi_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
|
|
||||||
|
io_sethandler(addr + 2, 0x0004,
|
||||||
|
ess_base_read, NULL, NULL,
|
||||||
|
ess_base_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
|
io_sethandler(addr + 6, 0x0001,
|
||||||
|
ess_base_read, NULL, NULL,
|
||||||
|
ess_base_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
|
io_sethandler(addr + 0x0a, 0x0006,
|
||||||
|
ess_base_read, NULL, NULL,
|
||||||
|
ess_base_write, NULL, NULL,
|
||||||
|
ess);
|
||||||
|
|
||||||
ess->mixer_enabled = 1;
|
ess->mixer_enabled = 1;
|
||||||
ess->mixer_ess.regs[0x40] = 0x0a;
|
ess->mixer_ess.regs[0x40] = 0x0a;
|
||||||
|
@@ -726,6 +726,8 @@ sb_8_read_dma(void *priv)
|
|||||||
sb_dsp_t *dsp = (sb_dsp_t *) priv;
|
sb_dsp_t *dsp = (sb_dsp_t *) priv;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
dsp->activity &= 0xdf;
|
||||||
|
|
||||||
if (dsp->sb_8_dmanum >= 4) {
|
if (dsp->sb_8_dmanum >= 4) {
|
||||||
if (dsp->dma_ff) {
|
if (dsp->dma_ff) {
|
||||||
uint32_t temp = (dsp->dma_data & 0xff00) >> 8;
|
uint32_t temp = (dsp->dma_data & 0xff00) >> 8;
|
||||||
@@ -750,7 +752,9 @@ sb_8_read_dma(void *priv)
|
|||||||
int
|
int
|
||||||
sb_8_write_dma(void *priv, uint8_t val)
|
sb_8_write_dma(void *priv, uint8_t val)
|
||||||
{
|
{
|
||||||
const sb_dsp_t *dsp = (sb_dsp_t *) priv;
|
sb_dsp_t *dsp = (sb_dsp_t *) priv;
|
||||||
|
|
||||||
|
dsp->activity &= 0xdf;
|
||||||
|
|
||||||
return dma_channel_write(dsp->sb_8_dmanum, val) == DMA_NODATA;
|
return dma_channel_write(dsp->sb_8_dmanum, val) == DMA_NODATA;
|
||||||
}
|
}
|
||||||
@@ -770,11 +774,13 @@ sb_8_write_dma(void *priv, uint8_t val)
|
|||||||
int
|
int
|
||||||
sb_16_read_dma(void *priv)
|
sb_16_read_dma(void *priv)
|
||||||
{
|
{
|
||||||
const sb_dsp_t *dsp = (sb_dsp_t *) priv;
|
sb_dsp_t *dsp = (sb_dsp_t *) priv;
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
int dma_ch = dsp->sb_16_dmanum;
|
int dma_ch = dsp->sb_16_dmanum;
|
||||||
|
|
||||||
|
dsp->activity &= 0xdf;
|
||||||
|
|
||||||
if (dsp->sb_16_dma_enabled && dsp->sb_16_dma_supported && !dsp->sb_16_dma_translate && (dma_ch != 4))
|
if (dsp->sb_16_dma_enabled && dsp->sb_16_dma_supported && !dsp->sb_16_dma_translate && (dma_ch != 4))
|
||||||
ret = dma_channel_read(dma_ch);
|
ret = dma_channel_read(dma_ch);
|
||||||
else {
|
else {
|
||||||
@@ -808,10 +814,12 @@ sb_16_read_dma(void *priv)
|
|||||||
int
|
int
|
||||||
sb_16_write_dma(void *priv, uint16_t val)
|
sb_16_write_dma(void *priv, uint16_t val)
|
||||||
{
|
{
|
||||||
const sb_dsp_t *dsp = (sb_dsp_t *) priv;
|
sb_dsp_t *dsp = (sb_dsp_t *) priv;
|
||||||
int dma_ch = dsp->sb_16_dmanum;
|
int dma_ch = dsp->sb_16_dmanum;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
dsp->activity &= 0xdf;
|
||||||
|
|
||||||
if (dsp->sb_16_dma_enabled && dsp->sb_16_dma_supported && !dsp->sb_16_dma_translate && (dma_ch != 4))
|
if (dsp->sb_16_dma_enabled && dsp->sb_16_dma_supported && !dsp->sb_16_dma_translate && (dma_ch != 4))
|
||||||
ret = dma_channel_write(dma_ch, val) == DMA_NODATA;
|
ret = dma_channel_write(dma_ch, val) == DMA_NODATA;
|
||||||
else {
|
else {
|
||||||
@@ -1723,17 +1731,14 @@ sb_exec_command(sb_dsp_t *dsp)
|
|||||||
break;
|
break;
|
||||||
case 0xF2: /* Trigger 8-bit IRQ */
|
case 0xF2: /* Trigger 8-bit IRQ */
|
||||||
sb_dsp_log("Trigger 8-bit IRQ\n");
|
sb_dsp_log("Trigger 8-bit IRQ\n");
|
||||||
if (!timer_is_enabled(&dsp->irq_timer)) {
|
timer_set_delay_u64(&dsp->irq_timer, (10ULL * TIMER_USEC));
|
||||||
timer_set_delay_u64(&dsp->irq_timer, (100ULL * TIMER_USEC));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 0xF3: /* Trigger 16-bit IRQ */
|
case 0xF3: /* Trigger 16-bit IRQ */
|
||||||
sb_dsp_log("Trigger 16-bit IRQ\n");
|
sb_dsp_log("Trigger 16-bit IRQ\n");
|
||||||
if (IS_ESS(dsp))
|
if (IS_ESS(dsp))
|
||||||
dsp->ess_irq_generic = true;
|
dsp->ess_irq_generic = true;
|
||||||
else if (!timer_is_enabled(&dsp->irq16_timer)) {
|
else
|
||||||
timer_set_delay_u64(&dsp->irq16_timer, (100ULL * TIMER_USEC));
|
timer_set_delay_u64(&dsp->irq16_timer, (10ULL * TIMER_USEC));
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 0xF8:
|
case 0xF8:
|
||||||
if (dsp->sb_type < SB16)
|
if (dsp->sb_type < SB16)
|
||||||
@@ -1886,7 +1891,11 @@ sb_read(uint16_t a, void *priv)
|
|||||||
|
|
||||||
switch (a & 0xf) {
|
switch (a & 0xf) {
|
||||||
case 0x6:
|
case 0x6:
|
||||||
ret = IS_ESS(dsp) ? 0x00 : 0xff;
|
if (IS_ESS(dsp)) {
|
||||||
|
ret = (dsp->espcm_fifo_reset & 0x03) | 0x08 | (dsp->activity & 0xe0);
|
||||||
|
dsp->activity |= 0xe0;
|
||||||
|
} else
|
||||||
|
ret = 0xff;
|
||||||
break;
|
break;
|
||||||
case 0xA: /* Read data */
|
case 0xA: /* Read data */
|
||||||
if (dsp->mpu && dsp->uart_midi)
|
if (dsp->mpu && dsp->uart_midi)
|
||||||
@@ -2075,6 +2084,7 @@ sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent)
|
|||||||
dsp->sb_type = type;
|
dsp->sb_type = type;
|
||||||
dsp->sb_subtype = subtype;
|
dsp->sb_subtype = subtype;
|
||||||
dsp->parent = parent;
|
dsp->parent = parent;
|
||||||
|
dsp->activity = 0xe0;
|
||||||
|
|
||||||
/* Default values. Use sb_dsp_setxxx() methods to change. */
|
/* Default values. Use sb_dsp_setxxx() methods to change. */
|
||||||
dsp->sb_irqnum = 7;
|
dsp->sb_irqnum = 7;
|
||||||
|
Reference in New Issue
Block a user