comparison genesis.c @ 1440:7d4483944d4d

Allow actually saving a save state in more Z80 states. Save busreq/reset state in bus arbiter section for "native" save states
author Michael Pavone <pavone@retrodev.com>
date Thu, 24 Aug 2017 19:28:56 -0700
parents c886c54d8cf1
children 14a2834d010c
comparison
equal deleted inserted replaced
1439:7da675d0c512 1440:7d4483944d4d
52 52
53 start_section(buf, SECTION_PSG); 53 start_section(buf, SECTION_PSG);
54 psg_serialize(gen->psg, buf); 54 psg_serialize(gen->psg, buf);
55 end_section(buf); 55 end_section(buf);
56 56
57 //TODO: bus arbiter state 57 start_section(buf, SECTION_GEN_BUS_ARBITER);
58 save_int8(buf, gen->z80->reset);
59 save_int8(buf, gen->z80->busreq);
60 end_section(buf);
58 61
59 start_section(buf, SECTION_SEGA_IO_1); 62 start_section(buf, SECTION_SEGA_IO_1);
60 io_serialize(gen->io.ports, buf); 63 io_serialize(gen->io.ports, buf);
61 end_section(buf); 64 end_section(buf);
62 65
97 uint32_t ram_size = load_int8(buf) * 1024; 100 uint32_t ram_size = load_int8(buf) * 1024;
98 if (ram_size > Z80_RAM_BYTES) { 101 if (ram_size > Z80_RAM_BYTES) {
99 fatal_error("State has a Z80 RAM size of %d bytes", ram_size); 102 fatal_error("State has a Z80 RAM size of %d bytes", ram_size);
100 } 103 }
101 load_buffer8(buf, gen->zram, ram_size); 104 load_buffer8(buf, gen->zram, ram_size);
105 }
106
107 static void bus_arbiter_deserialize(deserialize_buffer *buf, void *vgen)
108 {
109 genesis_context *gen = vgen;
110 gen->z80->reset = load_int8(buf);
111 gen->z80->busreq = load_int8(buf);
102 } 112 }
103 113
104 void genesis_deserialize(deserialize_buffer *buf, genesis_context *gen) 114 void genesis_deserialize(deserialize_buffer *buf, genesis_context *gen)
105 { 115 {
106 register_section_handler(buf, (section_handler){.fun = m68k_deserialize, .data = gen->m68k}, SECTION_68000); 116 register_section_handler(buf, (section_handler){.fun = m68k_deserialize, .data = gen->m68k}, SECTION_68000);
107 register_section_handler(buf, (section_handler){.fun = z80_deserialize, .data = gen->z80}, SECTION_Z80); 117 register_section_handler(buf, (section_handler){.fun = z80_deserialize, .data = gen->z80}, SECTION_Z80);
108 register_section_handler(buf, (section_handler){.fun = vdp_deserialize, .data = gen->vdp}, SECTION_VDP); 118 register_section_handler(buf, (section_handler){.fun = vdp_deserialize, .data = gen->vdp}, SECTION_VDP);
109 register_section_handler(buf, (section_handler){.fun = ym_deserialize, .data = gen->ym}, SECTION_YM2612); 119 register_section_handler(buf, (section_handler){.fun = ym_deserialize, .data = gen->ym}, SECTION_YM2612);
110 register_section_handler(buf, (section_handler){.fun = psg_deserialize, .data = gen->psg}, SECTION_PSG); 120 register_section_handler(buf, (section_handler){.fun = psg_deserialize, .data = gen->psg}, SECTION_PSG);
111 //TODO: bus arbiter 121 register_section_handler(buf, (section_handler){.fun = bus_arbiter_deserialize, .data = gen}, SECTION_GEN_BUS_ARBITER);
112 //HACK
113 gen->z80->reset = 0;
114 gen->z80->busreq = 0;
115 register_section_handler(buf, (section_handler){.fun = io_deserialize, .data = gen->io.ports}, SECTION_SEGA_IO_1); 122 register_section_handler(buf, (section_handler){.fun = io_deserialize, .data = gen->io.ports}, SECTION_SEGA_IO_1);
116 register_section_handler(buf, (section_handler){.fun = io_deserialize, .data = gen->io.ports + 1}, SECTION_SEGA_IO_2); 123 register_section_handler(buf, (section_handler){.fun = io_deserialize, .data = gen->io.ports + 1}, SECTION_SEGA_IO_2);
117 register_section_handler(buf, (section_handler){.fun = io_deserialize, .data = gen->io.ports + 2}, SECTION_SEGA_IO_EXT); 124 register_section_handler(buf, (section_handler){.fun = io_deserialize, .data = gen->io.ports + 2}, SECTION_SEGA_IO_EXT);
118 register_section_handler(buf, (section_handler){.fun = ram_deserialize, .data = gen}, SECTION_MAIN_RAM); 125 register_section_handler(buf, (section_handler){.fun = ram_deserialize, .data = gen}, SECTION_MAIN_RAM);
119 register_section_handler(buf, (section_handler){.fun = zram_deserialize, .data = gen}, SECTION_SOUND_RAM); 126 register_section_handler(buf, (section_handler){.fun = zram_deserialize, .data = gen}, SECTION_SOUND_RAM);
325 if (address) { 332 if (address) {
326 if (gen->header.enter_debugger) { 333 if (gen->header.enter_debugger) {
327 gen->header.enter_debugger = 0; 334 gen->header.enter_debugger = 0;
328 debugger(context, address); 335 debugger(context, address);
329 } 336 }
330 if (gen->header.save_state && (z_context->pc || (!z_context->reset && !z_context->busreq))) { 337 if (gen->header.save_state && (z_context->pc || !z_context->native_pc || z_context->reset || !z_context->busreq)) {
331 uint8_t slot = gen->header.save_state - 1; 338 uint8_t slot = gen->header.save_state - 1;
332 gen->header.save_state = 0; 339 gen->header.save_state = 0;
333 //advance Z80 core to the start of an instruction 340 if (z_context->native_pc && !z_context->reset) {
334 while (!z_context->pc) 341 //advance Z80 core to the start of an instruction
335 { 342 while (!z_context->pc)
336 sync_z80(z_context, z_context->current_cycle + MCLKS_PER_Z80); 343 {
344 sync_z80(z_context, z_context->current_cycle + MCLKS_PER_Z80);
345 }
337 } 346 }
338 char *save_path; 347 char *save_path;
339 if (slot == QUICK_SAVE_SLOT) { 348 if (slot == QUICK_SAVE_SLOT) {
340 save_path = save_state_path; 349 save_path = save_state_path;
341 } else { 350 } else {