From d786cf3aa747c71192a239f3606d3d7343869406 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 12 May 2024 16:48:43 +0200 Subject: [PATCH] ESS AudioDrive: Fix some regressions and implement DRQ setting in compatibility mode, fixes Windows 3.1x ES1688 drivers. --- src/sound/snd_sb.c | 10 ++++++++-- src/sound/snd_sb_dsp.c | 26 +++++++++++++++++++++++--- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 80642adbe..364c01557 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -1492,7 +1492,8 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) break; case 0x64: - mixer->regs[mixer->index] &= ~0x8; + mixer->regs[mixer->index] = (mixer->regs[mixer->index] & 0xf7) | 0x20; + // mixer->regs[mixer->index] &= ~0x8; break; case 0x40: @@ -1615,9 +1616,13 @@ ess_mixer_read(uint16_t addr, void *priv) ret = 0x0a; 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. */ case 0x64: - ret = 0x00; + ret = (mixer->regs[mixer->index] & 0xf7) | 0x20; break; default: @@ -3463,6 +3468,7 @@ ess_x688_init(UNUSED(const device_t *info)) } ess->mixer_enabled = 1; + ess->mixer_ess.regs[0x40] = 0x0a; io_sethandler(addr + 4, 0x0002, ess_mixer_read, NULL, NULL, ess_mixer_write, NULL, NULL, diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 9c148339d..e5c2359a0 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -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); dsp->sbleftright = dsp->sbleftright_default; dsp->sbdacpos = 0; + + dma_set_drq(dsp->sb_8_dmanum, 1); } else { dsp->sb_16_length = dsp->sb_16_origlength = len; 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; if (!timer_is_enabled(&dsp->output_timer)) 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. */ @@ -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; if (!timer_is_enabled(&dsp->input_timer)) timer_set_delay_u64(&dsp->input_timer, (uint64_t) dsp->sblatchi); + + dma_set_drq(dsp->sb_8_dmanum, 1); } else { dsp->sb_16_length = dsp->sb_16_origlength = len; 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; if (!timer_is_enabled(&dsp->input_timer)) 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)); @@ -771,7 +785,10 @@ sb_16_write_dma(void *priv, uint16_t val) void 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 */ if (legacy) { t |= 0x80; @@ -779,6 +796,7 @@ sb_ess_update_irq_drq_readback_regs(sb_dsp_t *dsp, bool legacy) switch (dsp->sb_irqnum) { default: break; + case 2: case 9: t |= 0x0; break; @@ -793,6 +811,8 @@ sb_ess_update_irq_drq_readback_regs(sb_dsp_t *dsp, bool legacy) break; } 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 */ t = 0x00; @@ -1802,7 +1822,7 @@ sb_read(uint16_t a, void *priv) switch (a & 0xf) { case 0x6: - ret = 0xff; + ret = IS_ESS(dsp) ? 0x00 : 0xff; break; case 0xA: /* Read data */ if (dsp->mpu && dsp->uart_midi) @@ -1821,7 +1841,7 @@ sb_read(uint16_t a, void *priv) dsp->state = DSP_S_NORMAL; break; 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) dsp->busy_count = (dsp->busy_count + 1) & 3; else