cd: clean up dmna handling, stuff
authornotaz <notasas@gmail.com>
Wed, 28 Aug 2013 00:07:33 +0000 (03:07 +0300)
committernotaz <notasas@gmail.com>
Wed, 28 Aug 2013 00:56:45 +0000 (03:56 +0300)
pico/cd/mcd.c
pico/cd/memory.c
pico/pico_int.h

index 539d157..82ae1bc 100644 (file)
@@ -252,15 +252,18 @@ int pcd_sync_s68k(unsigned int m68k_target, int m68k_poll_sync)
   #undef now
 }
 
+#define pcd_run_cpus_normal pcd_run_cpus
+//#define pcd_run_cpus_lockstep pcd_run_cpus
+
 static void SekSyncM68k(void);
 
-static void pcd_run_cpus(int m68k_cycles)
+static inline void pcd_run_cpus_normal(int m68k_cycles)
 {
   SekCycleAim += m68k_cycles;
   if (Pico_mcd->m.m68k_poll_cnt >= 16 && !SekShouldInterrupt()) {
     int s68k_left = pcd_sync_s68k(SekCycleAim, 1);
     if (s68k_left <= 0) {
-      elprintf(EL_CDPOLL, "m68k poll [%02x] %d @%06x",
+      elprintf(EL_CDPOLL, "m68k poll [%02x] x%d @%06x",
         Pico_mcd->m.m68k_poll_a, Pico_mcd->m.m68k_poll_cnt, SekPc);
       SekCycleCnt = SekCycleAim;
       return;
@@ -271,6 +274,16 @@ static void pcd_run_cpus(int m68k_cycles)
   SekSyncM68k();
 }
 
+static inline void pcd_run_cpus_lockstep(int m68k_cycles)
+{
+  unsigned int target = SekCycleAim + m68k_cycles;
+  do {
+    SekCycleAim += 8;
+    SekSyncM68k();
+    pcd_sync_s68k(SekCycleAim, 0);
+  } while (CYCLES_GT(target, SekCycleAim));
+}
+
 #define PICO_CD
 #define CPUS_RUN(m68k_cycles) \
   pcd_run_cpus(m68k_cycles)
index 82e6d6d..f8ffaeb 100644 (file)
@@ -184,24 +184,24 @@ void m68k_reg_write8(u32 a, u32 d)
     case 3:\r
       dold = Pico_mcd->s68k_regs[3];\r
       elprintf(EL_CDREG3, "m68k_regs w3: %02x @%06x", (u8)d, SekPc);\r
-      //if ((Pico_mcd->s68k_regs[3]&4) != (d&4)) dprintf("m68k: ram mode %i mbit", (d&4) ? 1 : 2);\r
-      //if ((Pico_mcd->s68k_regs[3]&2) != (d&2)) dprintf("m68k: %s", (d&4) ? ((d&2) ? "word swap req" : "noop?") :\r
-      //                                             ((d&2) ? "word ram to s68k" : "word ram to m68k"));\r
-      if (dold & 4) {   // 1M mode\r
-        d ^= 2;         // writing 0 to DMNA actually sets it, 1 does nothing\r
-      } else {\r
-        if ((d ^ dold) & d & 2) { // DMNA is being set\r
-          dold &= ~1;   // return word RAM to s68k\r
-          /* Silpheed hack: bset(w3), r3, btst, bne, r3 */\r
-          SekEndRun(20+16+10+12+16);\r
-        }\r
-      }\r
-      d = (d & 0xc2) | (dold & 0x1f);\r
       if ((d ^ dold) & 0xc0) {\r
         elprintf(EL_CDREGS, "m68k: prg bank: %i -> %i",\r
           (Pico_mcd->s68k_regs[a]>>6), ((d>>6)&3));\r
         remap_prg_window(d);\r
       }\r
+\r
+      // 2M mode state is tracked regardless of current mode\r
+      if (d & 2) {\r
+        Pico_mcd->m.dmna_ret_2m |= 2;\r
+        Pico_mcd->m.dmna_ret_2m &= ~1;\r
+      }\r
+      if (dold & 4) { // 1M mode\r
+        d ^= 2;       // 0 sets DMNA, 1 does nothing\r
+        d = (d & 0xc2) | (dold & 0x1f);\r
+      }\r
+      else\r
+        d = (d & 0xc0) | (dold & 0x1c) | Pico_mcd->m.dmna_ret_2m;\r
+\r
       goto write_comm;\r
     case 6:\r
       Pico_mcd->bios[0x72 + 1] = d; // simple hint vector changer\r
@@ -343,35 +343,34 @@ void s68k_reg_write8(u32 a, u32 d)
       elprintf(EL_CDREG3, "s68k_regs w3: %02x @%06x", (u8)d, SekPcS68k);\r
       d &= 0x1d;\r
       d |= dold & 0xc2;\r
+\r
+      // 2M mode state\r
+      if (d & 1) {\r
+        Pico_mcd->m.dmna_ret_2m |= 1;\r
+        Pico_mcd->m.dmna_ret_2m &= ~2; // DMNA clears\r
+      }\r
+\r
       if (d & 4)\r
       {\r
-        if ((d ^ dold) & 0x1d) {\r
-          d &= ~2; // in case of mode or bank change we clear DMNA (m68k req) bit\r
-          remap_word_ram(d);\r
-        }\r
         if (!(dold & 4)) {\r
           elprintf(EL_CDREG3, "wram mode 2M->1M");\r
           wram_2M_to_1M(Pico_mcd->word_ram2M);\r
         }\r
+\r
+        if ((d ^ dold) & 0x1d)\r
+          remap_word_ram(d);\r
+\r
+        if ((d ^ dold) & 0x05)\r
+          d &= ~2; // clear DMNA - swap complete\r
       }\r
       else\r
       {\r
         if (dold & 4) {\r
           elprintf(EL_CDREG3, "wram mode 1M->2M");\r
-          if (!(d&1)) { // it didn't set the ret bit, which means it doesn't want to give WRAM to m68k\r
-            d &= ~3;\r
-            d |= (dold&1) ? 2 : 1; // then give it to the one which had bank0 in 1M mode\r
-          }\r
           wram_1M_to_2M(Pico_mcd->word_ram2M);\r
           remap_word_ram(d);\r
         }\r
-        // s68k can only set RET, writing 0 has no effect\r
-        else if ((dold ^ d) & d & 1) {   // RET being set\r
-          SekEndRunS68k(20+16+10+12+16); // see DMNA case\r
-        } else\r
-          d |= dold & 1;\r
-        if (d & 1)\r
-          d &= ~2;                       // DMNA clears\r
+        d = (d & ~3) | Pico_mcd->m.dmna_ret_2m;\r
       }\r
       goto write_comm;\r
     }\r
@@ -806,20 +805,22 @@ static u32 PicoReadS68k8_pr(u32 a)
   // regs\r
   if ((a & 0xfe00) == 0x8000) {\r
     a &= 0x1ff;\r
-    elprintf(EL_CDREGS, "s68k_regs r8: [%02x] @ %06x", a, SekPcS68k);\r
     if (a >= 0x0e && a < 0x30) {\r
       d = Pico_mcd->s68k_regs[a];\r
       s68k_poll_detect(a, d);\r
-      elprintf(EL_CDREGS, "ret = %02x", (u8)d);\r
-      return d;\r
+      goto regs_done;\r
     }\r
     else if (a >= 0x58 && a < 0x68)\r
          d = gfx_cd_read(a & ~1);\r
     else d = s68k_reg_read16(a & ~1);\r
     if (!(a & 1))\r
       d >>= 8;\r
-    elprintf(EL_CDREGS, "ret = %02x", (u8)d);\r
-    return d & 0xff;\r
+\r
+regs_done:\r
+    d &= 0xff;\r
+    elprintf(EL_CDREGS, "s68k_regs r8: [%02x] %02x @ %06x",\r
+      a, d, SekPcS68k);\r
+    return d;\r
   }\r
 \r
   // PCM\r
@@ -847,11 +848,12 @@ static u32 PicoReadS68k16_pr(u32 a)
   // regs\r
   if ((a & 0xfe00) == 0x8000) {\r
     a &= 0x1fe;\r
-    elprintf(EL_CDREGS, "s68k_regs r16: [%02x] @ %06x", a, SekPcS68k);\r
     if (0x58 <= a && a < 0x68)\r
          d = gfx_cd_read(a);\r
     else d = s68k_reg_read16(a);\r
-    elprintf(EL_CDREGS, "ret = %04x", d);\r
+\r
+    elprintf(EL_CDREGS, "s68k_regs r16: [%02x] %04x @ %06x",\r
+      a, d, SekPcS68k);\r
     return d;\r
   }\r
 \r
@@ -1024,6 +1026,7 @@ void pcd_state_loaded_mem(void)
     wram_2M_to_1M(Pico_mcd->word_ram2M);\r
   remap_word_ram(r3);\r
   remap_prg_window(r3);\r
+  Pico_mcd->m.dmna_ret_2m &= 3;\r
 \r
   // restore hint vector\r
   *(unsigned short *)(Pico_mcd->bios + 0x72) = Pico_mcd->m.hint_vector;\r
index be56abd..2053ac6 100644 (file)
@@ -395,7 +395,7 @@ struct mcd_misc
        unsigned short s68k_poll_cnt;\r
        unsigned int   s68k_poll_clk;\r
        unsigned char  bcram_reg;       // 18: battery-backed RAM cart register\r
-       unsigned char  pad2;\r
+       unsigned char  dmna_ret_2m;\r
        unsigned short pad3;\r
        int pad4[9];\r
 };\r