CMI8x38: Some SB emulation fixes

This commit is contained in:
RichardG867
2022-03-12 16:45:46 -03:00
parent ed792c0321
commit a924622216

View File

@@ -82,8 +82,7 @@ typedef struct _cmi8x38_ {
cmi8x38_dma_t dma[2];
uint16_t tdma_base_addr, tdma_base_count;
uint8_t prev_mask;
int tdma_8, tdma_16, tdma_mask;
int tdma_8, tdma_16, tdma_mask, prev_mask;
int master_vol_l, master_vol_r, cd_vol_l, cd_vol_r;
} cmi8x38_t;
@@ -173,7 +172,11 @@ cmi8x38_sb_dma_post(cmi8x38_t *dev, uint16_t *addr, uint16_t *count, int channel
/* Copy TDMA registers to DMA on CMI8738+. Everything so far suggests that
those chips use PCI bus mastering to directly write to the DMA registers. */
#if 0 /* TSRs don't set ENWR8237, except for the patched C3DPCI - does that bit have no effect? */
if ((dev->type != CMEDIA_CMI8338) && (dev->io_regs[0x17] & 0x10)) {
#else
if (dev->type != CMEDIA_CMI8338) {
#endif
if (channel & 4)
dma[channel].ab = (dma[channel].ab & 0xfffe0000) | ((*addr) << 1);
else
@@ -196,6 +199,11 @@ cmi8x38_sb_dma_post(cmi8x38_t *dev, uint16_t *addr, uint16_t *count, int channel
/* Mask TDMA. */
dev->tdma_mask |= 1 << channel;
}
/* Set the mysterious LHBTOG bit, assuming it corresponds to
the 8237 channel status bit. Nothing appears to read it. */
dev->io_regs[0x10] |= 0x40;
return DMA_OVER;
}
return 0;
@@ -309,29 +317,34 @@ cmi8x38_dma_write(uint16_t addr, uint8_t val, void *priv)
if (!(dev->io_regs[0x27] & 0x01))
return;
/* Write TDMA registers if this is a TDMA channel. */
/* Stop if this is not a TDMA channel. Also set or
clear the high channel flag while we're here. */
int channel;
if (addr < 0x08)
if (addr < 0x08) {
channel = addr >> 1;
else
if (channel != dev->tdma_8)
return;
dev->io_regs[0x10] &= ~0x20;
} else {
channel = 4 | ((addr >> 2) & 3);
if ((channel == dev->tdma_8) || (channel == dev->tdma_16)) {
if (channel != dev->tdma_16)
return;
dev->io_regs[0x10] |= 0x20;
}
/* Write base address and count. */
uint16_t *addr = (uint16_t *) &dev->io_regs[0x1c],
uint16_t *daddr = (uint16_t *) &dev->io_regs[0x1c],
*count = (uint16_t *) &dev->io_regs[0x1e];
*addr = dev->tdma_base_addr = dma[channel].ab >> !!(channel & 4);
*daddr = dev->tdma_base_addr = dma[channel].ab >> !!(channel & 4);
*count = dev->tdma_base_count = dma[channel].cb;
cmi8x38_log("CMI8x38: Starting TDMA on DMA %d with addr %08X count %04X\n",
channel,
(channel & 4) ? ((dma[channel].ab & 0xfffe0000) | ((*addr) << 1)) : ((dma[channel].ab & 0xffff0000) | *addr),
(channel & 4) ? ((dma[channel].ab & 0xfffe0000) | ((*daddr) << 1)) : ((dma[channel].ab & 0xffff0000) | *daddr),
*count);
/* Set high channel flag. */
if (channel & 4)
dev->io_regs[0x10] |= 0x20;
else
dev->io_regs[0x10] &= ~0x20;
}
/* Clear the mysterious LHBTOG bit, assuming it corresponds to
the 8237 channel status bit. Nothing appears to read it. */
dev->io_regs[0x10] &= ~0x40;
}
static void
@@ -655,8 +668,14 @@ cmi8x38_write(uint16_t addr, uint8_t val, void *priv)
case 0x02:
/* Reset DMA channels if requested. */
if (val & 0x04)
if (val & 0x04) {
val &= ~0x01;
if (dev->sb->dsp.sb_8_enable || dev->sb->dsp.sb_16_enable || dev->sb->dsp.sb_irq8 || dev->sb->dsp.sb_irq16) {
dev->sb->dsp.sb_8_enable = dev->sb->dsp.sb_16_enable = dev->sb->dsp.sb_irq8 = dev->sb->dsp.sb_irq16 = 0;
cmi8x38_update_irqs(dev);
}
}
if (val & 0x08)
val &= ~0x02;