1 /***************************************************************************************
2 * Genesis Plus
3 * Savestate support
4 *
5 * Copyright (C) 2007-2016 Eke-Eke (Genesis Plus GX)
6 *
7 * Redistribution and use of this code or any derivative works are permitted
8 * provided that the following conditions are met:
9 *
10 * - Redistributions may not be sold, nor may they be used in a commercial
11 * product or activity.
12 *
13 * - Redistributions that are modified from the original source must include the
14 * complete source code, including the source code for all components used by a
15 * binary built from the modified sources. However, as a special exception, the
16 * source code distributed need not include anything that is normally distributed
17 * (in either source or binary form) with the major components (compiler, kernel,
18 * and so on) of the operating system on which the executable runs, unless that
19 * component itself accompanies the executable.
20 *
21 * - Redistributions must reproduce the above copyright notice, this list of
22 * conditions and the following disclaimer in the documentation and/or other
23 * materials provided with the distribution.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
29 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 *
37 ****************************************************************************************/
38
39 #include "shared.h"
40
41 int8 fast_savestates = false;
42 int8 reset_do_not_clear_buffers = false;
43
state_load(unsigned char * state)44 int state_load(unsigned char *state)
45 {
46 int i, bufferptr = 0;
47
48 /* signature check (GENPLUS-GX x.x.x) */
49 char version[17];
50 load_param(version,16);
51 version[16] = 0;
52 if (memcmp(version,STATE_VERSION,11))
53 {
54 return 0;
55 }
56
57 /* version check */
58 if ((version[11] < 0x31) || (version[13] < 0x37) || (version[15] < 0x35))
59 {
60 return 0;
61 }
62
63 /* reset system */
64 reset_do_not_clear_buffers = fast_savestates;
65 system_reset();
66 reset_do_not_clear_buffers = false;
67
68 /* enable VDP access for TMSS systems */
69 for (i=0xc0; i<0xe0; i+=8)
70 {
71 m68k.memory_map[i].read8 = vdp_read_byte;
72 m68k.memory_map[i].read16 = vdp_read_word;
73 m68k.memory_map[i].write8 = vdp_write_byte;
74 m68k.memory_map[i].write16 = vdp_write_word;
75 zbank_memory_map[i].read = zbank_read_vdp;
76 zbank_memory_map[i].write = zbank_write_vdp;
77 }
78
79 /* GENESIS */
80 if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
81 {
82 load_param(work_ram, sizeof(work_ram));
83 load_param(zram, sizeof(zram));
84 load_param(&zstate, sizeof(zstate));
85 load_param(&zbank, sizeof(zbank));
86 if (zstate == 3)
87 {
88 m68k.memory_map[0xa0].read8 = z80_read_byte;
89 m68k.memory_map[0xa0].read16 = z80_read_word;
90 m68k.memory_map[0xa0].write8 = z80_write_byte;
91 m68k.memory_map[0xa0].write16 = z80_write_word;
92 }
93 else
94 {
95 m68k.memory_map[0xa0].read8 = m68k_read_bus_8;
96 m68k.memory_map[0xa0].read16 = m68k_read_bus_16;
97 m68k.memory_map[0xa0].write8 = m68k_unused_8_w;
98 m68k.memory_map[0xa0].write16 = m68k_unused_16_w;
99 }
100 }
101 else
102 {
103 load_param(work_ram, 0x2000);
104 }
105
106 /* IO */
107 load_param(io_reg, sizeof(io_reg));
108 if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
109 {
110 io_reg[0] = region_code | 0x20 | (config.bios & 1);
111 }
112 else
113 {
114 io_reg[0] = 0x80 | (region_code >> 1);
115 }
116
117 /* VDP */
118 bufferptr += vdp_context_load(&state[bufferptr]);
119
120 /* SOUND */
121 bufferptr += sound_context_load(&state[bufferptr]);
122 if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
123 {
124 psg_config(0, config.psg_preamp, 0xff);
125 }
126 else
127 {
128 psg_config(0, config.psg_preamp, io_reg[6]);
129 }
130
131 /* 68000 */
132 if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
133 {
134 uint16 tmp16;
135 uint32 tmp32;
136 load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D0, tmp32);
137 load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D1, tmp32);
138 load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D2, tmp32);
139 load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D3, tmp32);
140 load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D4, tmp32);
141 load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D5, tmp32);
142 load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D6, tmp32);
143 load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D7, tmp32);
144 load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A0, tmp32);
145 load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A1, tmp32);
146 load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A2, tmp32);
147 load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A3, tmp32);
148 load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A4, tmp32);
149 load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A5, tmp32);
150 load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A6, tmp32);
151 load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A7, tmp32);
152 load_param(&tmp32, 4); m68k_set_reg(M68K_REG_PC, tmp32);
153 load_param(&tmp16, 2); m68k_set_reg(M68K_REG_SR, tmp16);
154 load_param(&tmp32, 4); m68k_set_reg(M68K_REG_USP,tmp32);
155 load_param(&tmp32, 4); m68k_set_reg(M68K_REG_ISP,tmp32);
156
157 load_param(&m68k.cycles, sizeof(m68k.cycles));
158 load_param(&m68k.int_level, sizeof(m68k.int_level));
159 load_param(&m68k.stopped, sizeof(m68k.stopped));
160 }
161
162 /* Z80 */
163 load_param(&Z80, sizeof(Z80_Regs));
164 Z80.irq_callback = z80_irq_callback;
165
166 /* Extra HW */
167 if (system_hw == SYSTEM_MCD)
168 {
169 /* handle case of MD cartridge using or not CD hardware */
170 char id[5];
171 load_param(id,4);
172 id[4] = 0;
173
174 /* check if CD hardware was enabled before attempting to restore */
175 if (memcmp(id,"SCD!",4))
176 {
177 return 0;
178 }
179
180 /* CD hardware */
181 bufferptr += scd_context_load(&state[bufferptr]);
182 }
183 else if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
184 {
185 /* MD cartridge hardware */
186 bufferptr += md_cart_context_load(&state[bufferptr]);
187 }
188 else
189 {
190 /* MS cartridge hardware */
191 bufferptr += sms_cart_context_load(&state[bufferptr]);
192 sms_cart_switch(~io_reg[0x0E]);
193 }
194
195 return bufferptr;
196 }
197
state_save(unsigned char * state)198 int state_save(unsigned char *state)
199 {
200 /* buffer size */
201 int bufferptr = 0;
202
203 /* version string */
204 char version[16];
205 strncpy(version,STATE_VERSION,16);
206 save_param(version, 16);
207
208 /* GENESIS */
209 if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
210 {
211 save_param(work_ram, sizeof(work_ram));
212 save_param(zram, sizeof(zram));
213 save_param(&zstate, sizeof(zstate));
214 save_param(&zbank, sizeof(zbank));
215 }
216 else
217 {
218 save_param(work_ram, 0x2000);
219 }
220
221 /* IO */
222 save_param(io_reg, sizeof(io_reg));
223
224 /* VDP */
225 bufferptr += vdp_context_save(&state[bufferptr]);
226
227 /* SOUND */
228 bufferptr += sound_context_save(&state[bufferptr]);
229
230 /* 68000 */
231 if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
232 {
233 uint16 tmp16;
234 uint32 tmp32;
235 tmp32 = m68k_get_reg(M68K_REG_D0); save_param(&tmp32, 4);
236 tmp32 = m68k_get_reg(M68K_REG_D1); save_param(&tmp32, 4);
237 tmp32 = m68k_get_reg(M68K_REG_D2); save_param(&tmp32, 4);
238 tmp32 = m68k_get_reg(M68K_REG_D3); save_param(&tmp32, 4);
239 tmp32 = m68k_get_reg(M68K_REG_D4); save_param(&tmp32, 4);
240 tmp32 = m68k_get_reg(M68K_REG_D5); save_param(&tmp32, 4);
241 tmp32 = m68k_get_reg(M68K_REG_D6); save_param(&tmp32, 4);
242 tmp32 = m68k_get_reg(M68K_REG_D7); save_param(&tmp32, 4);
243 tmp32 = m68k_get_reg(M68K_REG_A0); save_param(&tmp32, 4);
244 tmp32 = m68k_get_reg(M68K_REG_A1); save_param(&tmp32, 4);
245 tmp32 = m68k_get_reg(M68K_REG_A2); save_param(&tmp32, 4);
246 tmp32 = m68k_get_reg(M68K_REG_A3); save_param(&tmp32, 4);
247 tmp32 = m68k_get_reg(M68K_REG_A4); save_param(&tmp32, 4);
248 tmp32 = m68k_get_reg(M68K_REG_A5); save_param(&tmp32, 4);
249 tmp32 = m68k_get_reg(M68K_REG_A6); save_param(&tmp32, 4);
250 tmp32 = m68k_get_reg(M68K_REG_A7); save_param(&tmp32, 4);
251 tmp32 = m68k_get_reg(M68K_REG_PC); save_param(&tmp32, 4);
252 tmp16 = m68k_get_reg(M68K_REG_SR); save_param(&tmp16, 2);
253 tmp32 = m68k_get_reg(M68K_REG_USP); save_param(&tmp32, 4);
254 tmp32 = m68k_get_reg(M68K_REG_ISP); save_param(&tmp32, 4);
255
256 save_param(&m68k.cycles, sizeof(m68k.cycles));
257 save_param(&m68k.int_level, sizeof(m68k.int_level));
258 save_param(&m68k.stopped, sizeof(m68k.stopped));
259 }
260
261 /* Z80 */
262 save_param(&Z80, sizeof(Z80_Regs));
263
264 /* External HW */
265 if (system_hw == SYSTEM_MCD)
266 {
267 /* CD hardware ID flag */
268 char id[5];
269 strncpy(id,"SCD!",4);
270 save_param(id, 4);
271
272 /* CD hardware */
273 bufferptr += scd_context_save(&state[bufferptr]);
274 }
275 else if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
276 {
277 /* MD cartridge hardware */
278 bufferptr += md_cart_context_save(&state[bufferptr]);
279 }
280 else
281 {
282 /* MS cartridge hardware */
283 bufferptr += sms_cart_context_save(&state[bufferptr]);
284 }
285
286 /* return total size */
287 return bufferptr;
288 }
289