comparison m68k_core_x86.c @ 1692:5dacaef602a7 segacd

Merge from default
author Michael Pavone <pavone@retrodev.com>
date Sat, 05 Jan 2019 00:58:08 -0800
parents 15116d4fdf40
children 37afb9cf58be
comparison
equal deleted inserted replaced
1504:95b3a1a8b26c 1692:5dacaef602a7
740 740
741 //add cycles for prefetch 741 //add cycles for prefetch
742 cycles(&opts->gen, BUS); 742 cycles(&opts->gen, BUS);
743 } 743 }
744 744
745 void translate_m68k_clr(m68k_options * opts, m68kinst * inst)
746 {
747 code_info *code = &opts->gen.code;
748 update_flags(opts, N0|V0|C0|Z1);
749 int8_t reg = native_reg(&(inst->dst), opts);
750 if (reg >= 0) {
751 cycles(&opts->gen, (inst->extra.size == OPSIZE_LONG ? 6 : 4));
752 xor_rr(code, reg, reg, inst->extra.size);
753 return;
754 }
755 host_ea dst_op;
756 //TODO: fix timing
757 translate_m68k_op(inst, &dst_op, opts, 1);
758 if (dst_op.mode == MODE_REG_DIRECT) {
759 xor_rr(code, dst_op.base, dst_op.base, inst->extra.size);
760 } else {
761 mov_irdisp(code, 0, dst_op.base, dst_op.disp, inst->extra.size);
762 }
763 m68k_save_result(inst, opts);
764 }
765
766 void translate_m68k_ext(m68k_options * opts, m68kinst * inst) 745 void translate_m68k_ext(m68k_options * opts, m68kinst * inst)
767 { 746 {
768 code_info *code = &opts->gen.code; 747 code_info *code = &opts->gen.code;
769 host_ea dst_op; 748 host_ea dst_op;
770 uint8_t dst_size = inst->extra.size; 749 uint8_t dst_size = inst->extra.size;
778 cmp_ir(code, 0, opts->gen.scratch1, dst_size); 757 cmp_ir(code, 0, opts->gen.scratch1, dst_size);
779 mov_rrdisp(code, opts->gen.scratch1, dst_op.base, dst_op.disp, dst_size); 758 mov_rrdisp(code, opts->gen.scratch1, dst_op.base, dst_op.disp, dst_size);
780 } 759 }
781 inst->extra.size = dst_size; 760 inst->extra.size = dst_size;
782 update_flags(opts, N|V0|C0|Z); 761 update_flags(opts, N|V0|C0|Z);
762 cycles(&opts->gen, BUS);
783 //M68K EXT only operates on registers so no need for a call to save result here 763 //M68K EXT only operates on registers so no need for a call to save result here
784 } 764 }
785 765
786 uint8_t m68k_eval_cond(m68k_options * opts, uint8_t cc) 766 uint8_t m68k_eval_cond(m68k_options * opts, uint8_t cc)
787 { 767 {
1208 } 1188 }
1209 1189
1210 void translate_m68k_reset(m68k_options *opts, m68kinst *inst) 1190 void translate_m68k_reset(m68k_options *opts, m68kinst *inst)
1211 { 1191 {
1212 code_info *code = &opts->gen.code; 1192 code_info *code = &opts->gen.code;
1213 cycles(&opts->gen, BUS); 1193 //RESET instructions take a long time to give peripherals time to reset themselves
1194 cycles(&opts->gen, 132);
1214 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);
1215 cmp_ir(code, 0, opts->gen.scratch1, SZ_PTR); 1196 cmp_ir(code, 0, opts->gen.scratch1, SZ_PTR);
1216 code_ptr no_reset_handler = code->cur + 1; 1197 code_ptr no_reset_handler = code->cur + 1;
1217 jcc(code, CC_Z, code->cur+2); 1198 jcc(code, CC_Z, code->cur+2);
1218 call(code, opts->gen.save_context); 1199 call(code, opts->gen.save_context);
1435 1416
1436 void op_r(code_info *code, m68kinst *inst, uint8_t dst, uint8_t size) 1417 void op_r(code_info *code, m68kinst *inst, uint8_t dst, uint8_t size)
1437 { 1418 {
1438 switch(inst->op) 1419 switch(inst->op)
1439 { 1420 {
1421 case M68K_CLR: xor_rr(code, dst, dst, size); break;
1440 case M68K_NEG: neg_r(code, dst, size); break; 1422 case M68K_NEG: neg_r(code, dst, size); break;
1441 case M68K_NOT: not_r(code, dst, size); cmp_ir(code, 0, dst, size); break; 1423 case M68K_NOT: not_r(code, dst, size); cmp_ir(code, 0, dst, size); break;
1442 case M68K_ROL: rol_clr(code, dst, size); break; 1424 case M68K_ROL: rol_clr(code, dst, size); break;
1443 case M68K_ROR: ror_clr(code, dst, size); break; 1425 case M68K_ROR: ror_clr(code, dst, size); break;
1444 case M68K_ROXL: rcl_clr(code, dst, size); break; 1426 case M68K_ROXL: rcl_clr(code, dst, size); break;
1450 1432
1451 void op_rdisp(code_info *code, m68kinst *inst, uint8_t dst, int32_t disp, uint8_t size) 1433 void op_rdisp(code_info *code, m68kinst *inst, uint8_t dst, int32_t disp, uint8_t size)
1452 { 1434 {
1453 switch(inst->op) 1435 switch(inst->op)
1454 { 1436 {
1437 case M68K_CLR: mov_irdisp(code, 0, dst, disp, size); break;
1455 case M68K_NEG: neg_rdisp(code, dst, disp, size); break; 1438 case M68K_NEG: neg_rdisp(code, dst, disp, size); break;
1456 case M68K_NOT: not_rdisp(code, dst, disp, size); cmp_irdisp(code, 0, dst, disp, size); break; 1439 case M68K_NOT: not_rdisp(code, dst, disp, size); cmp_irdisp(code, 0, dst, disp, size); break;
1457 case M68K_ROL: rol_clrdisp(code, dst, disp, size); break; 1440 case M68K_ROL: rol_clrdisp(code, dst, disp, size); break;
1458 case M68K_ROR: ror_clrdisp(code, dst, disp, size); break; 1441 case M68K_ROR: ror_clrdisp(code, dst, disp, size); break;
1459 case M68K_ROXL: rcl_clrdisp(code, dst, disp, size); break; 1442 case M68K_ROXL: rcl_clrdisp(code, dst, disp, size); break;
1464 } 1447 }
1465 1448
1466 void translate_m68k_unary(m68k_options *opts, m68kinst *inst, uint32_t flag_mask, host_ea *dst_op) 1449 void translate_m68k_unary(m68k_options *opts, m68kinst *inst, uint32_t flag_mask, host_ea *dst_op)
1467 { 1450 {
1468 code_info *code = &opts->gen.code; 1451 code_info *code = &opts->gen.code;
1469 cycles(&opts->gen, BUS); 1452 uint32_t num_cycles = BUS;
1453 if (inst->extra.size == OPSIZE_LONG && (inst->dst.addr_mode == MODE_REG || inst->dst.addr_mode == MODE_AREG)) {
1454 num_cycles += 2;
1455 }
1456 cycles(&opts->gen, num_cycles);
1470 if (dst_op->mode == MODE_REG_DIRECT) { 1457 if (dst_op->mode == MODE_REG_DIRECT) {
1471 op_r(code, inst, dst_op->base, inst->extra.size); 1458 op_r(code, inst, dst_op->base, inst->extra.size);
1472 } else { 1459 } else {
1473 op_rdisp(code, inst, dst_op->base, dst_op->disp, inst->extra.size); 1460 op_rdisp(code, inst, dst_op->base, dst_op->disp, inst->extra.size);
1474 } 1461 }
1506 } 1493 }
1507 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) {
1508 //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
1509 push_r(code, opts->gen.scratch2); 1496 push_r(code, opts->gen.scratch2);
1510 } 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);
1511 uint8_t other_reg; 1500 uint8_t other_reg;
1512 //WARNING: This may need adjustment if register assignments change 1501 //WARNING: This may need adjustment if register assignments change
1513 if (opts->gen.scratch2 > RBX) { 1502 if (opts->gen.scratch2 > RBX) {
1514 other_reg = RAX; 1503 other_reg = RAX;
1515 xchg_rr(code, opts->gen.scratch2, RAX, SZ_D); 1504 xchg_rr(code, opts->gen.scratch2, RAX, SZ_D);
2363 //leave supervisor mode 2352 //leave supervisor mode
2364 swap_ssp_usp(opts); 2353 swap_ssp_usp(opts);
2365 } 2354 }
2366 code_ptr loop_top = code->cur; 2355 code_ptr loop_top = code->cur;
2367 call(code, opts->do_sync); 2356 call(code, opts->do_sync);
2368 cmp_rr(code, opts->gen.limit, opts->gen.cycles, SZ_D); 2357 cmp_rr(code, opts->gen.cycles, opts->gen.limit, SZ_D);
2369 code_ptr normal_cycle_up = code->cur + 1; 2358 code_ptr normal_cycle_up = code->cur + 1;
2370 jcc(code, CC_A, code->cur + 2); 2359 jcc(code, CC_A, code->cur + 2);
2371 cycles(&opts->gen, BUS); 2360 cycles(&opts->gen, BUS);
2372 code_ptr after_cycle_up = code->cur + 1; 2361 code_ptr after_cycle_up = code->cur + 1;
2373 jmp(code, code->cur + 2); 2362 jmp(code, code->cur + 2);
2452 } 2441 }
2453 2442
2454 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)
2455 { 2444 {
2456 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);
2457 call(code, opts->get_sr); 2447 call(code, opts->get_sr);
2458 if (dst_op->mode == MODE_REG_DIRECT) { 2448 if (dst_op->mode == MODE_REG_DIRECT) {
2459 mov_rr(code, opts->gen.scratch1, dst_op->base, SZ_W); 2449 mov_rr(code, opts->gen.scratch1, dst_op->base, SZ_W);
2460 } else { 2450 } else {
2461 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);