changeset 726:7367b14ac01c

Don't attempt to translate or map code at odd addresses. This fixes a bug that shows up when playing College Footbal USA 96
author Michael Pavone <pavone@retrodev.com>
date Fri, 22 May 2015 23:49:32 -0700
parents a92ca6f0ed83
children 59a98179d3ba
files m68k_core.c m68k_core.h m68k_core_x86.c m68k_internal.h
diffstat 4 files changed, 28 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/m68k_core.c	Fri May 22 21:11:41 2015 -0700
+++ b/m68k_core.c	Fri May 22 23:49:32 2015 -0700
@@ -195,7 +195,7 @@
 void jump_m68k_abs(m68k_options * opts, uint32_t address)
 {
 	code_info *code = &opts->gen.code;
-	code_ptr dest_addr = get_native_address(opts->gen.native_code_map, address);
+	code_ptr dest_addr = get_native_address(opts, address);
 	if (!dest_addr) {
 		opts->gen.deferred = defer_address(opts->gen.deferred, address, code->cur + 1);
 		//dummy address to be replaced later, make sure it generates a 4-byte displacement
@@ -551,10 +551,13 @@
 	jmp_r(code, opts->gen.scratch1);
 }
 
-code_ptr get_native_address(native_map_slot * native_code_map, uint32_t address)
+code_ptr get_native_address(m68k_options *opts, uint32_t address)
 {
-	//FIXME: Use opts->gen.address_mask
-	address &= 0xFFFFFF;
+	native_map_slot * native_code_map = opts->gen.native_code_map;
+	address &= opts->gen.address_mask;
+	if (address & 1) {
+		return opts->odd_address;
+	}
 	address /= 2;
 	uint32_t chunk = address / NATIVE_CHUNK_SIZE;
 	if (!native_code_map[chunk].base) {
@@ -569,7 +572,7 @@
 
 code_ptr get_native_from_context(m68k_context * context, uint32_t address)
 {
-	return get_native_address(context->native_code_map, address);
+	return get_native_address(context->options, address);
 }
 
 uint32_t get_instruction_start(native_map_slot * native_code_map, uint32_t address)
@@ -837,7 +840,7 @@
 	m68kinst instbuf;
 	m68k_options * opts = context->options;
 	code_info *code = &opts->gen.code;
-	if(get_native_address(opts->gen.native_code_map, address)) {
+	if(get_native_address(opts, address)) {
 		return;
 	}
 	uint16_t *encoded, *next;
@@ -847,13 +850,16 @@
 			fflush(opts->address_log);
 		}
 		do {
+			if (address & 1) {
+				break;
+			}
 			encoded = get_native_pointer(address, (void **)context->mem_pointers, &opts->gen);
 			if (!encoded) {
 				map_native_address(context, address, code->cur, 2, 1);
 				translate_out_of_bounds(code);
 				break;
 			}
-			code_ptr existing = get_native_address(opts->gen.native_code_map, address);
+			code_ptr existing = get_native_address(opts, address);
 			if (existing) {
 				jmp(code, existing);
 				break;
@@ -887,7 +893,7 @@
 	m68k_options * opts = context->options;
 	code_info *code = &opts->gen.code;
 	uint8_t orig_size = get_native_inst_size(opts, address);
-	code_ptr orig_start = get_native_address(context->native_code_map, address);
+	code_ptr orig_start = get_native_address(context->options, address);
 	uint32_t orig = address;
 	code_info orig_code;
 	orig_code.cur = orig_start;
@@ -961,19 +967,17 @@
 
 code_ptr get_native_address_trans(m68k_context * context, uint32_t address)
 {
-	//FIXME: Use opts->gen.address_mask
-	address &= 0xFFFFFF;
-	code_ptr ret = get_native_address(context->native_code_map, address);
+	code_ptr ret = get_native_address(context->options, address);
 	if (!ret) {
 		translate_m68k_stream(address, context);
-		ret = get_native_address(context->native_code_map, address);
+		ret = get_native_address(context->options, address);
 	}
 	return ret;
 }
 
 void remove_breakpoint(m68k_context * context, uint32_t address)
 {
-	code_ptr native = get_native_address(context->native_code_map, address);
+	code_ptr native = get_native_address(context->options, address);
 	code_info tmp = context->options->gen.code;
 	context->options->gen.code.cur = native;
 	context->options->gen.code.last = native + MAX_NATIVE_SIZE;
--- a/m68k_core.h	Fri May 22 21:11:41 2015 -0700
+++ b/m68k_core.h	Fri May 22 23:49:32 2015 -0700
@@ -34,6 +34,7 @@
 	code_ptr        write_32_highfirst;
 	code_ptr        do_sync;
 	code_ptr        trap;
+	code_ptr        odd_address;
 	start_fun       start_context;
 	code_ptr        retrans_stub;
 	code_ptr        native_addr;
--- a/m68k_core_x86.c	Fri May 22 21:11:41 2015 -0700
+++ b/m68k_core_x86.c	Fri May 22 23:49:32 2015 -0700
@@ -801,7 +801,7 @@
 	if (inst->extra.cond == COND_TRUE) {
 		jump_m68k_abs(opts, after + disp);
 	} else {
-		code_ptr dest_addr = get_native_address(opts->gen.native_code_map, after + disp);
+		code_ptr dest_addr = get_native_address(opts, after + disp);
 		uint8_t cond = m68k_eval_cond(opts, inst->extra.cond);
 		if (!dest_addr) {
 			opts->gen.deferred = defer_address(opts->gen.deferred, after + disp, code->cur + 2);
@@ -2089,7 +2089,7 @@
 	if (inst_start) {
 		m68k_options * options = context->options;
 		code_info *code = &options->gen.code;
-		code_ptr dst = get_native_address(context->native_code_map, inst_start);
+		code_ptr dst = get_native_address(context->options, inst_start);
 		code_info orig;
 		orig.cur = dst;
 		orig.last = dst + 128;
@@ -2475,4 +2475,11 @@
 	call(code, opts->native_addr_and_sync);
 	cycles(&opts->gen, 18);
 	jmp_r(code, opts->gen.scratch1);
+	
+	opts->odd_address = code->cur;
+	mov_ir(code, (int64_t)stderr, RDI, SZ_PTR);
+	mov_ir(code, (int64_t)"Attempt to execute code at odd address\n", RSI, SZ_PTR);
+	call_args_abi(code, (code_ptr)fprintf, 2, RDI, RSI, RDX);
+	xor_rr(code, RDI, RDI, SZ_D);
+	call_args(code, (code_ptr)exit, 1, RDI);
 }
--- a/m68k_internal.h	Fri May 22 21:11:41 2015 -0700
+++ b/m68k_internal.h	Fri May 22 23:49:32 2015 -0700
@@ -46,7 +46,7 @@
 void push_const(m68k_options *opts, int32_t value);
 void jump_m68k_abs(m68k_options * opts, uint32_t address);
 void swap_ssp_usp(m68k_options * opts);
-code_ptr get_native_address(native_map_slot * native_code_map, uint32_t address);
+code_ptr get_native_address(m68k_options *opts, uint32_t address);
 void map_native_address(m68k_context * context, uint32_t address, code_ptr native_addr, uint8_t size, uint8_t native_size);
 uint8_t get_native_inst_size(m68k_options * opts, uint32_t address);
 uint8_t m68k_is_terminal(m68kinst * inst);