diff options
Diffstat (limited to 'blastem.c')
-rw-r--r-- | blastem.c | 114 |
1 files changed, 103 insertions, 11 deletions
@@ -4,7 +4,7 @@ BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text. */ #include "68kinst.h" -#include "m68k_to_x86.h" +#include "m68k_core.h" #include "z80_to_x86.h" #include "mem.h" #include "vdp.h" @@ -182,6 +182,7 @@ uint8_t new_busack = 0; void sync_z80(z80_context * z_context, uint32_t mclks) { +#ifndef NO_Z80 if (z80_enabled && !reset && !busreq) { genesis_context * gen = z_context->system; z_context->sync_cycle = mclks / MCLKS_PER_Z80; @@ -198,14 +199,18 @@ void sync_z80(z80_context * z_context, uint32_t mclks) } if (z_context->iff1) { z_context->int_cycle = z_context->int_pulse_start < z_context->int_enable_cycle ? z_context->int_enable_cycle : z_context->int_pulse_start; + } else { + z_context->int_cycle = CYCLE_NEVER; } z_context->target_cycle = z_context->sync_cycle < z_context->int_cycle ? z_context->sync_cycle : z_context->int_cycle; dprintf("Running Z80 from cycle %d to cycle %d. Int cycle: %d\n", z_context->current_cycle, z_context->sync_cycle, z_context->int_cycle); - z80_run(z_context); + z_context->run(z_context); dprintf("Z80 ran to cycle %d\n", z_context->current_cycle); } } - } else { + } else +#endif + { z_context->current_cycle = mclks / MCLKS_PER_Z80; } } @@ -410,8 +415,9 @@ m68k_context * vdp_port_write_b(uint32_t vdp_port, m68k_context * context, uint8 return vdp_port_write(vdp_port, context, vdp_port < 0x10 ? value | value << 8 : ((vdp_port & 1) ? value : 0)); } -z80_context * z80_vdp_port_write(uint16_t vdp_port, z80_context * context, uint8_t value) +void * z80_vdp_port_write(uint32_t vdp_port, void * vcontext, uint8_t value) { + z80_context * context = vcontext; genesis_context * gen = context->system; if (vdp_port & 0xE0) { printf("machine freeze due to write to Z80 address %X\n", 0x7F00 | vdp_port); @@ -480,6 +486,34 @@ uint8_t vdp_port_read_b(uint32_t vdp_port, m68k_context * context) } } +uint8_t z80_vdp_port_read(uint32_t vdp_port, void * vcontext) +{ + z80_context * context = vcontext; + if (vdp_port & 0xE0) { + printf("machine freeze due to read from Z80 address %X\n", 0x7F00 | vdp_port); + exit(1); + } + genesis_context * gen = context->system; + vdp_port &= 0x1F; + uint16_t ret; + if (vdp_port < 0x10) { + //These probably won't currently interact well with the 68K accessing the VDP + vdp_run_context(gen->vdp, context->current_cycle * MCLKS_PER_Z80); + if (vdp_port < 4) { + ret = vdp_data_port_read(gen->vdp); + } else if (vdp_port < 8) { + ret = vdp_control_port_read(gen->vdp); + } else { + printf("Illegal write to HV Counter port %X\n", vdp_port); + exit(1); + } + } else { + //TODO: Figure out the correct value today + ret = 0xFFFF; + } + return vdp_port & 1 ? ret : ret >> 8; +} + uint32_t zram_counter = 0; #define Z80_ACK_DELAY 3 #define Z80_BUSY_DELAY 1//TODO: Find the actual value for this @@ -499,7 +533,9 @@ m68k_context * io_write(uint32_t location, m68k_context * context, uint8_t value location &= 0x7FFF; if (location < 0x4000) { z80_ram[location & 0x1FFF] = value; +#ifndef NO_Z80 z80_handle_code_write(location & 0x1FFF, gen->z80); +#endif } else if (location < 0x6000) { sync_sound(gen, context->current_cycle * MCLKS_PER_68K); if (location & 1) { @@ -699,8 +735,9 @@ uint16_t io_read_w(uint32_t location, m68k_context * context) return value; } -z80_context * z80_write_ym(uint16_t location, z80_context * context, uint8_t value) +void * z80_write_ym(uint32_t location, void * vcontext, uint8_t value) { + z80_context * context = vcontext; genesis_context * gen = context->system; sync_sound(gen, context->current_cycle * MCLKS_PER_Z80); if (location & 1) { @@ -713,13 +750,55 @@ z80_context * z80_write_ym(uint16_t location, z80_context * context, uint8_t val return context; } -uint8_t z80_read_ym(uint16_t location, z80_context * context) +uint8_t z80_read_ym(uint32_t location, void * vcontext) { + z80_context * context = vcontext; genesis_context * gen = context->system; sync_sound(gen, context->current_cycle * MCLKS_PER_Z80); return ym_read_status(gen->ym); } +uint8_t z80_read_bank(uint32_t location, void * vcontext) +{ + z80_context * context = vcontext; + uint32_t address = context->bank_reg << 15 | location; + if (address >= 0xC00000 && address < 0xE00000) { + return z80_vdp_port_read(location & 0xFF, context); + } else { + fprintf(stderr, "Unhandled read by Z80 from address %X through banked memory area\n", address); + } + return 0; +} + +void *z80_write_bank(uint32_t location, void * vcontext, uint8_t value) +{ + z80_context * context = vcontext; + uint32_t address = context->bank_reg << 15 | location; + if (address >= 0xE00000) { + address &= 0xFFFF; + ((uint8_t *)ram)[address ^ 1] = value; + } else if (address >= 0xC00000) { + z80_vdp_port_write(location & 0xFF, context, value); + } else { + fprintf(stderr, "Unhandled write by Z80 to address %X through banked memory area\n", address); + } + return context; +} + +void *z80_write_bank_reg(uint32_t location, void * vcontext, uint8_t value) +{ + z80_context * context = vcontext; + + context->bank_reg = (context->bank_reg >> 1 | value << 8) & 0x1FF; + if (context->bank_reg < 0x80) { + context->mem_pointers[1] = context->mem_pointers[2] + (context->bank_reg << 15); + } else { + context->mem_pointers[1] = NULL; + } + + return context; +} + uint16_t read_sram_w(uint32_t address, m68k_context * context) { genesis_context * gen = context->system; @@ -894,7 +973,7 @@ void save_sram() void init_run_cpu(genesis_context * gen, FILE * address_log, char * statefile, uint8_t * debugger) { m68k_context context; - x86_68k_options opts; + m68k_options opts; gen->m68k = &context; memmap_chunk memmap[MAX_MAP_CHUNKS]; uint32_t num_chunks; @@ -988,9 +1067,9 @@ void init_run_cpu(genesis_context * gen, FILE * address_log, char * statefile, u } atexit(save_sram); } - init_x86_68k_opts(&opts, memmap, num_chunks); + init_m68k_opts(&opts, memmap, num_chunks); opts.address_log = address_log; - init_68k_context(&context, opts.native_code_map, &opts); + init_68k_context(&context, opts.gen.native_code_map, &opts); context.video_context = gen->vdp; context.system = gen; @@ -1016,7 +1095,9 @@ void init_run_cpu(genesis_context * gen, FILE * address_log, char * statefile, u insert_breakpoint(&context, pc, debugger); } adjust_int_cycle(gen->m68k, gen->vdp); +#ifndef NO_Z80 gen->z80->native_pc = z80_get_native_address_trans(gen->z80, gen->z80->pc); +#endif start_68k_context(&context, pc); } else { if (debugger) { @@ -1095,6 +1176,15 @@ void detect_region() } } } +#ifndef NO_Z80 +const memmap_chunk z80_map[] = { + { 0x0000, 0x4000, 0x1FFF, 0, MMAP_READ | MMAP_WRITE | MMAP_CODE, z80_ram, NULL, NULL, NULL, NULL }, + { 0x8000, 0x10000, 0x7FFF, 1, MMAP_READ | MMAP_PTR_IDX | MMAP_FUNC_NULL | MMAP_BYTESWAP, NULL, NULL, NULL, z80_read_bank, z80_write_bank}, + { 0x4000, 0x6000, 0x0003, 0, 0, NULL, NULL, NULL, z80_read_ym, z80_write_ym}, + { 0x6000, 0x6100, 0xFFFF, 0, 0, NULL, NULL, NULL, NULL, z80_write_bank_reg}, + { 0x7F00, 0x8000, 0x00FF, 0, 0, NULL, NULL, NULL, z80_vdp_port_read, z80_vdp_port_write} +}; +#endif int main(int argc, char ** argv) { @@ -1260,9 +1350,11 @@ int main(int argc, char ** argv) psg_init(&p_context, render_sample_rate(), gen.master_clock, MCLKS_PER_PSG, render_audio_buffer()); z80_context z_context; - x86_z80_options z_opts; - init_x86_z80_opts(&z_opts); +#ifndef NO_Z80 + z80_options z_opts; + init_x86_z80_opts(&z_opts, z80_map, 5); init_z80_context(&z_context, &z_opts); +#endif z_context.system = &gen; z_context.mem_pointers[0] = z80_ram; |