random cleanups
[picodrive.git] / pico / area.c
index 876320d..23e00da 100644 (file)
@@ -8,6 +8,7 @@
 \r
 \r
 #include "pico_int.h"\r
+#include <zlib/zlib.h>\r
 \r
 // ym2612\r
 #include "sound/ym2612.h"\r
@@ -15,7 +16,6 @@
 // sn76496\r
 extern int *sn76496_regs;\r
 \r
-\r
 struct PicoArea { void *data; int len; char *name; };\r
 \r
 // strange observation on Symbian OS 9.1, m600 organizer fw r3a06:\r
@@ -32,16 +32,18 @@ void (*PicoLoadStateHook)(void) = NULL;
 \r
 \r
 // Scan one variable and callback\r
-static int ScanVar(void *data,int len,char *name,void *PmovFile,int PmovAction)\r
+static int ScanVar(void *data,int len,char *name,void *PmovFile,int is_write)\r
 {\r
   int ret = 0;\r
-  if ((PmovAction&3)==1) ret = areaWrite(data,1,len,PmovFile);\r
-  if ((PmovAction&3)==2) ret = areaRead (data,1,len,PmovFile);\r
+  if (is_write)\r
+    ret = areaWrite(data,1,len,PmovFile);\r
+  else\r
+    ret = areaRead (data,1,len,PmovFile);\r
   return (ret != len);\r
 }\r
 \r
-#define SCAN_VAR(x,y) ScanVar(&x,sizeof(x),y,PmovFile,PmovAction);\r
-#define SCANP(x)      ScanVar(&Pico.x,sizeof(Pico.x),#x,PmovFile,PmovAction);\r
+#define SCAN_VAR(x,y) ScanVar(&x,sizeof(x),y,PmovFile,is_write);\r
+#define SCANP(x)      ScanVar(&Pico.x,sizeof(Pico.x),#x,PmovFile,is_write);\r
 \r
 // Pack the cpu into a common format:\r
 PICO_INTERNAL void PicoAreaPackCpu(unsigned char *cpu, int is_sub)\r
@@ -86,8 +88,9 @@ PICO_INTERNAL void PicoAreaUnpackCpu(unsigned char *cpu, int is_sub)
   CycloneSetSr(context, *(unsigned int *)(cpu+0x44));\r
   context->osp=*(unsigned int *)(cpu+0x48);\r
   memcpy(context->d,cpu,0x40);\r
-  context->membase=0;\r
-  context->pc = context->checkpc(*(unsigned int *)(cpu+0x40)); // Base pc\r
+  context->membase = 0;\r
+  context->pc = *(unsigned int *)(cpu+0x40);\r
+  CycloneUnpack(context, NULL); // rebase PC\r
   context->irq = cpu[0x4c];\r
   context->state_flags = 0;\r
   if (cpu[0x4d])\r
@@ -115,7 +118,7 @@ PICO_INTERNAL void PicoAreaUnpackCpu(unsigned char *cpu, int is_sub)
 }\r
 \r
 // Scan the contents of the virtual machine's memory for saving or loading\r
