summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Pavone <pavone@retrodev.com>2014-06-21 09:36:15 -0700
committerMichael Pavone <pavone@retrodev.com>2014-06-21 09:36:15 -0700
commit24d56647b3b2baa4e7016ac5d66c0167d51688be (patch)
tree5f0c25ef2d9bf2f84a5a0649c59eae0dc0b58716
parent4c06b02583a69756a7cdf6561c0760087eb642ec (diff)
Fix Z80 interrupts
-rw-r--r--blastem.c35
-rw-r--r--z80_to_x86.c2
-rw-r--r--z80_to_x86.h2
3 files changed, 36 insertions, 3 deletions
diff --git a/blastem.c b/blastem.c
index 15f7932..18e11b6 100644
--- a/blastem.c
+++ b/blastem.c
@@ -190,10 +190,14 @@ void sync_z80(z80_context * z_context, uint32_t mclks)
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 @@ m68k_context * sync_components(m68k_context * context, uint32_t address)
} 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 --git a/z80_to_x86.c b/z80_to_x86.c
index a714991..c46bed8 100644
--- a/z80_to_x86.c
+++ b/z80_to_x86.c
@@ -2022,6 +2022,8 @@ void init_z80_context(z80_context * context, x86_z80_options * options)
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 --git a/z80_to_x86.h b/z80_to_x86.h
index fc30179..fdf7866 100644
--- a/z80_to_x86.h
+++ b/z80_to_x86.h
@@ -56,6 +56,8 @@ typedef struct {
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;