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);