32x: sh2 irqs (irls), preliminary DMAC implementation
[picodrive.git] / cpu / sh2mame / sh2pico.c
index e77329c..ac3df3e 100644 (file)
@@ -9,19 +9,19 @@ typedef unsigned short UINT16;
 typedef unsigned char  UINT8;
 
 // pico memhandlers
-unsigned int pico32x_read8(unsigned int a);
-unsigned int pico32x_read16(unsigned int a);
-unsigned int pico32x_read32(unsigned int a);
-void pico32x_write8(unsigned int a, unsigned int d);
-void pico32x_write16(unsigned int a, unsigned int d);
-void pico32x_write32(unsigned int a, unsigned int d);
-
-#define RB pico32x_read8
-#define RW pico32x_read16
-#define RL pico32x_read32
-#define WB pico32x_write8
-#define WW pico32x_write16
-#define WL pico32x_write32
+unsigned int p32x_sh2_read8(unsigned int a);
+unsigned int p32x_sh2_read16(unsigned int a);
+unsigned int p32x_sh2_read32(unsigned int a);
+void p32x_sh2_write8(unsigned int a, unsigned int d);
+void p32x_sh2_write16(unsigned int a, unsigned int d);
+void p32x_sh2_write32(unsigned int a, unsigned int d);
+
+#define RB p32x_sh2_read8
+#define RW p32x_sh2_read16
+#define RL p32x_sh2_read32
+#define WB p32x_sh2_write8
+#define WW p32x_sh2_write16
+#define WL p32x_sh2_write32
 
 // some stuff from sh2comn.h
 #define T      0x00000001
@@ -42,15 +42,15 @@ void pico32x_write32(unsigned int a, unsigned int d);
 void sh2_reset(SH2 *sh2)
 {
        int save_is_slave;
-//     cpu_irq_callback save_irqcallback;
+       void *save_irqcallback;
 
-//     save_irqcallback = sh2->irq_callback;
+       save_irqcallback = sh2->irq_callback;
        save_is_slave = sh2->is_slave;
 
        memset(sh2, 0, sizeof(SH2));
 
        sh2->is_slave = save_is_slave;
-//     sh2->irq_callback = save_irqcallback;
+       sh2->irq_callback = save_irqcallback;
 
        sh2->pc = RL(0);
        sh2->r[15] = RL(4);
@@ -103,7 +103,8 @@ int sh2_execute(SH2 *sh2_, int cycles)
 
                if (sh2->test_irq && !sh2->delay)
                {
-//                     CHECK_PENDING_IRQ("mame_sh2_execute");
+                       if (sh2->pending_irq)
+                               sh2_irl_irq(sh2, sh2->pending_irq);
                        sh2->test_irq = 0;
                }
                sh2_icount--;
@@ -118,4 +119,31 @@ void sh2_init(SH2 *sh2)
        memset(sh2, 0, sizeof(*sh2));
 }
 
+void sh2_irl_irq(SH2 *sh2, int level)
+{
+       int vector;
+
+       sh2->pending_irq = level;
+
+       if (level <= ((sh2->sr >> 4) & 0x0f))
+               /* masked */
+               return;
+
+       sh2->irq_callback(level);
+       vector = 64 + level/2;
+
+       sh2->r[15] -= 4;
+       WL(sh2->r[15], sh2->sr);                /* push SR onto stack */
+       sh2->r[15] -= 4;
+       WL(sh2->r[15], sh2->pc);                /* push PC onto stack */
+
+       /* set I flags in SR */
+       sh2->sr = (sh2->sr & ~I) | (level << 4);
+
+       /* fetch PC */
+       sh2->pc = RL(sh2->vbr + vector * 4);
+
+       /* 13 cycles at best */
+       sh2_icount -= 13;
+}