From 78c60846942cad7d41d6d23a7c3d2b905ee4b822 Mon Sep 17 00:00:00 2001 From: notaz Date: Wed, 27 Jul 2011 20:10:49 +0300 Subject: [PATCH] spu: handle non-playing channel irqs --- plugins/dfsound/spu.c | 47 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/plugins/dfsound/spu.c b/plugins/dfsound/spu.c index f9c13d4b..780b0917 100644 --- a/plugins/dfsound/spu.c +++ b/plugins/dfsound/spu.c @@ -656,6 +656,53 @@ ENDX: ; } } + // advance "stopped" channels that can cause irqs + // (all chans are always playing on the real thing..) + if(!bIRQReturn && (spuCtrl&CTRL_IRQ)) + for(ch=0;ch pSpuIrq && s_chan[ch].pLoop > pSpuIrq) + continue; + + if(s_chan[ch].iActFreq!=s_chan[ch].iUsedFreq) // new psx frequency? + VoiceChangeFrequency(ch); + + s_chan[ch].spos += s_chan[ch].sinc * NSSIZE; + while(s_chan[ch].spos >= 28 * 0x10000) + { + unsigned char *start=s_chan[ch].pCurr; + int flags = start[1]; + + // Tron Bonne hack, probably wrong (could be wrong memory contents..) + if(flags & ~7) flags = 0; + + if(start == pSpuIrq) + { + do_irq(); + bIRQReturn = 1; + } + else if((flags & 1) && start == s_chan[ch].pLoop) + { + // looping on self + s_chan[ch].pCurr=(unsigned char *)-1; + break; + } + + if((flags&4) && !s_chan[ch].bIgnoreLoop) + s_chan[ch].pLoop=start; + + s_chan[ch].pCurr += 16; + + if(flags & 1) + s_chan[ch].pCurr = s_chan[ch].pLoop; + + s_chan[ch].spos -= 28 * 0x10000; + } + } + if(bIRQReturn && iSPUIRQWait) // special return for "spu irq - wait for cpu action" { iSpuAsyncWait=1; -- 2.39.5