recognize the MED ssf2 header
[picodrive.git] / pico / sek.c
index 2fe77cb..8bf0341 100644 (file)
@@ -11,9 +11,8 @@
 #include "memory.h"\r
 \r
 \r
-int SekCycleCnt=0; // cycles done in this frame\r
-int SekCycleAim=0; // cycle aim\r
-unsigned int SekCycleCntT=0;\r
+unsigned int SekCycleCnt;\r
+unsigned int SekCycleAim;\r
 \r
 \r
 /* context */\r
@@ -61,6 +60,8 @@ static int SekUnrecognizedOpcode()
     PicoCpuCM68k.state_flags |= 1;\r
     return 1;\r
   }\r
+  // happened once - may happen again\r
+  SekFinishIdleDet();\r
 #ifdef EMU_M68K // debugging cyclone\r
   {\r
     extern int have_illegal;\r
@@ -91,8 +92,14 @@ static int SekTasCallback(void)
 #ifdef EMU_F68K\r
 static void SekIntAckF68K(unsigned level)\r
 {\r
-  if     (level == 4) { Pico.video.pending_ints  =  0;    elprintf(EL_INTS, "hack: @ %06x [%i]", SekPc, SekCycleCnt); }\r
-  else if(level == 6) { Pico.video.pending_ints &= ~0x20; elprintf(EL_INTS, "vack: @ %06x [%i]", SekPc, SekCycleCnt); }\r
+  if     (level == 4) {\r
+    Pico.video.pending_ints = 0;\r
+    elprintf(EL_INTS, "hack: @ %06x [%i]", SekPc, SekCyclesDone());\r
+  }\r
+  else if(level == 6) {\r
+    Pico.video.pending_ints &= ~0x20;\r
+    elprintf(EL_INTS, "vack: @ %06x [%i]", SekPc, SekCyclesDone());\r
+  }\r
   PicoCpuFM68k.interrupts[0] = 0;\r
 }\r
 #endif\r
@@ -171,7 +178,7 @@ void SekStepM68k(void)
 #elif defined(EMU_M68K)\r
   SekCycleCnt+=m68k_execute(1);\r
 #elif defined(EMU_F68K)\r
-  SekCycleCnt+=fm68k_emulate(1, 0, 0);\r
+  SekCycleCnt+=fm68k_emulate(1, 0);\r
 #endif\r
 }\r
 \r
@@ -220,7 +227,8 @@ PICO_INTERNAL void SekPackCpu(unsigned char *cpu, int is_sub)
 #endif\r
 \r
   *(unsigned int *)(cpu+0x40) = pc;\r
-  *(unsigned int *)(cpu+0x50) = SekCycleCntT;\r
+  *(unsigned int *)(cpu+0x50) =\r
+    is_sub ? SekCycleCntS68k : SekCycleCnt;\r
 }\r
 \r
 PICO_INTERNAL void SekUnpackCpu(const unsigned char *cpu, int is_sub)\r
@@ -257,7 +265,10 @@ PICO_INTERNAL void SekUnpackCpu(const unsigned char *cpu, int is_sub)
   context->execinfo &= ~FM68K_HALTED;\r
   if (cpu[0x4d]&1) context->execinfo |= FM68K_HALTED;\r
 #endif\r
-  SekCycleCntT = *(unsigned int *)(cpu+0x50);\r
+  if (is_sub)\r
+    SekCycleCntS68k = *(unsigned int *)(cpu+0x50);\r
+  else\r
+    SekCycleCnt = *(unsigned int *)(cpu+0x50);\r
 }\r
 \r
 \r
@@ -268,7 +279,7 @@ PICO_INTERNAL void SekUnpackCpu(const unsigned char *cpu, int is_sub)
 \r
 static unsigned short **idledet_ptrs = NULL;\r
 static int idledet_count = 0, idledet_bads = 0;\r
-int idledet_start_frame = 0;\r
+static int idledet_start_frame = 0;\r
 \r
 #if 0\r
 #define IDLE_STATS 1\r
@@ -308,10 +319,15 @@ void SekInitIdleDet(void)
   CycloneInitIdle();\r
 #endif\r
 #ifdef EMU_F68K\r
-  fm68k_emulate(0, 0, 1);\r
+  fm68k_emulate(0, 1);\r
 #endif\r
 }\r
 \r
