mcd, improve polling detection
authorkub <derkub@gmail.com>
Fri, 14 May 2021 14:50:13 +0000 (16:50 +0200)
committerkub <derkub@gmail.com>
Fri, 14 May 2021 14:50:13 +0000 (16:50 +0200)
pico/cd/mcd.c
pico/cd/memory.c

index 7554f8c..732a429 100644 (file)
@@ -281,7 +281,8 @@ void pcd_irq_s68k(int irq, int state)
 {
   if (state) {
     SekInterruptS68k(irq);
-    SekSetStopS68k(0);
+    if (SekIsStoppedS68k())
+      SekSetStopS68k(0);
     Pico_mcd->m.s68k_poll_a = 0;
   } else
     SekInterruptClearS68k(irq);
@@ -342,21 +343,24 @@ void pcd_run_cpus_normal(int m68k_cycles)
 
 #ifdef USE_POLL_DETECT
     if (Pico_mcd->m.m68k_poll_cnt >= 16) {
+      int s68k_left;
       // main CPU is polling, (wake and) run sub only
-      SekSetStopS68k(0);
-      pcd_sync_s68k(Pico.t.m68c_aim, 1);
+      if (SekIsStoppedS68k())
+        SekSetStopS68k(0);
+      s68k_left = pcd_sync_s68k(Pico.t.m68c_aim, 1);
 
       Pico.t.m68c_cnt = Pico.t.m68c_aim;
+      if (s68k_left > 0)
+        Pico.t.m68c_cnt -= ((long long)s68k_left * mcd_s68k_cycle_mult >> 16);
       if (SekIsStoppedS68k()) {
         // slave has stopped, wake master to avoid lockups
         Pico_mcd->m.m68k_poll_cnt = 0;
       }
       elprintf(EL_CDPOLL, "m68k poll [%02x] x%d @%06x",
         Pico_mcd->m.m68k_poll_a, Pico_mcd->m.m68k_poll_cnt, SekPc);
-    }
+    } else
 #endif
-
-    SekRunM68kOnce();
+      SekRunM68kOnce();
     if (Pico_mcd->m.need_sync) {
       Pico_mcd->m.need_sync = 0;
       pcd_sync_s68k(Pico.t.m68c_cnt, 0);
index 558251c..a7b47b9 100644 (file)
@@ -144,6 +144,8 @@ void m68k_reg_write8(u32 a, u32 d)
   u32 dold;\r
   a &= 0x3f;\r
 \r
+  Pico_mcd->m.m68k_poll_cnt = 0;\r
+\r
   switch (a) {\r
     case 0:\r
       d &= 1;\r
@@ -180,8 +182,7 @@ void m68k_reg_write8(u32 a, u32 d)
       return;\r
     case 2:\r
       elprintf(EL_CDREGS, "m68k: prg wp=%02x", d);\r
-      Pico_mcd->s68k_regs[2] = d; // really use s68k side register\r
-      return;\r
+      goto write_comm;\r
     case 3:\r
       dold = Pico_mcd->s68k_regs[3];\r
       elprintf(EL_CDREG3, "m68k_regs w3: %02x @%06x", (u8)d, SekPc);\r
@@ -331,7 +332,7 @@ u32 s68k_reg_read16(u32 a)
 \r
   d = (Pico_mcd->s68k_regs[a]<<8) | Pico_mcd->s68k_regs[a+1];\r
 \r
-  if (a >= 0x0e && a < 0x20)\r
+  if (a >= 0x0e && a < 0x30)\r
     return s68k_poll_detect(a, d);\r
 \r
   return d;\r
@@ -494,6 +495,8 @@ void s68k_reg_write16(u32 a, u32 d)
 {\r
   u8 *r = Pico_mcd->s68k_regs;\r
 \r
+  Pico_mcd->m.s68k_poll_cnt = 0;\r
+\r
   if ((a & 0x1f0) == 0x20)\r
     goto write_comm;\r
 \r
@@ -501,8 +504,8 @@ void s68k_reg_write16(u32 a, u32 d)
     case 0x0e:\r
       // special case, 2 byte writes would be handled differently\r
       // TODO: verify\r
-      r[0xf] = d;\r
-      return;\r
+      d = (u8)d | (r[0xe] << 8);\r
+      goto write_comm;\r
     case 0x58: // stamp data size\r
       r[0x59] = d & 7;\r
       return;\r