-static int PicoAreaScan(int PmovAction,unsigned int ver, void *PmovFile)\r
+static int PicoAreaScan(int is_write, unsigned int ver, void *PmovFile)\r
 {\r
   void *ym2612_regs;\r
   unsigned char cpu[0x60];\r
@@ -124,59 +127,60 @@ static int PicoAreaScan(int PmovAction,unsigned int ver, void *PmovFile)
 \r
   memset(&cpu,0,sizeof(cpu));\r
   memset(&cpu_z80,0,sizeof(cpu_z80));\r
+  Pico.m.scanline=0;\r
 \r
   ym2612_regs = YM2612GetRegs();\r
 \r
-  if (PmovAction&4)\r
-  {\r
-    Pico.m.scanline=0;\r
-\r
-    // Scan all the memory areas:\r
-    SCANP(ram) SCANP(vram) SCANP(zram) SCANP(cram) SCANP(vsram)\r
-\r
-    // Pack, scan and unpack the cpu data:\r
-    if((PmovAction&3)==1) PicoAreaPackCpu(cpu, 0);\r
-    //PicoMemInit();\r
-    SCAN_VAR(cpu,"cpu")\r
-    if((PmovAction&3)==2) PicoAreaUnpackCpu(cpu, 0);\r
-\r
-    SCAN_VAR(Pico.m    ,"misc")\r
-    SCAN_VAR(Pico.video,"video")\r
-\r
-    if (PicoOpt&7) {\r
-      if((PmovAction&3)==1) z80_pack(cpu_z80);\r
-      ret = SCAN_VAR(cpu_z80,"cpu_z80")\r
-      // do not unpack if we fail to load z80 state\r
-      if((PmovAction&3)==2) {\r
-        if(ret) z80_reset();\r
-        else    z80_unpack(cpu_z80);\r
-      }\r
-    }\r
-    if (PicoOpt&3)\r
-      ScanVar(sn76496_regs,28*4,"SN76496state", PmovFile, PmovAction); // regs and other stuff\r
-    if (PicoOpt&1) {\r
-      if((PmovAction&3)==1) ym2612_pack_state();\r
-      ScanVar(ym2612_regs, 0x200+4, "YM2612state", PmovFile, PmovAction); // regs + addr line\r
-      if((PmovAction&3)==2) ym2612_unpack_state(); // reload YM2612 state from it's regs\r
-    }\r
+  // Scan all the memory areas:\r
+  SCANP(ram) SCANP(vram) SCANP(zram) SCANP(cram) SCANP(vsram)\r
+\r
+  // Pack, scan and unpack the cpu data:\r
+  if (is_write)\r
+    PicoAreaPackCpu(cpu, 0);\r
+  SCAN_VAR(cpu,"cpu")\r
+  if (!is_write)\r
+    PicoAreaUnpackCpu(cpu, 0);\r
+\r
+  SCAN_VAR(Pico.m    ,"misc")\r
+  SCAN_VAR(Pico.video,"video")\r
+\r
+  // no longer keeping eeprom data in sram_reg\r
+  if (!is_write && (Pico.m.sram_reg & 4))\r
+    Pico.m.sram_reg = SRR_MAPPED;\r
+\r
+  if (is_write)\r
+    z80_pack(cpu_z80);\r
+  ret = SCAN_VAR(cpu_z80,"cpu_z80")\r
+  // do not unpack if we fail to load z80 state\r
+  if (!is_write) {\r
+    if (ret) z80_reset();\r
+    else     z80_unpack(cpu_z80);\r
   }\r
 \r
+  ScanVar(sn76496_regs, 28*4, "SN76496state", PmovFile, is_write);\r
+  if (is_write)\r
+    ym2612_pack_state();\r
+  ret = ScanVar(ym2612_regs, 0x200+4, "YM2612state", PmovFile, is_write); // regs + addr line\r
+  if (!is_write && !ret)\r
+    ym2612_unpack_state();\r
+\r
   return 0;\r
 }\r
 \r
 // ---------------------------------------------------------------------------\r
 // Helper code to save/load to a file handle\r
 \r
+// XXX: error checking\r
 // Save or load the state from PmovFile:\r
-int PmovState(int PmovAction, void *PmovFile)\r
+static int PmovState(int is_write, void *PmovFile)\r
 {\r
-  int minimum=0;\r
   unsigned char head[32];\r
 \r
   if ((PicoAHW & PAHW_MCD) || carthw_chunks != NULL)\r
   {\r
-    if (PmovAction&1) return PicoCdSaveState(PmovFile);\r
-    if (PmovAction&2) {\r
+    if (is_write)\r
+      return PicoCdSaveState(PmovFile);\r
+    else {\r
       int ret = PicoCdLoadState(PmovFile);\r
       if (PicoLoadStateHook) PicoLoadStateHook();\r
       return ret;\r
@@ -185,23 +189,112 @@ int PmovState(int PmovAction, void *PmovFile)
 \r
   memset(head,0,sizeof(head));\r
 \r
-  // Find out minimal compatible version:\r
-  //PicoAreaScan(PmovAction&0xc,&minimum);\r
-  minimum = 0x0021;\r
-\r
+  // not really used..\r
   memcpy(head,"Pico",4);\r
-  *(unsigned int *)(head+0x8)=PicoVer;\r
-  *(unsigned int *)(head+0xc)=minimum;\r
+  *(unsigned int *)(head+0x8)=0x0133;\r
+  *(unsigned int *)(head+0xc)=0x0021;\r
 \r
   // Scan header:\r
-  if (PmovAction&1) areaWrite(head,1,sizeof(head),PmovFile);\r
-  if (PmovAction&2) areaRead (head,1,sizeof(head),PmovFile);\r
+  if (is_write)\r
+    areaWrite(head,1,sizeof(head),PmovFile);\r
+  else\r
+    areaRead (head,1,sizeof(head),PmovFile);\r
 \r
   // Scan memory areas:\r
-  PicoAreaScan(PmovAction, *(unsigned int *)(head+0x8), PmovFile);\r
+  PicoAreaScan(is_write, *(unsigned int *)(head+0x8), PmovFile);\r
+\r
+  if (!is_write && PicoLoadStateHook)\r
+    PicoLoadStateHook();\r
+\r
+  return 0;\r
+}\r
 \r
-  if ((PmovAction&2) && PicoLoadStateHook) PicoLoadStateHook();\r
+static size_t gzRead2(void *p, size_t _size, size_t _n, void *file)\r
+{\r
+  return gzread(file, p, _n);\r
+}\r
+\r
+static size_t gzWrite2(void *p, size_t _size, size_t _n, void *file)\r
+{\r
+  return gzwrite(file, p, _n);\r
+}\r
 \r
+static void set_cbs(int gz)\r
+{\r
+  if (gz) {\r
+    areaRead  = gzRead2;\r
+    areaWrite = gzWrite2;\r
+    areaEof   = (areaeof *) gzeof;\r
+    areaSeek  = (areaseek *) gzseek;\r
+    areaClose = (areaclose *) gzclose;\r
+  } else {\r
+    areaRead  = (arearw *) fread;\r
+    areaWrite = (arearw *) fwrite;\r
+    areaEof   = (areaeof *) feof;\r
+    areaSeek  = (areaseek *) fseek;\r
+    areaClose = (areaclose *) fclose;\r
+  }\r
+}\r
+\r
+int PicoState(const char *fname, int is_save)\r
+{\r
+  void *afile = NULL;\r
+  int ret;\r
+\r
+  if (strcmp(fname + strlen(fname) - 3, ".gz") == 0)\r
+  {\r
+    if ( (afile = gzopen(fname, is_save ? "wb" : "rb")) ) {\r
+      set_cbs(1);\r
+      if (is_save)\r
+        gzsetparams(afile, 9, Z_DEFAULT_STRATEGY);\r
+    }\r
+  }\r
+  else\r
+  {\r
+    if ( (afile = fopen(fname, is_save ? "wb" : "rb")) ) {\r
+      set_cbs(0);\r
+    }\r
+  }\r
+\r
+  if (afile == NULL)\r
+    return -1;\r
+\r
+  ret = PmovState(is_save, afile);\r
+  areaClose(afile);\r
+  if (!is_save)\r
+    Pico.m.dirtyPal=1;\r
+\r
+  return ret;\r
+}\r
+\r
+int PicoStateLoadVDP(const char *fname)\r
+{\r
+  void *afile = NULL;\r
+  if (strcmp(fname + strlen(fname) - 3, ".gz") == 0)\r
+  {\r
+    if ( (afile = gzopen(fname, "rb")) )\r
+      set_cbs(1);\r
+  }\r
+  else\r
+  {\r
+    if ( (afile = fopen(fname, "rb")) )\r
+      set_cbs(0);\r
+  }\r
+  if (afile == NULL)\r
+    return -1;\r
+\r
+  if ((PicoAHW & PAHW_MCD) || carthw_chunks != NULL) {\r
+    PicoCdLoadStateGfx(afile);\r
+  } else {\r
+    areaSeek(afile, 0x10020, SEEK_SET);  // skip header and RAM in state file\r
+    areaRead(Pico.vram, 1, sizeof(Pico.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
+    areaSeek(afile, 0x221a0, SEEK_SET);\r
+    areaRead(&Pico.video, 1, sizeof(Pico.video), afile);\r
+  }\r
+  areaClose(afile);\r
   return 0;\r
 }\r
 \r