bugfixes in cd/Memory.s, poll loop detection
[picodrive.git] / Pico / cd / Memory.c
index 0b11e98..fdbf316 100644 (file)
@@ -33,6 +33,12 @@ typedef unsigned int   u32;
 \r
 // -----------------------------------------------------------------\r
 \r
+// poller detection\r
+#define USE_POLL_DETECT\r
+#define POLL_LIMIT 16\r
+#define POLL_CYCLES 124\r
+// int m68k_poll_addr, m68k_poll_cnt;\r
+unsigned int s68k_poll_adclk, s68k_poll_cnt;\r
 \r
 #ifndef _ASM_CD_MEMORY_C\r
 static u32 m68k_reg_read16(u32 a)\r
@@ -126,12 +132,12 @@ void m68k_reg_write8(u32 a, u32 d)
         if (d & 2) dold &= ~1; // return word RAM to s68k in 2M mode\r
       }\r
       Pico_mcd->s68k_regs[3] = d | dold; // really use s68k side register\r
-\r
-/*\r
-     d |= Pico_mcd->s68k_regs[3]&0x1d;\r
-     if (!(d & 4) && (d & 2)) d &= ~1; // return word RAM to s68k in 2M mode\r
-     Pico_mcd->s68k_regs[3] = d; // really use s68k side register\r
-*/\r
+#ifdef USE_POLL_DETECT\r
+      if ((s68k_poll_adclk&0xfe) == 2 && s68k_poll_cnt > POLL_LIMIT) {\r
+        SekSetStopS68k(0); s68k_poll_adclk = 0;\r
+        //printf("%05i:%03i: s68k poll release, a=%02x\n", Pico.m.frame_count, Pico.m.scanline, a);\r
+      }\r
+#endif\r
       return;\r
     }\r
     case 6:\r
@@ -141,14 +147,28 @@ void m68k_reg_write8(u32 a, u32 d)
       Pico_mcd->bios[0x72] = d;\r
       dprintf("hint vector set to %08x", PicoRead32(0x70));\r
       return;\r
+    case 0xf:\r
+      d = (d << 1) | ((d >> 7) & 1); // rol8 1 (special case)\r
     case 0xe:\r
       //dprintf("m68k: comm flag: %02x", d);\r
       Pico_mcd->s68k_regs[0xe] = d;\r
+#ifdef USE_POLL_DETECT\r
+      if ((s68k_poll_adclk&0xfe) == 0xe && s68k_poll_cnt > POLL_LIMIT) {\r
+        SekSetStopS68k(0); s68k_poll_adclk = 0;\r
+        //printf("%05i:%03i: s68k poll release, a=%02x\n", Pico.m.frame_count, Pico.m.scanline, a);\r
+      }\r
+#endif\r
       return;\r
   }\r
 \r
   if ((a&0xf0) == 0x10) {\r
       Pico_mcd->s68k_regs[a] = d;\r
+#ifdef USE_POLL_DETECT\r
+      if ((a&0xfe) == (s68k_poll_adclk&0xfe) && s68k_poll_cnt > POLL_LIMIT) {\r
+        SekSetStopS68k(0); s68k_poll_adclk = 0;\r
+        //printf("%05i:%03i: s68k poll release, a=%02x\n", Pico.m.frame_count, Pico.m.scanline, a);\r
+      }\r
+#endif\r
       return;\r
   }\r
 \r
@@ -178,48 +198,64 @@ u32 s68k_reg_read16(u32 a)
 \r
   switch (a) {\r
     case 0:\r
-      d = ((Pico_mcd->s68k_regs[0]&3)<<8) | 1; // ver = 0, not in reset state\r
-      goto end;\r
+      return ((Pico_mcd->s68k_regs[0]&3)<<8) | 1; // ver = 0, not in reset state\r
     case 2:\r
       d = (Pico_mcd->s68k_regs[a]<<8) | (Pico_mcd->s68k_regs[a+1]&0x1f);\r
       dprintf("s68k_regs r3: %02x @%06x", (u8)d, SekPcS68k);\r
-      goto end;\r
+      goto poll_detect;\r
     case 6:\r
-      d = CDC_Read_Reg();\r
-      goto end;\r
+      return CDC_Read_Reg();\r
     case 8:\r
-      d = Read_CDC_Host(1); // Gens returns 0 here on byte reads\r
-      goto end;\r
+      return Read_CDC_Host(1); // Gens returns 0 here on byte reads\r
     case 0xC:\r
       d = Pico_mcd->m.timer_stopwatch >> 16;\r
       dprintf("s68k stopwatch timer read (%04x)", d);\r
-      goto end;\r
+      return d;\r
     case 0x30:\r
-      dprintf("s68k int3 timer read (%02x%02x)", Pico_mcd->s68k_regs[30], Pico_mcd->s68k_regs[31]);\r
-      break;\r
+      dprintf("s68k int3 timer read (%02x)", Pico_mcd->s68k_regs[31]);\r
+      return Pico_mcd->s68k_regs[31];\r
     case 0x34: // fader\r
-      d = 0; // no busy bit\r
-      goto end;\r
+      return 0; // no busy bit\r
     case 0x50: // font data (check: Lunar 2, Silpheed)\r
       READ_FONT_DATA(0x00100000);\r
-      goto end;\r
+      return d;\r
     case 0x52:\r
       READ_FONT_DATA(0x00010000);\r
-      goto end;\r
+      return d;\r
     case 0x54:\r
       READ_FONT_DATA(0x10000000);\r
-      goto end;\r
+      return d;\r
     case 0x56:\r
       READ_FONT_DATA(0x01000000);\r
-      goto end;\r
+      return d;\r
   }\r
 \r
   d = (Pico_mcd->s68k_regs[a]<<8) | Pico_mcd->s68k_regs[a+1];\r
 \r
