changeset 989:d70000fdff0b

Implemented IR and undefined bits of info word for address error exception frames
author Michael Pavone <pavone@retrodev.com>
date Wed, 27 Apr 2016 21:39:17 -0700
parents ce9df7a5fdf2
children 33a46d35b913
files m68k_core.c m68k_core.h m68k_core_x86.c
diffstat 3 files changed, 56 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/m68k_core.c	Wed Apr 27 19:10:50 2016 -0700
+++ b/m68k_core.c	Wed Apr 27 21:39:17 2016 -0700
@@ -702,6 +702,17 @@
 	}
 }
 
+uint16_t m68k_get_ir(m68k_context *context)
+{
+	uint32_t inst_addr = get_instruction_start(context->options, context->native_code_map, context->last_prefetch_address-2);
+	uint16_t *native_addr = get_native_pointer(inst_addr, (void **)context->mem_pointers, &context->options->gen);
+	if (native_addr) {
+		return *native_addr;
+	}
+	fprintf(stderr, "M68K: Failed to calculate value of IR. Last prefetch address: %X\n", context->last_prefetch_address);
+	return 0xFFFF;
+}
+
 typedef enum {
 	RAW_FUNC = 1,
 	BINARY_ARITH,
@@ -826,6 +837,7 @@
 	if (
 		(inst->src.addr_mode > MODE_AREG && inst->src.addr_mode < MODE_IMMEDIATE) 
 		|| (inst->dst.addr_mode > MODE_AREG && inst->dst.addr_mode < MODE_IMMEDIATE)
+		|| (inst->op == M68K_BCC && (inst->src.params.immed & 1))
 	) {
 		//Not accurate for all cases, but probably good enough for now
 		m68k_set_last_prefetch(opts, inst->address + inst->bytes);
--- a/m68k_core.h	Wed Apr 27 19:10:50 2016 -0700
+++ b/m68k_core.h	Wed Apr 27 21:39:17 2016 -0700
@@ -79,6 +79,7 @@
 void remove_breakpoint(m68k_context * context, uint32_t address);
 m68k_context * m68k_handle_code_write(uint32_t address, m68k_context * context);
 uint32_t get_instruction_start(m68k_options *opts, native_map_slot * native_code_map, uint32_t address);
+uint16_t m68k_get_ir(m68k_context *context);
 
 #endif //M68K_CORE_H_
 
--- a/m68k_core_x86.c	Wed Apr 27 19:10:50 2016 -0700
+++ b/m68k_core_x86.c	Wed Apr 27 21:39:17 2016 -0700
@@ -2145,8 +2145,15 @@
 	call(code, opts->write_16);
 	//save instruction register
 	subi_areg(opts, 2, 7);
-	//TODO: Use actual value
-	mov_ir(code, 0, opts->gen.scratch1, SZ_W);
+	//calculate IR
+	push_r(code, opts->gen.context_reg);
+	call(code, opts->gen.save_context);
+	call_args_abi(code, (code_ptr)m68k_get_ir, 1, opts->gen.context_reg);
+	mov_rr(code, RAX, opts->gen.scratch1, SZ_W);
+	pop_r(code, opts->gen.context_reg);
+	push_r(code, RAX); //save it for use in the "info" word
+	call(code, opts->gen.load_context);
+	//write it to the stack
 	areg_to_native(opts, 7, opts->gen.scratch2);
 	call(code, opts->write_16);
 	//save access address
@@ -2162,7 +2169,10 @@
 	and_ir(code, 4, opts->gen.scratch1, SZ_B);
 	//set FC1 to one to indicate instruction fetch, and R/W to indicate read
 	or_ir(code, 0x12, opts->gen.scratch1, SZ_B);
-	//TODO: Figure out what undefined bits get set to, looks like it might be value of IR
+	//set undefined bits to IR value
+	pop_r(code, opts->gen.scratch2);
+	and_ir(code, 0xFFE0, opts->gen.scratch2, SZ_W);
+	or_rr(code, opts->gen.scratch2, opts->gen.scratch1, SZ_W);
 	subi_areg(opts, 2, 7);
 	areg_to_native(opts, 7, opts->gen.scratch2);
 	call(code, opts->write_16);
@@ -2571,8 +2581,17 @@
 	call(code, opts->write_16);
 	//save instruction register
 	subi_areg(opts, 2, 7);
-	//TODO: Use actual value
-	mov_ir(code, 0, opts->gen.scratch1, SZ_W);
+	//calculate IR
+	push_r(code, opts->gen.context_reg);
+	call(code, opts->gen.save_context);
+	call_args_abi(code, (code_ptr)m68k_get_ir, 1, opts->gen.context_reg);
+	mov_rr(code, RAX, opts->gen.scratch1, SZ_W);
+	pop_r(code, opts->gen.context_reg);
+	pop_r(code, opts->gen.scratch2); //access address
+	push_r(code, RAX); //save it for use in the "info" word
+	push_r(code, opts->gen.scratch2); //access address
+	call(code, opts->gen.load_context);
+	//write it to the stack
 	areg_to_native(opts, 7, opts->gen.scratch2);
 	call(code, opts->write_16);
 	//save access address
@@ -2588,7 +2607,10 @@
 	and_ir(code, 4, opts->gen.scratch1, SZ_B);
 	//set FC0 to one to indicate data access
 	or_ir(code, 1, opts->gen.scratch1, SZ_B);
-	//TODO: Figure out what undefined bits get set to, looks like it might be value of IR
+	//set undefined bits to IR value
+	pop_r(code, opts->gen.scratch2);
+	and_ir(code, 0xFFE0, opts->gen.scratch2, SZ_W);
+	or_rr(code, opts->gen.scratch2, opts->gen.scratch1, SZ_W);
 	subi_areg(opts, 2, 7);
 	areg_to_native(opts, 7, opts->gen.scratch2);
 	call(code, opts->write_16);
@@ -2621,8 +2643,17 @@
 	call(code, opts->write_16);
 	//save instruction register
 	subi_areg(opts, 2, 7);
-	//TODO: Use actual value
-	mov_ir(code, 0, opts->gen.scratch1, SZ_W);
+	//calculate IR
+	push_r(code, opts->gen.context_reg);
+	call(code, opts->gen.save_context);
+	call_args_abi(code, (code_ptr)m68k_get_ir, 1, opts->gen.context_reg);
+	mov_rr(code, RAX, opts->gen.scratch1, SZ_W);
+	pop_r(code, opts->gen.context_reg);
+	pop_r(code, opts->gen.scratch2); //access address
+	push_r(code, RAX); //save it for use in the "info" word
+	push_r(code, opts->gen.scratch2); //access address
+	call(code, opts->gen.load_context);
+	//write it to the stack
 	areg_to_native(opts, 7, opts->gen.scratch2);
 	call(code, opts->write_16);
 	//save access address
@@ -2638,7 +2669,10 @@
 	and_ir(code, 4, opts->gen.scratch1, SZ_B);
 	//set FC0 to one to indicate data access, and R/W to indicate read
 	or_ir(code, 0x11, opts->gen.scratch1, SZ_B);
-	//TODO: Figure out what undefined bits get set to, looks like it might be value of IR
+	//set undefined bits to IR value
+	pop_r(code, opts->gen.scratch2);
+	and_ir(code, 0xFFE0, opts->gen.scratch2, SZ_W);
+	or_rr(code, opts->gen.scratch2, opts->gen.scratch1, SZ_W);
 	subi_areg(opts, 2, 7);
 	areg_to_native(opts, 7, opts->gen.scratch2);
 	call(code, opts->write_16);