summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--m68k_core.c12
-rw-r--r--m68k_core.h1
-rw-r--r--m68k_core_x86.c52
3 files changed, 56 insertions, 9 deletions
diff --git a/m68k_core.c b/m68k_core.c
index f2817cf..69cd94d 100644
--- a/m68k_core.c
+++ b/m68k_core.c
@@ -702,6 +702,17 @@ void m68k_handle_deferred(m68k_context * context)
}
}
+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 @@ void translate_m68k(m68k_options * opts, m68kinst * inst)
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);
diff --git a/m68k_core.h b/m68k_core.h
index 204ba44..3b62eda 100644
--- a/m68k_core.h
+++ b/m68k_core.h
@@ -79,6 +79,7 @@ void insert_breakpoint(m68k_context * context, uint32_t address, uint8_t * bp_ha
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_
diff --git a/m68k_core_x86.c b/m68k_core_x86.c
index 2533452..9c082e5 100644
--- a/m68k_core_x86.c
+++ b/m68k_core_x86.c
@@ -2145,8 +2145,15 @@ void translate_m68k_odd(m68k_options *opts, m68kinst *inst)
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 @@ void translate_m68k_odd(m68k_options *opts, m68kinst *inst)
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 @@ void init_m68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chu
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 @@ void init_m68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chu
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 @@ void init_m68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chu
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 @@ void init_m68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chu
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);