Mercurial > repos > blastem
comparison m68k_core.c @ 1507:2455662378ed mame_interp
Added MAME Z80 core, re-enabled 68K tracing in Musashi core, disabled a bunch of code gen stuff when using interpreters from MAME
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 30 Dec 2017 18:27:06 -0800 |
parents | ded16f3d7eb4 |
children | b7ecd0d6a77b |
comparison
equal
deleted
inserted
replaced
1506:ded16f3d7eb4 | 1507:2455662378ed |
---|---|
2 Copyright 2014 Michael Pavone | 2 Copyright 2014 Michael Pavone |
3 This file is part of BlastEm. | 3 This file is part of BlastEm. |
4 BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text. | 4 BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text. |
5 */ | 5 */ |
6 #include "m68k_core.h" | 6 #include "m68k_core.h" |
7 #ifdef USE_NATIVE | |
7 #include "m68k_internal.h" | 8 #include "m68k_internal.h" |
9 #endif | |
8 #include "68kinst.h" | 10 #include "68kinst.h" |
9 #include "backend.h" | 11 #include "backend.h" |
12 #ifdef USE_NATIVE | |
10 #include "gen.h" | 13 #include "gen.h" |
14 #endif | |
11 #include "util.h" | 15 #include "util.h" |
12 #include "serialize.h" | 16 #include "serialize.h" |
17 #ifndef USE_NATIVE | |
13 #include "musashi/m68kcpu.h" | 18 #include "musashi/m68kcpu.h" |
19 #endif | |
14 #include <stdio.h> | 20 #include <stdio.h> |
15 #include <stddef.h> | 21 #include <stddef.h> |
16 #include <stdlib.h> | 22 #include <stdlib.h> |
17 #include <string.h> | 23 #include <string.h> |
18 | 24 |
19 char disasm_buf[1024]; | 25 char disasm_buf[1024]; |
20 | 26 #ifdef USE_NATIVE |
21 int8_t native_reg(m68k_op_info * op, m68k_options * opts) | 27 int8_t native_reg(m68k_op_info * op, m68k_options * opts) |
22 { | 28 { |
23 if (op->addr_mode == MODE_REG) { | 29 if (op->addr_mode == MODE_REG) { |
24 return opts->dregs[op->params.regs.pri]; | 30 return opts->dregs[op->params.regs.pri]; |
25 } | 31 } |
42 //must be called with an m68k_op_info that uses a register | 48 //must be called with an m68k_op_info that uses a register |
43 size_t reg_offset(m68k_op_info *op) | 49 size_t reg_offset(m68k_op_info *op) |
44 { | 50 { |
45 return op->addr_mode == MODE_REG ? dreg_offset(op->params.regs.pri) : areg_offset(op->params.regs.pri); | 51 return op->addr_mode == MODE_REG ? dreg_offset(op->params.regs.pri) : areg_offset(op->params.regs.pri); |
46 } | 52 } |
47 | 53 #endif |
48 void m68k_print_regs(m68k_context * context) | 54 void m68k_print_regs(m68k_context * context) |
49 { | 55 { |
50 printf("XNZVC\n%d%d%d%d%d\n", context->flags[0], context->flags[1], context->flags[2], context->flags[3], context->flags[4]); | 56 printf("XNZVC\n%d%d%d%d%d\n", context->flags[0], context->flags[1], context->flags[2], context->flags[3], context->flags[4]); |
51 for (int i = 0; i < 8; i++) { | 57 for (int i = 0; i < 8; i++) { |
52 printf("d%d: %X\n", i, context->dregs[i]); | 58 printf("d%d: %X\n", i, context->dregs[i]); |
53 } | 59 } |
54 for (int i = 0; i < 8; i++) { | 60 for (int i = 0; i < 8; i++) { |
55 printf("a%d: %X\n", i, context->aregs[i]); | 61 printf("a%d: %X\n", i, context->aregs[i]); |
56 } | 62 } |
57 } | 63 } |
58 | 64 #ifdef USE_NATIVE |
59 void m68k_read_size(m68k_options *opts, uint8_t size) | 65 void m68k_read_size(m68k_options *opts, uint8_t size) |
60 { | 66 { |
61 switch (size) | 67 switch (size) |
62 { | 68 { |
63 case OPSIZE_BYTE: | 69 case OPSIZE_BYTE: |
758 meta_off += (address - chunk->start) & chunk->mask; | 764 meta_off += (address - chunk->start) & chunk->mask; |
759 } | 765 } |
760 uint32_t slot = meta_off/1024; | 766 uint32_t slot = meta_off/1024; |
761 return opts->gen.ram_inst_sizes[slot][(meta_off/2)%512]; | 767 return opts->gen.ram_inst_sizes[slot][(meta_off/2)%512]; |
762 } | 768 } |
769 #endif | |
763 | 770 |
764 uint8_t m68k_is_terminal(m68kinst * inst) | 771 uint8_t m68k_is_terminal(m68kinst * inst) |
765 { | 772 { |
766 return inst->op == M68K_RTS || inst->op == M68K_RTE || inst->op == M68K_RTR || inst->op == M68K_JMP | 773 return inst->op == M68K_RTS || inst->op == M68K_RTE || inst->op == M68K_RTR || inst->op == M68K_JMP |
767 || inst->op == M68K_TRAP || inst->op == M68K_ILLEGAL || inst->op == M68K_INVALID | 774 || inst->op == M68K_TRAP || inst->op == M68K_ILLEGAL || inst->op == M68K_INVALID |
768 || (inst->op == M68K_BCC && inst->extra.cond == COND_TRUE); | 775 || (inst->op == M68K_BCC && inst->extra.cond == COND_TRUE); |
769 } | 776 } |
770 | 777 |
778 #ifdef USE_NATIVE | |
771 static void m68k_handle_deferred(m68k_context * context) | 779 static void m68k_handle_deferred(m68k_context * context) |
772 { | 780 { |
773 m68k_options * opts = context->options; | 781 m68k_options * opts = context->options; |
774 process_deferred(&opts->gen.deferred, context, (native_addr_func)get_native_from_context); | 782 process_deferred(&opts->gen.deferred, context, (native_addr_func)get_native_from_context); |
775 if (opts->gen.deferred) { | 783 if (opts->gen.deferred) { |
776 translate_m68k_stream(opts->gen.deferred->address, context); | 784 translate_m68k_stream(opts->gen.deferred->address, context); |
777 } | 785 } |
778 } | 786 } |
787 #endif | |
779 | 788 |
780 uint16_t m68k_get_ir(m68k_context *context) | 789 uint16_t m68k_get_ir(m68k_context *context) |
781 { | 790 { |
791 #ifdef USE_NATIVE | |
782 uint32_t inst_addr = get_instruction_start(context->options, context->last_prefetch_address-2); | 792 uint32_t inst_addr = get_instruction_start(context->options, context->last_prefetch_address-2); |
783 uint16_t *native_addr = get_native_pointer(inst_addr, (void **)context->mem_pointers, &context->options->gen); | 793 uint16_t *native_addr = get_native_pointer(inst_addr, (void **)context->mem_pointers, &context->options->gen); |
784 if (native_addr) { | 794 if (native_addr) { |
785 return *native_addr; | 795 return *native_addr; |
786 } | 796 } |
787 fprintf(stderr, "M68K: Failed to calculate value of IR. Last prefetch address: %X\n", context->last_prefetch_address); | 797 fprintf(stderr, "M68K: Failed to calculate value of IR. Last prefetch address: %X\n", context->last_prefetch_address); |
788 return 0xFFFF; | 798 return 0xFFFF; |
799 #else | |
800 return ((m68000_base_device *)context)->ir; | |
801 #endif | |
789 } | 802 } |
790 | 803 |
791 static m68k_debug_handler find_breakpoint(m68k_context *context, uint32_t address) | 804 static m68k_debug_handler find_breakpoint(m68k_context *context, uint32_t address) |
792 { | 805 { |
793 for (uint32_t i = 0; i < context->num_breakpoints; i++) | 806 for (uint32_t i = 0; i < context->num_breakpoints; i++) |
811 } | 824 } |
812 context->breakpoints[context->num_breakpoints++] = (m68k_breakpoint){ | 825 context->breakpoints[context->num_breakpoints++] = (m68k_breakpoint){ |
813 .handler = bp_handler, | 826 .handler = bp_handler, |
814 .address = address | 827 .address = address |
815 }; | 828 }; |
829 #ifdef USE_NATIVE | |
816 m68k_breakpoint_patch(context, address, bp_handler, NULL); | 830 m68k_breakpoint_patch(context, address, bp_handler, NULL); |
831 #endif | |
817 } | 832 } |
818 } | 833 } |
819 | 834 |
820 m68k_context *m68k_bp_dispatcher(m68k_context *context, uint32_t address) | 835 m68k_context *m68k_bp_dispatcher(m68k_context *context, uint32_t address) |
821 { | 836 { |
829 } | 844 } |
830 | 845 |
831 return context; | 846 return context; |
832 } | 847 } |
833 | 848 |
849 #ifdef USE_NATIVE | |
834 typedef enum { | 850 typedef enum { |
835 RAW_FUNC = 1, | 851 RAW_FUNC = 1, |
836 BINARY_ARITH, | 852 BINARY_ARITH, |
837 UNARY_ARITH, | 853 UNARY_ARITH, |
838 OP_FUNC | 854 OP_FUNC |
1139 translate_m68k_stream(address, context); | 1155 translate_m68k_stream(address, context); |
1140 ret = get_native_address(context->options, address); | 1156 ret = get_native_address(context->options, address); |
1141 } | 1157 } |
1142 return ret; | 1158 return ret; |
1143 } | 1159 } |
1160 #endif | |
1144 | 1161 |
1145 void remove_breakpoint(m68k_context * context, uint32_t address) | 1162 void remove_breakpoint(m68k_context * context, uint32_t address) |
1146 { | 1163 { |
1147 for (uint32_t i = 0; i < context->num_breakpoints; i++) | 1164 for (uint32_t i = 0; i < context->num_breakpoints; i++) |
1148 { | 1165 { |
1152 } | 1169 } |
1153 context->num_breakpoints--; | 1170 context->num_breakpoints--; |
1154 break; | 1171 break; |
1155 } | 1172 } |
1156 } | 1173 } |
1174 #ifdef USE_NATIVE | |
1157 code_ptr native = get_native_address(context->options, address); | 1175 code_ptr native = get_native_address(context->options, address); |
1158 if (!native) { | 1176 if (!native) { |
1159 return; | 1177 return; |
1160 } | 1178 } |
1161 code_info tmp = context->options->gen.code; | 1179 code_info tmp = context->options->gen.code; |
1162 context->options->gen.code.cur = native; | 1180 context->options->gen.code.cur = native; |
1163 context->options->gen.code.last = native + MAX_NATIVE_SIZE; | 1181 context->options->gen.code.last = native + MAX_NATIVE_SIZE; |
1164 check_cycles_int(&context->options->gen, address); | 1182 check_cycles_int(&context->options->gen, address); |
1165 context->options->gen.code = tmp; | 1183 context->options->gen.code = tmp; |
1166 } | 1184 #endif |
1167 | 1185 } |
1186 | |
1187 m68k_context * sync_components(m68k_context * context, uint32_t address); | |
1168 void start_68k_context(m68k_context * context, uint32_t address) | 1188 void start_68k_context(m68k_context * context, uint32_t address) |
1169 { | 1189 { |
1170 code_ptr addr = get_native_address_trans(context, address); | |
1171 m68k_options * options = context->options; | 1190 m68k_options * options = context->options; |
1172 context->should_return = 0; | 1191 context->should_return = 0; |
1173 #ifdef USE_NATIVE | 1192 #ifdef USE_NATIVE |
1193 code_ptr addr = get_native_address_trans(context, address); | |
1174 options->start_context(addr, context); | 1194 options->start_context(addr, context); |
1175 #else | 1195 #else |
1176 while (!context->should_return) { | 1196 while (!context->should_return) { |
1177 if (context->current_cycle >= context->target_cycle) { | 1197 if (context->current_cycle >= context->target_cycle) { |
1178 context->target_cycle += 4 * options->gen.clock_divider; | 1198 context->target_cycle += 4 * options->gen.clock_divider; |
1212 start_68k_context(context, address); | 1232 start_68k_context(context, address); |
1213 } | 1233 } |
1214 | 1234 |
1215 void m68k_options_free(m68k_options *opts) | 1235 void m68k_options_free(m68k_options *opts) |
1216 { | 1236 { |
1237 #ifdef USE_NATIVE | |
1217 free(opts->gen.native_code_map); | 1238 free(opts->gen.native_code_map); |
1218 free(opts->gen.ram_inst_sizes); | 1239 free(opts->gen.ram_inst_sizes); |
1240 #endif | |
1219 free(opts); | 1241 free(opts); |
1220 } | 1242 } |
1221 | 1243 |
1244 #ifndef USE_NATIVE | |
1245 void init_m68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chunks, uint32_t clock_divider) | |
1246 { | |
1247 memset(opts, 0, sizeof(*opts)); | |
1248 opts->gen.memmap = memmap; | |
1249 opts->gen.memmap_chunks = num_chunks; | |
1250 opts->gen.address_mask = 0xFFFFFF; | |
1251 opts->gen.byte_swap = 1; | |
1252 opts->gen.max_address = 0x1000000; | |
1253 opts->gen.bus_cycles = 4; | |
1254 opts->gen.clock_divider = clock_divider; | |
1255 } | |
1256 #endif | |
1222 | 1257 |
1223 m68k_context * init_68k_context(m68k_options * opts, m68k_reset_handler reset_handler) | 1258 m68k_context * init_68k_context(m68k_options * opts, m68k_reset_handler reset_handler) |
1224 { | 1259 { |
1225 #ifdef USE_NATIVE | 1260 #ifdef USE_NATIVE |
1226 size_t ctx_size = sizeof(m68k_context) + ram_size(&opts->gen) / (1 << opts->gen.ram_flags_shift) / 8; | 1261 size_t ctx_size = sizeof(m68k_context) + ram_size(&opts->gen) / (1 << opts->gen.ram_flags_shift) / 8; |