1
0
Fork 0

Fix SBlaster issue with counter not being restarted with an autoinit transfer

Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4077
This commit is contained in:
Sjoerd van der Berg 2018-02-13 22:07:41 +00:00
parent 06337c9b13
commit eb2448316b

View file

@ -73,7 +73,7 @@ enum DSP_MODES {
MODE_DMA_MASKED
};
enum DMA_MODES {
DSP_DMA_NONE,
DSP_DMA_2,DSP_DMA_3,DSP_DMA_4,DSP_DMA_8,
@ -601,21 +601,11 @@ static void DSP_DoDMATransfer(DMA_MODES mode,Bitu freq,bool autoinit, bool stere
char const * type;
//Fill up before changing state?
sb.chan->FillUp();
//No active autoinit transfer then just assume it's a completely new one
if (sb.mode != MODE_DMA || !sb.dma.autoinit) {
sb.dma.left = sb.dma.total;
//The new transfer won't be autoinit so can clear the total now
if (!autoinit) {
sb.dma.total = 0;
}
//Starting a new transfer might as well clear the irq's
sb.irq.pending_8bit = false;
sb.irq.pending_16bit = false;
}
sb.mode = MODE_DMA_MASKED;
sb.dma.mode=mode;
sb.dma.stereo=stereo;
sb.dma.autoinit = autoinit;
//Starting a new transfer will clear any active irqs?
sb.irq.pending_8bit = false;
sb.irq.pending_16bit = false;
PIC_DeActivateIRQ(sb.hw.irq);
switch (mode) {
case DSP_DMA_2:
@ -646,21 +636,42 @@ static void DSP_DoDMATransfer(DMA_MODES mode,Bitu freq,bool autoinit, bool stere
LOG(LOG_SB,LOG_ERROR)("DSP:Illegal transfer mode %d",mode);
return;
}
if (sb.dma.stereo) sb.dma.mul*=2;
#if (C_DEBUG)
LOG(LOG_SB, LOG_NORMAL)("DMA Transfer:%s %s %s freq %d rate %d size %d",
type,
stereo ? "Stereo" : "Mono",
autoinit ? "Auto-Init" : "Single-Cycle",
freq, sb.dma.rate, sb.dma.total
);
#endif
//Going from an active autoinit into a single cycle
if (sb.mode >= MODE_DMA && sb.dma.autoinit && !autoinit) {
//Don't do anything, the total will flip over on the next transfer
}
//Just a normal single cycle transfer
else if (!autoinit) {
sb.dma.left = sb.dma.total;
sb.dma.total = 0;
}
//Going into an autoinit transfer
else {
//Transfer full cycle again
sb.dma.left = sb.dma.total;
}
//Double the reading speed for stereo mode
if (sb.dma.stereo)
sb.dma.mul*=2;
sb.dma.rate=(sb.freq*sb.dma.mul) >> SB_SH;
sb.dma.min=(sb.dma.rate*3)/1000;
sb.chan->SetFreq(freq);
sb.dma.mode=mode;
sb.dma.mode = mode;
sb.dma.stereo = stereo;
sb.dma.autoinit = autoinit;
PIC_RemoveEvents(END_DMA_Event);
//Set to be masked, the dma call can change this again.
sb.mode = MODE_DMA_MASKED;
sb.dma.chan->Register_Callback(DSP_DMA_CallBack);
#if (C_DEBUG)
LOG(LOG_SB,LOG_NORMAL)("DMA Transfer:%s %s %s freq %d rate %d size %d",
type,
sb.dma.stereo ? "Stereo" : "Mono",
sb.dma.autoinit ? "Auto-Init" : "Single-Cycle",
freq,sb.dma.rate,sb.dma.total
);
#endif
}
static void DSP_PrepareDMA_Old(DMA_MODES mode,bool autoinit,bool sign) {