spu: implement some more irq details
authornotaz <notasas@gmail.com>
Thu, 2 Nov 2023 17:24:40 +0000 (19:24 +0200)
committernotaz <notasas@gmail.com>
Thu, 2 Nov 2023 23:37:53 +0000 (01:37 +0200)
libretro/pcsx_rearmed#787

plugins/dfsound/dma.c
plugins/dfsound/externals.h
plugins/dfsound/registers.c
plugins/dfsound/spu.c

index 13f9c26..25a0aef 100644 (file)
@@ -52,7 +52,7 @@ void CALLBACK SPUreadDMAMem(unsigned short *pusPSXMem, int iSize,
  }\r
  if ((spu.spuCtrl & CTRL_IRQ) && irq_after < iSize * 2) {\r
   log_unhandled("rdma spu irq: %x/%x+%x\n", irq_addr, spu.spuAddr, iSize * 2);\r
-  spu.irqCallback(irq_after);\r
+  do_irq_io(irq_after);\r
  }\r
  spu.spuAddr = addr;\r
  set_dma_end(iSize, cycles);\r
@@ -91,7 +91,7 @@ void CALLBACK SPUwriteDMAMem(unsigned short *pusPSXMem, int iSize,
     irq_addr, spu.spuAddr, iSize * 2, irq_after);\r
   // this should be consistent with psxdma.c timing\r
   // might also need more delay like in set_dma_end()\r
-  spu.irqCallback(irq_after);\r
+  do_irq_io(irq_after);\r
  }\r
  spu.spuAddr = addr;\r
  set_dma_end(iSize, cycles);\r
index 4f48c65..fef5f9c 100644 (file)
@@ -279,6 +279,7 @@ extern SPUInfo spu;
 void do_samples(unsigned int cycles_to, int do_sync);\r
 void schedule_next_irq(void);\r
 void check_irq_io(unsigned int addr);\r
+void do_irq_io(int cycles_after);\r
 \r
 #define do_samples_if_needed(c, sync, samples) \\r
  do { \\r
index 05968b6..5d79f25 100644 (file)
@@ -132,7 +132,7 @@ void CALLBACK SPUwriteRegister(unsigned long reg, unsigned short val,
    {\r
     //-------------------------------------------------//\r
     case H_SPUaddr:\r
-      spu.spuAddr = (unsigned long) val<<3;\r
+      spu.spuAddr = (unsigned int)val << 3;\r
       //check_irq_io(spu.spuAddr);\r
       break;\r
     //-------------------------------------------------//\r
@@ -144,8 +144,8 @@ void CALLBACK SPUwriteRegister(unsigned long reg, unsigned short val,
       break;\r
     //-------------------------------------------------//\r
     case H_SPUctrl:\r
+      spu.spuStat &= ~STAT_IRQ | val;\r
       if (!(spu.spuCtrl & CTRL_IRQ)) {\r
-        spu.spuStat&=~STAT_IRQ;\r
         if (val & CTRL_IRQ)\r
          schedule_next_irq();\r
       }\r
@@ -153,7 +153,7 @@ void CALLBACK SPUwriteRegister(unsigned long reg, unsigned short val,
       break;\r
     //-------------------------------------------------//\r
     case H_SPUstat:\r
-      spu.spuStat=val&0xf800;\r
+      //spu.spuStat=val&0xf800;\r
       break;\r
     //-------------------------------------------------//\r
     case H_SPUReverbAddr:\r
index 502567b..f202388 100644 (file)
@@ -198,12 +198,15 @@ static void InterpolateDown(sample_buf *sb, int sinc)
 #include "gauss_i.h"
 #include "xa.c"
 
-static void do_irq(void)
+static void do_irq(int cycles_after)
 {
- //if(!(spu.spuStat & STAT_IRQ))
+ if (spu.spuStat & STAT_IRQ)
+  log_unhandled("spu: missed irq?\n");
+ else
  {
   spu.spuStat |= STAT_IRQ;                             // asserted status?
-  if(spu.irqCallback) spu.irqCallback(0);
+  if (spu.irqCallback)
+   spu.irqCallback(cycles_after);
  }
 }
 
@@ -212,7 +215,7 @@ static int check_irq(int ch, unsigned char *pos)
  if((spu.spuCtrl & (CTRL_ON|CTRL_IRQ)) == (CTRL_ON|CTRL_IRQ) && pos == spu.pSpuIrq)
  {
   //printf("ch%d irq %04zx\n", ch, pos - spu.spuMemC);
-  do_irq();
+  do_irq(0);
   return 1;
  }
  return 0;
@@ -225,7 +228,15 @@ void check_irq_io(unsigned int addr)
  if((spu.spuCtrl & (CTRL_ON|CTRL_IRQ)) == (CTRL_ON|CTRL_IRQ) && addr == irq_addr)
  {
   //printf("io   irq %04x\n", irq_addr);
-  do_irq();
+  do_irq(0);
+ }
+}
+
+void do_irq_io(int cycles_after)
+{
+ if ((spu.spuCtrl & (CTRL_ON|CTRL_IRQ)) == (CTRL_ON|CTRL_IRQ))
+ {
+  do_irq(cycles_after);
  }
 }
 
@@ -1182,7 +1193,7 @@ void do_samples(unsigned int cycles_to, int do_direct)
     if (0 < left && left <= ns_to)
      {
       //xprintf("decoder irq %x\n", spu.decode_pos);
-      do_irq();
+      do_irq(0);
      }
    }
   if (!spu.cycles_dma_end || (int)(spu.cycles_dma_end - cycles_to) < 0) {