changeset 2500:d44fe974fb85

Get blastem compiling with new 68K core
author Michael Pavone <pavone@retrodev.com>
date Tue, 30 Apr 2024 22:32:08 -0700
parents d74d3998482c
children 6cd5a1d76e34
files cpu_dsl.py debug.c gdb_remote.c genesis.c gst.c m68k.cpu m68k_util.c sega_mapper.c segacd.c sms.c
diffstat 10 files changed, 135 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/cpu_dsl.py	Tue Apr 30 00:02:14 2024 -0700
+++ b/cpu_dsl.py	Tue Apr 30 22:32:08 2024 -0700
@@ -1595,10 +1595,11 @@
 		macro = header.upper().replace('.', '_')
 		hFile.write('#ifndef {0}_'.format(macro))
 		hFile.write('\n#define {0}_'.format(macro))
+		hFile.write('\n#include <stdio.h>')
 		hFile.write('\n#include "backend.h"')
 		hFile.write('\n\ntypedef struct {')
 		hFile.write('\n\tcpu_options gen;')
-		hFile.write('\n\tuint8_t address_log;')
+		hFile.write('\n\tFILE* address_log;')
 		hFile.write('\n}} {0}options;'.format(self.prefix))
 		hFile.write('\n\ntypedef struct {')
 		hFile.write('\n\t{0}options *opts;'.format(self.prefix))
--- a/debug.c	Tue Apr 30 00:02:14 2024 -0700
+++ b/debug.c	Tue Apr 30 22:32:08 2024 -0700
@@ -1630,10 +1630,14 @@
 	m68k_context *context = var->ptr;
 	debug_val ret;
 	ret.v.u32 = context->status << 8;
+#ifdef NEW_CORE
+	//TODO: implement me
+#else
 	for (int flag = 0; flag < 5; flag++)
 	{
 		ret.v.u32 |= context->flags[flag] << (4-flag);
 	}
+#endif
 	ret.type = DBG_VAL_U32;
 	return ret;
 }
@@ -1647,9 +1651,13 @@
 		return;
 	}
 	context->status = ival >> 8;
+#ifdef NEW_CORE
+	//TODO: implement me
+#else
 	for (int flag = 0; flag < 5; flag++) {
 		context->flags[flag] = (ival & (1 << (4 - flag))) != 0;
 	}
+#endif
 }
 
 static debug_val m68k_cycle_get(debug_var *var)
@@ -3742,6 +3750,9 @@
 static uint8_t cmd_backtrace_m68k(debug_root *root, parsed_command *cmd)
 {
 	m68k_context *context = root->cpu_context;
+#ifdef NEW_CORE
+	//TODO: implement me
+#else
 	uint32_t stack = context->aregs[7];
 	uint8_t non_adr_count = 0;
 	do {
@@ -3762,6 +3773,7 @@
 		}
 		//TODO: Make sure we don't wander into an invalid memory region
 	} while (stack && non_adr_count < 6);
+#endif
 	return 1;
 }
 
@@ -3775,6 +3787,7 @@
 			return 1;
 		}
 	}
+#ifndef NEW_CORE
 	char disasm_buf[1024];
 	m68kinst inst;
 	do {
@@ -3790,6 +3803,7 @@
 		m68k_disasm_labels(&inst, disasm_buf, root->disasm);
 		printf("\t%s\n", disasm_buf);
 	} while(!m68k_is_terminal(&inst));
+#endif
 	return 1;
 }
 
@@ -4372,6 +4386,7 @@
 #define NUM_SCD_SUB (sizeof(scd_main_commands)/sizeof(*scd_main_commands))
 
 #ifndef NO_Z80
+#ifndef NEW_CORE
 
 static uint8_t cmd_delete_z80(debug_root *root, parsed_command *cmd)
 {
@@ -4591,6 +4606,7 @@
 	} while(!z80_is_terminal(&inst));
 	return 1;
 }
