changeset 420:9fb111b5641f

Fix access to int_enable_cycle in EI
author Mike Pavone <pavone@retrodev.com>
date Mon, 24 Jun 2013 21:32:25 -0700
parents d1bf9734ce94
children d0cacb4ade0b
files gen_x86.c z80_to_x86.c
diffstat 2 files changed, 55 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/gen_x86.c	Mon Jun 24 21:30:38 2013 -0700
+++ b/gen_x86.c	Mon Jun 24 21:32:25 2013 -0700
@@ -517,6 +517,54 @@
 	return out;
 }
 
+uint8_t * x86_irdisp32(uint8_t * out, uint8_t opcode, uint8_t op_ex, int32_t val, uint8_t dst, int32_t disp, uint8_t size)
+{
+	uint8_t sign_extend = 0;
+	if ((size == SZ_D || size == SZ_Q) && val <= 0x7F && val >= -0x80) {
+		sign_extend = 1;
+		opcode |= BIT_DIR;
+	}
+	if (size == SZ_W) {
+		*(out++) = PRE_SIZE;
+	}
+
+	if (size == SZ_Q || dst >= R8) {
+		*out = PRE_REX;
+		if (size == SZ_Q) {
+			*out |= REX_QUAD;
+		}
+		if (dst >= R8) {
+			*out |= REX_RM_FIELD;
+			dst -= (R8 - X86_R8);
+		}
+		out++;
+	}
+	if (size != SZ_B) {
+		opcode |= BIT_SIZE;
+	}
+	*(out++) = opcode;
+	*(out++) = MODE_REG_DISPLACE32 | dst | (op_ex << 3);
+	*(out++) = disp;
+	disp >>= 8;
+	*(out++) = disp;
+	disp >>= 8;
+	*(out++) = disp;
+	disp >>= 8;
+	*(out++) = disp;
+	*(out++) = val;
+	if (size != SZ_B && !sign_extend) {
+		val >>= 8;
+		*(out++) = val;
+		if (size != SZ_W) {
+			val >>= 8;
+			*(out++) = val;
+			val >>= 8;
+			*(out++) = val;
+		}
+	}
+	return out;
+}
+
 
 uint8_t * x86_shiftrot_ir(uint8_t * out, uint8_t op_ex, uint8_t val, uint8_t dst, uint8_t size)
 {
@@ -781,6 +829,11 @@
 	return x86_irdisp8(out, OP_IMMED_ARITH, OP_EX_ADDI, val, dst_base, disp, size);
 }
 
+uint8_t * add_irdisp32(uint8_t * out, int32_t val, uint8_t dst_base, int32_t disp, uint8_t size)
+{
+	return x86_irdisp32(out, OP_IMMED_ARITH, OP_EX_ADDI, val, dst_base, disp, size);
+}
+
 uint8_t * add_rrdisp8(uint8_t * out, uint8_t src, uint8_t dst_base, int8_t disp, uint8_t size)
 {
 	return x86_rrdisp8_sizedir(out, OP_ADD, src, dst_base, disp, size, 0);
--- a/z80_to_x86.c	Mon Jun 24 21:30:38 2013 -0700
+++ b/z80_to_x86.c	Mon Jun 24 21:32:25 2013 -0700
@@ -901,11 +901,11 @@
 		break;
 	case Z80_EI:
 		dst = zcycles(dst, 4);
-		dst = mov_rrdisp8(dst, ZCYCLES, CONTEXT, offsetof(z80_context, int_enable_cycle), SZ_D);
+		dst = mov_rrdisp32(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 = add_irdisp32(dst, 4, CONTEXT, offsetof(z80_context, int_enable_cycle), SZ_D);
 		dst = call(dst, (uint8_t *)z80_do_sync);
 		break;
 	case Z80_IM: