summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Pavone <pavone@retrodev.com>2015-05-22 23:49:32 -0700
committerMichael Pavone <pavone@retrodev.com>2015-05-22 23:49:32 -0700
commit057e8fb32092e1c1c642791cf915c2522b5662e0 (patch)
treeac0fbfb841c64651d6da61af2b8cc2221a503f1c
parenteb8ad570f140b57480ba8ce28819d7cd68d6548e (diff)
Don't attempt to translate or map code at odd addresses. This fixes a bug that shows up when playing College Footbal USA 96
-rw-r--r--m68k_core.c30
-rw-r--r--m68k_core.h1
-rw-r--r--m68k_core_x86.c11
-rw-r--r--m68k_internal.h2
4 files changed, 28 insertions, 16 deletions
diff --git a/m68k_core.c b/m68k_core.c
index 8bf9582..5d88a2d 100644
--- a/m68k_core.c
+++ b/m68k_core.c
@@ -195,7 +195,7 @@ void push_const(m68k_options *opts, int32_t value)
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 @@ void translate_m68k_rte(m68k_options *opts, m68kinst *inst)
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_address(native_map_slot * native_code_map, uint32_t address)
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 @@ void translate_m68k_stream(uint32_t address, m68k_context * context)
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 @@ void translate_m68k_stream(uint32_t address, m68k_context * context)
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 @@ void * m68k_retranslate_inst(uint32_t address, m68k_context * context)
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 @@ void * m68k_retranslate_inst(uint32_t address, m68k_context * context)
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 --git a/m68k_core.h b/m68k_core.h
index 2635a09..b91a37b 100644
--- a/m68k_core.h
+++ b/m68k_core.h
@@ -34,6 +34,7 @@ typedef struct {
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 --git a/m68k_core_x86.c b/m68k_core_x86.c
index 2792bc6..62588b7 100644
--- a/m68k_core_x86.c
+++ b/m68k_core_x86.c
@@ -801,7 +801,7 @@ void translate_m68k_bcc(m68k_options * opts, m68kinst * inst)
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 @@ m68k_context * m68k_handle_code_write(uint32_t address, m68k_context * context)
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 @@ void init_m68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chu
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 --git a/m68k_internal.h b/m68k_internal.h
index 755fd99..13b7c15 100644
--- a/m68k_internal.h
+++ b/m68k_internal.h
@@ -46,7 +46,7 @@ void m68k_save_result(m68kinst * inst, m68k_options * opts);
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);