+#endif //NEW_CORE
 
 static uint8_t cmd_gen_m68k(debug_root *root, parsed_command *cmd)
 {
@@ -4637,6 +4653,7 @@
 }
 
 command_def z80_commands[] = {
+#ifndef NEW_CORE
 	{
 		.names = (const char *[]){
 			"breakpoint", "b", NULL
@@ -4727,6 +4744,7 @@
 		.min_args = 0,
 		.max_args = 1
 	}
+#endif //NEW_CORE
 };
 
 #define NUM_Z80 (sizeof(z80_commands)/sizeof(*z80_commands))
@@ -4874,14 +4892,19 @@
 }
 
 #ifndef NO_Z80
+#ifdef NEW_CORE
+#define Z80_OPTS opts
+#else
+#define Z80_OPTS options
+#endif
 
 static uint8_t read_z80(debug_root *root, uint32_t *out, char size)
 {
 	z80_context *context = root->cpu_context;
 	uint32_t address = *out;
-	*out = read_byte(address, (void **)context->mem_pointers, &context->options->gen, context);
+	*out = read_byte(address, (void **)context->mem_pointers, &context->Z80_OPTS->gen, context);
 	if (size == 'w') {
-		*out |= read_byte(address + 1, (void **)context->mem_pointers, &context->options->gen, context) << 8;
+		*out |= read_byte(address + 1, (void **)context->mem_pointers, &context->Z80_OPTS->gen, context) << 8;
 	}
 	return 1;
 }
@@ -4889,13 +4912,14 @@
 static uint8_t write_z80(debug_root *root, uint32_t address, uint32_t value, char size)
 {
 	z80_context *context = root->cpu_context;
-	write_byte(address, value, (void **)context->mem_pointers, &context->options->gen, context);
+	write_byte(address, value, (void **)context->mem_pointers, &context->Z80_OPTS->gen, context);
 	if (size == 'w') {
-		write_byte(address + 1, value >> 8, (void **)context->mem_pointers, &context->options->gen, context);
+		write_byte(address + 1, value >> 8, (void **)context->mem_pointers, &context->Z80_OPTS->gen, context);
 	}
 	return 1;
 }
 
+#ifndef NEW_CORE
 static debug_val z80_reg8_get(debug_var *var)
 {
 	z80_context *context = var->ptr;
@@ -5212,15 +5236,16 @@
 	root->variables = tern_insert_ptr(root->variables, "pc", var);
 	root->variables = tern_insert_ptr(root->variables, "PC", var);
 }
+#endif //NEW_CORE
 
 static uint32_t z80_chunk_end(debug_root *root, uint32_t start_address)
 {
 	z80_context *z80 = root->cpu_context;
-	memmap_chunk const *chunk = find_map_chunk(start_address, &z80->options->gen, 0, NULL);
+	memmap_chunk const *chunk = find_map_chunk(start_address, &z80->Z80_OPTS->gen, 0, NULL);
 	if (!chunk) {
 		return start_address;
 	}
-	if (chunk->mask == z80->options->gen.address_mask) {
+	if (chunk->mask == z80->Z80_OPTS->gen.address_mask) {
 		return chunk->end;
 	}
 	return (start_address & ~chunk->mask) + chunk->mask + 1;
@@ -5232,7 +5257,9 @@
 	if (root && !root->commands) {
 		add_commands(root, common_commands, NUM_COMMON);
 		add_commands(root, z80_commands, NUM_Z80);
+#ifndef NEW_CORE
 		z80_names(root);
+#endif
 		genesis_context *gen;
 		sms_context *sms;
 		coleco_context *coleco;
@@ -5315,6 +5342,7 @@
 	} else {
 		zremove_breakpoint(context, address);
 	}
+#ifndef NEW_CORE
 	if (context->wp_hit) {
 		context->wp_hit = 0;
 		this_bp = find_breakpoint(&root->breakpoints, context->wp_hit_address, BP_TYPE_CPU_WATCH);
@@ -5348,6 +5376,7 @@
 			}
 		}
 	}
