Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/genplus-gx32/core/state.c
2 views
1
/***************************************************************************************
2
* Genesis Plus
3
* Savestate support
4
*
5
* Copyright (C) 2007-2012 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
int state_load(unsigned char *state)
42
{
43
int i, bufferptr = 0;
44
45
/* signature check (GENPLUS-GX x.x.x) */
46
char version[17];
47
load_param(version,16);
48
version[16] = 0;
49
if (memcmp(version,STATE_VERSION,11))
50
{
51
return 0;
52
}
53
54
/* version check (keep compatibility with previous & current state version) */
55
if ((version[11] < 0x31) || (version[13] < 0x37) || (version[15] < 0x31))
56
{
57
return 0;
58
}
59
60
/* reset system */
61
system_reset();
62
63
/* enable VDP access for TMSS systems */
64
for (i=0xc0; i<0xe0; i+=8)
65
{
66
m68k.memory_map[i].read8 = vdp_read_byte;
67
m68k.memory_map[i].read16 = vdp_read_word;
68
m68k.memory_map[i].write8 = vdp_write_byte;
69
m68k.memory_map[i].write16 = vdp_write_word;
70
zbank_memory_map[i].read = zbank_read_vdp;
71
zbank_memory_map[i].write = zbank_write_vdp;
72
}
73
74
/* GENESIS */
75
if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
76
{
77
load_param(work_ram, sizeof(work_ram));
78
load_param(zram, sizeof(zram));
79
load_param(&zstate, sizeof(zstate));
80
load_param(&zbank, sizeof(zbank));
81
if (zstate == 3)
82
{
83
m68k.memory_map[0xa0].read8 = z80_read_byte;
84
m68k.memory_map[0xa0].read16 = z80_read_word;
85
m68k.memory_map[0xa0].write8 = z80_write_byte;
86
m68k.memory_map[0xa0].write16 = z80_write_word;
87
}
88
else
89
{
90
m68k.memory_map[0xa0].read8 = m68k_read_bus_8;
91
m68k.memory_map[0xa0].read16 = m68k_read_bus_16;
92
m68k.memory_map[0xa0].write8 = m68k_unused_8_w;
93
m68k.memory_map[0xa0].write16 = m68k_unused_16_w;
94
}
95
}
96
else
97
{
98
load_param(work_ram, 0x2000);
99
}
100
101
/* IO */
102
load_param(io_reg, sizeof(io_reg));
103
load_param(gamepad, sizeof(gamepad));
104
if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
105
{
106
io_reg[0] = region_code | 0x20 | (config.bios & 1);
107
}
108
else
109
{
110
io_reg[0] = 0x80 | (region_code >> 1);
111
}
112
113
/* VDP */
114
bufferptr += vdp_context_load(&state[bufferptr], version[15]);
115
116
/* SOUND */
117
bufferptr += sound_context_load(&state[bufferptr]);
118
if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
119
{
120
SN76489_Init(snd.blips[0][0], snd.blips[0][1], SN_INTEGRATED);
121
SN76489_Config(0, config.psg_preamp, config.psgBoostNoise, 0xff);
122
}
123
else
124
{
125
SN76489_Init(snd.blips[0][0], snd.blips[0][1], (system_hw < SYSTEM_MARKIII) ? SN_DISCRETE : SN_INTEGRATED);
126
SN76489_Config(0, config.psg_preamp, config.psgBoostNoise, io_reg[6]);
127
}
128
129
/* 68000 */
130
if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
131
{
132
uint16 tmp16;
133
uint32 tmp32;
134
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D0, tmp32);
135
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D1, tmp32);
136
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D2, tmp32);
137
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D3, tmp32);
138
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D4, tmp32);
139
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D5, tmp32);
140
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D6, tmp32);
141
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D7, tmp32);
142
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A0, tmp32);
143
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A1, tmp32);
144
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A2, tmp32);
145
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A3, tmp32);
146
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A4, tmp32);
147
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A5, tmp32);
148
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A6, tmp32);
149
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A7, tmp32);
150
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_PC, tmp32);
151
load_param(&tmp16, 2); m68k_set_reg(M68K_REG_SR, tmp16);
152
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_USP,tmp32);
153
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_ISP,tmp32);
154
155
load_param(&m68k.cycles, sizeof(m68k.cycles));
156
load_param(&m68k.int_level, sizeof(m68k.int_level));
157
load_param(&m68k.stopped, sizeof(m68k.stopped));
158
}
159
160
/* Z80 */
161
load_param(&Z80, sizeof(Z80_Regs));
162
Z80.irq_callback = z80_irq_callback;
163
164
/* Extra HW */
165
if (system_hw == SYSTEM_MCD)
166
{
167
/* handle case of MD cartridge using or not CD hardware */
168
char id[5];
169
load_param(id,4);
170
id[4] = 0;
171
172
/* check if CD hardware was enabled before attempting to restore */
173
if (memcmp(id,"SCD!",4))
174
{
175
return 0;
176
}
177
178
/* CD hardware */
179
bufferptr += scd_context_load(&state[bufferptr]);
180
}
181
else if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
182
{
183
/* MD cartridge hardware */
184
bufferptr += md_cart_context_load(&state[bufferptr]);
185
}
186
else
187
{
188
/* MS cartridge hardware */
189
bufferptr += sms_cart_context_load(&state[bufferptr]);
190
sms_cart_switch(~io_reg[0x0E]);
191
}
192
193
bufferptr += sram_context_load(&state[bufferptr]);
194
195
load_param(&bitmap.viewport, sizeof(bitmap.viewport));
196
197
return bufferptr;
198
}
199
200
int state_save(unsigned char *state)
201
{
202
/* buffer size */
203
int bufferptr = 0;
204
205
/* version string */
206
char version[16];
207
strncpy(version,STATE_VERSION,16);
208
save_param(version, 16);
209
210
/* GENESIS */
211
if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
212
{
213
save_param(work_ram, sizeof(work_ram));
214
save_param(zram, sizeof(zram));
215
save_param(&zstate, sizeof(zstate));
216
save_param(&zbank, sizeof(zbank));
217
}
218
else
219
{
220
save_param(work_ram, 0x2000);
221
}
222
223
/* IO */
224
save_param(io_reg, sizeof(io_reg));
225
save_param(gamepad, sizeof(gamepad));
226
227
/* VDP */
228
bufferptr += vdp_context_save(&state[bufferptr]);
229
230
/* SOUND */
231
bufferptr += sound_context_save(&state[bufferptr]);
232
233
/* 68000 */
234
if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
235
{
236
uint16 tmp16;
237
uint32 tmp32;
238
tmp32 = m68k_get_reg(M68K_REG_D0); save_param(&tmp32, 4);
239
tmp32 = m68k_get_reg(M68K_REG_D1); save_param(&tmp32, 4);
240
tmp32 = m68k_get_reg(M68K_REG_D2); save_param(&tmp32, 4);
241
tmp32 = m68k_get_reg(M68K_REG_D3); save_param(&tmp32, 4);
242
tmp32 = m68k_get_reg(M68K_REG_D4); save_param(&tmp32, 4);
243
tmp32 = m68k_get_reg(M68K_REG_D5); save_param(&tmp32, 4);
244
tmp32 = m68k_get_reg(M68K_REG_D6); save_param(&tmp32, 4);
245
tmp32 = m68k_get_reg(M68K_REG_D7); save_param(&tmp32, 4);
246
tmp32 = m68k_get_reg(M68K_REG_A0); save_param(&tmp32, 4);
247
tmp32 = m68k_get_reg(M68K_REG_A1); save_param(&tmp32, 4);
248
tmp32 = m68k_get_reg(M68K_REG_A2); save_param(&tmp32, 4);
249
tmp32 = m68k_get_reg(M68K_REG_A3); save_param(&tmp32, 4);
250
tmp32 = m68k_get_reg(M68K_REG_A4); save_param(&tmp32, 4);
251
tmp32 = m68k_get_reg(M68K_REG_A5); save_param(&tmp32, 4);
252
tmp32 = m68k_get_reg(M68K_REG_A6); save_param(&tmp32, 4);
253
tmp32 = m68k_get_reg(M68K_REG_A7); save_param(&tmp32, 4);
254
tmp32 = m68k_get_reg(M68K_REG_PC); save_param(&tmp32, 4);
255
tmp16 = m68k_get_reg(M68K_REG_SR); save_param(&tmp16, 2);
256
tmp32 = m68k_get_reg(M68K_REG_USP); save_param(&tmp32, 4);
257
tmp32 = m68k_get_reg(M68K_REG_ISP); save_param(&tmp32, 4);
258
259
save_param(&m68k.cycles, sizeof(m68k.cycles));
260
save_param(&m68k.int_level, sizeof(m68k.int_level));
261
save_param(&m68k.stopped, sizeof(m68k.stopped));
262
}
263
264
/* Z80 */
265
save_param(&Z80, sizeof(Z80_Regs));
266
267
/* External HW */
268
if (system_hw == SYSTEM_MCD)
269
{
270
/* CD hardware ID flag */
271
char id[5];
272
strncpy(id,"SCD!",4);
273
save_param(id, 4);
274
275
/* CD hardware */
276
bufferptr += scd_context_save(&state[bufferptr]);
277
}
278
else if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
279
{
280
/* MD cartridge hardware */
281
bufferptr += md_cart_context_save(&state[bufferptr]);
282
}
283
else
284
{
285
/* MS cartridge hardware */
286
bufferptr += sms_cart_context_save(&state[bufferptr]);
287
}
288
289
bufferptr += sram_context_save(&state[bufferptr]);
290
291
save_param(&bitmap.viewport, sizeof(bitmap.viewport));
292
293
/* return total size */
294
return bufferptr;
295
}
296
297