32x: mode2 draw, debug, poll detection
authornotaz <notasas@gmail.com>
Fri, 18 Sep 2009 12:06:42 +0000 (12:06 +0000)
committernotaz <notasas@gmail.com>
Fri, 18 Sep 2009 12:06:42 +0000 (12:06 +0000)
git-svn-id: file:///home/notaz/opt/svn/PicoDrive@783 be3aeb3a-fb24-0410-a615-afba39da0efa

cpu/sh2mame/sh2.c
cpu/sh2mame/sh2.h
pico/32x/32x.c
pico/32x/draw.c
pico/32x/memory.c
pico/debug.c
pico/debug.h
pico/pico_int.h
platform/common/menu.c

index acd6a61..c466645 100644 (file)
 \r
 #define LOG(x) do { if (VERBOSE) logerror x; } while (0)\r
 \r
-static int sh2_icount;\r
+int sh2_icount;\r
 SH2 *sh2;\r
 \r
 #if 0\r
index cdcdecf..6684d11 100644 (file)
@@ -50,6 +50,8 @@ typedef struct
        int   is_slave;\r
 } SH2;\r
 \r
+extern int sh2_icount;\r
+\r
 void sh2_init(SH2 *sh2);\r
 void sh2_reset(SH2 *sh2);\r
 int sh2_execute(SH2 *sh2_, int cycles);\r
index c964d88..8e3553a 100644 (file)
@@ -82,9 +82,14 @@ static __inline void SekRunM68k(int cyc)
 #endif
 }
 
+// ~1463.8, but due to cache misses and slow mem
+// it's much lower than that
+#define SH2_LINE_CYCLES 700
+
 #define PICO_32X
 #define RUN_SH2S \
-  sh2_execute(&msh2, 1000);
+  if (!(Pico32x.emu_flags & P32XF_MSH2POLL)) \
+    sh2_execute(&msh2, SH2_LINE_CYCLES);
 
 #include "../pico_cmn.c"
 
index 1e2f57c..7e0911e 100644 (file)
@@ -27,7 +27,8 @@ void FinalizeLine32xRGB555(int sh, int line)
   unsigned short *pd = DrawLineDest;
   unsigned short *pal = Pico32xMem->pal_native;
   unsigned char *pb = HighCol + 8;
-  unsigned short cram0;
+  unsigned short *dram, *ps, cram0;
+  int i;
 
   // this is a bit hackish:
   // we swap cram color 0 with color that is used for background,
@@ -44,14 +45,30 @@ void FinalizeLine32xRGB555(int sh, int line)
   if (!(PicoDrawMask & PDRAW_32X_ON))
     return;
 
+  dram = (void *)Pico32xMem->dram[Pico32x.vdp_regs[0x0a/2] & P32XV_FS];
+  ps = dram + dram[line];
+
+  if ((Pico32x.vdp_regs[0] & P32XV_Mx) == 2) { // Direct Color Mode
+    int inv = (Pico32x.vdp_regs[0] & P32XV_PRI) ? 0x8000 : 0;
+    unsigned int m1 = 0x001f001f;
+    unsigned int m2 = 0x03e003e0;
+    unsigned int m3 = 0xfc00fc00;
+
+    for (i = 320; i > 0; i--, ps++, pd++, pb++) {
+      unsigned short t = *ps;
+      if (*pb != 0 && !((t ^ inv) & 0x8000))
+        continue;
+
+      *pd = ((t & m1) << 11) | ((t & m2) << 1) | ((t & m3) >> 10);
+    }
+    return;
+  }
+
   if (Pico32x.dirty_pal)
     convert_pal555(Pico32x.vdp_regs[0] & P32XV_PRI);
 
-  if ((Pico32x.vdp_regs[0] & P32XV_Mx) == 1) {
-    unsigned short *dram = (void *)Pico32xMem->dram[Pico32x.vdp_regs[0x0a/2] & P32XV_FS];
-    unsigned short *ps = dram + dram[line];
+  if ((Pico32x.vdp_regs[0] & P32XV_Mx) == 1) { // Packed Pixel Mode
     unsigned short t;
-    int i;
     for (i = 320/2; i > 0; i--, ps++, pd += 2, pb += 2) {
       t = pal[*ps >> 8];
       if (pb[0] == 0 || (t & 0x20))
@@ -61,5 +78,8 @@ void FinalizeLine32xRGB555(int sh, int line)
         pd[1] = t;
     }
   }
+  else { // Run Length Mode
+
+  }
 }
 
index b89c577..a897529 100644 (file)
@@ -9,8 +9,50 @@ static void bank_switch(int b);
 
 #define MSB8(x) ((x) >> 8)
 
