# HG changeset patch # User Mike Pavone # Date 1367307571 25200 # Node ID 625f8e4d5fd2f88f250cdcdefa0a770addc81f2c # Parent d9417261366fe75b81ececbcc4e42eae32283190 Initial stab at integartiong Z80 core diff -r d9417261366f -r 625f8e4d5fd2 Makefile --- a/Makefile Tue Apr 30 00:39:20 2013 -0700 +++ b/Makefile Tue Apr 30 00:39:31 2013 -0700 @@ -7,8 +7,8 @@ all : dis trans stateview blastem -blastem : blastem.o 68kinst.o gen_x86.o m68k_to_x86.o x86_backend.o runtime.o mem.o vdp.o render_sdl.o - $(CC) -o blastem blastem.o 68kinst.o gen_x86.o m68k_to_x86.o x86_backend.o runtime.o mem.o vdp.o render_sdl.o `pkg-config --libs $(LIBS)` +blastem : blastem.o 68kinst.o gen_x86.o m68k_to_x86.o z80inst.o z80_to_x86.o x86_backend.o runtime.o zruntime.o mem.o vdp.o render_sdl.o + $(CC) -o blastem blastem.o 68kinst.o gen_x86.o m68k_to_x86.o z80inst.o z80_to_x86.o x86_backend.o runtime.o zruntime.o mem.o vdp.o render_sdl.o `pkg-config --libs $(LIBS)` dis : dis.o 68kinst.o $(CC) -o dis dis.o 68kinst.o diff -r d9417261366f -r 625f8e4d5fd2 blastem.c --- a/blastem.c Tue Apr 30 00:39:20 2013 -0700 +++ b/blastem.c Tue Apr 30 00:39:31 2013 -0700 @@ -1,5 +1,6 @@ #include "68kinst.h" #include "m68k_to_x86.h" +#include "z80_to_x86.h" #include "mem.h" #include "vdp.h" #include "render.h" @@ -12,6 +13,7 @@ #define RAM_WORDS 32 * 1024 #define Z80_RAM_BYTES 8 * 1024 #define MCLKS_PER_68K 7 +#define MCLKS_PER_Z80 15 //TODO: Figure out the exact value for this #define MCLKS_PER_FRAME (MCLKS_LINE*262) #define CYCLE_NEVER 0xFFFFFFFF @@ -105,6 +107,7 @@ } #define VINT_CYCLE ((MCLKS_LINE * 226)/MCLKS_PER_68K) +#define ZVINT_CYCLE ((MCLKS_LINE * 226)/MCLKS_PER_Z80) void adjust_int_cycle(m68k_context * context, vdp_context * v_context) { @@ -121,12 +124,35 @@ } int break_on_sync = 0; +#define Z80_ACK_DELAY 3 //TODO: Calculate this on the fly based on how synced up the Z80 and 68K clocks are + +uint8_t reset = 1; +uint8_t need_reset = 0; +uint8_t busreq = 0; +uint8_t busack = 0; +uint32_t busack_cycle = CYCLE_NEVER; +uint8_t new_busack = 0; m68k_context * sync_components(m68k_context * context, uint32_t address) { //TODO: Handle sync targets smaller than a single frame - vdp_context * v_context = context->next_context; + z80_context * z_context = context->next_context; + vdp_context * v_context = z_context->next_context; uint32_t mclks = context->current_cycle * MCLKS_PER_68K; + if (!reset && !busreq) { + if (need_reset) { + z80_reset(z_context); + need_reset = 0; + } + z_context->sync_cycle = mclks / MCLKS_PER_Z80; + while (z_context->current_cycle < z_context->sync_cycle) { + if (z_context->iff1 && z_context->current_cycle < ZVINT_CYCLE) { + z_context->int_cycle = ZVINT_CYCLE; + } + z_context->target_cycle = z_context->sync_cycle < z_context->int_cycle ? z_context->sync_cycle : z_context->int_cycle; + z80_run(z_context); + } + } if (mclks >= MCLKS_PER_FRAME) { //printf("reached frame end | 68K Cycles: %d, MCLK Cycles: %d\n", context->current_cycle, mclks); vdp_run_context(v_context, MCLKS_PER_FRAME); @@ -138,6 +164,11 @@ io_adjust_cycles(&gamepad_1, context->current_cycle, MCLKS_PER_FRAME/MCLKS_PER_68K); io_adjust_cycles(&gamepad_2, context->current_cycle, MCLKS_PER_FRAME/MCLKS_PER_68K); context->current_cycle -= MCLKS_PER_FRAME/MCLKS_PER_68K; + if (z_context->current_cycle >= MCLKS_PER_FRAME/MCLKS_PER_Z80) { + z_context->current_cycle -= MCLKS_PER_FRAME/MCLKS_PER_Z80; + } else { + z_context->current_cycle = 0; + } if (mclks) { vdp_run_context(v_context, mclks); } @@ -157,7 +188,8 @@ { //printf("vdp_port write: %X, value: %X, cycle: %d\n", vdp_port, value, context->current_cycle); sync_components(context, 0); - vdp_context * v_context = context->next_context; + z80_context * z_context = context->next_context; + vdp_context * v_context = z_context->next_context; if (vdp_port < 0x10) { int blocked; if (vdp_port < 4) { @@ -216,7 +248,8 @@ m68k_context * vdp_port_read(uint32_t vdp_port, m68k_context * context) { sync_components(context, 0); - vdp_context * v_context = context->next_context; + z80_context * z_context = context->next_context; + vdp_context * v_context = z_context->next_context; if (vdp_port < 0x10) { if (vdp_port < 4) { context->value = vdp_data_port_read(v_context); @@ -236,13 +269,6 @@ #define TH 0x40 #define TH_TIMEOUT 8000 -#define Z80_ACK_DELAY 3 //TODO: Calculate this on the fly based on how synced up the Z80 and 68K clocks are - -uint8_t reset = 1; -uint8_t busreq = 0; -uint8_t busack = 0; -uint32_t busack_cycle = CYCLE_NEVER; -uint8_t new_busack = 0; void io_adjust_cycles(io_port * pad, uint32_t current_cycle, uint32_t deduction) { @@ -356,6 +382,11 @@ new_busack = 0; } } else { + if (busreq) { + z80_context * z_context = context->next_context; + //TODO: Add necessary delay between release of busreq and resumption of execution + z_context->current_cycle = (context->current_cycle * MCLKS_PER_68K) / MCLKS_PER_Z80; + } busreq = 0; busack_cycle = CYCLE_NEVER; busack = 1; @@ -366,6 +397,13 @@ new_busack = 0; busack_cycle = context->current_cycle + Z80_ACK_DELAY; } + //TODO: Deal with the scenario in which reset is not asserted long enough + if (reset) { + z80_context * z_context = context->next_context; + need_reset = 1; + //TODO: Add necessary delay between release of reset and start of execution + z_context->current_cycle = (context->current_cycle * MCLKS_PER_68K) / MCLKS_PER_Z80; + } reset = 0; } else { reset = 1; @@ -423,6 +461,11 @@ new_busack = 0; } } else { + if (busreq) { + z80_context * z_context = context->next_context; + //TODO: Add necessary delay between release of busreq and resumption of execution + z_context->current_cycle = (context->current_cycle * MCLKS_PER_68K) / MCLKS_PER_Z80; + } busreq = 0; busack_cycle = CYCLE_NEVER; busack = 1; @@ -433,6 +476,13 @@ new_busack = 0; busack_cycle = context->current_cycle + Z80_ACK_DELAY; } + //TODO: Deal with the scenario in which reset is not asserted long enough + if (reset) { + z80_context * z_context = context->next_context; + need_reset = 1; + //TODO: Add necessary delay between release of reset and start of execution + z_context->current_cycle = (context->current_cycle * MCLKS_PER_68K) / MCLKS_PER_Z80; + } reset = 0; } else { reset = 1; @@ -804,7 +854,7 @@ return context; } -void init_run_cpu(vdp_context * vcontext, int debug, FILE * address_log) +void init_run_cpu(z80_context * zcontext, int debug, FILE * address_log) { m68k_context context; x86_68k_options opts; @@ -812,7 +862,7 @@ opts.address_log = address_log; init_68k_context(&context, opts.native_code_map, &opts); - context.next_context = vcontext; + context.next_context = zcontext; //cartridge ROM context.mem_pointers[0] = cart; context.target_cycle = context.sync_cycle = MCLKS_PER_FRAME/MCLKS_PER_68K; @@ -877,6 +927,17 @@ vdp_context v_context; init_vdp_context(&v_context); - init_run_cpu(&v_context, debug, address_log); + + z80_context z_context; + x86_z80_options z_opts; + init_x86_z80_opts(&z_opts); + init_z80_context(&z_context, &z_opts); + z_context.next_context = &v_context; + z_context.mem_pointers[0] = z80_ram; + z_context.sync_cycle = z_context.target_cycle = MCLKS_PER_FRAME/MCLKS_PER_Z80; + z_context.int_cycle = CYCLE_NEVER; + z_context.mem_pointers[1] = z_context.mem_pointers[2] = (uint8_t *)cart; + + init_run_cpu(&z_context, debug, address_log); return 0; }