+#endif
 	uint8_t * pc = get_native_pointer(address, (void **)context->mem_pointers, &context->Z80_OPTS->gen);
 	if (!pc) {
 		fatal_error("Failed to get native pointer on entering Z80 debugger at address %X\n", address);
@@ -5382,7 +5411,9 @@
 
 	init_terminal();
 
+#ifndef NEW_CORE
 	context->opts->sync_components(context, 0);
+#endif
 	debug_root *root = find_m68k_root(context);
 	if (!root) {
 		return;
@@ -5469,9 +5500,11 @@
 		genesis_context *gen = context->system;
 		vdp_force_update_framebuffer(gen->vdp);
 	}
+#ifndef NEW_CORE
 	uint32_t after = m68k_decode(m68k_instruction_fetch, context, &inst, address);
 	root->after = after;
 	root->inst = &inst;
+#endif
 	for (disp_def * cur = root->displays; cur; cur = cur->next) {
 		char format_str[8];
 		make_format_str(format_str, cur->format);
--- a/gdb_remote.c	Tue Apr 30 00:02:14 2024 -0700
+++ b/gdb_remote.c	Tue Apr 30 22:32:08 2024 -0700
@@ -107,22 +107,30 @@
 uint32_t calc_status(m68k_context * context)
 {
 	uint32_t status = context->status << 3;
+#ifdef NEW_CORE
+	//TODO: implement me
+#else
 	for (int i = 0; i < 5; i++)
 	{
 		status <<= 1;
 		status |= context->flags[i];
 	}
+#endif
 	return status;
 }
 
 void update_status(m68k_context * context, uint16_t value)
 {
 	context->status = value >> 8;
+#ifdef NEW_CORE
+	//TODO: implement me
+#else
 	for (int i = 4; i >= 0; i--)
 	{
 		context->flags[i] = value & 1;
 		value >>= 1;
 	}
+#endif
 }
 
 static uint8_t m68k_read_byte(m68k_context *context, uint32_t address)
@@ -184,6 +192,7 @@
 			//TODO: implement resuming at an arbitrary address
 			goto not_impl;
 		}
+#ifndef NEW_CORE
 		m68kinst inst;
 		genesis_context *gen = context->system;
 		uint32_t after = m68k_decode(m68k_instruction_fetch, context, &inst, pc & 0xFFFFFF);
@@ -206,6 +215,7 @@
 			}
 		}
 		insert_breakpoint(context, after, gdb_debug_enter);
+#endif
 
 		cont = 1;
 		expect_break_response = 1;
@@ -441,6 +451,7 @@
 				break;
 			case 's':
 			case 'S': {
+#ifndef NEW_CORE
 				m68kinst inst;
 				genesis_context *gen = context->system;
 				uint32_t after = m68k_decode(m68k_instruction_fetch, context, &inst, pc & 0xFFFFFF);
@@ -463,6 +474,7 @@
 					}
 				}
 				insert_breakpoint(context, after, gdb_debug_enter);
+#endif
 
 				cont = 1;
 				expect_break_response = 1;
