# HG changeset patch # User Michael Pavone # Date 1403368575 25200 # Node ID 04157869332921b21b41e0c210f80a967896f1e8 # Parent c5820734a5b6130dd29772ea80dd5a1823e19039 Fix Z80 interrupts diff -r c5820734a5b6 -r 041578693329 blastem.c --- a/blastem.c Fri Jun 20 07:57:32 2014 -0700 +++ b/blastem.c Sat Jun 21 09:36:15 2014 -0700 @@ -190,10 +190,14 @@ z80_reset(z_context); need_reset = 0; } - uint32_t vint_cycle = vdp_next_vint_z80(gen->vdp) / MCLKS_PER_Z80; + while (z_context->current_cycle < z_context->sync_cycle) { - if (z_context->iff1 && z_context->int_cycle == CYCLE_NEVER && z_context->current_cycle < (vint_cycle + Z80_VINT_DURATION)) { - z_context->int_cycle = vint_cycle < z_context->int_enable_cycle ? z_context->int_enable_cycle : vint_cycle; + if (z_context->int_pulse_end < z_context->current_cycle || z_context->int_pulse_end == CYCLE_NEVER) { + z_context->int_pulse_start = vdp_next_vint_z80(gen->vdp) / MCLKS_PER_Z80; + z_context->int_pulse_end = z_context->int_pulse_start + Z80_VINT_DURATION; + } + 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; } 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); @@ -269,6 +273,31 @@ } else { z_context->current_cycle = 0; } + if (z_context->int_cycle != CYCLE_NEVER) { + if (z_context->int_cycle >= mclk_target/MCLKS_PER_Z80) { + z_context->int_cycle -= mclk_target/MCLKS_PER_Z80; + } else { + z_context->int_cycle = 0; + } + } + if (z_context->int_pulse_start != CYCLE_NEVER) { + if (z_context->int_pulse_end >= mclk_target/MCLKS_PER_Z80) { + z_context->int_pulse_end -= mclk_target/MCLKS_PER_Z80; + if (z_context->int_pulse_start >= mclk_target/MCLKS_PER_Z80) { + z_context->int_pulse_start -= mclk_target/MCLKS_PER_Z80; + } else { + z_context->int_pulse_start = 0; + } + } + } else { + z_context->int_pulse_start = CYCLE_NEVER; + z_context->int_pulse_end = CYCLE_NEVER; + } + if (z_context->int_enable_cycle >= mclk_target/MCLKS_PER_Z80) { + z_context->int_enable_cycle -= mclk_target/MCLKS_PER_Z80; + } else { + z_context->int_enable_cycle = 0; + } if (mclks) { vdp_run_context(v_context, mclks); } diff -r c5820734a5b6 -r 041578693329 z80_to_x86.c --- a/z80_to_x86.c Fri Jun 20 07:57:32 2014 -0700 +++ b/z80_to_x86.c Sat Jun 21 09:36:15 2014 -0700 @@ -2022,6 +2022,8 @@ 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; } void z80_reset(z80_context * context) diff -r c5820734a5b6 -r 041578693329 z80_to_x86.h --- a/z80_to_x86.h Fri Jun 20 07:57:32 2014 -0700 +++ b/z80_to_x86.h Sat Jun 21 09:36:15 2014 -0700 @@ -56,6 +56,8 @@ uint8_t ram_code_flags[(8 * 1024)/128/8]; uint32_t int_enable_cycle; uint16_t pc; + uint32_t int_pulse_start; + uint32_t int_pulse_end; uint8_t breakpoint_flags[(16 * 1024)/sizeof(uint8_t)]; uint8_t * bp_handler; uint8_t * bp_stub;