32x: improve irq handling + few bugfixes
authornotaz <notasas@gmail.com>
Sat, 23 Jan 2010 23:36:58 +0000 (23:36 +0000)
committernotaz <notasas@gmail.com>
Sat, 23 Jan 2010 23:36:58 +0000 (23:36 +0000)
git-svn-id: file:///home/notaz/opt/svn/PicoDrive@866 be3aeb3a-fb24-0410-a615-afba39da0efa

cpu/sh2/compiler.c
cpu/sh2/mame/sh2pico.c
cpu/sh2/sh2.c
cpu/sh2/sh2.h
pico/32x/32x.c
pico/32x/memory.c
pico/32x/pwm.c
pico/pico.c
pico/pico_int.h
platform/gp2x/version.h

index 7f0ba66..9861a85 100644 (file)
@@ -17,7 +17,6 @@
  * - some constant propagation
  *
  * TODO:
- * - proper SMC handling
  * - better constant propagation
  * - stack caching?
  * - bug fixing
index a65638b..233e0a1 100644 (file)
@@ -74,15 +74,6 @@ void sh2_execute(SH2 *sh2_, int cycles)
        {
                UINT32 opcode;
 
-               /* FIXME: Darxide doesn't like this */
-               if (sh2->test_irq && !sh2->delay && sh2->pending_level > ((sh2->sr >> 4) & 0x0f))
-               {
-                       int level = sh2->pending_level;
-                       int vector = sh2->irq_callback(sh2, level);
-                       sh2_do_irq(sh2, level, vector);
-                       sh2->test_irq = 0;
-               }
-
                if (sh2->delay)
                {
                        sh2->ppc = sh2->delay;
@@ -119,6 +110,15 @@ void sh2_execute(SH2 *sh2_, int cycles)
                }
 
                sh2->icount--;
+
+               if (sh2->test_irq && !sh2->delay && sh2->pending_level > ((sh2->sr >> 4) & 0x0f))
+               {
+                       int level = sh2->pending_level;
+                       int vector = sh2->irq_callback(sh2, level);
+                       sh2_do_irq(sh2, level, vector);
+                       sh2->test_irq = 0;
+               }
+
        }
        while (sh2->icount > 0 || sh2->delay);  /* can't interrupt before delay */
 
index a873d18..80c458f 100644 (file)
@@ -54,15 +54,23 @@ void sh2_do_irq(SH2 *sh2, int level, int vector)
 //     sh2->icount -= 13;
 }
 
-void sh2_irl_irq(SH2 *sh2, int level)
+void sh2_irl_irq(SH2 *sh2, int level, int nested_call)
 {
        sh2->pending_irl = level;
-       if (level > sh2->pending_int_irq)
-               sh2->pending_level = level;
-       else
-               sh2->pending_level = sh2->pending_int_irq;
+       if (level < sh2->pending_int_irq)
+               level = sh2->pending_int_irq;
+       sh2->pending_level = level;
 
-       sh2->test_irq = 1;
+       if (!nested_call) {
+               // not in memhandler, so handle this now (recompiler friendly)
+               // do this to avoid missing irqs that other SH2 might clear
+               if (level > ((sh2->sr >> 4) & 0x0f)) {
+                       int vector = sh2->irq_callback(sh2, level);
+                       sh2_do_irq(sh2, level, vector);
+               }
+       }
+       else
+               sh2->test_irq = 1;
 }
 
 void sh2_internal_irq(SH2 *sh2, int level, int vector)
index a91a597..a69a159 100644 (file)
@@ -61,7 +61,7 @@ extern SH2 *sh2; // active sh2. XXX: consider removing
 int  sh2_init(SH2 *sh2, int is_slave);\r
 void sh2_finish(SH2 *sh2);\r
 void sh2_reset(SH2 *sh2);\r
-void sh2_irl_irq(SH2 *sh2, int level);\r
+void sh2_irl_irq(SH2 *sh2, int level, int nested_call);\r
 void sh2_internal_irq(SH2 *sh2, int level, int vector);\r
 void sh2_do_irq(SH2 *sh2, int level, int vector);\r
 \r
index f9ac533..e7779b9 100644 (file)
@@ -19,7 +19,7 @@ static int REGPARM(2) sh2_irq_cb(SH2 *sh2, int level)
   }
 }
 
-void p32x_update_irls(void)
+void p32x_update_irls(int nested_call)
 {
   int irqs, mlvl = 0, slvl = 0;
 
@@ -36,8 +36,8 @@ void p32x_update_irls(void)
   slvl *= 2;
 
   elprintf(EL_32X, "update_irls: m %d, s %d", mlvl, slvl);
-  sh2_irl_irq(&msh2, mlvl);
-  sh2_irl_irq(&ssh2, slvl);
+  sh2_irl_irq(&msh2, mlvl, nested_call);
+  sh2_irl_irq(&ssh2, slvl, nested_call);
   mlvl = mlvl ? 1 : 0;
   slvl = slvl ? 1 : 0;
   p32x_poll_event(mlvl | (slvl << 1), 0);
@@ -141,7 +141,7 @@ void PicoReset32x(void)
 {
   if (PicoAHW & PAHW_32X) {
     Pico32x.sh2irqs |= P32XI_VRES;
-    p32x_update_irls();
+    p32x_update_irls(0);
     p32x_poll_event(3, 0);
   }
 }
@@ -186,7 +186,7 @@ static void p32x_start_blank(void)
   }
 
   Pico32x.sh2irqs |= P32XI_VINT;
