added copyright line to top of source files next to license information
[cyclone68000.git] / Pico / Area.cpp
1 \r
2 // This file is part of the PicoDrive Megadrive Emulator\r
3 \r
4 // Copyright (c) 2011 FinalDave (emudave (at) gmail.com)\r
5 \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
8 \r
9 // SVN repository can be found at http://code.google.com/p/cyclone68000/\r
10 \r
11 #include "PicoInt.h"\r
12 \r
13 int (*PicoAcb)(struct PicoArea *)=NULL; // Area callback for each block of memory\r
14 FILE *PmovFile=NULL;\r
15 int PmovAction=0;\r
16 \r
17 // Scan one variable and callback\r
18 static void ScanVar(void *data,int len,char *name)\r
19 {\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
23 }\r
24 \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
27 \r
28 // Pack the cpu into a common format:\r
29 static int PackCpu(unsigned char *cpu)\r
30 {\r
31   unsigned int pc=0;\r
32 \r
33 #ifdef EMU_A68K\r
34   memcpy(cpu,M68000_regs.d,0x40);\r
35   pc=M68000_regs.pc;\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
39 #endif\r
40 \r
41 #ifdef EMU_C68K\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
47 #endif\r
48 \r
49   *(unsigned int *)(cpu+0x40)=pc;\r
50   return 0;\r
51 }\r
52 \r
53 static int UnpackCpu(unsigned char *cpu)\r
54 {\r
55   unsigned int pc=0;\r
56 \r
57   pc=*(unsigned int *)(cpu+0x40);\r
58 \r
59 #ifdef EMU_A68K\r
60   memcpy(M68000_regs.d,cpu,0x40);\r
61   M68000_regs.pc=pc;\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
65 #endif\r
66 \r
67 #ifdef EMU_C68K\r
68   memcpy(PicoCpu.d,cpu,0x40);\r
69   PicoCpu.membase=0;\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
74 #endif\r
75   return 0;\r
76 }\r
77 \r
78 // Scan the contents of the virtual machine's memory for saving or loading\r
79 int PicoAreaScan(int action,int *pmin)\r
80 {\r
81   unsigned char cpu[0x60];\r
82 \r
83   memset(&cpu,0,sizeof(cpu));\r
84 \r
85   if (action&4)\r
86   {\r
87     // Scan all the memory areas:\r
88     SCANP(ram) SCANP(vram) SCANP(zram) SCANP(cram) SCANP(vsram)\r
89 \r
90     // Pack, scan and unpack the cpu data:\r
91     PackCpu(cpu);\r
92     SekInit();\r
93     PicoMemInit();\r
94     SCAN_VAR(cpu,"cpu")\r
95     UnpackCpu(cpu);\r
96 \r
97     SCAN_VAR(Pico.m    ,"misc")\r
98     SCAN_VAR(Pico.video,"video")\r
99     SCAN_VAR(Pico.s    ,"sound")\r
100 \r
101     Pico.m.scanline=0;\r
102     if (action&2)\r
103     {\r
104       memset(Pico.highpal,0,sizeof(Pico.highpal));\r
105       Pico.m.dirtyPal=1; // Recalculate palette\r
106     }\r
107   }\r
108 \r
109   if (pmin) *pmin=0x0021;\r
110 \r
111   return 0;\r
112 }\r
113 \r
114 // ---------------------------------------------------------------------------\r
115 // Helper code to save/load to a file handle\r
116 \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
119 {\r
120   if (PmovFile==NULL) return 1;\r
121 \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
124   return 0;\r
125 }\r
126 \r
127 // Save or load the state from PmovFile:\r
128 int PmovState()\r
129 {\r
130   int minimum=0;\r
131   unsigned char head[32];\r
132 \r
133   memset(head,0,sizeof(head));\r
134 \r
135   // Find out minial compatible version:\r
136   PicoAreaScan(PmovAction&0xc,&minimum);  \r
137 \r
138   memcpy(head,"Pico",4);\r
139   *(unsigned int *)(head+0x8)=PicoVer;\r
140   *(unsigned int *)(head+0xc)=minimum;\r
141 \r
142   // Scan header:\r
143   if (PmovAction&1) fwrite(head,1,sizeof(head),PmovFile);\r
144   if (PmovAction&2) fread (head,1,sizeof(head),PmovFile);\r
145 \r
146   // Scan memory areas:\r
147   PicoAcb=StateAcb;\r
148   PicoAreaScan(PmovAction,NULL);\r
149   PicoAcb=NULL;\r
150   return 0;\r
151 }\r
152 \r
153 int PmovUpdate()\r
154 {\r
155   int ret=0;\r
156   if (PmovFile==NULL) return 1;\r
157   \r
158   if ((PmovAction&3)==0) return 0;\r
159 \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
163 \r
164   if (ret!=2)\r
165   {\r
166     // End of file\r
167     fclose(PmovFile); PmovFile=NULL;\r
168     PmovAction=0;\r
169   }\r
170 \r
171   return 0;\r
172 }\r