summaryrefslogtreecommitdiff
path: root/apps/plugins/rockboy/save.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/rockboy/save.c')
-rw-r--r--apps/plugins/rockboy/save.c286
1 files changed, 286 insertions, 0 deletions
diff --git a/apps/plugins/rockboy/save.c b/apps/plugins/rockboy/save.c
new file mode 100644
index 0000000000..bb9f905b8f
--- /dev/null
+++ b/apps/plugins/rockboy/save.c
@@ -0,0 +1,286 @@
1
2
3#include "rockmacros.h"
4#include <stdio.h>
5
6#include "defs.h"
7#include "cpu.h"
8#include "cpuregs.h"
9#include "hw.h"
10#include "regs.h"
11#include "lcd.h"
12#include "rtc.h"
13#include "mem.h"
14#include "sound.h"
15
16
17
18#ifdef LITTLE_ENDIAN
19#define LIL(x) (x)
20#else
21#define LIL(x) ((x<<24)|((x&0xff00)<<8)|((x>>8)&0xff00)|(x>>24))
22#endif
23
24#define I1(s, p) { 1, s, p }
25#define I2(s, p) { 2, s, p }
26#define I4(s, p) { 4, s, p }
27#define R(r) I1(#r, &R_##r)
28#define NOSAVE { -1, "\0\0\0\0", 0 }
29#define END { 0, "\0\0\0\0", 0 }
30
31struct svar
32{
33 int len;
34 char key[4];
35 void *ptr;
36};
37
38static int ver;
39static int sramblock, iramblock, vramblock;
40static int hramofs, hiofs, palofs, oamofs, wavofs;
41
42struct svar svars[] =
43{
44 I4("GbSs", &ver),
45
46 I2("PC ", &PC),
47 I2("SP ", &SP),
48 I2("BC ", &BC),
49 I2("DE ", &DE),
50 I2("HL ", &HL),
51 I2("AF ", &AF),
52
53 I4("IME ", &cpu.ime),
54 I4("ima ", &cpu.ima),
55 I4("spd ", &cpu.speed),
56 I4("halt", &cpu.halt),
57 I4("div ", &cpu.div),
58 I4("tim ", &cpu.tim),
59 I4("lcdc", &cpu.lcdc),
60 I4("snd ", &cpu.snd),
61
62 I1("ints", &hw.ilines),
63 I1("pad ", &hw.pad),
64 I4("cgb ", &hw.cgb),
65 I4("gba ", &hw.gba),
66
67 I4("mbcm", &mbc.model),
68 I4("romb", &mbc.rombank),
69 I4("ramb", &mbc.rambank),
70 I4("enab", &mbc.enableram),
71 I4("batt", &mbc.batt),
72
73 I4("rtcR", &rtc.sel),
74 I4("rtcL", &rtc.latch),
75 I4("rtcC", &rtc.carry),
76 I4("rtcS", &rtc.stop),
77 I4("rtcd", &rtc.d),
78 I4("rtch", &rtc.h),
79 I4("rtcm", &rtc.m),
80 I4("rtcs", &rtc.s),
81 I4("rtct", &rtc.t),
82 I1("rtR8", &rtc.regs[0]),
83 I1("rtR9", &rtc.regs[1]),
84 I1("rtRA", &rtc.regs[2]),
85 I1("rtRB", &rtc.regs[3]),
86 I1("rtRC", &rtc.regs[4]),
87
88 I4("S1on", &snd.ch[0].on),
89 I4("S1p ", &snd.ch[0].pos),
90 I4("S1c ", &snd.ch[0].cnt),
91 I4("S1ec", &snd.ch[0].encnt),
92 I4("S1sc", &snd.ch[0].swcnt),
93 I4("S1sf", &snd.ch[0].swfreq),
94
95 I4("S2on", &snd.ch[1].on),
96 I4("S2p ", &snd.ch[1].pos),
97 I4("S2c ", &snd.ch[1].cnt),
98 I4("S2ec", &snd.ch[1].encnt),
99
100 I4("S3on", &snd.ch[2].on),
101 I4("S3p ", &snd.ch[2].pos),
102 I4("S3c ", &snd.ch[2].cnt),
103
104 I4("S4on", &snd.ch[3].on),
105 I4("S4p ", &snd.ch[3].pos),
106 I4("S4c ", &snd.ch[3].cnt),
107 I4("S4ec", &snd.ch[3].encnt),
108
109 I4("hdma", &hw.hdma),
110
111 I4("sram", &sramblock),
112 I4("iram", &iramblock),
113 I4("vram", &vramblock),
114 I4("hi ", &hiofs),
115 I4("pal ", &palofs),
116 I4("oam ", &oamofs),
117 I4("wav ", &wavofs),
118
119 /* NOSAVE is a special code to prevent the rest of the table
120 * from being saved, used to support old stuff for backwards
121 * compatibility... */
122 NOSAVE,
123
124 /* the following are obsolete as of 0x104 */
125
126 I4("hram", &hramofs),
127
128 R(P1), R(SB), R(SC),
129 R(DIV), R(TIMA), R(TMA), R(TAC),
130 R(IE), R(IF),
131 R(LCDC), R(STAT), R(LY), R(LYC),
132 R(SCX), R(SCY), R(WX), R(WY),
133 R(BGP), R(OBP0), R(OBP1),
134 R(DMA),
135
136 R(VBK), R(SVBK), R(KEY1),
137 R(BCPS), R(BCPD), R(OCPS), R(OCPD),
138
139 R(NR10), R(NR11), R(NR12), R(NR13), R(NR14),
140 R(NR21), R(NR22), R(NR23), R(NR24),
141 R(NR30), R(NR31), R(NR32), R(NR33), R(NR34),
142 R(NR41), R(NR42), R(NR43), R(NR44),
143 R(NR50), R(NR51), R(NR52),
144
145 I1("DMA1", &R_HDMA1),
146 I1("DMA2", &R_HDMA2),
147 I1("DMA3", &R_HDMA3),
148 I1("DMA4", &R_HDMA4),
149 I1("DMA5", &R_HDMA5),
150
151 END
152};
153
154
155void loadstate(int fd)
156{
157 int i, j;
158 byte buf[4096];
159 un32 (*header)[2] = (un32 (*)[2])buf;
160 un32 d;
161 int irl = hw.cgb ? 8 : 2;
162 int vrl = hw.cgb ? 4 : 2;
163 int srl = mbc.ramsize << 1;
164
165 ver = hramofs = hiofs = palofs = oamofs = wavofs = 0;
166
167 read(fd,buf, 4096);
168
169 for (j = 0; header[j][0]; j++)
170 {
171 for (i = 0; svars[i].ptr; i++)
172 {
173 if (header[j][0] != *(un32 *)svars[i].key)
174 continue;
175 d = LIL(header[j][1]);
176 switch (svars[i].len)
177 {
178 case 1:
179 *(byte *)svars[i].ptr = d;
180 break;
181 case 2:
182 *(un16 *)svars[i].ptr = d;
183 break;
184 case 4:
185 *(un32 *)svars[i].ptr = d;
186 break;
187 }
188 break;
189 }
190 }
191
192 /* obsolete as of version 0x104 */
193 if (hramofs) memcpy(ram.hi+128, buf+hramofs, 127);
194
195 if (hiofs) memcpy(ram.hi, buf+hiofs, sizeof ram.hi);
196 if (palofs) memcpy(lcd.pal, buf+palofs, sizeof lcd.pal);
197 if (oamofs) memcpy(lcd.oam.mem, buf+oamofs, sizeof lcd.oam);
198
199 if (wavofs) memcpy(snd.wave, buf+wavofs, sizeof snd.wave);
200 else memcpy(snd.wave, ram.hi+0x30, 16); /* patch data from older files */
201
202 lseek(fd, iramblock<<12, SEEK_SET);
203 read(fd,ram.ibank, 4096*irl);
204
205 lseek(fd, vramblock<<12, SEEK_SET);
206 read(fd,lcd.vbank, 4096*vrl);
207
208 lseek(fd, sramblock<<12, SEEK_SET);
209 read(fd,ram.sbank, 4096*srl);
210}
211
212void savestate(int fd)
213{
214 int i;
215 byte buf[4096];
216 un32 (*header)[2] = (un32 (*)[2])buf;
217 un32 d = 0;
218 int irl = hw.cgb ? 8 : 2;
219 int vrl = hw.cgb ? 4 : 2;
220 int srl = mbc.ramsize << 1;
221
222 ver = 0x105;
223 iramblock = 1;
224 vramblock = 1+irl;
225 sramblock = 1+irl+vrl;
226 wavofs = 4096 - 784;
227 hiofs = 4096 - 768;
228 palofs = 4096 - 512;
229 oamofs = 4096 - 256;
230 memset(buf, 0, sizeof buf);
231
232 for (i = 0; svars[i].len > 0; i++)
233 {
234 header[i][0] = *(un32 *)svars[i].key;
235 switch (svars[i].len)
236 {
237 case 1:
238 d = *(byte *)svars[i].ptr;
239 break;
240 case 2:
241 d = *(un16 *)svars[i].ptr;
242 break;
243 case 4:
244 d = *(un32 *)svars[i].ptr;
245 break;
246 }
247 header[i][1] = LIL(d);
248 }
249 header[i][0] = header[i][1] = 0;
250
251 memcpy(buf+hiofs, ram.hi, sizeof ram.hi);
252 memcpy(buf+palofs, lcd.pal, sizeof lcd.pal);
253 memcpy(buf+oamofs, lcd.oam.mem, sizeof lcd.oam);
254 memcpy(buf+wavofs, snd.wave, sizeof snd.wave);
255
256 lseek(fd, 0, SEEK_SET);
257 write(fd,buf, 4096);
258
259 lseek(fd, iramblock<<12, SEEK_SET);
260 write(fd,ram.ibank, 4096*irl);
261
262 lseek(fd, vramblock<<12, SEEK_SET);
263 write(fd,lcd.vbank, 4096*vrl);
264
265 lseek(fd, sramblock<<12, SEEK_SET);
266 write(fd,ram.sbank, 4096*srl);
267}
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286