-  p32x_update_irls();
+  p32x_update_irls(0);
   p32x_poll_event(3, 1);
 }
 
index a958737..ee33caa 100644 (file)
@@ -224,12 +224,12 @@ static void p32x_reg_write8(u32 a, u32 d)
     case 3: // irq ctl
       if ((d & 1) && !(Pico32x.sh2irqi[0] & P32XI_CMD)) {
         Pico32x.sh2irqi[0] |= P32XI_CMD;
-        p32x_update_irls();
+        p32x_update_irls(0);
         SekEndRun(16);
       }
       if ((d & 2) && !(Pico32x.sh2irqi[1] & P32XI_CMD)) {
         Pico32x.sh2irqi[1] |= P32XI_CMD;
-        p32x_update_irls();
+        p32x_update_irls(0);
         SekEndRun(16);
       }
       return;
@@ -431,7 +431,7 @@ static void p32x_sh2reg_write8(u32 a, u32 d, int cpuid)
       Pico32x.sh2irq_mask[cpuid] = d & 0x8f;
       Pico32x.sh2_regs[0] &= ~0x80;
       Pico32x.sh2_regs[0] |= d & 0x80;
-      p32x_update_irls();
+      p32x_update_irls(1);
       return;
     case 5: // H count
       Pico32x.sh2_regs[4 / 2] = d & 0xff;
@@ -486,7 +486,7 @@ static void p32x_sh2reg_write16(u32 a, u32 d, int cpuid)
   return;
 
 irls:
-  p32x_update_irls();
+  p32x_update_irls(1);
 }
 
 // ------------------------------------------------------------------
@@ -950,7 +950,7 @@ static u32 sh2_read8_cs0(u32 a, int id)
   if (id == 1 && a < sizeof(Pico32xMem->sh2_rom_s))
     return Pico32xMem->sh2_rom_s[a ^ 1];
 
-  if ((a & 0x3ff00) == 0x4200) {
+  if ((a & 0x3fe00) == 0x4200) {
     d = Pico32xMem->pal[(a & 0x1ff) / 2];
     goto out_16to8;
   }
@@ -1004,7 +1004,7 @@ static u32 sh2_read16_cs0(u32 a, int id)
   if (id == 1 && a < sizeof(Pico32xMem->sh2_rom_s))
     return *(u16 *)(Pico32xMem->sh2_rom_s + a);
 
-  if ((a & 0x3ff00) == 0x4200) {
+  if ((a & 0x3fe00) == 0x4200) {
     d = Pico32xMem->pal[(a & 0x1ff) / 2];
     goto out;
   }
index 64d6722..8e36589 100644 (file)
@@ -47,7 +47,7 @@ void p32x_timers_recalc(void)
 }
 
 // PWM irq for every tm samples
-void p32x_timers_do(int new_line)
+void p32x_timers_do(int line_call)
 {
   int tm, cnt, i;
 
@@ -55,17 +55,17 @@ void p32x_timers_do(int new_line)
   {
     tm = (Pico32x.regs[0x30 / 2] & 0x0f00) >> 8;
     if (tm != 0) {
-      if (new_line)
+      if (line_call)
         Pico32x.pwm_irq_sample_cnt += pwm_line_samples;
       if (Pico32x.pwm_irq_sample_cnt >= (tm << 16)) {
         Pico32x.pwm_irq_sample_cnt -= tm << 16;
         Pico32x.sh2irqs |= P32XI_PWM;
-        p32x_update_irls();
+        p32x_update_irls(!line_call);
       }
     }
   }
 
-  if (!new_line)
+  if (!line_call)
     return;
 
   for (i = 0; i < 2; i++) {
index c63360c..22f45a3 100644 (file)
@@ -192,10 +192,8 @@ int PicoReset(void)
   if (!(PicoOpt & POPT_DIS_IDLE_DET))\r
     SekInitIdleDet();\r
 \r
-  if (PicoOpt & POPT_EN_32X) {\r
+  if (PicoOpt & POPT_EN_32X)\r
     PicoReset32x();\r
-    return 0;\r
-  }\r
 \r
   // reset sram state; enable sram access by default if it doesn't overlap with ROM\r
   Pico.m.sram_reg = 0;\r
index bb40086..3ee4ea1 100644 (file)
@@ -706,7 +706,7 @@ void PicoReset32x(void);
 void Pico32xStartup(void);\r
 void PicoUnload32x(void);\r
 void PicoFrame32x(void);\r
-void p32x_update_irls(void);\r
+void p32x_update_irls(int nested_call);\r
 void p32x_reset_sh2s(void);\r
 \r
 // 32x/memory.c\r
@@ -734,7 +734,7 @@ extern int Pico32xDrawMode;
 unsigned int p32x_pwm_read16(unsigned int a);\r
 void p32x_pwm_write16(unsigned int a, unsigned int d);\r
 void p32x_pwm_update(int *buf32, int length, int stereo);\r
-void p32x_timers_do(int new_line);\r
+void p32x_timers_do(int line_call);\r
 void p32x_timers_recalc(void);\r
 extern int pwm_frame_smp_cnt;\r
 \r
index 1fddda5..8028c0d 100644 (file)
@@ -1,2 +1,2 @@
-#define VERSION "1.70b2"\r
+#define VERSION "1.70b3"\r
 \r