+// poll detection
+struct poll_det {
+       int addr, pc, cnt;
+};
+static struct poll_det m68k_poll;
+static struct poll_det msh2_poll;
+
+#define POLL_THRESHOLD 6
+
+static int poll_detect(struct poll_det *pd, u32 a, u32 pc, int flag)
+{
+  int ret = 0;
+
+  if (a - 2 <= pd->addr && pd->addr <= a + 2 && pd->pc == pc) {
+    pd->cnt++;
+    if (pd->cnt > POLL_THRESHOLD) {
+      if (!(Pico32x.emu_flags & flag)) {
+        elprintf(EL_32X, "%s poll addr %08x @ %06x",
+          flag == P32XF_68KPOLL ? "m68k" : (flag == P32XF_MSH2POLL ? "msh2" : "ssh2"), a, pc);
+        ret = 1;
+      }
+      Pico32x.emu_flags |= flag;
+    }
+  }
+  else
+    pd->cnt = 0;
+  pd->addr = a;
+  pd->pc = pc;
+
+  return ret;
+}
+
+static int poll_undetect(struct poll_det *pd, int flag)
+{
+  int ret = 0;
+  if (pd->cnt > POLL_THRESHOLD)
+    ret = 1;
+  pd->addr = pd->cnt = 0;
+  Pico32x.emu_flags &= ~flag;
+  return ret;
+}
+
 // SH2 faking
-#define FAKE_SH2
+//#define FAKE_SH2
 int p32x_csum_faked;
 #ifdef FAKE_SH2
 static const u16 comm_fakevals[] = {
@@ -45,6 +87,11 @@ static u32 p32x_reg_read16(u32 a)
 #ifdef FAKE_SH2
   if ((a & 0x30) == 0x20)
     return sh2_comm_faker(a);
+#else
+  if (poll_detect(&m68k_poll, a, SekPc, P32XF_68KPOLL)) {
+    SekSetStop(1);
+    SekEndRun(16);
+  }
 #endif
 
   return Pico32x.regs[a / 2];
@@ -91,6 +138,7 @@ static void p32x_reg_write16(u32 a, u32 d)
 
   if ((a & 0x30) == 0x20) {
     r[a / 2] = d;
+    poll_undetect(&msh2_poll, P32XF_MSH2POLL);
     return;
   }
 
@@ -131,6 +179,7 @@ static void p32x_vdp_write8(u32 a, u32 d)
       if ((r[0x0a/2] & P32XV_VBLK) && ((r[0x0a/2] ^ d) & P32XV_FS)) {
         r[0x0a/2] ^= 1;
        Pico32xSwapDRAM(d ^ 1);
+        elprintf(EL_32X, "VDP FS: %d", r[0x0a/2] & P32XV_FS);
       }
       break;
   }
@@ -145,9 +194,15 @@ static void p32x_vdp_write16(u32 a, u32 d)
 static u32 p32x_sh2reg_read16(u32 a)
 {
   a &= 0xff; // ?
+
+  if (poll_detect(&msh2_poll, a, ash2_pc(), P32XF_MSH2POLL))
+    ash2_end_run(8);
+
   if (a == 0) {
     return (Pico32x.regs[0] & P32XS_FM) | P32XS2_ADEN;
   }
+  if ((a & 0x30) == 0x20)
+    return Pico32x.regs[a / 2];
 
   return 0;
 }
@@ -162,6 +217,10 @@ static void p32x_sh2reg_write16(u32 a, u32 d)
 
   if ((a & 0x30) == 0x20) {
     Pico32x.regs[a/2] = d;
+    if (poll_undetect(&m68k_poll, P32XF_68KPOLL))
+      // dangerous, but let's just assume 68k program
+      // didn't issue STOP itself.
+      SekSetStop(0);
     return;
   }
 
@@ -450,6 +509,12 @@ void pico32x_write8(u32 a, u32 d)
     return;
   }
 
+  if ((a & 0x0ffe0000) == 0x04000000) {
+    u8 *dram = (u8 *)Pico32xMem->dram[(Pico32x.vdp_regs[0x0a/2] & P32XV_FS) ^ 1];
+    dram[(a & 0x1ffff) ^ 1] = d;
+    return;
+  }
+
   if ((a & 0x0fffff00) == 0x4100) {
     p32x_vdp_write8(a, d);
     return;
@@ -473,6 +538,11 @@ void pico32x_write16(u32 a, u32 d)
     return;
   }
 
+  if ((a & 0x0ffe0000) == 0x04000000) {
+    Pico32xMem->dram[(Pico32x.vdp_regs[0x0a/2] & P32XV_FS) ^ 1][(a & 0x1ffff) / 2] = d;
+    return;
+  }
+
   if ((a & 0x0fffff00) == 0x4100) {
     p32x_vdp_write16(a, d);
     return;
index d81cf45..5bbf8c4 100644 (file)
@@ -59,6 +59,35 @@ char *PDebugMain(void)
   return dstr;
 }
 