+int SekIsIdleReady(void)\r
+{\r
+       return (Pico.m.frame_count >= idledet_start_frame);\r
+}\r
+\r
 int SekIsIdleCode(unsigned short *dst, int bytes)\r
 {\r
   // printf("SekIsIdleCode %04x %i\n", *dst, bytes);\r
@@ -322,11 +338,16 @@ int SekIsIdleCode(unsigned short *dst, int bytes)
         return 1;\r
       break;\r
     case 4:\r
-      if (  (*dst & 0xfff8) == 0x4a10 || // tst.b ($aX)      // there should be no need to wait\r
-            (*dst & 0xfff8) == 0x4a28 || // tst.b ($xxxx,a0) // for byte change anywhere\r
-            (*dst & 0xff3f) == 0x4a38 || // tst.x ($xxxx.w); tas ($xxxx.w)\r
-            (*dst & 0xc1ff) == 0x0038 || // move.x ($xxxx.w), dX\r
-            (*dst & 0xf13f) == 0xb038)   // cmp.x ($xxxx.w), dX\r
+      if ( (*dst & 0xff3f) == 0x4a38 || // tst.x ($xxxx.w); tas ($xxxx.w)\r
+           (*dst & 0xc1ff) == 0x0038 || // move.x ($xxxx.w), dX\r
+           (*dst & 0xf13f) == 0xb038)   // cmp.x ($xxxx.w), dX\r
+        return 1;\r
+      if (PicoAHW & (PAHW_MCD|PAHW_32X))\r
+        break;\r
+      // with no addons, there should be no need to wait\r
+      // for byte change anywhere\r
+      if ( (*dst & 0xfff8) == 0x4a10 || // tst.b ($aX)\r
+           (*dst & 0xfff8) == 0x4a28)   // tst.b ($xxxx,a0)\r
         return 1;\r
       break;\r
     case 6:\r
@@ -348,7 +369,9 @@ int SekIsIdleCode(unsigned short *dst, int bytes)
         return 1;\r
       break;\r
     case 12:\r
-       if ((*dst & 0xf1f8) == 0x3010 && // move.w (aX), dX\r
+      if (PicoAHW & (PAHW_MCD|PAHW_32X))\r
+        break;\r
+      if ( (*dst & 0xf1f8) == 0x3010 && // move.w (aX), dX\r
             (dst[1]&0xf100) == 0x0000 && // arithmetic\r
             (dst[3]&0xf100) == 0x0000)   // arithmetic\r
         return 1;\r
@@ -372,6 +395,7 @@ int SekRegisterIdlePatch(unsigned int pc, int oldop, int newop, void *ctx)
   is_main68k = ctx == &PicoCpuFM68k;\r
 #endif\r
   pc &= ~0xff000000;\r
+  if (!(newop&0x200))\r
   elprintf(EL_IDLE, "idle: patch %06x %04x %04x %c %c #%i", pc, oldop, newop,\r
     (newop&0x200)?'n':'y', is_main68k?'m':'s', idledet_count);\r
 \r
@@ -399,11 +423,13 @@ int SekRegisterIdlePatch(unsigned int pc, int oldop, int newop, void *ctx)
 \r
 void SekFinishIdleDet(void)\r
 {\r
+  if (idledet_count < 0)\r
+    return;\r
 #ifdef EMU_C68K\r
   CycloneFinishIdle();\r
 #endif\r
 #ifdef EMU_F68K\r
-  fm68k_emulate(0, 0, 2);\r
+  fm68k_emulate(0, 2);\r
 #endif\r
   while (idledet_count > 0)\r
   {\r
@@ -417,6 +443,7 @@ void SekFinishIdleDet(void)
     else\r
       elprintf(EL_STATUS|EL_IDLE, "idle: don't know how to restore %04x", *op);\r
   }\r
+  idledet_count = -1;\r
 }\r
 \r
 \r
@@ -527,6 +554,7 @@ breakloop:
                        printf("D%d: %08x  A%d: %08x\n", i, x68k->dar[i],\r
         i, x68k->dar[i + 8]);\r
                printf("PC: %08x, %08x\n", x68k->pc, x68k->pc_prev);\r
+               printf("SR: %04x\n", x68k->sr);\r
 \r
     PDebugDumpMem();\r
     exit(1);\r