comparison m68k_core_x86.c @ 2499:d74d3998482c

Make some progress on compiling full emulator with new 68K core
author Michael Pavone <pavone@retrodev.com>
date Tue, 30 Apr 2024 00:02:14 -0700
parents 4aef84fbe2e2
children b58ca7af1e60
comparison
equal deleted inserted replaced
2498:dffda054d218 2499:d74d3998482c
1783 bit = 0; 1783 bit = 0;
1784 cycles += 8; 1784 cycles += 8;
1785 } 1785 }
1786 } 1786 }
1787 cycles += force ? 6 : bit ? 4 : 2; 1787 cycles += force ? 6 : bit ? 4 : 2;
1788 context->current_cycle += cycles * context->options->gen.clock_divider; 1788 context->cycles += cycles * context->opts->gen.clock_divider;
1789 quotient = quotient << 1 | bit; 1789 quotient = quotient << 1 | bit;
1790 return dividend | quotient; 1790 return dividend | quotient;
1791 } 1791 }
1792 1792
1793 static uint32_t divs(uint32_t dividend, m68k_context *context, uint32_t divisor_shift) 1793 static uint32_t divs(uint32_t dividend, m68k_context *context, uint32_t divisor_shift)
1806 if (divisor_shift <= dividend) { 1806 if (divisor_shift <= dividend) {
1807 context->flags[FLAG_V] = 1; 1807 context->flags[FLAG_V] = 1;
1808 context->flags[FLAG_N] = 1; 1808 context->flags[FLAG_N] = 1;
1809 context->flags[FLAG_Z] = 0; 1809 context->flags[FLAG_Z] = 0;
1810 cycles += 4; 1810 cycles += 4;
1811 context->current_cycle += cycles * context->options->gen.clock_divider; 1811 context->cycles += cycles * context->opts->gen.clock_divider;
1812 return orig_dividend; 1812 return orig_dividend;
1813 } 1813 }
1814 uint16_t quotient = 0; 1814 uint16_t quotient = 0;
1815 uint16_t bit = 0; 1815 uint16_t bit = 0;
1816 for (int i = 0; i < 15; i++) 1816 for (int i = 0; i < 15; i++)
1843 if (orig_dividend & 0x80000000) { 1843 if (orig_dividend & 0x80000000) {
1844 if (quotient & 0x8000) { 1844 if (quotient & 0x8000) {
1845 context->flags[FLAG_V] = 1; 1845 context->flags[FLAG_V] = 1;
1846 context->flags[FLAG_N] = 1; 1846 context->flags[FLAG_N] = 1;
1847 context->flags[FLAG_Z] = 0; 1847 context->flags[FLAG_Z] = 0;
1848 context->current_cycle += cycles * context->options->gen.clock_divider; 1848 context->cycles += cycles * context->opts->gen.clock_divider;
1849 return orig_dividend; 1849 return orig_dividend;
1850 } else { 1850 } else {
1851 dividend = -dividend; 1851 dividend = -dividend;
1852 } 1852 }
1853 } else { 1853 } else {
1871 } 1871 }
1872 } 1872 }
1873 if (context->flags[FLAG_V]) { 1873 if (context->flags[FLAG_V]) {
1874 context->flags[FLAG_N] = 1; 1874 context->flags[FLAG_N] = 1;
1875 context->flags[FLAG_Z] = 0; 1875 context->flags[FLAG_Z] = 0;
1876 context->current_cycle += cycles * context->options->gen.clock_divider; 1876 context->cycles += cycles * context->opts->gen.clock_divider;
1877 return orig_dividend; 1877 return orig_dividend;
1878 } 1878 }
1879 context->flags[FLAG_N] = (quotient & 0x8000) ? 1 : 0; 1879 context->flags[FLAG_N] = (quotient & 0x8000) ? 1 : 0;
1880 context->flags[FLAG_Z] = quotient == 0; 1880 context->flags[FLAG_Z] = quotient == 0;
1881 //V was cleared above, C is cleared by the generated machine code 1881 //V was cleared above, C is cleared by the generated machine code
1882 context->current_cycle += cycles * context->options->gen.clock_divider; 1882 context->cycles += cycles * context->opts->gen.clock_divider;
1883 return dividend | quotient; 1883 return dividend | quotient;
1884 } 1884 }
1885 1885
1886 void translate_m68k_div(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op) 1886 void translate_m68k_div(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op)
1887 { 1887 {
2053 push_r(code, opts->gen.context_reg); 2053 push_r(code, opts->gen.context_reg);
2054 call_args(code, (code_ptr)(inst->op == M68K_MULS ? muls_cycles : mulu_cycles), 1, opts->gen.scratch1); 2054 call_args(code, (code_ptr)(inst->op == M68K_MULS ? muls_cycles : mulu_cycles), 1, opts->gen.scratch1);
2055 pop_r(code, opts->gen.context_reg); 2055 pop_r(code, opts->gen.context_reg);
2056 //turn 68K cycles into master clock cycles and add to the current cycle count 2056 //turn 68K cycles into master clock cycles and add to the current cycle count
2057 imul_irr(code, opts->gen.clock_divider, RAX, RAX, SZ_D); 2057 imul_irr(code, opts->gen.clock_divider, RAX, RAX, SZ_D);
2058 add_rrdisp(code, RAX, opts->gen.context_reg, offsetof(m68k_context, current_cycle), SZ_D); 2058 add_rrdisp(code, RAX, opts->gen.context_reg, offsetof(m68k_context, cycles), SZ_D);
2059 //restore context and scratch1 2059 //restore context and scratch1
2060 call(code, opts->gen.load_context); 2060 call(code, opts->gen.load_context);
2061 pop_r(code, opts->gen.scratch1); 2061 pop_r(code, opts->gen.scratch1);
2062 } 2062 }
2063 2063
2509 2509
2510 #define M68K_MAX_INST_SIZE (2*(1+2+2)) 2510 #define M68K_MAX_INST_SIZE (2*(1+2+2))
2511 2511
2512 m68k_context * m68k_handle_code_write(uint32_t address, m68k_context * context) 2512 m68k_context * m68k_handle_code_write(uint32_t address, m68k_context * context)
2513 { 2513 {
2514 m68k_options * options = context->options; 2514 m68k_options * options = context->opts;
2515 uint32_t inst_start = get_instruction_start(options, address); 2515 uint32_t inst_start = get_instruction_start(options, address);
2516 while (inst_start && (address - inst_start) < M68K_MAX_INST_SIZE) { 2516 while (inst_start && (address - inst_start) < M68K_MAX_INST_SIZE) {
2517 code_ptr dst = get_native_address(context->options, inst_start); 2517 code_ptr dst = get_native_address(context->opts, inst_start);
2518 patch_for_retranslate(&options->gen, dst, options->retrans_stub); 2518 patch_for_retranslate(&options->gen, dst, options->retrans_stub);
2519 inst_start = get_instruction_start(options, inst_start - 2); 2519 inst_start = get_instruction_start(options, inst_start - 2);
2520 } 2520 }
2521 return context; 2521 return context;
2522 } 2522 }
2523 2523
2524 void m68k_invalidate_code_range(m68k_context *context, uint32_t start, uint32_t end) 2524 void m68k_invalidate_code_range(m68k_context *context, uint32_t start, uint32_t end)
2525 { 2525 {
2526 m68k_options *opts = context->options; 2526 m68k_options *opts = context->opts;
2527 native_map_slot *native_code_map = opts->gen.native_code_map; 2527 native_map_slot *native_code_map = opts->gen.native_code_map;
2528 if (start > M68K_MAX_INST_SIZE - 2) { 2528 if (start > M68K_MAX_INST_SIZE - 2) {
2529 start -= M68K_MAX_INST_SIZE - 2; 2529 start -= M68K_MAX_INST_SIZE - 2;
2530 } else { 2530 } else {
2531 start = 0; 2531 start = 0;
2562 } 2562 }
2563 } 2563 }
2564 2564
2565 void m68k_breakpoint_patch(m68k_context *context, uint32_t address, m68k_debug_handler bp_handler, code_ptr native_addr) 2565 void m68k_breakpoint_patch(m68k_context *context, uint32_t address, m68k_debug_handler bp_handler, code_ptr native_addr)
2566 { 2566 {
2567 m68k_options * opts = context->options; 2567 m68k_options * opts = context->opts;
2568 code_info native; 2568 code_info native;
2569 native.cur = native_addr ? native_addr : get_native_address(context->options, address); 2569 native.cur = native_addr ? native_addr : get_native_address(context->opts, address);
2570 2570
2571 if (!native.cur) { 2571 if (!native.cur) {
2572 return; 2572 return;
2573 } 2573 }
2574 2574
2667 } 2667 }
2668 if (opts->aregs[i] >= 0) { 2668 if (opts->aregs[i] >= 0) {
2669 mov_rrdisp(code, opts->aregs[i], opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t) * i, SZ_D); 2669 mov_rrdisp(code, opts->aregs[i], opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t) * i, SZ_D);
2670 } 2670 }
2671 } 2671 }
2672 mov_rrdisp(code, opts->gen.cycles, opts->gen.context_reg, offsetof(m68k_context, current_cycle), SZ_D); 2672 mov_rrdisp(code, opts->gen.cycles, opts->gen.context_reg, offsetof(m68k_context, cycles), SZ_D);
2673 retn(code); 2673 retn(code);
2674 2674
2675 opts->load_context_scratch = code->cur; 2675 opts->load_context_scratch = code->cur;
2676 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, scratch1), opts->gen.scratch1, SZ_D); 2676 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, scratch1), opts->gen.scratch1, SZ_D);
2677 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, scratch2), opts->gen.scratch2, SZ_D); 2677 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, scratch2), opts->gen.scratch2, SZ_D);
2689 } 2689 }
2690 if (opts->aregs[i] >= 0) { 2690 if (opts->aregs[i] >= 0) {
2691 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t) * i, opts->aregs[i], SZ_D); 2691 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t) * i, opts->aregs[i], SZ_D);
2692 } 2692 }
2693 } 2693 }
2694 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, current_cycle), opts->gen.cycles, SZ_D); 2694 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, cycles), opts->gen.cycles, SZ_D);
2695 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, target_cycle), opts->gen.limit, SZ_D); 2695 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, target_cycle), opts->gen.limit, SZ_D);
2696 retn(code); 2696 retn(code);
2697 2697
2698 opts->start_context = (start_fun)code->cur; 2698 opts->start_context = (start_fun)code->cur;
2699 save_callee_save_regs(code); 2699 save_callee_save_regs(code);