Mercurial > repos > blastem
comparison m68k_core_x86.c @ 1585:15116d4fdf40
Fix cycle counts for BCD instructions, RESET, and MOVE from SR
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Fri, 18 May 2018 19:00:10 -0700 |
parents | e01adbe1a75b |
children | 37afb9cf58be |
comparison
equal
deleted
inserted
replaced
1584:e01adbe1a75b | 1585:15116d4fdf40 |
---|---|
1188 } | 1188 } |
1189 | 1189 |
1190 void translate_m68k_reset(m68k_options *opts, m68kinst *inst) | 1190 void translate_m68k_reset(m68k_options *opts, m68kinst *inst) |
1191 { | 1191 { |
1192 code_info *code = &opts->gen.code; | 1192 code_info *code = &opts->gen.code; |
1193 cycles(&opts->gen, BUS); | 1193 //RESET instructions take a long time to give peripherals time to reset themselves |
1194 cycles(&opts->gen, 132); | |
1194 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, reset_handler), opts->gen.scratch1, SZ_PTR); | 1195 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, reset_handler), opts->gen.scratch1, SZ_PTR); |
1195 cmp_ir(code, 0, opts->gen.scratch1, SZ_PTR); | 1196 cmp_ir(code, 0, opts->gen.scratch1, SZ_PTR); |
1196 code_ptr no_reset_handler = code->cur + 1; | 1197 code_ptr no_reset_handler = code->cur + 1; |
1197 jcc(code, CC_Z, code->cur+2); | 1198 jcc(code, CC_Z, code->cur+2); |
1198 call(code, opts->gen.save_context); | 1199 call(code, opts->gen.save_context); |
1492 } | 1493 } |
1493 if (inst->dst.addr_mode != MODE_REG && inst->dst.addr_mode != MODE_AREG && inst->dst.addr_mode != MODE_AREG_PREDEC) { | 1494 if (inst->dst.addr_mode != MODE_REG && inst->dst.addr_mode != MODE_AREG && inst->dst.addr_mode != MODE_AREG_PREDEC) { |
1494 //destination is in memory so we need to preserve scratch2 for the write at the end | 1495 //destination is in memory so we need to preserve scratch2 for the write at the end |
1495 push_r(code, opts->gen.scratch2); | 1496 push_r(code, opts->gen.scratch2); |
1496 } | 1497 } |
1498 //MC68000 User's Manual suggests NBCD hides the 2 cycle penalty during the write cycle somehow | |
1499 cycles(&opts->gen, inst->op == M68K_NBCD && inst->dst.addr_mode != MODE_REG_DIRECT ? BUS : BUS + 2); | |
1497 uint8_t other_reg; | 1500 uint8_t other_reg; |
1498 //WARNING: This may need adjustment if register assignments change | 1501 //WARNING: This may need adjustment if register assignments change |
1499 if (opts->gen.scratch2 > RBX) { | 1502 if (opts->gen.scratch2 > RBX) { |
1500 other_reg = RAX; | 1503 other_reg = RAX; |
1501 xchg_rr(code, opts->gen.scratch2, RAX, SZ_D); | 1504 xchg_rr(code, opts->gen.scratch2, RAX, SZ_D); |
2438 } | 2441 } |
2439 | 2442 |
2440 void translate_m68k_move_from_sr(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op) | 2443 void translate_m68k_move_from_sr(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op) |
2441 { | 2444 { |
2442 code_info *code = &opts->gen.code; | 2445 code_info *code = &opts->gen.code; |
2446 cycles(&opts->gen, inst->dst.addr_mode == MODE_REG_DIRECT ? BUS+2 : BUS); | |
2443 call(code, opts->get_sr); | 2447 call(code, opts->get_sr); |
2444 if (dst_op->mode == MODE_REG_DIRECT) { | 2448 if (dst_op->mode == MODE_REG_DIRECT) { |
2445 mov_rr(code, opts->gen.scratch1, dst_op->base, SZ_W); | 2449 mov_rr(code, opts->gen.scratch1, dst_op->base, SZ_W); |
2446 } else { | 2450 } else { |
2447 mov_rrdisp(code, opts->gen.scratch1, dst_op->base, dst_op->disp, SZ_W); | 2451 mov_rrdisp(code, opts->gen.scratch1, dst_op->base, dst_op->disp, SZ_W); |