+char *PDebug32x(void)
+{
+  char *dstrp = dstr;
+  unsigned short *r;
+  int i;
+
+  r = Pico32x.regs;
+  sprintf(dstrp, "regs:\n"); MVP;
+  for (i = 0; i < 0x40/2; i += 8) {
+    sprintf(dstrp, "%02x: %04x %04x %04x %04x %04x %04x %04x %04x\n",
+      i*2, r[i+0], r[i+1], r[i+2], r[i+3], r[i+4], r[i+5], r[i+6], r[i+7]); MVP;
+  }
+
+  i = 0;
+  r = Pico32x.vdp_regs;
+  sprintf(dstrp, "VDP regs:\n"); MVP;
+  sprintf(dstrp, "%02x: %04x %04x %04x %04x %04x %04x %04x %04x\n",
+    i*2, r[i+0], r[i+1], r[i+2], r[i+3], r[i+4], r[i+5], r[i+6], r[i+7]); MVP;
+
+  sprintf(dstrp, "                   mSH2              sSH2\n"); MVP;
+  sprintf(dstrp, "PC:            %08x          %08x\n", msh2_pc(), ssh2_pc()); MVP;
+  for (i = 0; i < 16/2; i++) {
+    sprintf(dstrp, "R%d,%2d %08x,%08x %08x,%08x\n", i, i + 8,
+      msh2_reg(i), msh2_reg(i+8), ssh2_reg(i), ssh2_reg(i+8)); MVP;
+  }
+
+  return dstr;
+}
+
 char *PDebugSpriteList(void)
 {
   struct PicoVideo *pvid=&Pico.video;
@@ -298,6 +327,14 @@ void PDebugDumpMem(void)
     dump_ram_noswab(Pico_mcd->pcm_ram,"dumps/pcm_ram.bin");
     dump_ram_noswab(Pico_mcd->bram,   "dumps/bram.bin");
   }
+
+  if (PicoAHW & PAHW_32X)
+  {
+    dump_ram(Pico32xMem->sdram, "dumps/sdram.bin");
+    dump_ram(Pico32xMem->dram[0], "dumps/dram0.bin");
+    dump_ram(Pico32xMem->dram[1], "dumps/dram1.bin");
+    dump_ram(Pico32xMem->pal, "dumps/pal32x.bin");
+  }
 }
 
 void PDebugZ80Frame(void)
index d2ac82c..53dc668 100644 (file)
@@ -1,5 +1,6 @@
 
 char *PDebugMain(void);
+char *PDebug32x(void);
 char *PDebugSpriteList(void);
 void PDebugShowSpriteStats(unsigned short *screen, int stride);
 void PDebugShowPalette(unsigned short *screen, int stride);
index e50d468..d73041e 100644 (file)
@@ -232,6 +232,13 @@ typedef void (z80_write_f)(unsigned int a, unsigned char data);
 \r
 SH2 msh2, ssh2;\r
 #define ash2_pc() msh2.ppc\r
+#define ash2_end_run(after) sh2_icount = after\r
+\r
+#define msh2_pc() msh2.ppc\r
+#define ssh2_pc() ssh2.ppc\r
+\r
+#define msh2_reg(x) msh2.r[x]\r
+#define ssh2_reg(x) ssh2.r[x]\r
 \r
 // ---------------------------------------------------------\r
 \r
@@ -409,6 +416,10 @@ typedef struct
 #define P32XV_nFEN  (1<< 1)\r
 #define P32XV_FS    (1<< 0)\r
 \r
+#define P32XF_68KPOLL  (1 << 0)\r
+#define P32XF_MSH2POLL (1 << 1)\r
+#define P32XF_SSH2POLL (1 << 2)\r
+\r
 struct Pico32x\r
 {\r
   unsigned short regs[0x20];\r
@@ -416,6 +427,7 @@ struct Pico32x
   unsigned char pending_fb;\r
   unsigned char dirty_pal;\r
   unsigned char pad[2];\r
+  unsigned int emu_flags;\r
 };\r
 \r
 struct Pico32xMem\r
index 1788033..8673784 100644 (file)
@@ -1797,14 +1797,18 @@ static void debug_menu_loop(void)
                                        g_screen_width, spr_offs);\r
                                draw_text_debug(PDebugSpriteList(), spr_offs, 6);\r
                                break;\r
+                       case 4: plat_video_menu_begin();\r
+                               tmp = PDebug32x();\r
+                               draw_text_debug(tmp, 0, 0);\r
+                               break;\r
                }\r
                plat_video_menu_end();\r
 \r
                inp = in_menu_wait(PBTN_MOK|PBTN_MBACK|PBTN_MA2|PBTN_MA3|PBTN_L|PBTN_R |\r
                                        PBTN_UP|PBTN_DOWN|PBTN_LEFT|PBTN_RIGHT, 70);\r
                if (inp & PBTN_MBACK) return;\r
-               if (inp & PBTN_L) { mode--; if (mode < 0) mode = 3; }\r
-               if (inp & PBTN_R) { mode++; if (mode > 3) mode = 0; }\r
+               if (inp & PBTN_L) { mode--; if (mode < 0) mode = 4; }\r
+               if (inp & PBTN_R) { mode++; if (mode > 4) mode = 0; }\r
                switch (mode)\r
                {\r
                        case 0:\r