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