license info added to Pico directory
[cyclone68000.git] / Pico / Area.cpp
CommitLineData
15eb0001 1\r
4abeeb4b 2// This file is part of the PicoDrive Megadrive Emulator\r
3\r
4// This code is licensed under the GNU General Public License version 2.0 and the MAME License.\r
5// You can choose the license that has the most advantages for you.\r
6\r
7// SVN repository can be found at http://code.google.com/p/cyclone68000/\r
8\r
15eb0001 9#include "PicoInt.h"\r
10\r
11int (*PicoAcb)(struct PicoArea *)=NULL; // Area callback for each block of memory\r
12FILE *PmovFile=NULL;\r
13int PmovAction=0;\r
14\r
15// Scan one variable and callback\r
16static void ScanVar(void *data,int len,char *name)\r
17{\r
18 struct PicoArea pa={NULL,0,NULL};\r
19 pa.data=data; pa.len=len; pa.name=name;\r
20 if (PicoAcb) PicoAcb(&pa);\r
21}\r
22\r
23#define SCAN_VAR(x,y) ScanVar(&x,sizeof(x),y);\r
24#define SCANP(x) ScanVar(&Pico.x,sizeof(Pico.x),#x);\r
25\r
26// Pack the cpu into a common format:\r
27static int PackCpu(unsigned char *cpu)\r
28{\r
29 unsigned int pc=0;\r
30\r
31#ifdef EMU_A68K\r
32 memcpy(cpu,M68000_regs.d,0x40);\r
33 pc=M68000_regs.pc;\r
34 *(unsigned char *)(cpu+0x44)=(unsigned char)M68000_regs.ccr;\r
35 *(unsigned char *)(cpu+0x45)=(unsigned char)M68000_regs.srh;\r
36 *(unsigned int *)(cpu+0x48)=M68000_regs.isp;\r
37#endif\r
38\r
39#ifdef EMU_C68K\r
40 memcpy(cpu,PicoCpu.d,0x40);\r
41 pc=PicoCpu.pc-PicoCpu.membase;\r
42 *(unsigned char *)(cpu+0x44)=PicoCpu.ccr;\r
43 *(unsigned char *)(cpu+0x45)=PicoCpu.srh;\r
44 *(unsigned int *)(cpu+0x48)=PicoCpu.osp;\r
45#endif\r
46\r
47 *(unsigned int *)(cpu+0x40)=pc;\r
48 return 0;\r
49}\r
50\r
51static int UnpackCpu(unsigned char *cpu)\r
52{\r
53 unsigned int pc=0;\r
54\r
55 pc=*(unsigned int *)(cpu+0x40);\r
56\r
57#ifdef EMU_A68K\r
58 memcpy(M68000_regs.d,cpu,0x40);\r
59 M68000_regs.pc=pc;\r
60 M68000_regs.ccr=*(unsigned char *)(cpu+0x44);\r
61 M68000_regs.srh=*(unsigned char *)(cpu+0x45);\r
62 M68000_regs.isp=*(unsigned int *)(cpu+0x48);\r
63#endif\r
64\r
65#ifdef EMU_C68K\r
66 memcpy(PicoCpu.d,cpu,0x40);\r
67 PicoCpu.membase=0;\r
68 PicoCpu.pc =PicoCpu.checkpc(pc); // Base pc\r
69 PicoCpu.ccr=*(unsigned char *)(cpu+0x44);\r
70 PicoCpu.srh=*(unsigned char *)(cpu+0x45);\r
71 PicoCpu.osp=*(unsigned int *)(cpu+0x48);\r
72#endif\r
73 return 0;\r
74}\r
75\r
76// Scan the contents of the virtual machine's memory for saving or loading\r
77int PicoAreaScan(int action,int *pmin)\r
78{\r
79 unsigned char cpu[0x60];\r
80\r
81 memset(&cpu,0,sizeof(cpu));\r
82\r
83 if (action&4)\r
84 {\r
85 // Scan all the memory areas:\r
86 SCANP(ram) SCANP(vram) SCANP(zram) SCANP(cram) SCANP(vsram)\r
87\r
88 // Pack, scan and unpack the cpu data:\r
89 PackCpu(cpu);\r
90 SekInit();\r
91 PicoMemInit();\r
92 SCAN_VAR(cpu,"cpu")\r
93 UnpackCpu(cpu);\r
94\r
95 SCAN_VAR(Pico.m ,"misc")\r
96 SCAN_VAR(Pico.video,"video")\r
97 SCAN_VAR(Pico.s ,"sound")\r
98\r
99 Pico.m.scanline=0;\r
100 if (action&2)\r
101 {\r
102 memset(Pico.highpal,0,sizeof(Pico.highpal));\r
103 Pico.m.dirtyPal=1; // Recalculate palette\r
104 }\r
105 }\r
106\r
107 if (pmin) *pmin=0x0021;\r
108\r
109 return 0;\r
110}\r
111\r
112// ---------------------------------------------------------------------------\r
113// Helper code to save/load to a file handle\r
114\r
115// Area callback for each piece of Megadrive memory, read or write to the file:\r
116static int StateAcb(struct PicoArea *pa)\r
117{\r
118 if (PmovFile==NULL) return 1;\r
119\r
120 if ((PmovAction&3)==1) fwrite(pa->data,1,pa->len,PmovFile);\r
121 if ((PmovAction&3)==2) fread (pa->data,1,pa->len,PmovFile);\r
122 return 0;\r
123}\r
124\r
125// Save or load the state from PmovFile:\r
126int PmovState()\r
127{\r
128 int minimum=0;\r
129 unsigned char head[32];\r
130\r
131 memset(head,0,sizeof(head));\r
132\r
133 // Find out minial compatible version:\r
134 PicoAreaScan(PmovAction&0xc,&minimum); \r
135\r
136 memcpy(head,"Pico",4);\r
137 *(unsigned int *)(head+0x8)=PicoVer;\r
138 *(unsigned int *)(head+0xc)=minimum;\r
139\r
140 // Scan header:\r
141 if (PmovAction&1) fwrite(head,1,sizeof(head),PmovFile);\r
142 if (PmovAction&2) fread (head,1,sizeof(head),PmovFile);\r
143\r
144 // Scan memory areas:\r
145 PicoAcb=StateAcb;\r
146 PicoAreaScan(PmovAction,NULL);\r
147 PicoAcb=NULL;\r
148 return 0;\r
149}\r
150\r
151int PmovUpdate()\r
152{\r
153 int ret=0;\r
154 if (PmovFile==NULL) return 1;\r
155 \r
156 if ((PmovAction&3)==0) return 0;\r
157\r
158 PicoPad[1]=0; // Make sure pad #2 is blank\r
159 if (PmovAction&1) ret=fwrite(PicoPad,1,2,PmovFile);\r
160 if (PmovAction&2) ret=fread (PicoPad,1,2,PmovFile);\r
161\r
162 if (ret!=2)\r
163 {\r
164 // End of file\r
165 fclose(PmovFile); PmovFile=NULL;\r
166 PmovAction=0;\r
167 }\r
168\r
169 return 0;\r
170}\r