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