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;