32x: improved lockstep mode, allows compatibility over 50%
authornotaz <notasas@gmail.com>
Wed, 30 Sep 2009 15:42:32 +0000 (15:42 +0000)
committernotaz <notasas@gmail.com>
Wed, 30 Sep 2009 15:42:32 +0000 (15:42 +0000)
git-svn-id: file:///home/notaz/opt/svn/PicoDrive@797 be3aeb3a-fb24-0410-a615-afba39da0efa

pico/32x/32x.c
pico/32x/draw.c
pico/32x/memory.c
pico/cd/pico.c
pico/debug.c
pico/pico_cmn.c
pico/pico_int.h

index 93d4e3e..9a981f6 100644 (file)
@@ -127,27 +127,38 @@ static __inline void SekRunM68k(int cyc)
 // ~1463.8, but due to cache misses and slow mem
 // it's much lower than that
 //#define SH2_LINE_CYCLES 735
-#define CYCLES_M68K2SH2(x) ((x) * 9 / 4)
+#define CYCLES_M68K2SH2(x) ((x) * 6 / 4)
 
 #define PICO_32X
-#define RUN_SH2S_SIMPLE(m68k_cycles) \
+#define CPUS_RUN_SIMPLE(m68k_cycles,s68k_cycles) \
+  SekRunM68k(m68k_cycles); \
   if (!(Pico32x.emu_flags & (P32XF_MSH2POLL|P32XF_MSH2VPOLL))) \
     sh2_execute(&msh2, CYCLES_M68K2SH2(m68k_cycles)); \
   if (!(Pico32x.emu_flags & (P32XF_SSH2POLL|P32XF_SSH2VPOLL))) \
     sh2_execute(&ssh2, CYCLES_M68K2SH2(m68k_cycles))
 
-#define STEP 66
-#define RUN_SH2S_LOCKSTEP(m68k_cycles) \
+#define STEP_68K 24
+#define CPUS_RUN_LOCKSTEP(m68k_cycles,s68k_cycles) \
 { \
   int i; \
-  for (i = 0; i < CYCLES_M68K2SH2(m68k_cycles); i+= STEP) { \
-    sh2_execute(&msh2, STEP); \
-    sh2_execute(&ssh2, STEP); \
+  for (i = 0; i <= (m68k_cycles) - STEP_68K; i += STEP_68K) { \
+    SekRunM68k(STEP_68K); \
+    if (!(Pico32x.emu_flags & (P32XF_MSH2POLL|P32XF_MSH2VPOLL))) \
+      sh2_execute(&msh2, CYCLES_M68K2SH2(STEP_68K)); \
+    if (!(Pico32x.emu_flags & (P32XF_SSH2POLL|P32XF_SSH2VPOLL))) \
+      sh2_execute(&ssh2, CYCLES_M68K2SH2(STEP_68K)); \
   } \
+  /* last step */ \
+  i = (m68k_cycles) - i; \
+  SekRunM68k(i); \
+  if (!(Pico32x.emu_flags & (P32XF_MSH2POLL|P32XF_MSH2VPOLL))) \
+    sh2_execute(&msh2, CYCLES_M68K2SH2(i)); \
+  if (!(Pico32x.emu_flags & (P32XF_SSH2POLL|P32XF_SSH2VPOLL))) \
+    sh2_execute(&ssh2, CYCLES_M68K2SH2(i)); \
 }
 
-#define RUN_SH2S RUN_SH2S_SIMPLE
-//#define RUN_SH2S RUN_SH2S_LOCKSTEP
+//#define CPUS_RUN CPUS_RUN_SIMPLE
+#define CPUS_RUN CPUS_RUN_LOCKSTEP
 
 #include "../pico_cmn.c"
 
index 3445121..e59fabb 100644 (file)
@@ -42,6 +42,10 @@ void FinalizeLine32xRGB555(int sh, int line)
   if ((Pico32x.vdp_regs[0] & P32XV_Mx) == 0)
     return; // blanking
 
+  // XXX: how is 32col mode hadled by real hardware?
+  if (!(Pico.video.reg[12] & 1))
+    return;
+
   if (!(PicoDrawMask & PDRAW_32X_ON))
     return;
 
index b179873..a7df073 100644 (file)
@@ -1,6 +1,13 @@
 #include "../pico_int.h"
 #include "../memory.h"
 
+#if 1
+#undef ash2_end_run
+#undef SekEndRun
+#define ash2_end_run(x)
+#define SekEndRun(x)
+#endif
+
 static const char str_mars[] = "MARS";
 
 struct Pico32xMem *Pico32xMem;
@@ -35,9 +42,10 @@ static int p32x_poll_detect(struct poll_det *pd, u32 a, u32 cycles, int is_vdp)
       Pico32x.emu_flags |= flag;
     }
   }
-  else
+  else {
     pd->cnt = 0;
-  pd->addr = a;
+    pd->addr = a;
+  }
   pd->cycles = cycles;
 
   return ret;
