Mercurial > repos > blastem
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); |