dma: don't generate irqs after aborted DMA
authornotaz <notasas@gmail.com>
Wed, 29 Jun 2011 11:35:10 +0000 (14:35 +0300)
committernotaz <notasas@gmail.com>
Thu, 7 Jul 2011 21:15:20 +0000 (00:15 +0300)
An idea from Shalma.
Verified on real thing with DMA2.

libpcsxcore/cdrom.c
libpcsxcore/mdec.c
libpcsxcore/psxdma.c

index 33b76fa..1569839 100644 (file)
@@ -2018,8 +2018,11 @@ void psxDma3(u32 madr, u32 bcr, u32 chcr) {
 
 void cdrDmaInterrupt()
 {
-       HW_DMA3_CHCR &= SWAP32(~0x01000000);
-       DMA_INTERRUPT(3);
+       if (HW_DMA3_CHCR & SWAP32(0x01000000))
+       {
+               HW_DMA3_CHCR &= SWAP32(~0x01000000);
+               DMA_INTERRUPT(3);
+       }
 }
 
 void cdrReset() {
index b25b961..6cf2886 100644 (file)
@@ -531,8 +531,11 @@ void psxDma0(u32 adr, u32 bcr, u32 chcr) {
 
 void mdec0Interrupt()
 {
-       HW_DMA0_CHCR &= SWAP32(~0x01000000);
-       DMA_INTERRUPT(0);
+       if (HW_DMA0_CHCR & SWAP32(0x01000000))
+       {
+               HW_DMA0_CHCR &= SWAP32(~0x01000000);
+               DMA_INTERRUPT(0);
+       }
 }
 
 #define SIZE_OF_24B_BLOCK (16*16*3)
@@ -651,22 +654,21 @@ void mdec1Interrupt() {
         *
         */
 
-       /* this else if avoid to read outside memory */
-       if(mdec.rl >= mdec.rl_end) {
-               mdec.reg1 &= ~MDEC1_STP;
-               HW_DMA0_CHCR &= SWAP32(~0x01000000);
-               DMA_INTERRUPT(0);
-               mdec.reg1 &= ~MDEC1_BUSY;
-       } else if (SWAP16(*(mdec.rl)) == MDEC_END_OF_DATA) {
-               mdec.reg1 &= ~MDEC1_STP;
-               HW_DMA0_CHCR &= SWAP32(~0x01000000);
-               DMA_INTERRUPT(0);
-               mdec.reg1 &= ~MDEC1_BUSY;
+       /* MDEC_END_OF_DATA avoids read outside memory */
+       if (mdec.rl >= mdec.rl_end || SWAP16(*(mdec.rl)) == MDEC_END_OF_DATA) {
+               mdec.reg1 &= ~(MDEC1_STP|MDEC1_BUSY);
+               if (HW_DMA0_CHCR & SWAP32(0x01000000))
+               {
+                       HW_DMA0_CHCR &= SWAP32(~0x01000000);
+                       DMA_INTERRUPT(0);
+               }
        }
 
-       HW_DMA1_CHCR &= SWAP32(~0x01000000);
-       DMA_INTERRUPT(1);
-       return;
+       if (HW_DMA1_CHCR & SWAP32(0x01000000))
+       {
+               HW_DMA1_CHCR &= SWAP32(~0x01000000);
+               DMA_INTERRUPT(1);
+       }
 }
 
 int mdecFreeze(gzFile f, int Mode) {
index df79b6d..6d7981f 100644 (file)
 // Dma3   in CdRom.c
 
 void spuInterrupt() {
-       HW_DMA4_CHCR &= SWAP32(~0x01000000);
-       DMA_INTERRUPT(4);
+       if (HW_DMA4_CHCR & SWAP32(0x01000000))
+       {
+               HW_DMA4_CHCR &= SWAP32(~0x01000000);
+               DMA_INTERRUPT(4);
+       }
 }
 
 void psxDma4(u32 madr, u32 bcr, u32 chcr) { // SPU
@@ -192,8 +195,11 @@ void psxDma2(u32 madr, u32 bcr, u32 chcr) { // GPU
 }
 
 void gpuInterrupt() {
-       HW_DMA2_CHCR &= SWAP32(~0x01000000);
-       DMA_INTERRUPT(2);
+       if (HW_DMA2_CHCR & SWAP32(0x01000000))
+       {
+               HW_DMA2_CHCR &= SWAP32(~0x01000000);
+               DMA_INTERRUPT(2);
+       }
 }
 
 void psxDma6(u32 madr, u32 bcr, u32 chcr) {
@@ -239,6 +245,9 @@ void psxDma6(u32 madr, u32 bcr, u32 chcr) {
 
 void gpuotcInterrupt()
 {
-       HW_DMA6_CHCR &= SWAP32(~0x01000000);
-       DMA_INTERRUPT(6);
+       if (HW_DMA6_CHCR & SWAP32(0x01000000))
+       {
+               HW_DMA6_CHCR &= SWAP32(~0x01000000);
+               DMA_INTERRUPT(6);
+       }
 }