diff options
-rw-r--r-- | m68k_to_x86.c | 75 | ||||
-rw-r--r-- | m68k_to_x86.h | 3 | ||||
-rw-r--r-- | runtime.S | 51 |
3 files changed, 69 insertions, 60 deletions
diff --git a/m68k_to_x86.c b/m68k_to_x86.c index 9c9f658..aef8116 100644 --- a/m68k_to_x86.c +++ b/m68k_to_x86.c @@ -40,9 +40,6 @@ char disasm_buf[1024]; m68k_context * sync_components(m68k_context * context, uint32_t address); void m68k_invalid(); -void set_sr(); -void set_ccr(); -void get_sr(); void bcd_add(); void bcd_sub(); @@ -3379,7 +3376,7 @@ uint8_t * translate_m68k(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) break; case M68K_MOVE_FROM_SR: //TODO: Trap if not in system mode - dst = call(dst, (uint8_t *)get_sr); + dst = call(dst, opts->get_sr); if (dst_op.mode == MODE_REG_DIRECT) { dst = mov_rr(dst, SCRATCH1, dst_op.base, SZ_W); } else { @@ -3415,7 +3412,7 @@ uint8_t * translate_m68k(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) dst = mov_rdisp8r(dst, src_op.base, src_op.disp, SCRATCH1, SZ_W); } } - dst = call(dst, (uint8_t *)(inst->op == M68K_MOVE_SR ? set_sr : set_ccr)); + dst = call(dst, inst->op == M68K_MOVE_SR ? opts->set_sr : opts->set_ccr); dst = cycles(dst, 12); } @@ -3834,7 +3831,7 @@ uint8_t * translate_m68k(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D); dst = call(dst, opts->read_16); dst = add_ir(dst, 2, opts->aregs[7], SZ_D); - dst = call(dst, (uint8_t *)set_sr); + dst = call(dst, opts->set_sr); //Read saved PC dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D); dst = call(dst, opts->read_32); @@ -3856,7 +3853,7 @@ uint8_t * translate_m68k(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D); dst = call(dst, opts->read_16); dst = add_ir(dst, 2, opts->aregs[7], SZ_D); - dst = call(dst, (uint8_t *)set_ccr); + dst = call(dst, opts->set_ccr); //Read saved PC dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D); dst = call(dst, opts->read_32); @@ -4724,6 +4721,66 @@ void init_x86_68k_opts(x86_68k_options * opts, memmap_chunk * memmap, uint32_t n dst = add_ir(dst, 2, SCRATCH2, SZ_D); dst = jmp(dst, opts->write_16); + opts->get_sr = dst; + dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, status), SCRATCH1, SZ_B); + dst = shl_ir(dst, 8, SCRATCH1, SZ_W); + if (opts->flag_regs[FLAG_X] >= 0) { + dst = mov_rr(dst, opts->flag_regs[FLAG_X], SCRATCH1, SZ_B); + } else { + int8_t offset = offsetof(m68k_context, flags); + if (offset) { + dst = mov_rdisp8r(dst, CONTEXT, offset, SCRATCH1, SZ_B); + } else { + dst = mov_rindr(dst, CONTEXT, SCRATCH1, SZ_B); + } + } + for (int flag = FLAG_N; flag <= FLAG_C; flag++) + { + dst = shl_ir(dst, 1, SCRATCH1, SZ_B); + if (opts->flag_regs[flag] >= 0) { + dst = or_rr(dst, opts->flag_regs[flag], SCRATCH1, SZ_B); + } else { + dst = or_rdisp8r(dst, CONTEXT, offsetof(m68k_context, flags) + flag, SCRATCH1, SZ_B); + } + } + dst = retn(dst); + + opts->set_sr = dst; + for (int flag = FLAG_C; flag >= FLAG_X; flag--) + { + dst = rcr_ir(dst, 1, SCRATCH1, SZ_B); + if (opts->flag_regs[flag] >= 0) { + dst = setcc_r(dst, CC_C, opts->flag_regs[flag]); + } else { + int8_t offset = offsetof(m68k_context, flags) + flag; + if (offset) { + dst = setcc_rdisp8(dst, CC_C, CONTEXT, offset); + } else { + dst = setcc_rind(dst, CC_C, CONTEXT); + } + } + } + dst = shr_ir(dst, 8, SCRATCH1, SZ_W); + dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, status), SZ_B); + dst = retn(dst); + + opts->set_ccr = dst; + for (int flag = FLAG_C; flag >= FLAG_X; flag--) + { + dst = rcr_ir(dst, 1, SCRATCH1, SZ_B); + if (opts->flag_regs[flag] >= 0) { + dst = setcc_r(dst, CC_C, opts->flag_regs[flag]); + } else { + int8_t offset = offsetof(m68k_context, flags) + flag; + if (offset) { + dst = setcc_rdisp8(dst, CC_C, CONTEXT, offset); + } else { + dst = setcc_rind(dst, CC_C, CONTEXT); + } + } + } + dst = retn(dst); + opts->handle_cycle_limit_int = dst; dst = cmp_rdisp8r(dst, CONTEXT, offsetof(m68k_context, int_cycle), CYCLES, SZ_D); uint8_t * do_int = dst+1; @@ -4766,7 +4823,7 @@ void init_x86_68k_opts(x86_68k_options * opts, memmap_chunk * memmap, uint32_t n dst = call(dst, opts->write_32_lowfirst); //save status register dst = sub_ir(dst, 2, opts->aregs[7], SZ_D); - dst = call(dst, (uint8_t *)get_sr); + dst = call(dst, opts->get_sr); dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); dst = call(dst, opts->write_16); //update status register @@ -4802,7 +4859,7 @@ void init_x86_68k_opts(x86_68k_options * opts, memmap_chunk * memmap, uint32_t n dst = call(dst, opts->write_32_lowfirst); //save status register dst = sub_ir(dst, 2, opts->aregs[7], SZ_D); - dst = call(dst, (uint8_t *)get_sr); + dst = call(dst, opts->get_sr); dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); dst = call(dst, opts->write_16); //set supervisor bit diff --git a/m68k_to_x86.h b/m68k_to_x86.h index c3a50d7..7fba62c 100644 --- a/m68k_to_x86.h +++ b/m68k_to_x86.h @@ -46,6 +46,9 @@ typedef struct { uint8_t *retrans_stub; uint8_t *native_addr; uint8_t *native_addr_and_sync; + uint8_t *get_sr; + uint8_t *set_sr; + uint8_t *set_ccr; } x86_68k_options; typedef struct { @@ -70,56 +70,5 @@ no_adjust_hs: mov %rdi, %rax ret - .global get_sr -get_sr: - mov 5(%rsi), %cl - shl $8, %cx - mov (%rsi), %cl - shl $1, %cl - or %bl, %cl - shl $1, %cl - or %dl, %cl - shl $1, %cl - or %bh, %cl - shl $1, %cl - or %dh, %cl - ret - - .global set_sr -set_sr: - mov %cl, %dh - and $1, %dh - shr $1, %cl - mov %cl, %bh - and $1, %bh - shr $1, %cl - mov %cl, %dl - and $1, %dl - shr $1, %cl - mov %cl, %bl - and $1, %bl - shr $1, %cl - and $1, %cl - mov %cl, (%rsi) - shr $8, %cx - mov %cl, 5(%rsi) - ret - .global set_ccr -set_ccr: - mov %cl, %dh - and $1, %dh - shr $1, %cl - mov %cl, %bh - and $1, %bh - shr $1, %cl - mov %cl, %dl - and $1, %dl - shr $1, %cl - mov %cl, %bl - and $1, %bl - shr $1, %cl - and $1, %cl - mov %cl, (%rsi) - ret |