stop IdleDet from affecting save states
[picodrive.git] / pico / state.c
index 94cefad..5092ddc 100644 (file)
@@ -7,7 +7,7 @@
  */\r
 \r
 #include "pico_int.h"\r
-#include <zlib/zlib.h>\r
+#include <zlib.h>\r
 \r
 #include "../cpu/sh2/sh2.h"\r
 #include "sound/ym2612.h"\r
@@ -78,54 +78,6 @@ static void *open_save_file(const char *fname, int is_save)
   return afile;\r
 }\r
 \r
-// legacy savestate loading\r
-#define SCANP(f, x) areaRead(&Pico.x, sizeof(Pico.x), 1, f)\r
-\r
-static int state_load_legacy(void *file)\r
-{\r
-  unsigned char head[32];\r
-  unsigned char cpu[0x60];\r
-  unsigned char cpu_z80[Z80_STATE_SIZE];\r
-  void *ym2612_regs;\r
-  int ok;\r
-\r
-  memset(&cpu,0,sizeof(cpu));\r
-  memset(&cpu_z80,0,sizeof(cpu_z80));\r
-\r
-  memset(head, 0, sizeof(head));\r
-  areaRead(head, sizeof(head), 1, file);\r
-  if (strcmp((char *)head, "Pico") != 0)\r
-    return -1;\r
-\r
-  elprintf(EL_STATUS, "legacy savestate");\r
-\r
-  // Scan all the memory areas:\r
-  SCANP(file, ram);\r
-  SCANP(file, vram);\r
-  SCANP(file, zram);\r
-  SCANP(file, cram);\r
-  SCANP(file, vsram);\r
-\r
-  // Pack, scan and unpack the cpu data:\r
-  areaRead(cpu, sizeof(cpu), 1, file);\r
-  SekUnpackCpu(cpu, 0);\r
-\r
-  SCANP(file, m);\r
-  SCANP(file, video);\r
-\r
-  ok = areaRead(cpu_z80, sizeof(cpu_z80), 1, file) == sizeof(cpu_z80);\r
-  // do not unpack if we fail to load z80 state\r
-  if (!ok) z80_reset();\r
-  else     z80_unpack(cpu_z80);\r
-\r
-  ym2612_regs = YM2612GetRegs();\r
-  areaRead(sn76496_regs, 28*4, 1, file);\r
-  areaRead(ym2612_regs, 0x200+4, 1, file);\r
-  ym2612_unpack_state();\r
-\r
-  return 0;\r
-}\r
-\r
 // ---------------------------------------------------------------------------\r
 \r
 typedef enum {\r
@@ -149,8 +101,8 @@ typedef enum {
   CHUNK_GA_REGS,\r
   CHUNK_PCM,\r
   CHUNK_CDC,     // old\r
-  CHUNK_CDD,     // 20\r
-  CHUNK_SCD,\r
+  CHUNK_CDD,     // 20 old\r
+  CHUNK_SCD,     // old\r
   CHUNK_RC,      // old\r
   CHUNK_MISC_CD,\r
   //\r
@@ -177,6 +129,7 @@ typedef enum {
   CHUNK_CD_EVT = 50,\r
   CHUNK_CD_GFX,\r
   CHUNK_CD_CDC,\r
+  CHUNK_CD_CDD,\r
   //\r
   CHUNK_DEFAULT_COUNT,\r
   CHUNK_CARTHW_ = CHUNK_CARTHW,  // 64 (defined in PicoInt)\r
@@ -273,23 +226,29 @@ static int state_save(void *file)
   areaWrite("PicoSEXT", 1, 8, file);\r
   areaWrite(&ver, 1, 4, file);\r
 \r
-  if (!(PicoAHW & PAHW_SMS)) {\r
+  if (!(PicoIn.AHW & PAHW_SMS)) {\r
+    // the patches can cause incompatible saves with no-idle\r
+    SekFinishIdleDet();\r
+\r
     memset(buff, 0, sizeof(buff));\r
     SekPackCpu(buff, 0);\r
     CHECKED_WRITE_BUFF(CHUNK_M68K,  buff);\r
-    CHECKED_WRITE_BUFF(CHUNK_RAM,   Pico.ram);\r
-    CHECKED_WRITE_BUFF(CHUNK_VSRAM, Pico.vsram);\r
-    CHECKED_WRITE_BUFF(CHUNK_IOPORTS, Pico.ioports);\r
+    CHECKED_WRITE_BUFF(CHUNK_RAM,   PicoMem.ram);\r
+    CHECKED_WRITE_BUFF(CHUNK_VSRAM, PicoMem.vsram);\r
+    CHECKED_WRITE_BUFF(CHUNK_IOPORTS, PicoMem.ioports);\r
     ym2612_pack_state();\r
     CHECKED_WRITE(CHUNK_FM, 0x200+4, ym2612_regs);\r
+\r
+    if (!(PicoIn.opt & POPT_DIS_IDLE_DET))\r
+      SekInitIdleDet();\r
   }\r
   else {\r
     CHECKED_WRITE_BUFF(CHUNK_SMS, Pico.ms);\r
   }\r
 \r
-  CHECKED_WRITE_BUFF(CHUNK_VRAM,  Pico.vram);\r
-  CHECKED_WRITE_BUFF(CHUNK_ZRAM,  Pico.zram);\r
-  CHECKED_WRITE_BUFF(CHUNK_CRAM,  Pico.cram);\r
+  CHECKED_WRITE_BUFF(CHUNK_VRAM,  PicoMem.vram);\r
+  CHECKED_WRITE_BUFF(CHUNK_ZRAM,  PicoMem.zram);\r
+  CHECKED_WRITE_BUFF(CHUNK_CRAM,  PicoMem.cram);\r
   CHECKED_WRITE_BUFF(CHUNK_MISC,  Pico.m);\r
   CHECKED_WRITE_BUFF(CHUNK_VIDEO, Pico.video);\r
 \r
@@ -297,7 +256,7 @@ static int state_save(void *file)
   CHECKED_WRITE_BUFF(CHUNK_Z80, buff_z80);\r
   CHECKED_WRITE(CHUNK_PSG, 28*4, sn76496_regs);\r
 \r
-  if (PicoAHW & PAHW_MCD)\r
+  if (PicoIn.AHW & PAHW_MCD)\r
   {\r
     buf2 = malloc(CHUNK_LIMIT_W);\r
     if (buf2 == NULL)\r
@@ -317,8 +276,6 @@ static int state_save(void *file)
     CHECKED_WRITE_BUFF(CHUNK_BRAM,     Pico_mcd->bram);\r
     CHECKED_WRITE_BUFF(CHUNK_GA_REGS,  Pico_mcd->s68k_regs); // GA regs, not CPU regs\r
     CHECKED_WRITE_BUFF(CHUNK_PCM,      Pico_mcd->pcm);\r
-    CHECKED_WRITE_BUFF(CHUNK_CDD,      Pico_mcd->cdd);\r
-    CHECKED_WRITE_BUFF(CHUNK_SCD,      Pico_mcd->scd);\r
     CHECKED_WRITE_BUFF(CHUNK_MISC_CD,  Pico_mcd->m);\r
     memset(buff, 0, 0x40);\r
     memcpy(buff, pcd_event_times, sizeof(pcd_event_times));\r
@@ -328,13 +285,15 @@ static int state_save(void *file)
     CHECKED_WRITE(CHUNK_CD_GFX, len, buf2);\r
     len = cdc_context_save(buf2);\r
     CHECKED_WRITE(CHUNK_CD_CDC, len, buf2);\r
+    len = cdd_context_save(buf2);\r
+    CHECKED_WRITE(CHUNK_CD_CDD, len, buf2);\r
 \r
     if (Pico_mcd->s68k_regs[3] & 4) // convert back\r
       wram_2M_to_1M(Pico_mcd->word_ram2M);\r
   }\r
 \r
 #ifndef NO_32X\r
-  if (PicoAHW & PAHW_32X)\r
+  if (PicoIn.AHW & PAHW_32X)\r
   {\r
     unsigned char cpubuff[SH2_STATE_SIZE];\r
 \r
@@ -453,9 +412,9 @@ static int state_load(void *file)
     CHECKED_READ(1, &chunk);\r
     CHECKED_READ(4, &len);\r
     if (len < 0 || len > 1024*512) R_ERROR_RETURN("bad length");\r
-    if (CHUNK_S68K <= chunk && chunk <= CHUNK_MISC_CD && !(PicoAHW & PAHW_MCD))\r
+    if (CHUNK_S68K <= chunk && chunk <= CHUNK_MISC_CD && !(PicoIn.AHW & PAHW_MCD))\r
       R_ERROR_RETURN("cd chunk in non CD state?");\r
-    if (CHUNK_32X_FIRST <= chunk && chunk <= CHUNK_32X_LAST && !(PicoAHW & PAHW_32X))\r
+    if (CHUNK_32X_FIRST <= chunk && chunk <= CHUNK_32X_LAST && !(PicoIn.AHW & PAHW_32X))\r
       Pico32xStartup();\r
 \r
     switch (chunk)\r
@@ -468,14 +427,14 @@ static int state_load(void *file)
         CHECKED_READ_BUFF(buff_z80);\r
         break;\r
 \r
-      case CHUNK_RAM:     CHECKED_READ_BUFF(Pico.ram); break;\r
-      case CHUNK_VRAM:    CHECKED_READ_BUFF(Pico.vram); break;\r
-      case CHUNK_ZRAM:    CHECKED_READ_BUFF(Pico.zram); break;\r
-      case CHUNK_CRAM:    CHECKED_READ_BUFF(Pico.cram); break;\r
-      case CHUNK_VSRAM:   CHECKED_READ_BUFF(Pico.vsram); break;\r
+      case CHUNK_RAM:     CHECKED_READ_BUFF(PicoMem.ram); break;\r
+      case CHUNK_VRAM:    CHECKED_READ_BUFF(PicoMem.vram); break;\r
+      case CHUNK_ZRAM:    CHECKED_READ_BUFF(PicoMem.zram); break;\r
+      case CHUNK_CRAM:    CHECKED_READ_BUFF(PicoMem.cram); break;\r
+      case CHUNK_VSRAM:   CHECKED_READ_BUFF(PicoMem.vsram); break;\r
       case CHUNK_MISC:    CHECKED_READ_BUFF(Pico.m); break;\r
       case CHUNK_VIDEO:   CHECKED_READ_BUFF(Pico.video); break;\r
-      case CHUNK_IOPORTS: CHECKED_READ_BUFF(Pico.ioports); break;\r
+      case CHUNK_IOPORTS: CHECKED_READ_BUFF(PicoMem.ioports); break;\r
       case CHUNK_PSG:     CHECKED_READ2(28*4, sn76496_regs); break;\r
       case CHUNK_FM:\r
         ym2612_regs = YM2612GetRegs();\r
@@ -498,8 +457,6 @@ static int state_load(void *file)
       case CHUNK_BRAM:     CHECKED_READ_BUFF(Pico_mcd->bram); break;\r
       case CHUNK_GA_REGS:  CHECKED_READ_BUFF(Pico_mcd->s68k_regs); break;\r
       case CHUNK_PCM:      CHECKED_READ_BUFF(Pico_mcd->pcm); break;\r
-      case CHUNK_CDD:      CHECKED_READ_BUFF(Pico_mcd->cdd); break;\r
-      case CHUNK_SCD:      CHECKED_READ_BUFF(Pico_mcd->scd); break;\r
       case CHUNK_MISC_CD:  CHECKED_READ_BUFF(Pico_mcd->m); break;\r
 \r
       case CHUNK_CD_EVT:\r
@@ -517,12 +474,22 @@ static int state_load(void *file)
         len_check = cdc_context_load(buf);\r
         break;\r
 \r
+      case CHUNK_CD_CDD:\r
+        CHECKED_READ_LIM(buf);\r
+        len_check = cdd_context_load(buf);\r
+        break;\r
+\r
       // old, to be removed:\r
       case CHUNK_CDC:\r
         CHECKED_READ_LIM(buf);\r
         cdc_context_load_old(buf);\r
         break;\r
 \r
+      case CHUNK_SCD:\r
+        CHECKED_READ_LIM(buf);\r
+        cdd_context_load_old(buf);\r
+        break;\r
+\r
       // 32x stuff\r
 #ifndef NO_32X\r
       case CHUNK_MSH2:\r
@@ -574,33 +541,38 @@ breakswitch:
   }\r
 \r
 readend:\r
-  if (PicoAHW & PAHW_SMS)\r
+  if (PicoIn.AHW & PAHW_SMS)\r
     PicoStateLoadedMS();\r
 \r
-  if (PicoAHW & PAHW_32X)\r
+  if (PicoIn.AHW & PAHW_32X)\r
     Pico32xStateLoaded(1);\r
 \r
+  if (PicoLoadStateHook != NULL)\r
+    PicoLoadStateHook();\r
+\r
   // must unpack 68k and z80 after banks are set up\r
-  if (!(PicoAHW & PAHW_SMS))\r
+  if (!(PicoIn.AHW & PAHW_SMS))\r
     SekUnpackCpu(buff_m68k, 0);\r
-  if (PicoAHW & PAHW_MCD)\r
+  if (PicoIn.AHW & PAHW_MCD)\r
     SekUnpackCpu(buff_s68k, 1);\r
 \r
   z80_unpack(buff_z80);\r
 \r
   // due to dep from 68k cycles..\r
-  SekCycleAim = SekCycleCnt;\r
-  if (PicoAHW & PAHW_32X)\r
+  Pico.t.m68c_aim = Pico.t.m68c_cnt;\r
+  if (PicoIn.AHW & PAHW_32X)\r
     Pico32xStateLoaded(0);\r
-  if (PicoAHW & PAHW_MCD)\r
+  if (PicoIn.AHW & PAHW_MCD)\r
   {\r
     SekCycleAimS68k = SekCycleCntS68k;\r
     pcd_state_loaded();\r
-\r
-    if (!(Pico_mcd->s68k_regs[0x36] & 1) && (Pico_mcd->scd.Status_CDC & 1))\r
-      cdda_start_play();\r
   }\r
 \r
+  Pico.m.dirtyPal = 1;\r
+  Pico.video.status &= ~(SR_VB | SR_F);\r
+  Pico.video.status |= ((Pico.video.reg[1] >> 3) ^ SR_VB) & SR_VB;\r
+  Pico.video.status |= (Pico.video.pending_ints << 2) & SR_F;\r
+\r
   retval = 0;\r
 \r
 out:\r
@@ -613,7 +585,7 @@ static int state_load_gfx(void *file)
   int ver, len, found = 0, to_find = 4;\r
   char buff[8];\r
 \r
-  if (PicoAHW & PAHW_32X)\r
+  if (PicoIn.AHW & PAHW_32X)\r
     to_find += 2;\r
 \r
   g_read_offs = 0;\r
@@ -627,14 +599,14 @@ static int state_load_gfx(void *file)
     CHECKED_READ(1, buff);\r
     CHECKED_READ(4, &len);\r
     if (len < 0 || len > 1024*512) R_ERROR_RETURN("bad length");\r
-    if (buff[0] > CHUNK_FM && buff[0] <= CHUNK_MISC_CD && !(PicoAHW & PAHW_MCD))\r
+    if (buff[0] > CHUNK_FM && buff[0] <= CHUNK_MISC_CD && !(PicoIn.AHW & PAHW_MCD))\r
       R_ERROR_RETURN("cd chunk in non CD state?");\r
 \r
     switch (buff[0])\r
     {\r
-      case CHUNK_VRAM:  CHECKED_READ_BUFF(Pico.vram);  found++; break;\r
-      case CHUNK_CRAM:  CHECKED_READ_BUFF(Pico.cram);  found++; break;\r
-      case CHUNK_VSRAM: CHECKED_READ_BUFF(Pico.vsram); found++; break;\r
+      case CHUNK_VRAM:  CHECKED_READ_BUFF(PicoMem.vram);  found++; break;\r
+      case CHUNK_CRAM:  CHECKED_READ_BUFF(PicoMem.cram);  found++; break;\r
+      case CHUNK_VSRAM: CHECKED_READ_BUFF(PicoMem.vsram); found++; break;\r
       case CHUNK_VIDEO: CHECKED_READ_BUFF(Pico.video); found++; break;\r
 \r
 #ifndef NO_32X\r
@@ -670,17 +642,8 @@ static int pico_state_internal(void *afile, int is_save)
 \r
   if (is_save)\r
     ret = state_save(afile);\r
-  else {\r
+  else\r
     ret = state_load(afile);\r
-    if (ret != 0) {\r
-      areaSeek(afile, 0, SEEK_SET);\r
-      ret = state_load_legacy(afile);\r
-    }\r
-\r
-    if (PicoLoadStateHook != NULL)\r
-      PicoLoadStateHook();\r
-    Pico.m.dirtyPal = 1;\r
-  }\r
 \r
   return ret;\r
 }\r
@@ -724,10 +687,10 @@ int PicoStateLoadGfx(const char *fname)
   if (ret != 0) {\r
     // assume legacy\r
     areaSeek(afile, 0x10020, SEEK_SET);  // skip header and RAM\r
-    areaRead(Pico.vram, 1, sizeof(Pico.vram), afile);\r
+    areaRead(PicoMem.vram, 1, sizeof(PicoMem.vram), afile);\r
     areaSeek(afile, 0x2000, SEEK_CUR);\r
-    areaRead(Pico.cram, 1, sizeof(Pico.cram), afile);\r
-    areaRead(Pico.vsram, 1, sizeof(Pico.vsram), afile);\r
+    areaRead(PicoMem.cram, 1, sizeof(PicoMem.cram), afile);\r
+    areaRead(PicoMem.vsram, 1, sizeof(PicoMem.vsram), afile);\r
     areaSeek(afile, 0x221a0, SEEK_SET);\r
     areaRead(&Pico.video, 1, sizeof(Pico.video), afile);\r
   }\r
@@ -760,13 +723,13 @@ void *PicoTmpStateSave(void)
   if (t == NULL)\r
     return NULL;\r
 \r
-  memcpy(t->vram, Pico.vram, sizeof(Pico.vram));\r
-  memcpy(t->cram, Pico.cram, sizeof(Pico.cram));\r
-  memcpy(t->vsram, Pico.vsram, sizeof(Pico.vsram));\r
+  memcpy(t->vram, PicoMem.vram, sizeof(PicoMem.vram));\r
+  memcpy(t->cram, PicoMem.cram, sizeof(PicoMem.cram));\r
+  memcpy(t->vsram, PicoMem.vsram, sizeof(PicoMem.vsram));\r
   memcpy(&t->video, &Pico.video, sizeof(Pico.video));\r
 \r
 #ifndef NO_32X\r
-  if (PicoAHW & PAHW_32X) {\r
+  if (PicoIn.AHW & PAHW_32X) {\r
     memcpy(&t->t32x.p32x, &Pico32x, sizeof(Pico32x));\r
     memcpy(t->t32x.dram, Pico32xMem->dram, sizeof(Pico32xMem->dram));\r
     memcpy(t->t32x.pal, Pico32xMem->pal, sizeof(Pico32xMem->pal));\r
@@ -782,14 +745,14 @@ void PicoTmpStateRestore(void *data)
   if (t == NULL)\r
     return;\r
 \r
-  memcpy(Pico.vram, t->vram, sizeof(Pico.vram));\r
-  memcpy(Pico.cram, t->cram, sizeof(Pico.cram));\r
-  memcpy(Pico.vsram, t->vsram, sizeof(Pico.vsram));\r
+  memcpy(PicoMem.vram, t->vram, sizeof(PicoMem.vram));\r
+  memcpy(PicoMem.cram, t->cram, sizeof(PicoMem.cram));\r
+  memcpy(PicoMem.vsram, t->vsram, sizeof(PicoMem.vsram));\r
   memcpy(&Pico.video, &t->video, sizeof(Pico.video));\r
   Pico.m.dirtyPal = 1;\r
 \r
 #ifndef NO_32X\r
-  if (PicoAHW & PAHW_32X) {\r
+  if (PicoIn.AHW & PAHW_32X) {\r
     memcpy(&Pico32x, &t->t32x.p32x, sizeof(Pico32x));\r
     memcpy(Pico32xMem->dram, t->t32x.dram, sizeof(Pico32xMem->dram));\r
     memcpy(Pico32xMem->pal, t->t32x.pal, sizeof(Pico32xMem->pal));\r