--- a/genesis.c	Tue Apr 30 00:02:14 2024 -0700
+++ b/genesis.c	Tue Apr 30 22:32:08 2024 -0700
@@ -137,6 +137,7 @@
 {
 	genesis_context *gen = (genesis_context *)sys;
 	uint32_t address;
+#ifndef NEW_CORE
 	if (gen->m68k->resume_pc) {
 		
 		gen->header.save_state = SERIALIZE_SLOT+1;
@@ -151,7 +152,9 @@
 		uint8_t *ret = gen->serialize_tmp;
 		gen->serialize_tmp = NULL;
 		return ret;
-	} else {
+	} else 
+#endif
+	{
 		serialize_buffer state;
 		init_serialize(&state);
 		uint32_t address = read_word(4, (void **)gen->m68k->mem_pointers, &gen->m68k->opts->gen, gen->m68k) << 16;
@@ -223,7 +226,9 @@
 static void adjust_int_cycle(m68k_context * context, vdp_context * v_context);
 static void check_tmss_lock(genesis_context *gen);
 static void toggle_tmss_rom(genesis_context *gen);
+#ifndef NEW_CORE
 #include "m68k_internal.h" //needed for get_native_address_trans, should be eliminated once handling of PC is cleaned up
+#endif
 void genesis_deserialize(deserialize_buffer *buf, genesis_context *gen)
 {
 	register_section_handler(buf, (section_handler){.fun = m68k_deserialize, .data = gen->m68k}, SECTION_68000);
@@ -268,6 +273,7 @@
 	}
 	update_z80_bank_pointer(gen);
 	adjust_int_cycle(gen->m68k, gen->vdp);
+#ifndef NEW_CORE
 	//HACK: Fix this once PC/IR is represented in a better way in 68K core
 	//Would be better for this hack to live in side the 68K core itself, but it's better to do it
 	//after RAM has been loaded to avoid any unnecessary retranslation
@@ -276,6 +282,7 @@
 		segacd_context *cd = gen->expansion;
 		cd->m68k->resume_pc = get_native_address_trans(cd->m68k, cd->m68k->last_prefetch_address);
 	}
+#endif
 	free(buf->handlers);
 	buf->handlers = NULL;
 }
@@ -301,9 +308,12 @@
 		uint32_t word_ram = cd->base + 0x200000;
 		uint32_t word_ram_end = cd->base + 0x240000;
 		if (address >= word_ram && address < word_ram_end) {
-			//FIXME: first word should just be garbage
 			if (!cd->has_vdp_dma_value) {
+#ifdef NEW_CORE
+				cd->vdp_dma_value = genesis->m68k->prefetch;
+#else
 				cd->vdp_dma_value = read_word(genesis->m68k->last_prefetch_address, (void **)genesis->m68k->mem_pointers, &genesis->m68k->opts->gen, genesis->m68k);
+#endif
 				cd->has_vdp_dma_value = 1;
 			}
 			uint16_t ret = cd->vdp_dma_value;
@@ -328,7 +338,11 @@
 static uint16_t get_open_bus_value(system_header *system)
 {
 	genesis_context *genesis = (genesis_context *)system;
+#ifdef NEW_CORE
+	return genesis->m68k->prefetch;
+#else
 	return read_dma_value(genesis->m68k->last_prefetch_address/2);
+#endif
 }
 
 static void adjust_int_cycle(m68k_context * context, vdp_context * v_context)
@@ -1945,6 +1959,7 @@
 	deserialize_buffer state;
 	uint32_t pc = 0;
 	uint8_t ret;
+#ifndef NEW_CORE
 	if (!gen->m68k->resume_pc) {
 		system->delayed_load_slot = slot + 1;
 		gen->m68k->should_return = 1;
@@ -1955,6 +1970,7 @@
 		}
 		goto done;
 	}
+#endif
 	if (load_from_file(&state, statepath)) {
 		genesis_deserialize(&state, gen);
 		free(state.data);
@@ -2015,8 +2031,12 @@
 		if (load_from_file(&state, statefile)) {
 			genesis_deserialize(&state, gen);
 			free(state.data);
+#ifdef NEW_CORE
+			pc = gen->m68k->pc;
+#else
 			//HACK
 			pc = gen->m68k->last_prefetch_address;
+#endif
 		} else {
 			pc = load_gst(gen, statefile);
 			if (!pc) {
@@ -2047,6 +2067,12 @@
 		}
 		m68k_reset(gen->m68k);
 	}
+#ifdef NEW_CORE
+	while (!gen->m68k->should_return) {
+		sync_components(gen->m68k, 0);
+		m68k_execute(gen->m68k, gen->m68k->target_cycle);
+	}
+#endif
 	handle_reset_requests(gen);
 	return;
 }
