From fdc5a0620031e3f049b121479d62d69005e3c1ab Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 11 Jun 2018 14:51:22 +0000 Subject: [PATCH] No irq generating when masking the IRQ channel. Fixes later sci games and bug #482. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4113 --- src/hardware/sblaster.cpp | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index d6d2a9da..9058df08 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -273,11 +273,27 @@ static INLINE void DSP_FlushData(void) { sb.dsp.out.pos=0; } +static double last_dma_callback = 0.0f; + static void DSP_DMA_CallBack(DmaChannel * chan, DMAEvent event) { if (chan!=sb.dma.chan || event==DMA_REACHED_TC) return; else if (event==DMA_MASKED) { if (sb.mode==MODE_DMA) { - GenerateDMASound(sb.dma.min); + //Catch up to current time, but don't generate an IRQ! + //Fixes problems with later sci games. + double t = PIC_FullIndex() - last_dma_callback; + Bitu s = static_cast(sb.dma.rate * t / 1000.0f); + if (s > sb.dma.min) { + LOG(LOG_SB,LOG_NORMAL)("limiting amount masked to sb.dma.min"); + s = sb.dma.min; + } + Bitu min_size = sb.dma.mul >> SB_SH; + if (!min_size) min_size = 1; + min_size *= 2; + if (sb.dma.left > min_size) { + if (s > (sb.dma.left-min_size)) s = sb.dma.left - min_size; + GenerateDMASound(s); + } sb.mode=MODE_DMA_MASKED; // DSP_ChangeMode(MODE_DMA_MASKED); LOG(LOG_SB,LOG_NORMAL)("DMA masked,stopping output, left %d",chan->currcnt); @@ -394,12 +410,15 @@ INLINE Bit8u decode_ADPCM_3_sample(Bit8u sample,Bit8u & reference,Bits& scale) { static void GenerateDMASound(Bitu size) { Bitu read=0;Bitu done=0;Bitu i=0; + last_dma_callback = PIC_FullIndex(); if(sb.dma.autoinit) { if (sb.dma.left <= size) size = sb.dma.left; - } else if (sb.dma.left <= sb.dma.min) - size = sb.dma.left; + } else { + if (sb.dma.left <= sb.dma.min) + size = sb.dma.left; + } switch (sb.dma.mode) { case DSP_DMA_2: