ESS AudioDrive: Fix some regressions and implement DRQ setting in compatibility mode, fixes Windows 3.1x ES1688 drivers.

This commit is contained in:
OBattler
2024-05-12 16:48:43 +02:00
parent 79c2ef95ed
commit d786cf3aa7
2 changed files with 31 additions and 5 deletions

View File

@@ -1492,7 +1492,8 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv)
break; break;
case 0x64: case 0x64:
mixer->regs[mixer->index] &= ~0x8; mixer->regs[mixer->index] = (mixer->regs[mixer->index] & 0xf7) | 0x20;
// mixer->regs[mixer->index] &= ~0x8;
break; break;
case 0x40: case 0x40:
@@ -1615,9 +1616,13 @@ ess_mixer_read(uint16_t addr, void *priv)
ret = 0x0a; ret = 0x0a;
break; break;
case 0x48:
ret = mixer->regs[mixer->index];
break;
/* Return 0x00 so it has bit 3 clear, so NT 5.x drivers don't misdetect it as ES1788. */ /* Return 0x00 so it has bit 3 clear, so NT 5.x drivers don't misdetect it as ES1788. */
case 0x64: case 0x64:
ret = 0x00; ret = (mixer->regs[mixer->index] & 0xf7) | 0x20;
break; break;
default: default:
@@ -3463,6 +3468,7 @@ ess_x688_init(UNUSED(const device_t *info))
} }
ess->mixer_enabled = 1; ess->mixer_enabled = 1;
ess->mixer_ess.regs[0x40] = 0x0a;
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,

View File

@@ -563,6 +563,8 @@ sb_start_dma(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len)
timer_set_delay_u64(&dsp->output_timer, (uint64_t) dsp->sblatcho); timer_set_delay_u64(&dsp->output_timer, (uint64_t) dsp->sblatcho);
dsp->sbleftright = dsp->sbleftright_default; dsp->sbleftright = dsp->sbleftright_default;
dsp->sbdacpos = 0; dsp->sbdacpos = 0;
dma_set_drq(dsp->sb_8_dmanum, 1);
} else { } else {
dsp->sb_16_length = dsp->sb_16_origlength = len; dsp->sb_16_length = dsp->sb_16_origlength = len;
dsp->sb_16_format = format; dsp->sb_16_format = format;
@@ -574,6 +576,11 @@ sb_start_dma(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len)
dsp->sb_16_output = 1; dsp->sb_16_output = 1;
if (!timer_is_enabled(&dsp->output_timer)) if (!timer_is_enabled(&dsp->output_timer))
timer_set_delay_u64(&dsp->output_timer, (uint64_t) dsp->sblatcho); timer_set_delay_u64(&dsp->output_timer, (uint64_t) dsp->sblatcho);
if (dsp->sb_16_dma_supported)
dma_set_drq(dsp->sb_16_dmanum, 1);
else
dma_set_drq(dsp->sb_16_8_dmanum, 1);
} }
/* This will be set later for ESS playback/record modes. */ /* This will be set later for ESS playback/record modes. */
@@ -594,6 +601,8 @@ sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len)
dsp->sb_8_output = 0; dsp->sb_8_output = 0;
if (!timer_is_enabled(&dsp->input_timer)) if (!timer_is_enabled(&dsp->input_timer))
timer_set_delay_u64(&dsp->input_timer, (uint64_t) dsp->sblatchi); timer_set_delay_u64(&dsp->input_timer, (uint64_t) dsp->sblatchi);
dma_set_drq(dsp->sb_8_dmanum, 1);
} else { } else {
dsp->sb_16_length = dsp->sb_16_origlength = len; dsp->sb_16_length = dsp->sb_16_origlength = len;
dsp->sb_16_format = format; dsp->sb_16_format = format;
@@ -605,6 +614,11 @@ sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len)
dsp->sb_16_output = 0; dsp->sb_16_output = 0;
if (!timer_is_enabled(&dsp->input_timer)) if (!timer_is_enabled(&dsp->input_timer))
timer_set_delay_u64(&dsp->input_timer, (uint64_t) dsp->sblatchi); timer_set_delay_u64(&dsp->input_timer, (uint64_t) dsp->sblatchi);
if (dsp->sb_16_dma_supported)
dma_set_drq(dsp->sb_16_dmanum, 1);
else
dma_set_drq(dsp->sb_16_8_dmanum, 1);
} }
memset(dsp->record_buffer, 0, sizeof(dsp->record_buffer)); memset(dsp->record_buffer, 0, sizeof(dsp->record_buffer));
@@ -771,7 +785,10 @@ sb_16_write_dma(void *priv, uint16_t val)
void void
sb_ess_update_irq_drq_readback_regs(sb_dsp_t *dsp, bool legacy) sb_ess_update_irq_drq_readback_regs(sb_dsp_t *dsp, bool legacy)
{ {
uint8_t t = 0x00; sb_t *ess = (sb_t *) dsp->parent;
ess_mixer_t *mixer = &ess->mixer_ess;
uint8_t t = 0x00;
/* IRQ control */ /* IRQ control */
if (legacy) { if (legacy) {
t |= 0x80; t |= 0x80;
@@ -779,6 +796,7 @@ sb_ess_update_irq_drq_readback_regs(sb_dsp_t *dsp, bool legacy)
switch (dsp->sb_irqnum) { switch (dsp->sb_irqnum) {
default: default:
break; break;
case 2:
case 9: case 9:
t |= 0x0; t |= 0x0;
break; break;
@@ -793,6 +811,8 @@ sb_ess_update_irq_drq_readback_regs(sb_dsp_t *dsp, bool legacy)
break; break;
} }
ESSreg(0xB1) = (ESSreg(0xB1) & 0xF0) | t; ESSreg(0xB1) = (ESSreg(0xB1) & 0xF0) | t;
if ((mixer != NULL) && (ess->mpu != NULL) && (((mixer->regs[0x40] >> 5) & 0x7) == 2))
mpu401_setirq(ess->mpu, ess->dsp.sb_irqnum);
/* DRQ control */ /* DRQ control */
t = 0x00; t = 0x00;
@@ -1802,7 +1822,7 @@ sb_read(uint16_t a, void *priv)
switch (a & 0xf) { switch (a & 0xf) {
case 0x6: case 0x6:
ret = 0xff; ret = IS_ESS(dsp) ? 0x00 : 0xff;
break; break;
case 0xA: /* Read data */ case 0xA: /* Read data */
if (dsp->mpu && dsp->uart_midi) if (dsp->mpu && dsp->uart_midi)
@@ -1821,7 +1841,7 @@ sb_read(uint16_t a, void *priv)
dsp->state = DSP_S_NORMAL; dsp->state = DSP_S_NORMAL;
break; break;
case 0xC: /* Write data ready */ case 0xC: /* Write data ready */
if (dsp->state == DSP_S_NORMAL) { if ((dsp->state == DSP_S_NORMAL) || IS_ESS(dsp)) {
if (dsp->sb_8_enable || dsp->sb_type >= SB16) if (dsp->sb_8_enable || dsp->sb_type >= SB16)
dsp->busy_count = (dsp->busy_count + 1) & 3; dsp->busy_count = (dsp->busy_count + 1) & 3;
else else