summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Pavone <pavone@retrodev.com>2017-10-19 03:21:24 -0700
committerMichael Pavone <pavone@retrodev.com>2017-10-19 03:21:24 -0700
commit15b6f9038a33cdab77f7fe380d6f41fd284fd9c5 (patch)
tree0b150350de9e69c834b0d8ab47f5adb7d3c5f8a9
parent65de831ad38f0846261f3dd3fbab787234d45627 (diff)
Implemented Z80 IM 2 and attempted correct intack cycle delay
-rw-r--r--genesis.c1
-rw-r--r--z80_to_x86.c30
-rw-r--r--z80_to_x86.h1
3 files changed, 31 insertions, 1 deletions
diff --git a/genesis.c b/genesis.c
index bc07662..4514b9e 100644
--- a/genesis.c
+++ b/genesis.c
@@ -242,6 +242,7 @@ static void z80_next_int_pulse(z80_context * z_context)
genesis_context * gen = z_context->system;
z_context->int_pulse_start = vdp_next_vint_z80(gen->vdp);
z_context->int_pulse_end = z_context->int_pulse_start + Z80_INT_PULSE_MCLKS;
+ z_context->im2_vector = 0xFF;
}
static void sync_z80(z80_context * z_context, uint32_t mclks)
diff --git a/z80_to_x86.c b/z80_to_x86.c
index b88b3ba..6e9629c 100644
--- a/z80_to_x86.c
+++ b/z80_to_x86.c
@@ -3454,15 +3454,43 @@ void init_z80_opts(z80_options * options, memmap_chunk const * chunks, uint32_t
cmp_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, int_is_nmi), SZ_B);
is_nmi = code->cur + 1;
jcc(code, CC_NZ, is_nmi);
- //TODO: Support interrupt mode 0 and 2
+ cycles(&options->gen, 6); //interupt ack cycle
+ //TODO: Support interrupt mode 0, not needed for Genesis sit it seems to read $FF during intack
+ //which is conveniently rst $38, i.e. the same thing that im 1 does
+ //check interrupt mode
+ cmp_irdisp(code, 2, options->gen.context_reg, offsetof(z80_context, im), SZ_B);
+ code_ptr im2 = code->cur + 1;
+ jcc(code, CC_Z, im2);
mov_ir(code, 0x38, options->gen.scratch1, SZ_W);
code_ptr after_int_dest = code->cur + 1;
jmp(code, after_int_dest);
+ *im2 = code->cur - (im2 + 1);
+ //read vector address from I << 8 | vector
+ mov_rdispr(code, options->gen.context_reg, offsetof(z80_context, regs) + Z80_I, options->gen.scratch1, SZ_B);
+ shl_ir(code, 8, options->gen.scratch1, SZ_W);
+ movzx_rdispr(code, options->gen.context_reg, offsetof(z80_context, im2_vector), options->gen.scratch2, SZ_B, SZ_W);
+ or_rr(code, options->gen.scratch2, options->gen.scratch1, SZ_W);
+ push_r(code, options->gen.scratch1);
+ cycles(&options->gen, 3);
+ call(code, options->read_8_noinc);
+ pop_r(code, options->gen.scratch2);
+ push_r(code, options->gen.scratch1);
+ mov_rr(code, options->gen.scratch2, options->gen.scratch1, SZ_W);
+ add_ir(code, 1, options->gen.scratch1, SZ_W);
+ cycles(&options->gen, 3);
+ call(code, options->read_8_noinc);
+ pop_r(code, options->gen.scratch2);
+ shl_ir(code, 8, options->gen.scratch1, SZ_W);
+ movzx_rr(code, options->gen.scratch2, options->gen.scratch2, SZ_B, SZ_W);
+ or_rr(code, options->gen.scratch2, options->gen.scratch1, SZ_W);
+ code_ptr after_int_dest2 = code->cur + 1;
+ jmp(code, after_int_dest2);
*is_nmi = code->cur - (is_nmi + 1);
mov_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, int_is_nmi), SZ_B);
mov_irdisp(code, CYCLE_NEVER, options->gen.context_reg, offsetof(z80_context, nmi_start), SZ_D);
mov_ir(code, 0x66, options->gen.scratch1, SZ_W);
*after_int_dest = code->cur - (after_int_dest + 1);
+ *after_int_dest2 = code->cur - (after_int_dest2 + 1);
call(code, options->native_addr);
mov_rrind(code, options->gen.scratch1, options->gen.context_reg, SZ_PTR);
tmp_stack_off = code->stack_off;
diff --git a/z80_to_x86.h b/z80_to_x86.h
index 0a1f09c..85626de 100644
--- a/z80_to_x86.h
+++ b/z80_to_x86.h
@@ -87,6 +87,7 @@ struct z80_context {
uint8_t busreq;
uint8_t busack;
uint8_t int_is_nmi;
+ uint8_t im2_vector;
uint8_t ram_code_flags[];
};