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