Mercurial > repos > blastem
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 { |