2 // Megadrive C++ module saving and loading
11 void md::m68k_state_dump()
14 32 and 16-bit values must be stored LSB first even though M68K is
15 big-endian for compatibility with other emulators.
20 if (md_set_musa(true))
21 md_set_musa_sync(false);
27 if (md_set_star(true))
28 md_set_star_sync(false);
34 if (md_set_cyclone(true))
35 md_set_cyclone_sync(false);
36 md_set_cyclone(false);
44 void md::m68k_state_restore()
46 /* 32 and 16-bit values are stored LSB first. */
50 if (md_set_musa(true))
51 md_set_musa_sync(true);
57 if (md_set_star(true))
58 md_set_star_sync(true);
64 if (md_set_cyclone(true))
65 md_set_cyclone_sync(true);
66 md_set_cyclone(false);
74 void md::z80_state_dump()
76 /* 16-bit values must be stored LSB first. */
77 z80_state
.irq_asserted
= z80_st_irq
;
78 z80_state
.irq_vector
= z80_irq_vector
;
82 if (md_set_cz80(true))
83 md_set_cz80_sync(false);
89 if (md_set_mz80(true))
90 md_set_mz80_sync(false);
96 if (md_set_drz80(true))
97 md_set_drz80_sync(false);
106 void md::z80_state_restore()
108 /* 16-bit values are stored LSB first. */
112 if (md_set_cz80(true))
113 md_set_cz80_sync(true);
119 if (md_set_mz80(true))
120 md_set_mz80_sync(true);
126 if (md_set_drz80(true))
127 md_set_drz80_sync(true);
134 if (z80_state
.irq_asserted
)
135 z80_irq(z80_state
.irq_vector
);
141 gs0 genecyst save file INfo
145 80-9f = d0-d7 almost certain
146 a0-bf = a0-a7 almost certain
147 c8 = pc fairly certain
148 d0 = sr fairly certain
151 112 Start of cram len 0x80
152 192 Start of vsram len 0x50
153 1e2-474 UNKNOWN sound info?
154 Start of z80 ram at 474 (they store 2000)
155 Start of RAM at 2478 almost certain (BYTE SWAPPED)
156 Start of VRAM at 12478
161 2011-11-05 - Adapted from Gens' genecyst_save_file_format.txt:
163 Range Size Description
164 ----------- ----- -----------
166 00003-00004 2 "\x40\xe0" (Gens and new DGen format)
167 00006-00007 2 "\xe0\x40" (old DGen format)
168 00040-00043 4 Last VDP control data written
169 00044-00044 1 Second write flag
170 00045-00045 1 DMA fill flag
171 00048-0004B 4 VDP write address
172 00050-00050 1 Version
173 00051-00051 1 Emulator ID
174 00052-00052 1 System ID
175 00060-0006F 16 PSG registers
176 00080-000D9 90 M68K registers
177 000FA-00111 24 VDP registers
178 00112-00191 128 Color RAM
179 00192-001E1 80 Vertical scroll RAM
180 001E2-001E2 1 YM2612 part I address register (DGen)
181 001E3-001E3 1 YM2612 part II address register (DGen)
182 001E4-003E3 512 YM2612 registers
183 00404-00437 52 Z80 registers
184 00438-0043F 8 Z80 state
185 00474-02473 8192 Z80 RAM
186 02478-12477 65536 68K RAM
187 12478-22477 65536 Video RAM
189 M68K registers (stored little-endian for compatibility)
198 Z80 registers (little-endian)
215 00436 : x x x x x IFF1 x IFF2 (Gens v5)
224 0043C : Z80 BANK (DWORD)
228 00040 : last VDP Control data written (DWORD)
229 00044 : second write flag (1 for second write)
230 00045 : DMA Fill flag (1 mean next data write will cause a DMA fill)
231 00048 : VDP write address (DWORD)
233 00050 : Version (Genecyst=0; Kega=5; Gens=5; DGen=5)
234 00051 : Emulator ID (Genecyst=0; Kega=0; Gens=1; DGen=9)
235 00052 : System ID (Genesis=0; SegaCD=1; 32X=2; SegaCD32X=3)
237 00060-0007F : PSG registers (DWORDs, little endian).
240 static void *swap16cpy(void *dest
, const void *src
, size_t n
)
244 for (i
= 0; (i
!= (n
& ~1)); ++i
)
245 ((uint8_t *)dest
)[(i
^ 1)] = ((uint8_t *)src
)[i
];
246 ((uint8_t *)dest
)[i
] = ((uint8_t *)src
)[i
];
250 int md::import_gst(FILE *hand
)
252 uint8_t (*buf
)[0x22478] =
253 (uint8_t (*)[sizeof(*buf
)])malloc(sizeof(*buf
));
260 (fread((*buf
), sizeof(*buf
), 1, hand
) != 1) ||
262 ((memcmp((*buf
), "GST\x0\x0\0\xe0\x40", 8) != 0) &&
263 (memcmp((*buf
), "GST\x40\xe0", 5) != 0))) {
265 "%s: error: invalid save file header.\n",
273 "%s: error: this is not a Genesis/Mega Drive"
281 "%s: warning: save file was probably not generated by"
287 "%s: warning: unknown save file version.\n",
289 /* Reset console first. */
291 /* FIXME: VDP stuff */
292 /* PSG registers (8x16-bit, 16 bytes) */
293 SN76496_restore(0, &(*buf
)[0x60]);
294 /* M68K registers (19x32-bit, 1x16-bit, 90 bytes (padding: 12)) */
297 for (i
= 0; (i
!= 8); ++i
, p
+= 4, q
+= 4) {
298 memcpy(&m68k_state
.d
[i
], p
, 4);
299 memcpy(&m68k_state
.a
[i
], q
, 4);
301 memcpy(&m68k_state
.pc
, &(*buf
)[0xc8], 4);
302 memcpy(&m68k_state
.sr
, &(*buf
)[0xd0], 2);
305 memcpy(&m68k_state.usp, &(*buf)[0xd2], 4);
306 memcpy(&m68k_state.ssp, &(*buf)[0xd6], 4);
308 m68k_state_restore();
309 /* VDP registers (24x8-bit VDP registers, not sizeof(vdp.reg)) */
310 memcpy(vdp
.reg
, &(*buf
)[0xfa], 0x18);
311 memset(&vdp
.reg
[0x18], 0, (sizeof(vdp
.reg
) - 0x18));
312 /* CRAM (64x16-bit registers, 128 bytes), swapped */
313 swap16cpy(vdp
.cram
, &(*buf
)[0x112], 0x80);
314 /* VSRAM (40x16-bit words, 80 bytes), swapped */
315 swap16cpy(vdp
.vsram
, &(*buf
)[0x192], 0x50);
316 /* YM2612 registers */
321 YM2612_restore(0, p
);
322 fm_reg
[0][0x24] = p
[0x24];
323 fm_reg
[0][0x25] = p
[0x25];
324 fm_reg
[0][0x26] = p
[0x26];
325 fm_reg
[0][0x27] = p
[0x27];
326 dac_data
[0] = p
[0x2a];
327 dac_enabled
= (p
[0x2b] >> 7);
328 memset(fm_ticker
, 0, sizeof(fm_ticker
));
329 /* Z80 registers (12x16-bit and 4x8-bit, 52 bytes (padding: 24)) */
331 for (i
= 0; (i
!= 2); ++i
, p
= &(*buf
)[0x424]) {
332 memcpy(&z80_state
.alt
[i
].fa
, &p
[0x0], 2);
333 memcpy(&z80_state
.alt
[i
].cb
, &p
[0x4], 2);
334 memcpy(&z80_state
.alt
[i
].ed
, &p
[0x8], 2);
335 memcpy(&z80_state
.alt
[i
].lh
, &p
[0xc], 2);
338 memcpy(&z80_state
.ix
, &p
[0x0], 2);
339 memcpy(&z80_state
.iy
, &p
[0x4], 2);
340 memcpy(&z80_state
.pc
, &p
[0x8], 2);
341 memcpy(&z80_state
.sp
, &p
[0xc], 2);
345 z80_state
.iff
= ((p
[2] << 1) | p
[2]); /* IFF2 = IFF1 */
346 z80_state
.im
= ((p
[3] == 0) ? 1 : p
[3]);
348 /* Z80 state (8 bytes) */
350 z80_st_reset
= !p
[0]; /* BUS RESET state */
355 z80_st_busreq
= (p
[1] & 1); /* BUSREQ state */
356 memcpy(&tmp
, &(*buf
)[0x43c], 4);
357 z80_bank68k
= le2h32(tmp
);
358 /* Z80 RAM (8192 bytes) */
359 memcpy(z80ram
, &(*buf
)[0x474], 0x2000);
360 /* RAM (65536 bytes), swapped */
361 swap16cpy(ram
, &(*buf
)[0x2478], 0x10000);
362 /* VRAM (65536 bytes) */
363 memcpy(vdp
.vram
, &(*buf
)[0x12478], 0x10000);
364 /* Mark everything as changed */
365 memset(vdp
.dirt
, 0xff, 0x35);
370 int md::export_gst(FILE *hand
)
372 uint8_t (*buf
)[0x22478] =
373 (uint8_t (*)[sizeof(*buf
)])calloc(1, sizeof(*buf
));
382 memcpy((*buf
), "GST\x40\xe0", 5);
383 /* FIXME: VDP stuff */
390 /* PSG registers (8x16-bit, 16 bytes) */
391 SN76496_dump(0, &(*buf
)[0x60]);
392 /* M68K registers (19x32-bit, 1x16-bit, 90 bytes (padding: 12)) */
396 for (i
= 0; (i
!= 8); ++i
, p
+= 4, q
+= 4) {
397 memcpy(p
, &m68k_state
.d
[i
], 4);
398 memcpy(q
, &m68k_state
.a
[i
], 4);
400 memcpy(&(*buf
)[0xc8], &m68k_state
.pc
, 4);
401 memcpy(&(*buf
)[0xd0], &m68k_state
.sr
, 2);
404 memcpy(&(*buf)[0xd2], &m68k_state.usp, 4);
405 memcpy(&(*buf)[0xd6], &m68k_state.ssp, 4);
407 /* VDP registers (24x8-bit VDP registers, not sizeof(vdp.reg)) */
408 memcpy(&(*buf
)[0xfa], vdp
.reg
, 0x18);
409 /* CRAM (64x16-bit registers, 128 bytes), swapped */
410 swap16cpy(&(*buf
)[0x112], vdp
.cram
, 0x80);
411 /* VSRAM (40x16-bit words, 80 bytes), swapped */
412 swap16cpy(&(*buf
)[0x192], vdp
.vsram
, 0x50);
413 /* YM2612 registers */
419 p
[0x24] = fm_reg
[0][0x24];
420 p
[0x25] = fm_reg
[0][0x25];
421 p
[0x26] = fm_reg
[0][0x26];
422 p
[0x27] = fm_reg
[0][0x27];
424 p
[0x2b] = (dac_enabled
<< 7);
425 /* Z80 registers (12x16-bit and 4x8-bit, 52 bytes (padding: 24)) */
428 for (i
= 0; (i
!= 2); ++i
, p
= &(*buf
)[0x424]) {
429 memcpy(&p
[0x0], &z80_state
.alt
[i
].fa
, 2);
430 memcpy(&p
[0x4], &z80_state
.alt
[i
].cb
, 2);
431 memcpy(&p
[0x8], &z80_state
.alt
[i
].ed
, 2);
432 memcpy(&p
[0xc], &z80_state
.alt
[i
].lh
, 2);
435 memcpy(&p
[0x0], &z80_state
.ix
, 2);
436 memcpy(&p
[0x4], &z80_state
.iy
, 2);
437 memcpy(&p
[0x8], &z80_state
.pc
, 2);
438 memcpy(&p
[0xc], &z80_state
.sp
, 2);
442 p
[2] = ((z80_state
.iff
>> 1) | z80_state
.iff
);
444 /* Z80 state (8 bytes) */
446 p
[0] = !z80_st_reset
;
447 p
[1] = z80_st_busreq
;
448 tmp
= h2le32(z80_bank68k
);
449 memcpy(&(*buf
)[0x43c], &tmp
, 4);
450 /* Z80 RAM (8192 bytes) */
451 memcpy(&(*buf
)[0x474], z80ram
, 0x2000);
452 /* RAM (65536 bytes), swapped */
453 swap16cpy(&(*buf
)[0x2478], ram
, 0x10000);
454 /* VRAM (65536 bytes) */
455 memcpy(&(*buf
)[0x12478], vdp
.vram
, 0x10000);
457 i
= fwrite((*buf
), sizeof(*buf
), 1, hand
);