--- a/gst.c	Tue Apr 30 00:02:14 2024 -0700
+++ b/gst.c	Tue Apr 30 22:32:08 2024 -0700
@@ -86,10 +86,14 @@
 	uint32_t pc = read_le_32(buffer + GST_68K_PC_OFFSET);
 	uint16_t sr = read_le_16(buffer + GST_68K_SR_OFFSET);
 	context->status = sr >> 8;
+#ifdef NEW_CORE
+	//TODO: implement me
+#else
 	for (int flag = 4; flag >= 0; flag--) {
 		context->flags[flag] = sr & 1;
 		sr >>= 1;
 	}
+#endif
 	if (context->status & (1 << 5)) {
 		context->aregs[8] = read_le_32(buffer + GST_68K_USP_OFFSET);
 	} else {
@@ -113,10 +117,14 @@
 	}
 	write_le_32(buffer + GST_68K_PC_OFFSET, pc);
 	uint16_t sr = context->status << 3;
+#ifdef NEW_CORE
+	//TODO: implement me
+#else
 	for (int flag = 4; flag >= 0; flag--) {
 		sr <<= 1;
 		sr |= context->flags[flag];
 	}
+#endif
 	write_le_16(buffer + GST_68K_SR_OFFSET, sr);
 	if (context->status & (1 << 5)) {
 		write_le_32(buffer + GST_68K_USP_OFFSET, context->aregs[8]);
@@ -412,7 +420,9 @@
 	return 1;
 }
 
+#ifndef NEW_CORE
 #include "m68k_internal.h" //needed for get_native_address_trans, should be eliminated once handling of PC is cleaned up
+#endif
 uint32_t load_gst(genesis_context * gen, char * fname)
 {
 	char buffer[4096];
@@ -462,7 +472,11 @@
 			i++;
 		}
 	}
+#ifdef NEW_CORE
+	gen->m68k->pc = pc;
+#else
 	gen->m68k->resume_pc = get_native_address_trans(gen->m68k, pc);
+#endif
 	fclose(gstfile);
 	return pc;
 
--- a/m68k.cpu	Tue Apr 30 00:02:14 2024 -0700
+++ b/m68k.cpu	Tue Apr 30 22:32:08 2024 -0700
@@ -17,6 +17,7 @@
 	void m68k_print_regs(m68k_context *context);
 	void m68k_serialize(m68k_context *context, uint32_t pc, serialize_buffer *buf);
 	void m68k_deserialize(deserialize_buffer *buf, void *vcontext);
+	void start_68k_context(m68k_context *context, uint32_t pc);
 	define NUM_MEM_AREAS 10
 	define M68K_OPT_BROKEN_READ_MODIFY 1
 	define INT_PENDING_SR_CHANGE 254
@@ -25,7 +26,11 @@
 	define m68k_invalidate_code_range(context, start, end)
 	define m68k_options_free free
 	define m68k_handle_code_write(address, context)
-	define resume_68k(context) m68k_execute(context, context->cycles)
+	define resume_68k(context) m68k_execute(context, context->target_cycle)
+	define insert_breakpoint(context, address, handler)
+	define remove_breakpoint(context, address)
+	define m68k_add_watchpoint(context, address, size)
+	define m68k_remove_watchpoint(context, address, size)
 
 regs
 	dregs 32 d0 d1 d2 d3 d4 d5 d6 d7
@@ -54,9 +59,10 @@
 	cflag 8
 	wp_hit 8
 	trace_pending 8
+	should_return 8
 	system ptrvoid
 	reset_handler ptrvoid
-	mem_pointers ptrvoid 10
+	mem_pointers ptr16 10
 	
 flags
 	register ccr
--- a/m68k_util.c	Tue Apr 30 00:02:14 2024 -0700
+++ b/m68k_util.c	Tue Apr 30 22:32:08 2024 -0700
@@ -97,3 +97,11 @@
 {
 	//TODO: implement me
 }
