Mercurial > repos > blastem
diff genesis.c @ 1983:a7b753e260a2 mame_interp
Merge from default
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 09 May 2020 23:39:44 -0700 |
parents | 2c1c88cd1a3f 81df9aa2de9b |
children | 0d5f88e53dca |
line wrap: on
line diff
--- a/genesis.c Sun Apr 19 00:59:49 2020 -0700 +++ b/genesis.c Sat May 09 23:39:44 2020 -0700 @@ -19,6 +19,7 @@ #include "bindings.h" #include "jcart.h" #include "config.h" +#include "event_log.h" #define MCLKS_NTSC 53693175 #define MCLKS_PAL 53203395 @@ -50,15 +51,17 @@ #define Z80_OPTS options #endif -void genesis_serialize(genesis_context *gen, serialize_buffer *buf, uint32_t m68k_pc) +void genesis_serialize(genesis_context *gen, serialize_buffer *buf, uint32_t m68k_pc, uint8_t all) { - start_section(buf, SECTION_68000); - m68k_serialize(gen->m68k, m68k_pc, buf); - end_section(buf); - - start_section(buf, SECTION_Z80); - z80_serialize(gen->z80, buf); - end_section(buf); + if (all) { + start_section(buf, SECTION_68000); + m68k_serialize(gen->m68k, m68k_pc, buf); + end_section(buf); + + start_section(buf, SECTION_Z80); + z80_serialize(gen->z80, buf); + end_section(buf); + } start_section(buf, SECTION_VDP); vdp_serialize(gen->vdp, buf); @@ -72,35 +75,37 @@ psg_serialize(gen->psg, buf); end_section(buf); - start_section(buf, SECTION_GEN_BUS_ARBITER); - save_int8(buf, gen->z80->reset); - save_int8(buf, gen->z80->busreq); - save_int16(buf, gen->z80_bank_reg); - end_section(buf); - - start_section(buf, SECTION_SEGA_IO_1); - io_serialize(gen->io.ports, buf); - end_section(buf); - - start_section(buf, SECTION_SEGA_IO_2); - io_serialize(gen->io.ports + 1, buf); - end_section(buf); - - start_section(buf, SECTION_SEGA_IO_EXT); - io_serialize(gen->io.ports + 2, buf); - end_section(buf); - - start_section(buf, SECTION_MAIN_RAM); - save_int8(buf, RAM_WORDS * 2 / 1024); - save_buffer16(buf, gen->work_ram, RAM_WORDS); - end_section(buf); - - start_section(buf, SECTION_SOUND_RAM); - save_int8(buf, Z80_RAM_BYTES / 1024); - save_buffer8(buf, gen->zram, Z80_RAM_BYTES); - end_section(buf); - - cart_serialize(&gen->header, buf); + if (all) { + start_section(buf, SECTION_GEN_BUS_ARBITER); + save_int8(buf, gen->z80->reset); + save_int8(buf, gen->z80->busreq); + save_int16(buf, gen->z80_bank_reg); + end_section(buf); + + start_section(buf, SECTION_SEGA_IO_1); + io_serialize(gen->io.ports, buf); + end_section(buf); + + start_section(buf, SECTION_SEGA_IO_2); + io_serialize(gen->io.ports + 1, buf); + end_section(buf); + + start_section(buf, SECTION_SEGA_IO_EXT); + io_serialize(gen->io.ports + 2, buf); + end_section(buf); + + start_section(buf, SECTION_MAIN_RAM); + save_int8(buf, RAM_WORDS * 2 / 1024); + save_buffer16(buf, gen->work_ram, RAM_WORDS); + end_section(buf); + + start_section(buf, SECTION_SOUND_RAM); + save_int8(buf, Z80_RAM_BYTES / 1024); + save_buffer8(buf, gen->zram, Z80_RAM_BYTES); + end_section(buf); + + cart_serialize(&gen->header, buf); + } } static uint8_t *serialize(system_header *sys, size_t *size_out) @@ -120,7 +125,7 @@ init_serialize(&state); uint32_t address = read_word(4, (void **)gen->m68k->mem_pointers, &gen->m68k->options->gen, gen->m68k) << 16; address |= read_word(6, (void **)gen->m68k->mem_pointers, &gen->m68k->options->gen, gen->m68k); - genesis_serialize(gen, &state, address); + genesis_serialize(gen, &state, address, 1); if (size_out) { *size_out = state.size; } @@ -351,9 +356,6 @@ //printf("Target: %d, YM bufferpos: %d, PSG bufferpos: %d\n", target, gen->ym->buffer_pos, gen->psg->buffer_pos * 2); } -//TODO: move this inside the system context -static uint32_t last_frame_num; - //My refresh emulation isn't currently good enough and causes more problems than it solves #define REFRESH_EMULATION #ifdef REFRESH_EMULATION @@ -392,9 +394,11 @@ context->should_return = 1; gen->reset_cycle = CYCLE_NEVER; } - if (v_context->frame != last_frame_num) { - //printf("reached frame end %d | MCLK Cycles: %d, Target: %d, VDP cycles: %d, vcounter: %d, hslot: %d\n", last_frame_num, mclks, gen->frame_end, v_context->cycles, v_context->vcounter, v_context->hslot); - last_frame_num = v_context->frame; + if (v_context->frame != gen->last_frame) { + //printf("reached frame end %d | MCLK Cycles: %d, Target: %d, VDP cycles: %d, vcounter: %d, hslot: %d\n", gen->last_frame, mclks, gen->frame_end, v_context->cycles, v_context->vcounter, v_context->hslot); + gen->last_frame = v_context->frame; + event_flush(mclks); + gen->last_flush_cycle = mclks; if(exit_after){ --exit_after; @@ -421,7 +425,12 @@ if (gen->reset_cycle != CYCLE_NEVER) { gen->reset_cycle -= deduction; } + event_cycle_adjust(mclks, deduction); + gen->last_flush_cycle -= deduction; } + } else if (mclks - gen->last_flush_cycle > gen->soft_flush_cycles) { + event_soft_flush(mclks); + gen->last_flush_cycle = mclks; } gen->frame_end = vdp_cycles_to_frame_end(v_context); context->sync_cycle = gen->frame_end; @@ -461,9 +470,9 @@ } } #endif - char *save_path = slot == SERIALIZE_SLOT ? NULL : get_slot_name(&gen->header, slot, use_native_states ? "state" : "gst"); + char *save_path = slot >= SERIALIZE_SLOT ? NULL : get_slot_name(&gen->header, slot, use_native_states ? "state" : "gst"); #ifndef NEW_CORE - if (use_native_states || slot == SERIALIZE_SLOT) { + if (use_native_states || slot >= SERIALIZE_SLOT) { #endif serialize_buffer state; init_serialize(&state); @@ -473,6 +482,8 @@ gen->serialize_size = state.size; context->sync_cycle = context->current_cycle; context->should_return = 1; + } else if (slot == EVENTLOG_SLOT) { + event_state(context->current_cycle, &state); } else { save_to_file(&state, save_path); free(state.data); @@ -482,7 +493,9 @@ save_gst(gen, save_path, address); } #endif - printf("Saved state to %s\n", save_path); + if (slot != SERIALIZE_SLOT) { + debug_message("Saved state to %s\n", save_path); + } free(save_path); } else if(gen->header.save_state) { context->sync_cycle = context->current_cycle + 1; @@ -644,11 +657,11 @@ uint16_t value; #ifdef REFRESH_EMULATION if (context->current_cycle - 4*MCLKS_PER_68K > last_sync_cycle) { - //do refresh check here so we can avoid adding a penalty for a refresh that happens during a VDP access - refresh_counter += context->current_cycle - 4*MCLKS_PER_68K - last_sync_cycle; - context->current_cycle += REFRESH_DELAY * MCLKS_PER_68K * (refresh_counter / (MCLKS_PER_68K * REFRESH_INTERVAL)); - refresh_counter = refresh_counter % (MCLKS_PER_68K * REFRESH_INTERVAL); - last_sync_cycle = context->current_cycle; + //do refresh check here so we can avoid adding a penalty for a refresh that happens during a VDP access + refresh_counter += context->current_cycle - 4*MCLKS_PER_68K - last_sync_cycle; + context->current_cycle += REFRESH_DELAY * MCLKS_PER_68K * (refresh_counter / (MCLKS_PER_68K * REFRESH_INTERVAL)); + refresh_counter = refresh_counter % (MCLKS_PER_68K * REFRESH_INTERVAL); + last_sync_cycle = context->current_cycle; } #endif genesis_context *gen = context->system; @@ -1198,8 +1211,10 @@ if (region & HZ50) { gen->normal_clock = MCLKS_PAL; + gen->soft_flush_cycles = MCLKS_LINE * 262 / 3 + 2; } else { gen->normal_clock = MCLKS_NTSC; + gen->soft_flush_cycles = MCLKS_LINE * 313 / 3 + 2; } gen->master_clock = gen->normal_clock; } @@ -1265,7 +1280,7 @@ resume_68k(gen->m68k); } } - if (render_should_release_on_exit()) { + if (gen->header.force_release || render_should_release_on_exit()) { bindings_release_capture(); vdp_release_framebuffer(gen->vdp); render_pause_source(gen->ym->audio); @@ -1321,7 +1336,8 @@ static void resume_genesis(system_header *system) { genesis_context *gen = (genesis_context *)system; - if (render_should_release_on_exit()) { + if (gen->header.force_release || render_should_release_on_exit()) { + gen->header.force_release = 0; render_set_video_standard((gen->version_reg & HZ50) ? VID_PAL : VID_NTSC); bindings_reacquire_capture(); vdp_reacquire_framebuffer(gen->vdp); @@ -1565,8 +1581,13 @@ gen->int_latency_prev2 = MCLKS_PER_68K * 16; render_set_video_standard((gen->version_reg & HZ50) ? VID_PAL : VID_NTSC); + event_system_start(SYSTEM_GENESIS, (gen->version_reg & HZ50) ? VID_PAL : VID_NTSC, rom->name); gen->ym = malloc(sizeof(ym2612_context)); + char *fm = tern_find_ptr_default(model, "fm", "discrete 2612"); + if (!strcmp(fm + strlen(fm) -4, "3834")) { + system_opts |= YM_OPT_3834; + } ym_init(gen->ym, gen->master_clock, MCLKS_PER_YM, system_opts); gen->psg = malloc(sizeof(psg_context)); @@ -1676,6 +1697,7 @@ gen->bank_regs[i] = i; } } + gen->reset_cycle = CYCLE_NEVER; return gen; }