Mercurial > repos > blastem
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 { |