added copyright line to top of source files next to license information
[cyclone68000.git] / Pico / Area.cpp
CommitLineData
15eb0001 1\r
4abeeb4b 2// This file is part of the PicoDrive Megadrive Emulator\r
3\r
c41b9b97 4// Copyright (c) 2011 FinalDave (emudave (at) gmail.com)\r
5\r
4abeeb4b 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
15eb0001 11#include "PicoInt.h"\r
12\r
13int (*PicoAcb)(struct PicoArea *)=NULL; // Area callback for each block of memory\r
14FILE *PmovFile=NULL;\r
15int PmovAction=0;\r
16\r
17// Scan one variable and callback\r
18static 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
29static 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
53static 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
79int 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
118static 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
128int 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
153int 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