2 // This file is part of the PicoDrive Megadrive Emulator
\r
4 // Copyright (c) 2011 FinalDave (emudave (at) gmail.com)
\r
6 // This code is licensed under the GNU General Public License version 2.0 and the MAME License.
\r
7 // You can choose the license that has the most advantages for you.
\r
9 // SVN repository can be found at http://code.google.com/p/cyclone68000/
\r
11 #include "PicoInt.h"
\r
13 int (*PicoAcb)(struct PicoArea *)=NULL; // Area callback for each block of memory
\r
14 FILE *PmovFile=NULL;
\r
17 // Scan one variable and callback
\r
18 static void ScanVar(void *data,int len,char *name)
\r
20 struct PicoArea pa={NULL,0,NULL};
\r
21 pa.data=data; pa.len=len; pa.name=name;
\r
22 if (PicoAcb) PicoAcb(&pa);
\r
25 #define SCAN_VAR(x,y) ScanVar(&x,sizeof(x),y);
\r
26 #define SCANP(x) ScanVar(&Pico.x,sizeof(Pico.x),#x);
\r
28 // Pack the cpu into a common format:
\r
29 static int PackCpu(unsigned char *cpu)
\r
34 memcpy(cpu,M68000_regs.d,0x40);
\r
36 *(unsigned char *)(cpu+0x44)=(unsigned char)M68000_regs.ccr;
\r
37 *(unsigned char *)(cpu+0x45)=(unsigned char)M68000_regs.srh;
\r
38 *(unsigned int *)(cpu+0x48)=M68000_regs.isp;
\r
42 memcpy(cpu,PicoCpu.d,0x40);
\r
43 pc=PicoCpu.pc-PicoCpu.membase;
\r
44 *(unsigned char *)(cpu+0x44)=PicoCpu.ccr;
\r
45 *(unsigned char *)(cpu+0x45)=PicoCpu.srh;
\r
46 *(unsigned int *)(cpu+0x48)=PicoCpu.osp;
\r
49 *(unsigned int *)(cpu+0x40)=pc;
\r
53 static int UnpackCpu(unsigned char *cpu)
\r
57 pc=*(unsigned int *)(cpu+0x40);
\r
60 memcpy(M68000_regs.d,cpu,0x40);
\r
62 M68000_regs.ccr=*(unsigned char *)(cpu+0x44);
\r
63 M68000_regs.srh=*(unsigned char *)(cpu+0x45);
\r
64 M68000_regs.isp=*(unsigned int *)(cpu+0x48);
\r
68 memcpy(PicoCpu.d,cpu,0x40);
\r
70 PicoCpu.pc =PicoCpu.checkpc(pc); // Base pc
\r
71 PicoCpu.ccr=*(unsigned char *)(cpu+0x44);
\r
72 PicoCpu.srh=*(unsigned char *)(cpu+0x45);
\r
73 PicoCpu.osp=*(unsigned int *)(cpu+0x48);
\r
78 // Scan the contents of the virtual machine's memory for saving or loading
\r
79 int PicoAreaScan(int action,int *pmin)
\r
81 unsigned char cpu[0x60];
\r
83 memset(&cpu,0,sizeof(cpu));
\r
87 // Scan all the memory areas:
\r
88 SCANP(ram) SCANP(vram) SCANP(zram) SCANP(cram) SCANP(vsram)
\r
90 // Pack, scan and unpack the cpu data:
\r
97 SCAN_VAR(Pico.m ,"misc")
\r
98 SCAN_VAR(Pico.video,"video")
\r
99 SCAN_VAR(Pico.s ,"sound")
\r
104 memset(Pico.highpal,0,sizeof(Pico.highpal));
\r
105 Pico.m.dirtyPal=1; // Recalculate palette
\r
109 if (pmin) *pmin=0x0021;
\r
114 // ---------------------------------------------------------------------------
\r
115 // Helper code to save/load to a file handle
\r
117 // Area callback for each piece of Megadrive memory, read or write to the file:
\r
118 static int StateAcb(struct PicoArea *pa)
\r
120 if (PmovFile==NULL) return 1;
\r
122 if ((PmovAction&3)==1) fwrite(pa->data,1,pa->len,PmovFile);
\r
123 if ((PmovAction&3)==2) fread (pa->data,1,pa->len,PmovFile);
\r
127 // Save or load the state from PmovFile:
\r
131 unsigned char head[32];
\r
133 memset(head,0,sizeof(head));
\r
135 // Find out minial compatible version:
\r
136 PicoAreaScan(PmovAction&0xc,&minimum);
\r
138 memcpy(head,"Pico",4);
\r
139 *(unsigned int *)(head+0x8)=PicoVer;
\r
140 *(unsigned int *)(head+0xc)=minimum;
\r
143 if (PmovAction&1) fwrite(head,1,sizeof(head),PmovFile);
\r
144 if (PmovAction&2) fread (head,1,sizeof(head),PmovFile);
\r
146 // Scan memory areas:
\r
148 PicoAreaScan(PmovAction,NULL);
\r
156 if (PmovFile==NULL) return 1;
\r
158 if ((PmovAction&3)==0) return 0;
\r
160 PicoPad[1]=0; // Make sure pad #2 is blank
\r
161 if (PmovAction&1) ret=fwrite(PicoPad,1,2,PmovFile);
\r
162 if (PmovAction&2) ret=fread (PicoPad,1,2,PmovFile);
\r
167 fclose(PmovFile); PmovFile=NULL;
\r