Mercurial > repos > blastem
diff genesis.c @ 1111:2eb54e24914e
Mostly working changes to allow support for multiple emulated system types in main blastem program
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Mon, 19 Dec 2016 13:28:18 -0800 |
parents | 87114df913ec |
children | 45db303fc705 |
line wrap: on
line diff
--- a/genesis.c Wed Dec 14 23:27:42 2016 -0800 +++ b/genesis.c Mon Dec 19 13:28:18 2016 -0800 @@ -9,6 +9,8 @@ #include "render.h" #include "gst.h" #include "util.h" +#include "debug.h" +#include "gdb_remote.h" #define MCLKS_NTSC 53693175 #define MCLKS_PAL 53203395 @@ -27,6 +29,7 @@ uint16_t read_dma_value(uint32_t address) { + genesis_context *genesis = (genesis_context *)current_system; //addresses here are word addresses (i.e. bit 0 corresponds to A1), so no need to do multiply by 2 uint16_t *ptr = get_native_pointer(address*2, (void **)genesis->m68k->mem_pointers, &genesis->m68k->options->gen); if (ptr) { @@ -38,6 +41,7 @@ uint16_t get_open_bus_value() { + genesis_context *genesis = (genesis_context *)current_system; return read_dma_value(genesis->m68k->last_prefetch_address/2); } @@ -173,9 +177,9 @@ } vdp_adjust_cycles(v_context, mclks); - io_adjust_cycles(gen->ports, context->current_cycle, mclks); - io_adjust_cycles(gen->ports+1, context->current_cycle, mclks); - io_adjust_cycles(gen->ports+2, context->current_cycle, mclks); + io_adjust_cycles(gen->io.ports, context->current_cycle, mclks); + io_adjust_cycles(gen->io.ports+1, context->current_cycle, mclks); + io_adjust_cycles(gen->io.ports+2, context->current_cycle, mclks); context->current_cycle -= mclks; z80_adjust_cycles(z_context, mclks); gen->ym->current_cycle -= mclks; @@ -192,18 +196,18 @@ vdp_int_ack(v_context); context->int_ack = 0; } - if (!address && (break_on_sync || gen->save_state)) { + if (!address && (gen->header.enter_debugger || gen->header.save_state)) { context->sync_cycle = context->current_cycle + 1; } adjust_int_cycle(context, v_context); if (address) { - if (break_on_sync) { - break_on_sync = 0; + if (gen->header.enter_debugger) { + gen->header.enter_debugger = 0; debugger(context, address); } - if (gen->save_state && (z_context->pc || (!z_context->reset && !z_context->busreq))) { - uint8_t slot = gen->save_state - 1; - gen->save_state = 0; + if (gen->header.save_state && (z_context->pc || (!z_context->reset && !z_context->busreq))) { + uint8_t slot = gen->header.save_state - 1; + gen->header.save_state = 0; //advance Z80 core to the start of an instruction while (!z_context->pc) { @@ -215,7 +219,7 @@ } else { char slotname[] = "slot_0.gst"; slotname[5] = '0' + slot; - char const *parts[] = {gen->save_dir, PATH_SEP, slotname}; + char const *parts[] = {gen->header.save_dir, PATH_SEP, slotname}; save_path = alloc_concat_m(3, parts); } save_gst(gen, save_path, address); @@ -223,7 +227,7 @@ if (slot != QUICK_SAVE_SLOT) { free(save_path); } - } else if(gen->save_state) { + } else if(gen->header.save_state) { context->sync_cycle = context->current_cycle + 1; } } @@ -486,22 +490,22 @@ switch(location/2) { case 0x1: - io_data_write(gen->ports, value, context->current_cycle); + io_data_write(gen->io.ports, value, context->current_cycle); break; case 0x2: - io_data_write(gen->ports+1, value, context->current_cycle); + io_data_write(gen->io.ports+1, value, context->current_cycle); break; case 0x3: - io_data_write(gen->ports+2, value, context->current_cycle); + io_data_write(gen->io.ports+2, value, context->current_cycle); break; case 0x4: - gen->ports[0].control = value; + gen->io.ports[0].control = value; break; case 0x5: - gen->ports[1].control = value; + gen->io.ports[1].control = value; break; case 0x6: - gen->ports[2].control = value; + gen->io.ports[2].control = value; break; } } else { @@ -597,22 +601,22 @@ value = gen->version_reg; break; case 0x1: - value = io_data_read(gen->ports, context->current_cycle); + value = io_data_read(gen->io.ports, context->current_cycle); break; case 0x2: - value = io_data_read(gen->ports+1, context->current_cycle); + value = io_data_read(gen->io.ports+1, context->current_cycle); break; case 0x3: - value = io_data_read(gen->ports+2, context->current_cycle); + value = io_data_read(gen->io.ports+2, context->current_cycle); break; case 0x4: - value = gen->ports[0].control; + value = gen->io.ports[0].control; break; case 0x5: - value = gen->ports[1].control; + value = gen->io.ports[1].control; break; case 0x6: - value = gen->ports[2].control; + value = gen->io.ports[2].control; break; default: value = 0xFF; @@ -737,8 +741,9 @@ return context; } -void set_speed_percent(genesis_context * context, uint32_t percent) +static void set_speed_percent(system_header * system, uint32_t percent) { + genesis_context *context = (genesis_context *)system; uint32_t old_clock = context->master_clock; context->master_clock = ((uint64_t)context->normal_clock * (uint64_t)percent) / 100; while (context->ym->current_cycle != context->psg->cycles) { @@ -774,6 +779,109 @@ gen->master_clock = gen->normal_clock; } +static void start_genesis(system_header *system, char *statefile) +{ + genesis_context *gen = (genesis_context *)system; + set_keybindings(&gen->io); + if (statefile) { + uint32_t pc = load_gst(gen, statefile); + if (!pc) { + fatal_error("Failed to load save state %s\n", statefile); + } + printf("Loaded %s\n", statefile); + if (gen->header.enter_debugger) { + gen->header.enter_debugger = 0; + insert_breakpoint(gen->m68k, pc, gen->header.debugger_type == DEBUGGER_NATIVE ? debugger : gdb_debug_enter); + } + adjust_int_cycle(gen->m68k, gen->vdp); + start_68k_context(gen->m68k, pc); + } else { + if (gen->header.enter_debugger) { + gen->header.enter_debugger = 0; + uint32_t address = gen->cart[2] << 16 | gen->cart[3]; + insert_breakpoint(gen->m68k, address, gen->header.debugger_type == DEBUGGER_NATIVE ? debugger : gdb_debug_enter); + } + m68k_reset(gen->m68k); + } +} + +static void resume_genesis(system_header *system) +{ + genesis_context *gen = (genesis_context *)system; + map_all_bindings(&gen->io); + resume_68k(gen->m68k); +} + +static void inc_debug_mode(system_header *system) +{ + genesis_context *gen = (genesis_context *)system; + gen->vdp->debug++; + if (gen->vdp->debug == 7) { + gen->vdp->debug = 0; + } +} + +static void inc_debug_pal(system_header *system) +{ + genesis_context *gen = (genesis_context *)system; + gen->vdp->debug_pal++; + if (gen->vdp->debug_pal == 4) { + gen->vdp->debug_pal = 0; + } +} + +static void request_exit(system_header *system) +{ + genesis_context *gen = (genesis_context *)system; + gen->m68k->should_return = 1; +} + +static void persist_save(system_header *system) +{ + genesis_context *gen = (genesis_context *)system; + if (gen->save_type == SAVE_NONE) { + return; + } + FILE * f = fopen(save_filename, "wb"); + if (!f) { + fprintf(stderr, "Failed to open %s file %s for writing\n", gen->save_type == SAVE_I2C ? "EEPROM" : "SRAM", save_filename); + return; + } + fwrite(gen->save_storage, 1, gen->save_size, f); + fclose(f); + printf("Saved %s to %s\n", gen->save_type == SAVE_I2C ? "EEPROM" : "SRAM", save_filename); +} + +static void load_save(system_header *system) +{ + genesis_context *gen = (genesis_context *)system; + FILE * f = fopen(save_filename, "rb"); + if (f) { + uint32_t read = fread(gen->save_storage, 1, gen->save_size, f); + fclose(f); + if (read > 0) { + printf("Loaded %s from %s\n", gen->save_type == SAVE_I2C ? "EEPROM" : "SRAM", save_filename); + } + } +} + +static void free_genesis(system_header *system) +{ + genesis_context *gen = (genesis_context *)system; + vdp_free(gen->vdp); + m68k_options_free(gen->m68k->options); + free(gen->m68k); + free(gen->work_ram); + z80_options_free(gen->z80->options); + free(gen->z80); + free(gen->zram); + ym_free(gen->ym); + psg_free(gen->psg); + free(gen->save_storage); + free(gen->header.save_dir); + free(gen->lock_on); +} + genesis_context *alloc_init_genesis(rom_info *rom, void *main_rom, void *lock_on, uint32_t ym_opts, uint8_t force_region) { static memmap_chunk z80_map[] = { @@ -784,6 +892,15 @@ { 0x7F00, 0x8000, 0x00FF, 0, 0, 0, NULL, NULL, NULL, z80_vdp_port_read, z80_vdp_port_write} }; genesis_context *gen = calloc(1, sizeof(genesis_context)); + gen->header.set_speed_percent = set_speed_percent; + gen->header.start_context = start_genesis; + gen->header.resume_context = resume_genesis; + gen->header.load_save = load_save; + gen->header.persist_save = persist_save; + gen->header.free_context = free_genesis; + gen->header.request_exit = request_exit; + gen->header.inc_debug_mode = inc_debug_mode; + gen->header.inc_debug_pal = inc_debug_pal; set_region(gen, rom, force_region); gen->vdp = malloc(sizeof(vdp_context)); @@ -855,47 +972,6 @@ return gen; } - - -void free_genesis(genesis_context *gen) -{ - vdp_free(gen->vdp); - m68k_options_free(gen->m68k->options); - free(gen->m68k); - free(gen->work_ram); - z80_options_free(gen->z80->options); - free(gen->z80); - free(gen->zram); - ym_free(gen->ym); - psg_free(gen->psg); - free(gen->save_storage); - free(gen->save_dir); - free(gen->lock_on); -} - -void start_genesis(genesis_context *gen, char *statefile, uint8_t *debugger) -{ - - if (statefile) { - uint32_t pc = load_gst(gen, statefile); - if (!pc) { - fatal_error("Failed to load save state %s\n", statefile); - } - printf("Loaded %s\n", statefile); - if (debugger) { - insert_breakpoint(gen->m68k, pc, debugger); - } - adjust_int_cycle(gen->m68k, gen->vdp); - start_68k_context(gen->m68k, pc); - } else { - if (debugger) { - uint32_t address = gen->cart[2] << 16 | gen->cart[3]; - insert_breakpoint(gen->m68k, address, debugger); - } - m68k_reset(gen->m68k); - } -} - genesis_context *alloc_config_genesis(void *rom, uint32_t rom_size, void *lock_on, uint32_t lock_on_size, uint32_t ym_opts, uint8_t force_region, rom_info *info_out) { static memmap_chunk base_map[] = {