# HG changeset patch # User Michael Pavone # Date 1432363772 25200 # Node ID 7367b14ac01c27a6c4011275382928059a44f445 # Parent a92ca6f0ed8359f9a03ac5e65705ea808a78cea1 Don't attempt to translate or map code at odd addresses. This fixes a bug that shows up when playing College Footbal USA 96 diff -r a92ca6f0ed83 -r 7367b14ac01c m68k_core.c --- 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; diff -r a92ca6f0ed83 -r 7367b14ac01c m68k_core.h --- 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; diff -r a92ca6f0ed83 -r 7367b14ac01c m68k_core_x86.c --- 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); } diff -r a92ca6f0ed83 -r 7367b14ac01c m68k_internal.h --- 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);