comparison m68k_core.c @ 1931:374a5ae694e8 mame_interp

Merge from default
author Michael Pavone <pavone@retrodev.com>
date Sat, 18 Apr 2020 11:42:53 -0700
parents 0c6d07f91346 c157a535ceeb
children cafde1255ad3
comparison
equal deleted inserted replaced
1843:13abdc98379e 1931:374a5ae694e8
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 #ifndef NEW_CORE
8 #include "m68k_internal.h" 8 #include "m68k_internal.h"
9 #endif 9 #endif
10 #include "68kinst.h" 10 #include "68kinst.h"
11 #include "backend.h" 11 #include "backend.h"
12 #ifdef USE_NATIVE 12 #ifndef NEW_CORE
13 #include "gen.h" 13 #include "gen.h"
14 #endif 14 #endif
15 #include "util.h" 15 #include "util.h"
16 #include "serialize.h" 16 #include "serialize.h"
17 #ifndef USE_NATIVE 17 #ifdef NEW_CORE
18 #include "musashi/m68kcpu.h" 18 #include "musashi/m68kcpu.h"
19 #endif 19 #endif
20 #include <stdio.h> 20 #include <stdio.h>
21 #include <stddef.h> 21 #include <stddef.h>
22 #include <stdlib.h> 22 #include <stdlib.h>
23 #include <string.h> 23 #include <string.h>
24 24
25 char disasm_buf[1024]; 25 char disasm_buf[1024];
26 #ifdef USE_NATIVE 26 #ifndef NEW_CORE
27 int8_t native_reg(m68k_op_info * op, m68k_options * opts) 27 int8_t native_reg(m68k_op_info * op, m68k_options * opts)
28 { 28 {
29 if (op->addr_mode == MODE_REG) { 29 if (op->addr_mode == MODE_REG) {
30 return opts->dregs[op->params.regs.pri]; 30 return opts->dregs[op->params.regs.pri];
31 } 31 }
59 } 59 }
60 for (int i = 0; i < 8; i++) { 60 for (int i = 0; i < 8; i++) {
61 printf("a%d: %X\n", i, context->aregs[i]); 61 printf("a%d: %X\n", i, context->aregs[i]);
62 } 62 }
63 } 63 }
64 #ifdef USE_NATIVE 64 #ifndef NEW_CORE
65 void m68k_read_size(m68k_options *opts, uint8_t size) 65 void m68k_read_size(m68k_options *opts, uint8_t size)
66 { 66 {
67 switch (size) 67 switch (size)
68 { 68 {
69 case OPSIZE_BYTE: 69 case OPSIZE_BYTE:
777 return inst->op == M68K_RTS || inst->op == M68K_RTE || inst->op == M68K_RTR || inst->op == M68K_JMP 777 return inst->op == M68K_RTS || inst->op == M68K_RTE || inst->op == M68K_RTR || inst->op == M68K_JMP
778 || inst->op == M68K_TRAP || inst->op == M68K_ILLEGAL || inst->op == M68K_INVALID 778 || inst->op == M68K_TRAP || inst->op == M68K_ILLEGAL || inst->op == M68K_INVALID
779 || (inst->op == M68K_BCC && inst->extra.cond == COND_TRUE); 779 || (inst->op == M68K_BCC && inst->extra.cond == COND_TRUE);
780 } 780 }
781 781
782 #ifdef USE_NATIVE 782 #ifndef NEW_CORE
783 static void m68k_handle_deferred(m68k_context * context) 783 static void m68k_handle_deferred(m68k_context * context)
784 { 784 {
785 m68k_options * opts = context->options; 785 m68k_options * opts = context->options;
786 process_deferred(&opts->gen.deferred, context, (native_addr_func)get_native_from_context); 786 process_deferred(&opts->gen.deferred, context, (native_addr_func)get_native_from_context);
787 if (opts->gen.deferred) { 787 if (opts->gen.deferred) {
790 } 790 }
791 #endif 791 #endif
792 792
793 uint16_t m68k_get_ir(m68k_context *context) 793 uint16_t m68k_get_ir(m68k_context *context)
794 { 794 {
795 #ifdef USE_NATIVE 795 #ifndef NEW_CORE
796 uint32_t inst_addr = get_instruction_start(context->options, context->last_prefetch_address-2); 796 uint32_t inst_addr = get_instruction_start(context->options, context->last_prefetch_address-2);
797 uint16_t *native_addr = get_native_pointer(inst_addr, (void **)context->mem_pointers, &context->options->gen); 797 uint16_t *native_addr = get_native_pointer(inst_addr, (void **)context->mem_pointers, &context->options->gen);
798 if (native_addr) { 798 if (native_addr) {
799 return *native_addr; 799 return *native_addr;
800 } 800 }
828 } 828 }
829 context->breakpoints[context->num_breakpoints++] = (m68k_breakpoint){ 829 context->breakpoints[context->num_breakpoints++] = (m68k_breakpoint){
830 .handler = bp_handler, 830 .handler = bp_handler,
831 .address = address 831 .address = address
832 }; 832 };
833 #ifdef USE_NATIVE 833 #ifndef NEW_CORE
834 m68k_breakpoint_patch(context, address, bp_handler, NULL); 834 m68k_breakpoint_patch(context, address, bp_handler, NULL);
835 #endif 835 #endif
836 } 836 }
837 } 837 }
838 838
848 } 848 }
849 849
850 return context; 850 return context;
851 } 851 }
852 852
853 #ifdef USE_NATIVE 853 #ifndef NEW_CORE
854 typedef enum { 854 typedef enum {
855 RAW_FUNC = 1, 855 RAW_FUNC = 1,
856 BINARY_ARITH, 856 BINARY_ARITH,
857 UNARY_ARITH, 857 UNARY_ARITH,
858 OP_FUNC 858 OP_FUNC
1173 } 1173 }
1174 context->num_breakpoints--; 1174 context->num_breakpoints--;
1175 break; 1175 break;
1176 } 1176 }
1177 } 1177 }
1178 #ifdef USE_NATIVE 1178 #ifndef NEW_CORE
1179 code_ptr native = get_native_address(context->options, address); 1179 code_ptr native = get_native_address(context->options, address);
1180 if (!native) { 1180 if (!native) {
1181 return; 1181 return;
1182 } 1182 }
1183 code_info tmp = context->options->gen.code; 1183 code_info tmp = context->options->gen.code;
1190 1190
1191 m68k_context * sync_components(m68k_context * context, uint32_t address); 1191 m68k_context * sync_components(m68k_context * context, uint32_t address);
1192 void start_68k_context(m68k_context * context, uint32_t address) 1192 void start_68k_context(m68k_context * context, uint32_t address)
1193 { 1193 {
1194 m68k_options * options = context->options; 1194 m68k_options * options = context->options;
1195 #ifdef USE_NATIVE 1195 #ifndef NEW_CORE
1196 code_ptr addr = get_native_address_trans(context, address); 1196 code_ptr addr = get_native_address_trans(context, address);
1197 options->start_context(addr, context); 1197 options->start_context(addr, context);
1198 #else 1198 #else
1199 while (!context->should_return) { 1199 while (!context->should_return) {
1200 if (context->current_cycle >= context->target_cycle) { 1200 if (context->current_cycle >= context->target_cycle) {
1208 #endif 1208 #endif
1209 } 1209 }
1210 1210
1211 void resume_68k(m68k_context *context) 1211 void resume_68k(m68k_context *context)
1212 { 1212 {
1213 #ifdef USE_NATIVE 1213 #ifndef NEW_CORE
1214 code_ptr addr = context->resume_pc; 1214 code_ptr addr = context->resume_pc;
1215 context->resume_pc = NULL; 1215 context->resume_pc = NULL;
1216 m68k_options * options = context->options; 1216 m68k_options * options = context->options;
1217 context->should_return = 0; 1217 context->should_return = 0;
1218 options->start_context(addr, context); 1218 options->start_context(addr, context);
1221 #endif 1221 #endif
1222 } 1222 }
1223 1223
1224 void m68k_reset(m68k_context * context) 1224 void m68k_reset(m68k_context * context)
1225 { 1225 {
1226 #ifdef USE_NATIVE 1226 #ifndef NEW_CORE
1227 //TODO: Actually execute the M68K reset vector rather than simulating some of its behavior 1227 //TODO: Actually execute the M68K reset vector rather than simulating some of its behavior
1228 uint16_t *reset_vec = get_native_pointer(0, (void **)context->mem_pointers, &context->options->gen); 1228 uint16_t *reset_vec = get_native_pointer(0, (void **)context->mem_pointers, &context->options->gen);
1229 context->aregs[7] = reset_vec[0] << 16 | reset_vec[1]; 1229 context->aregs[7] = reset_vec[0] << 16 | reset_vec[1];
1230 uint32_t address = reset_vec[2] << 16 | reset_vec[3]; 1230 uint32_t address = reset_vec[2] << 16 | reset_vec[3];
1231 #else 1231 #else
1235 start_68k_context(context, address); 1235 start_68k_context(context, address);
1236 } 1236 }
1237 1237
1238 void m68k_options_free(m68k_options *opts) 1238 void m68k_options_free(m68k_options *opts)
1239 { 1239 {
1240 #ifdef USE_NATIVE 1240 #ifndef NEW_CORE
1241 for (uint32_t address = 0; address < opts->gen.address_mask; address += NATIVE_CHUNK_SIZE) 1241 for (uint32_t address = 0; address < opts->gen.address_mask; address += NATIVE_CHUNK_SIZE)
1242 { 1242 {
1243 uint32_t chunk = address / NATIVE_CHUNK_SIZE; 1243 uint32_t chunk = address / NATIVE_CHUNK_SIZE;
1244 if (opts->gen.native_code_map[chunk].base) { 1244 if (opts->gen.native_code_map[chunk].base) {
1245 free(opts->gen.native_code_map[chunk].offsets); 1245 free(opts->gen.native_code_map[chunk].offsets);
1255 free(opts->big_movem); 1255 free(opts->big_movem);
1256 #endif 1256 #endif
1257 free(opts); 1257 free(opts);
1258 } 1258 }
1259 1259
1260 #ifndef USE_NATIVE 1260 #ifdef NEW_CORE
1261 void init_m68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chunks, uint32_t clock_divider) 1261 void init_m68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chunks, uint32_t clock_divider)
1262 { 1262 {
1263 memset(opts, 0, sizeof(*opts)); 1263 memset(opts, 0, sizeof(*opts));
1264 opts->gen.memmap = memmap; 1264 opts->gen.memmap = memmap;
1265 opts->gen.memmap_chunks = num_chunks; 1265 opts->gen.memmap_chunks = num_chunks;
1271 } 1271 }
1272 #endif 1272 #endif
1273 1273
1274 m68k_context * init_68k_context(m68k_options * opts, m68k_reset_handler reset_handler) 1274 m68k_context * init_68k_context(m68k_options * opts, m68k_reset_handler reset_handler)
1275 { 1275 {
1276 #ifdef USE_NATIVE 1276 #ifndef NEW_CORE
1277 m68k_context * context = calloc(1, sizeof(m68k_context) + ram_size(&opts->gen) / (1 << opts->gen.ram_flags_shift) / 8); 1277 m68k_context * context = calloc(1, sizeof(m68k_context) + ram_size(&opts->gen) / (1 << opts->gen.ram_flags_shift) / 8);
1278 context->options = opts; 1278 context->options = opts;
1279 #else 1279 #else
1280 m68000_base_device *device = malloc(sizeof(m68000_base_device));; 1280 m68000_base_device *device = malloc(sizeof(m68000_base_device));;
1281 memset(device, 0, sizeof(m68000_base_device)); 1281 memset(device, 0, sizeof(m68000_base_device));
1299 } 1299 }
1300 for (int i = 0; i < 9; i++) 1300 for (int i = 0; i < 9; i++)
1301 { 1301 {
1302 save_int32(buf, context->aregs[i]); 1302 save_int32(buf, context->aregs[i]);
1303 } 1303 }
1304 #ifdef USE_NATIVE 1304 #ifndef NEW_CORE
1305 save_int32(buf, pc); 1305 save_int32(buf, pc);
1306 uint16_t sr = context->status << 3; 1306 uint16_t sr = context->status << 3;
1307 for (int flag = 4; flag >= 0; flag--) { 1307 for (int flag = 4; flag >= 0; flag--) {
1308 sr <<= 1; 1308 sr <<= 1;
1309 sr |= context->flags[flag] != 0; 1309 sr |= context->flags[flag] != 0;
1330 } 1330 }
1331 for (int i = 0; i < 9; i++) 1331 for (int i = 0; i < 9; i++)
1332 { 1332 {
1333 context->aregs[i] = load_int32(buf); 1333 context->aregs[i] = load_int32(buf);
1334 } 1334 }
1335 #ifdef USE_NATIVE 1335 #ifndef NEW_CORE
1336 //hack until both PC and IR registers are represented properly 1336 //hack until both PC and IR registers are represented properly
1337 context->last_prefetch_address = load_int32(buf); 1337 context->last_prefetch_address = load_int32(buf);
1338 uint16_t sr = load_int16(buf); 1338 uint16_t sr = load_int16(buf);
1339 context->status = sr >> 8; 1339 context->status = sr >> 8;
1340 for (int flag = 0; flag < 5; flag++) 1340 for (int flag = 0; flag < 5; flag++)
1352 context->int_num = load_int8(buf); 1352 context->int_num = load_int8(buf);
1353 context->int_pending = load_int8(buf); 1353 context->int_pending = load_int8(buf);
1354 context->trace_pending = load_int8(buf); 1354 context->trace_pending = load_int8(buf);
1355 } 1355 }
1356 1356
1357 #ifndef USE_NATIVE 1357 #ifdef NEW_CORE
1358 void m68k_invalidate_code_range(m68k_context *context, uint32_t start, uint32_t end) 1358 void m68k_invalidate_code_range(m68k_context *context, uint32_t start, uint32_t end)
1359 { 1359 {
1360 m68000_base_device *device = (m68000_base_device *)context; 1360 m68000_base_device *device = (m68000_base_device *)context;
1361 for(uint32_t address = start; address < end; address += 0x10000) 1361 for(uint32_t address = start; address < end; address += 0x10000)
1362 { 1362 {