+
+void start_68k_context(m68k_context *context, uint32_t pc)
+{
+	context->scratch1 = context->pc = pc;
+	m68k_read_16(context);
+	context->prefetch = context->scratch1;
+	context->pc += 2;
+}
--- a/sega_mapper.c	Tue Apr 30 00:02:14 2024 -0700
+++ b/sega_mapper.c	Tue Apr 30 22:32:08 2024 -0700
@@ -280,7 +280,11 @@
 		//ensure USB serial read returns "not-ready" status
 		return 0x02;
 	default:
+#ifdef NEW_CORE
+		return context->prefetch;
+#else
 		return read_word(context->last_prefetch_address, (void **)context->mem_pointers, &context->opts->gen, context);
+#endif
 	}
 }
 
--- a/segacd.c	Tue Apr 30 00:02:14 2024 -0700
+++ b/segacd.c	Tue Apr 30 22:32:08 2024 -0700
@@ -449,7 +449,11 @@
 	m68k_context *m68k = vcontext;
 	genesis_context *gen = m68k->system;
 	segacd_context *cd = gen->expansion;
+#ifdef NEW_CORE
+	uint16_t open_bus = m68k->prefetch;
+#else
 	uint16_t open_bus = read_word(m68k->last_prefetch_address, (void **)m68k->mem_pointers, &m68k->opts->gen, m68k);
+#endif
 	if (cd->bram_cart_id > 7) {
 		// No cart, just return open bus
 		return open_bus;
@@ -477,19 +481,31 @@
 	segacd_context *cd = gen->expansion;
 	if (!(address & 1) || cd->bram_cart_id > 7) {
 		//open bus
+#ifdef NEW_CORE
+		return (address & 1) ? m68k->prefetch : m68k->prefetch >> 8;
+#else
 		return read_byte(m68k->last_prefetch_address | (address & 1), (void **)m68k->mem_pointers, &m68k->opts->gen, m68k);
+#endif
 	}
 	address &= 0x3FFFFF;
 	if (address < 0x200000) {
 		if (address < 0x100000) {
 			return cd->bram_cart_id;
 		}
+#ifdef NEW_CORE
+		return m68k->prefetch;
+#else
 		return read_byte(m68k->last_prefetch_address | 1, (void **)m68k->mem_pointers, &m68k->opts->gen, m68k);
+#endif
 	} else {
 		address &= 0x1FFFFF;
 		uint32_t end = 0x2000 << (1 + cd->bram_cart_id);
 		if (address >= end) {
+#ifdef NEW_CORE
+			return m68k->prefetch;
+#else
 			return read_byte(m68k->last_prefetch_address | 1, (void **)m68k->mem_pointers, &m68k->opts->gen, m68k);
+#endif
 		}
 		return cd->bram_cart[address >> 1];
 	}
--- a/sms.c	Tue Apr 30 00:02:14 2024 -0700
+++ b/sms.c	Tue Apr 30 22:32:08 2024 -0700
@@ -478,6 +478,7 @@
 				}
 			}
 		}
+#ifndef NEW_CORE
 		if ((system->enter_debugger || sms->z80->wp_hit) && sms->z80->pc) {
 			if (!sms->z80->wp_hit) {
 				system->enter_debugger = 0;
@@ -486,6 +487,7 @@
 			zdebugger(sms->z80, sms->z80->pc);
 #endif
 		}
+#endif
 #ifdef NEW_CORE
 		if (sms->z80->nmi_cycle == CYCLE_NEVER) {
 #else
@@ -497,9 +499,11 @@
 			}
 		}
 
+#ifndef NEW_CORE
 		if (system->enter_debugger || sms->z80->wp_hit) {
 			target_cycle = sms->z80->Z80_CYCLE + 1;
 		}
+#endif
 		z80_run(sms->z80, target_cycle);
 		if (sms->z80->reset) {
 			z80_clear_reset(sms->z80, sms->z80->Z80_CYCLE + 128*15);