Mercurial > repos > blastem
diff m68k_core_x86.c @ 1648:b7ecd0d6a77b mame_interp
Merge from default
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Tue, 25 Dec 2018 11:12:26 -0800 |
parents | 15116d4fdf40 |
children | 37afb9cf58be |
line wrap: on
line diff
--- a/m68k_core_x86.c Sun Dec 31 10:11:16 2017 -0800 +++ b/m68k_core_x86.c Tue Dec 25 11:12:26 2018 -0800 @@ -742,27 +742,6 @@ cycles(&opts->gen, BUS); } -void translate_m68k_clr(m68k_options * opts, m68kinst * inst) -{ - code_info *code = &opts->gen.code; - update_flags(opts, N0|V0|C0|Z1); - int8_t reg = native_reg(&(inst->dst), opts); - if (reg >= 0) { - cycles(&opts->gen, (inst->extra.size == OPSIZE_LONG ? 6 : 4)); - xor_rr(code, reg, reg, inst->extra.size); - return; - } - host_ea dst_op; - //TODO: fix timing - translate_m68k_op(inst, &dst_op, opts, 1); - if (dst_op.mode == MODE_REG_DIRECT) { - xor_rr(code, dst_op.base, dst_op.base, inst->extra.size); - } else { - mov_irdisp(code, 0, dst_op.base, dst_op.disp, inst->extra.size); - } - m68k_save_result(inst, opts); -} - void translate_m68k_ext(m68k_options * opts, m68kinst * inst) { code_info *code = &opts->gen.code; @@ -780,6 +759,7 @@ } inst->extra.size = dst_size; update_flags(opts, N|V0|C0|Z); + cycles(&opts->gen, BUS); //M68K EXT only operates on registers so no need for a call to save result here } @@ -1210,7 +1190,8 @@ void translate_m68k_reset(m68k_options *opts, m68kinst *inst) { code_info *code = &opts->gen.code; - cycles(&opts->gen, BUS); + //RESET instructions take a long time to give peripherals time to reset themselves + cycles(&opts->gen, 132); mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, reset_handler), opts->gen.scratch1, SZ_PTR); cmp_ir(code, 0, opts->gen.scratch1, SZ_PTR); code_ptr no_reset_handler = code->cur + 1; @@ -1437,6 +1418,7 @@ { switch(inst->op) { + case M68K_CLR: xor_rr(code, dst, dst, size); break; case M68K_NEG: neg_r(code, dst, size); break; case M68K_NOT: not_r(code, dst, size); cmp_ir(code, 0, dst, size); break; case M68K_ROL: rol_clr(code, dst, size); break; @@ -1452,6 +1434,7 @@ { switch(inst->op) { + case M68K_CLR: mov_irdisp(code, 0, dst, disp, size); break; case M68K_NEG: neg_rdisp(code, dst, disp, size); break; case M68K_NOT: not_rdisp(code, dst, disp, size); cmp_irdisp(code, 0, dst, disp, size); break; case M68K_ROL: rol_clrdisp(code, dst, disp, size); break; @@ -1466,7 +1449,11 @@ void translate_m68k_unary(m68k_options *opts, m68kinst *inst, uint32_t flag_mask, host_ea *dst_op) { code_info *code = &opts->gen.code; - cycles(&opts->gen, BUS); + uint32_t num_cycles = BUS; + if (inst->extra.size == OPSIZE_LONG && (inst->dst.addr_mode == MODE_REG || inst->dst.addr_mode == MODE_AREG)) { + num_cycles += 2; + } + cycles(&opts->gen, num_cycles); if (dst_op->mode == MODE_REG_DIRECT) { op_r(code, inst, dst_op->base, inst->extra.size); } else { @@ -1508,6 +1495,8 @@ //destination is in memory so we need to preserve scratch2 for the write at the end push_r(code, opts->gen.scratch2); } + //MC68000 User's Manual suggests NBCD hides the 2 cycle penalty during the write cycle somehow + cycles(&opts->gen, inst->op == M68K_NBCD && inst->dst.addr_mode != MODE_REG_DIRECT ? BUS : BUS + 2); uint8_t other_reg; //WARNING: This may need adjustment if register assignments change if (opts->gen.scratch2 > RBX) { @@ -2365,7 +2354,7 @@ } code_ptr loop_top = code->cur; call(code, opts->do_sync); - cmp_rr(code, opts->gen.limit, opts->gen.cycles, SZ_D); + cmp_rr(code, opts->gen.cycles, opts->gen.limit, SZ_D); code_ptr normal_cycle_up = code->cur + 1; jcc(code, CC_A, code->cur + 2); cycles(&opts->gen, BUS); @@ -2454,6 +2443,7 @@ void translate_m68k_move_from_sr(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op) { code_info *code = &opts->gen.code; + cycles(&opts->gen, inst->dst.addr_mode == MODE_REG_DIRECT ? BUS+2 : BUS); call(code, opts->get_sr); if (dst_op->mode == MODE_REG_DIRECT) { mov_rr(code, opts->gen.scratch1, dst_op->base, SZ_W);