@@ -348,7 +356,9 @@ static u32 p32x_sh2reg_read16(u32 a, int cpuid)
   switch (a) {
     case 0x00: // adapter/irq ctl
       return (r[0] & P32XS_FM) | Pico32x.sh2_regs[0] | Pico32x.sh2irq_mask[cpuid];
-    case 0x04: // H count
+    case 0x04: // H count (often as comm too)
+      if (p32x_poll_detect(&sh2_poll[cpuid], a, ash2_cycles_done(), 0))
+        ash2_end_run(8);
       return Pico32x.sh2_regs[4 / 2];
     case 0x10: // DREQ len
       return r[a / 2];
@@ -387,6 +397,7 @@ static void p32x_sh2reg_write8(u32 a, u32 d, int cpuid)
       return;
     case 5: // H count
       Pico32x.sh2_regs[4 / 2] = d & 0xff;
+      p32x_poll_undetect(&sh2_poll[cpuid ^ 1], 0);
       return;
   }
 
@@ -730,7 +741,8 @@ u32 p32x_sh2_read8(u32 a, int id)
   if ((a & ~0xfff) == 0xc0000000)
     return Pico32xMem->data_array[id][(a & 0xfff) ^ 1];
 
-  if ((a & 0xdffe0000) == 0x04000000) {
+  if ((a & 0xdffc0000) == 0x04000000) {
+    /* XXX: overwrite readable as normal? */
     u8 *dram = (u8 *)Pico32xMem->dram[(Pico32x.vdp_regs[0x0a/2] & P32XV_FS) ^ 1];
     return dram[(a & 0x1ffff) ^ 1];
   }
@@ -846,8 +858,8 @@ void p32x_sh2_write8(u32 a, u32 d, int id)
     if (!(a & 0x20000) || d) {
       dram = (u8 *)Pico32xMem->dram[(Pico32x.vdp_regs[0x0a/2] & P32XV_FS) ^ 1];
       dram[(a & 0x1ffff) ^ 1] = d;
-      return;
     }
+    return;
   }
 
   if ((a & ~0xfff) == 0xc0000000) {
index eac8164..8b65f4f 100644 (file)
@@ -211,6 +211,16 @@ static __inline void update_chips(void)
 
 
 #define PICO_CD
+#define CPUS_RUN(m68k_cycles,s68k_cycles) \
+{ \
+    if ((PicoOpt&POPT_EN_MCD_PSYNC) && (Pico_mcd->m.busreq&3) == 1) { \
+      SekRunPS(m68k_cycles, s68k_cycles); /* "better/perfect sync" */ \
+    } else { \
+      SekRunM68k(m68k_cycles); \
+      if ((Pico_mcd->m.busreq&3) == 1) /* no busreq/no reset */ \
+        SekRunS68k(s68k_cycles); \
+    } \
+}
 #include "../pico_cmn.c"
 
 
index 1a3ca7c..ac8f120 100644 (file)
@@ -86,7 +86,7 @@ char *PDebug32x(void)
     sprintf(dstrp, "R%d,%2d %08x,%08x %08x,%08x\n", i, i + 8,
       sh2_reg(0,i), sh2_reg(0,i+8), sh2_reg(1,i), sh2_reg(1,i+8)); MVP;
   }
-  sprintf(dstrp, "gb,vb %08x,%08x %08x,%08x\n", sh2_gbr(0), sh2_vbr(0), sh2_gbr(1), sh2_vbr(1));
+  sprintf(dstrp, "gb,vb %08x,%08x %08x,%08x\n", sh2_gbr(0), sh2_vbr(0), sh2_gbr(1), sh2_vbr(1)); MVP;
   sprintf(dstrp, "IRQs/mask:        %02x/%02x             %02x/%02x\n",
     Pico32x.sh2irqi[0], Pico32x.sh2irq_mask[0], Pico32x.sh2irqi[1], Pico32x.sh2irq_mask[1]); MVP;
 
index 56658e7..5f31694 100644 (file)
   }
 
 // CPUS_RUN
-#ifndef RUN_SH2S
-#define RUN_SH2S(x)
-#endif
-
-#ifndef PICO_CD
-#define CPUS_RUN(m68k_cycles,s68k_cycles) \
-{ \
-    SekRunM68k(m68k_cycles); \
-    RUN_SH2S(m68k_cycles); \
-}
-#else
+#ifndef CPUS_RUN
 #define CPUS_RUN(m68k_cycles,s68k_cycles) \
-{ \
-    if ((PicoOpt&POPT_EN_MCD_PSYNC) && (Pico_mcd->m.busreq&3) == 1) { \
-      SekRunPS(m68k_cycles, s68k_cycles); /* "better/perfect sync" */ \
-    } else { \
-      SekRunM68k(m68k_cycles); \
-      if ((Pico_mcd->m.busreq&3) == 1) /* no busreq/no reset */ \
-        SekRunS68k(s68k_cycles); \
-    } \
-}
+  SekRunM68k(m68k_cycles)
 #endif
 
 static int PicoFrameHints(void)
index 3a1ac9c..ce6b499 100644 (file)
@@ -232,7 +232,7 @@ typedef void (z80_write_f)(unsigned int a, unsigned char data);
 \r
 SH2 msh2, ssh2;\r
 #define ash2_end_run(after) sh2_icount = after\r
-#define ash2_cycles_done() (10000 - sh2_icount) // HACK\r
+#define ash2_cycles_done() (sh2->cycles_aim - sh2_icount)\r
 \r
 #define sh2_pc(c)     (c) ? ssh2.ppc : msh2.ppc\r
 #define sh2_reg(c, x) (c) ? ssh2.r[x] : msh2.r[x]\r