changeset 1471:2e6320d261ff

Implemented Z80 IM 2 and attempted correct intack cycle delay
author Michael Pavone <pavone@retrodev.com>
date Thu, 19 Oct 2017 03:21:24 -0700
parents 1e3e0205640f
children 152a60c6787e f5d693bd694a ded16f3d7eb4 8f3b6a64b658
files genesis.c z80_to_x86.c z80_to_x86.h
diffstat 3 files changed, 31 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/genesis.c	Sat Oct 14 05:03:38 2017 -0700
+++ b/genesis.c	Thu Oct 19 03:21:24 2017 -0700
@@ -242,6 +242,7 @@
 	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)
--- a/z80_to_x86.c	Sat Oct 14 05:03:38 2017 -0700
+++ b/z80_to_x86.c	Thu Oct 19 03:21:24 2017 -0700
@@ -3454,15 +3454,43 @@
 	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;
--- a/z80_to_x86.h	Sat Oct 14 05:03:38 2017 -0700
+++ b/z80_to_x86.h	Thu Oct 19 03:21:24 2017 -0700
@@ -87,6 +87,7 @@
 	uint8_t           busreq;
 	uint8_t           busack;
 	uint8_t           int_is_nmi;
+	uint8_t           im2_vector;
 	uint8_t           ram_code_flags[];
 };