cd: some fixes
[picodrive.git] / pico / cd / memory.c
index 82e6d6d..1d669a2 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
@@ -212,7 +212,6 @@ void m68k_reg_write8(u32 a, u32 d)
         ((u16 *)Pico_mcd->bios)[0x70/2], ((u16 *)Pico_mcd->bios)[0x72/2]);\r
       return;\r
     case 0x0f:\r
-      d = (d << 1) | ((d >> 7) & 1); // rol8 1 (special case)\r
       a = 0x0e;\r
     case 0x0e:\r
       goto write_comm;\r
@@ -343,35 +342,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
@@ -395,8 +393,6 @@ void s68k_reg_write8(u32 a, u32 d)
       Pico_mcd->m.stopwatch_base_c = SekCyclesDoneS68k();\r
       return;\r
     case 0x0e:\r
-      d &= 0xff;\r
-      d = (d>>1) | (d<<7); // ror8 1, Gens note: Dragons lair\r
       a = 0x0f;\r
     case 0x0f:\r
       goto write_comm;\r
@@ -647,17 +643,17 @@ static void s68k_unmapped_write16(u32 a, u32 d)
   elprintf(EL_UIO, "s68k unmapped w16 [%06x] %04x @%06x", a, d & 0xffff, SekPc);\r
 }\r
 \r
-// PRG RAM protected range (000000 - 00ff00)?\r
+// PRG RAM protected range (000000 - 01fdff)?\r
 // XXX verify: ff00 or 1fe00 max?\r
 static void PicoWriteS68k8_prgwp(u32 a, u32 d)\r
 {\r
-  if (a >= (Pico_mcd->s68k_regs[2] << 8))\r
+  if (a >= (Pico_mcd->s68k_regs[2] << 9))\r
     Pico_mcd->prg_ram[a ^ 1] = d;\r
 }\r
 \r
 static void PicoWriteS68k16_prgwp(u32 a, u32 d)\r
 {\r
-  if (a >= (Pico_mcd->s68k_regs[2] << 8))\r
+  if (a >= (Pico_mcd->s68k_regs[2] << 9))\r
     *(u16 *)(Pico_mcd->prg_ram + a) = d;\r
 }\r
 \r
@@ -806,20 +802,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 +845,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 +1023,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
@@ -1064,8 +1064,8 @@ PICO_INTERNAL void PicoMemSetupCD(void)
   cpu68k_map_set(s68k_read16_map,  0x000000, 0x07ffff, Pico_mcd->prg_ram, 0);\r
   cpu68k_map_set(s68k_write8_map,  0x000000, 0x07ffff, Pico_mcd->prg_ram, 0);\r
   cpu68k_map_set(s68k_write16_map, 0x000000, 0x07ffff, Pico_mcd->prg_ram, 0);\r
-  cpu68k_map_set(s68k_write8_map,  0x000000, 0x00ffff, PicoWriteS68k8_prgwp, 1);\r
-  cpu68k_map_set(s68k_write16_map, 0x000000, 0x00ffff, PicoWriteS68k16_prgwp, 1);\r
+  cpu68k_map_set(s68k_write8_map,  0x000000, 0x01ffff, PicoWriteS68k8_prgwp, 1);\r
+  cpu68k_map_set(s68k_write16_map, 0x000000, 0x01ffff, PicoWriteS68k16_prgwp, 1);\r
 \r
   // BRAM\r
   cpu68k_map_set(s68k_read8_map,   0xfe0000, 0xfeffff, PicoReadS68k8_bram, 1);\r