changeset 335:14a937097c2b

Some Z80 interrupt fixes
author Mike Pavone <pavone@retrodev.com>
date Tue, 14 May 2013 21:59:56 -0700
parents 4c91470e1a53
children 87b65e5ce1ab
files blastem.c z80_to_x86.c z80_to_x86.h zruntime.S
diffstat 4 files changed, 7 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/blastem.c	Tue May 14 00:46:34 2013 -0700
+++ b/blastem.c	Tue May 14 21:59:56 2013 -0700
@@ -170,8 +170,8 @@
 		z_context->sync_cycle = mclks / MCLKS_PER_Z80;
 		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->current_cycle < ZVINT_CYCLE) {
-				z_context->int_cycle = vint_cycle;
+			if (z_context->iff1 && z_context->current_cycle < vint_cycle) {
+				z_context->int_cycle = vint_cycle < z_context->int_enable_cycle ? z_context->int_enable_cycle : vint_cycle;
 			}
 			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. Native PC: %p\n", z_context->current_cycle, z_context->sync_cycle, z_context->native_pc);
--- a/z80_to_x86.c	Tue May 14 00:46:34 2013 -0700
+++ b/z80_to_x86.c	Tue May 14 21:59:56 2013 -0700
@@ -893,8 +893,11 @@
 	case Z80_EI:
 		//TODO: Implement interrupt enable latency of 1 instruction afer EI
 		dst = zcycles(dst, 4);
+		dst = mov_rrdisp8(dst, ZCYCLES, CONTEXT, offsetof(z80_context, int_enable_cycle), SZ_D);
 		dst = mov_irdisp8(dst, 1, CONTEXT, offsetof(z80_context, iff1), SZ_B);
 		dst = mov_irdisp8(dst, 1, CONTEXT, offsetof(z80_context, iff2), SZ_B);
+		//interrupt enable has a one-instruction latency, minimum instruction duration is 4 cycles
+		dst = add_irdisp8(dst, 4, CONTEXT, offsetof(z80_context, int_enable_cycle), SZ_D);
 		dst = call(dst, (uint8_t *)z80_do_sync);
 		break;
 	case Z80_IM:
--- a/z80_to_x86.h	Tue May 14 00:46:34 2013 -0700
+++ b/z80_to_x86.h	Tue May 14 21:59:56 2013 -0700
@@ -49,6 +49,7 @@
 	void *            options;
 	void *            system;
 	uint8_t           ram_code_flags[(8 * 1024)/128/8];
+	uint32_t          int_enable_cycle;
 } z80_context;
 
 void translate_z80_stream(z80_context * context, uint32_t address);
--- a/zruntime.S	Tue May 14 00:46:34 2013 -0700
+++ b/zruntime.S	Tue May 14 21:59:56 2013 -0700
@@ -38,6 +38,7 @@
 	cmp 116(%rsi), %ebp
 	jb zskip_int
 	mov 112(%rsi), %ebp /* set cycle limit to sync cycle */
+	movl $0xFFFFFFFF, 116(%rsi) /* make sure the interrupt doesn't fire more than once */
 	add $7, %ebp
 	sub $2, %r9w
 	mov %r9w, %r14w