-end:\r
+  if (a >= 0x0e && a < 0x30) goto poll_detect;\r
 \r
-  // dprintf("ret = %04x", d);\r
+  return d;\r
 \r
+poll_detect:\r
+#ifdef USE_POLL_DETECT\r
+  // polling detection\r
+  if (a == (s68k_poll_adclk&0xfe)) {\r
+    unsigned int clkdiff = SekCyclesDoneS68k() - (s68k_poll_adclk>>8);\r
+    if (clkdiff <= POLL_CYCLES) {\r
+      s68k_poll_cnt++;\r
+      //printf("-- diff: %u, cnt = %i\n", clkdiff, s68k_poll_cnt);\r
+      if (s68k_poll_cnt > POLL_LIMIT) {\r
+        SekSetStopS68k(1);\r
+        //printf("%05i:%03i: s68k poll detected @ %06x, a=%02x\n", Pico.m.frame_count, Pico.m.scanline, SekPcS68k, a);\r
+      }\r
+      s68k_poll_adclk = (SekCyclesDoneS68k() << 8) | a;\r
+      return d;\r
+    }\r
+  }\r
+  s68k_poll_adclk = (SekCyclesDoneS68k() << 8) | a;\r
+  s68k_poll_cnt = 0;\r
+\r
+#endif\r
   return d;\r
 }\r
 \r
@@ -292,8 +328,7 @@ void s68k_reg_write8(u32 a, u32 d)
       Pico_mcd->m.timer_stopwatch = 0;\r
       return;\r
     case 0xe:\r
-      Pico_mcd->s68k_regs[0Xf] = (d>>1) | (d<<7); // ror8, Gens note: Dragons lair\r
-      Pico_mcd->m.timer_stopwatch = 0;\r
+      Pico_mcd->s68k_regs[0xf] = (d>>1) | (d<<7); // ror8 1, Gens note: Dragons lair\r
       return;\r
     case 0x31:\r
       dprintf("s68k set int3 timer: %02x", d);\r
@@ -634,8 +669,23 @@ static void PicoWriteM68k16(u32 a,u16 d)
     return;\r
   }\r
 \r
-  if ((a&0xffffc0)==0xa12000)\r
+  // regs\r
+  if ((a&0xffffc0)==0xa12000) {\r
     rdprintf("m68k_regs w16: [%02x] %04x @%06x", a&0x3f, d, SekPc);\r
+    if (a == 0xe) { // special case, 2 byte writes would be handled differently\r
+      Pico_mcd->s68k_regs[0xe] = d >> 8;\r
+#ifdef USE_POLL_DETECT\r
+      if ((s68k_poll_adclk&0xfe) == 0xe && s68k_poll_cnt > POLL_LIMIT) {\r
+        SekSetStopS68k(0); s68k_poll_adclk = -1;\r
+        //printf("%05i:%03i: s68k poll release, a=%02x\n", Pico.m.frame_count, Pico.m.scanline, a);\r
+      }\r
+#endif\r
+      return;\r
+    }\r
+    m68k_reg_write8(a,  d>>8);\r
+    m68k_reg_write8(a+1,d&0xff);\r
+    return;\r
+  }\r
 \r
   OtherWrite16(a,d);\r
 }\r
@@ -1408,6 +1458,8 @@ void PicoMemSetupCD()
   PicoCpuS68k.write16=PicoWriteS68k16;\r
   PicoCpuS68k.write32=PicoWriteS68k32;\r
 #endif\r
+  // m68k_poll_addr = m68k_poll_cnt = 0;\r
+  s68k_poll_adclk = s68k_poll_cnt = 0;\r
 }\r
 \r
 \r