Mercurial > repos > blastem
diff z80_to_x86.c @ 668:5439ae7946ca
Made the Z80 core more contained by refactoring some code in blastem.c into z80_to_x86.c
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 03 Jan 2015 18:23:04 -0800 |
parents | 30ccf56842d6 |
children | f4f3e74b0ce6 |
line wrap: on
line diff
--- a/z80_to_x86.c Sat Jan 03 16:08:23 2015 -0800 +++ b/z80_to_x86.c Sat Jan 03 18:23:04 2015 -0800 @@ -1777,7 +1777,7 @@ code_ptr dst = z80_get_native_address(context, inst_start); code_info code = {dst, dst+16}; z80_options * opts = context->options; - dprintf("patching code at %p for Z80 instruction at %X due to write to %X\n", code, inst_start, address); + dprintf("patching code at %p for Z80 instruction at %X due to write to %X\n", code.cur, inst_start, address); mov_ir(&code, inst_start, opts->gen.scratch1, SZ_D); call(&code, opts->retrans_stub); } @@ -2226,18 +2226,112 @@ context->banked_code_map = malloc(sizeof(native_map_slot)); memset(context->banked_code_map, 0, sizeof(native_map_slot)); context->options = options; - context->int_cycle = 0xFFFFFFFF; - context->int_pulse_start = 0xFFFFFFFF; - context->int_pulse_end = 0xFFFFFFFF; - context->run = options->run; + context->int_cycle = CYCLE_NEVER; + context->int_pulse_start = CYCLE_NEVER; + context->int_pulse_end = CYCLE_NEVER; +} + +void z80_run(z80_context * context, uint32_t target_cycle) +{ + if (context->reset || context->busack) { + context->current_cycle = target_cycle; + } else { + if (context->current_cycle < target_cycle) { + //busreq is sampled at the end of an m-cycle + //we can approximate that by running for a single m-cycle after a bus request + context->sync_cycle = context->busreq ? context->current_cycle + 3*context->options->gen.clock_divider : target_cycle; + if (!context->native_pc) { + context->native_pc = z80_get_native_address_trans(context, context->pc); + } + while (context->current_cycle < context->sync_cycle) + { + if (context->int_pulse_end < context->current_cycle || context->int_pulse_end == CYCLE_NEVER) { + z80_next_int_pulse(context); + } + if (context->iff1) { + context->int_cycle = context->int_pulse_start < context->int_enable_cycle ? context->int_enable_cycle : context->int_pulse_start; + } else { + context->int_cycle = CYCLE_NEVER; + } + context->target_cycle = context->sync_cycle < context->int_cycle ? context->sync_cycle : context->int_cycle; + dprintf("Running Z80 from cycle %d to cycle %d. Int cycle: %d\n", context->current_cycle, context->sync_cycle, context->int_cycle); + context->options->run(context); + dprintf("Z80 ran to cycle %d\n", context->current_cycle); + } + if (context->busreq) { + context->busack = 1; + context->current_cycle = target_cycle; + } + } + } +} + +void z80_assert_reset(z80_context * context, uint32_t cycle) +{ + z80_run(context, cycle); + context->reset = 1; } -void z80_reset(z80_context * context) +void z80_clear_reset(z80_context * context, uint32_t cycle) +{ + z80_run(context, cycle); + if (context->reset) { + //TODO: Handle case where reset is not asserted long enough + context->im = 0; + context->iff1 = context->iff2 = 0; + context->native_pc = NULL; + context->extra_pc = NULL; + context->pc = 0; + context->reset = 0; + } +} + +void z80_assert_busreq(z80_context * context, uint32_t cycle) +{ + z80_run(context, cycle); + context->busreq = 1; +} + +void z80_clear_busreq(z80_context * context, uint32_t cycle) +{ + z80_run(context, cycle); + context->busreq = 0; + context->busack = 0; +} + +uint8_t z80_get_busack(z80_context * context, uint32_t cycle) { - context->im = 0; - context->iff1 = context->iff2 = 0; - context->native_pc = z80_get_native_address_trans(context, 0); - context->extra_pc = NULL; + z80_run(context, cycle); + return context->busack; +} + +void z80_adjust_cycles(z80_context * context, uint32_t deduction) +{ + if (context->current_cycle < deduction) { + fprintf(stderr, "WARNING: Deduction of %u cycles when Z80 cycle counter is only %u\n", deduction, context->current_cycle); + context->current_cycle = 0; + } else { + context->current_cycle -= deduction; + } + if (context->int_enable_cycle != CYCLE_NEVER) { + if (context->int_enable_cycle < deduction) { + context->int_enable_cycle = 0; + } else { + context->int_enable_cycle -= deduction; + } + } + if (context->int_pulse_start != CYCLE_NEVER) { + if (context->int_pulse_end < deduction) { + context->int_pulse_start = context->int_pulse_end = CYCLE_NEVER; + } else { + context->int_pulse_end -= deduction; + if (context->int_pulse_start < deduction) { + context->int_pulse_start = 0; + } else { + context->int_pulse_start -= deduction; + } + } + } } uint32_t zbreakpoint_patch(z80_context * context, uint16_t address, code_ptr dst)