changeset 690:fc04781f4d28

Removed hardcoded assumptions in M68K core about which parts of the memory map are RAM
author Michael Pavone <pavone@retrodev.com>
date Wed, 14 Jan 2015 09:38:54 -0800
parents 858e31f977ae
children 74d636e85bf8
files backend.c backend.h backend_x86.c blastem.c m68k_core.c m68k_core.h m68k_core_x86.c
diffstat 7 files changed, 106 insertions(+), 37 deletions(-) [+]
line wrap: on
line diff
--- a/backend.c	Thu Jan 08 23:20:41 2015 -0800
+++ b/backend.c	Wed Jan 14 09:38:54 2015 -0800
@@ -72,3 +72,28 @@
 	}
 	return NULL;
 }
+
+uint32_t chunk_size(cpu_options *opts, memmap_chunk const *chunk)
+{
+	if (chunk->mask == opts->address_mask) {
+		return chunk->end - chunk->start;
+	} else {
+		return chunk->mask + 1;
+	}
+}
+
+uint32_t ram_size(cpu_options *opts)
+{
+	uint32_t size = 0;
+	for (int i = 0; i < opts->memmap_chunks; i++)
+	{
+		if ((opts->memmap[i].flags & (MMAP_WRITE | MMAP_CODE)) == (MMAP_WRITE | MMAP_CODE)) {
+			if (opts->memmap[i].mask == opts->address_mask) {
+				size += opts->memmap[i].end - opts->memmap[i].start;
+			} else {
+				size += opts->memmap[i].mask + 1;
+			}
+		}
+	}
+	return size;
+}
--- a/backend.h	Thu Jan 08 23:20:41 2015 -0800
+++ b/backend.h	Wed Jan 14 09:38:54 2015 -0800
@@ -116,6 +116,8 @@
 
 code_ptr gen_mem_fun(cpu_options * opts, memmap_chunk const * memmap, uint32_t num_chunks, ftype fun_type, code_ptr *after_inc);
 void * get_native_pointer(uint32_t address, void ** mem_pointers, cpu_options * opts);
+uint32_t chunk_size(cpu_options *opts, memmap_chunk const *chunk);
+uint32_t ram_size(cpu_options *opts);
 
 #endif //BACKEND_H_
 
--- a/backend_x86.c	Thu Jan 08 23:20:41 2015 -0800
+++ b/backend_x86.c	Wed Jan 14 09:38:54 2015 -0800
@@ -50,6 +50,7 @@
 	uint8_t adr_reg = is_write ? opts->scratch2 : opts->scratch1;
 	uint16_t access_flag = is_write ? MMAP_WRITE : MMAP_READ;
 	uint8_t size =  (fun_type == READ_16 || fun_type == WRITE_16) ? SZ_W : SZ_B;
+	uint32_t ram_flags_off = opts->ram_flags_off;
 	for (uint32_t chunk = 0; chunk < num_chunks; chunk++)
 	{
 		if (memmap[chunk].start > 0) {
@@ -173,7 +174,12 @@
 			if (is_write && (memmap[chunk].flags & MMAP_CODE)) {
 				mov_rr(code, opts->scratch2, opts->scratch1, opts->address_size);
 				shr_ir(code, opts->ram_flags_shift, opts->scratch1, opts->address_size);
-				bt_rrdisp(code, opts->scratch1, opts->context_reg, opts->ram_flags_off, opts->address_size);
+				bt_rrdisp(code, opts->scratch1, opts->context_reg, ram_flags_off, opts->address_size);
+				if (memmap[chunk].mask == opts->address_mask) {
+					ram_flags_off += memmap[chunk].end - memmap[chunk].start;
+				} else {
+					ram_flags_off += memmap[chunk].mask + 1;
+				}
 				code_ptr not_code = code->cur + 1;
 				jcc(code, CC_NC, code->cur + 2);
 				call(code, opts->save_context);
--- a/blastem.c	Thu Jan 08 23:20:41 2015 -0800
+++ b/blastem.c	Wed Jan 14 09:38:54 2015 -0800
@@ -901,9 +901,7 @@
 
 void init_run_cpu(genesis_context * gen, FILE * address_log, char * statefile, uint8_t * debugger)
 {
-	m68k_context context;
 	m68k_options opts;
-	gen->m68k = &context;
 	memmap_chunk memmap[MAX_MAP_CHUNKS];
 	uint32_t num_chunks;
 	void * initial_mapped = NULL;
@@ -998,21 +996,22 @@
 	}
 	init_m68k_opts(&opts, memmap, num_chunks, MCLKS_PER_68K);
 	opts.address_log = address_log;
-	init_68k_context(&context, opts.gen.native_code_map, &opts);
+	m68k_context *context = init_68k_context(&opts);
+	gen->m68k = context;
 
-	context.video_context = gen->vdp;
-	context.system = gen;
+	context->video_context = gen->vdp;
+	context->system = gen;
 	//cartridge ROM
-	context.mem_pointers[0] = cart;
-	context.target_cycle = context.sync_cycle = mclk_target;
+	context->mem_pointers[0] = cart;
+	context->target_cycle = context->sync_cycle = mclk_target;
 	//work RAM
-	context.mem_pointers[1] = ram;
+	context->mem_pointers[1] = ram;
 	//save RAM/map
-	context.mem_pointers[2] = initial_mapped;
-	context.mem_pointers[3] = (uint16_t *)gen->save_ram;
+	context->mem_pointers[2] = initial_mapped;
+	context->mem_pointers[3] = (uint16_t *)gen->save_ram;
 	uint32_t address;
 	address = cart[2] << 16 | cart[3];
-	translate_m68k_stream(address, &context);
+	translate_m68k_stream(address, context);
 	if (statefile) {
 		uint32_t pc = load_gst(gen, statefile);
 		if (!pc) {
@@ -1021,15 +1020,15 @@
 		}
 		printf("Loaded %s\n", statefile);
 		if (debugger) {
-			insert_breakpoint(&context, pc, debugger);
+			insert_breakpoint(context, pc, debugger);
 		}
 		adjust_int_cycle(gen->m68k, gen->vdp);
-		start_68k_context(&context, pc);
+		start_68k_context(context, pc);
 	} else {
 		if (debugger) {
-			insert_breakpoint(&context, address, debugger);
+			insert_breakpoint(context, address, debugger);
 		}
-		m68k_reset(&context);
+		m68k_reset(context);
 	}
 }
 
--- a/m68k_core.c	Thu Jan 08 23:20:41 2015 -0800
+++ b/m68k_core.c	Wed Jan 14 09:38:54 2015 -0800
@@ -553,6 +553,7 @@
 
 code_ptr get_native_address(native_map_slot * native_code_map, uint32_t address)
 {
+	//FIXME: Use opts->gen.address_mask
 	address &= 0xFFFFFF;
 	address /= 2;
 	uint32_t chunk = address / NATIVE_CHUNK_SIZE;
@@ -573,6 +574,7 @@
 
 uint32_t get_instruction_start(native_map_slot * native_code_map, uint32_t address)
 {
+	//FIXME: Use opts->gen.address_mask
 	address &= 0xFFFFFF;
 	address /= 2;
 	uint32_t chunk = address / NATIVE_CHUNK_SIZE;
@@ -595,17 +597,34 @@
 {
 	native_map_slot * native_code_map = context->native_code_map;
 	m68k_options * opts = context->options;
-	address &= 0xFFFFFF;
-	if (address > 0xE00000) {
-		context->ram_code_flags[(address & 0xC000) >> 14] |= 1 << ((address & 0x3800) >> 11);
-		if (((address & 0x3FFF) + size) & 0xC000) {
-			context->ram_code_flags[((address+size) & 0xC000) >> 14] |= 1 << (((address+size) & 0x3800) >> 11);
+	address &= opts->gen.address_mask;
+	uint32_t meta_off = 0;
+	//TODO: Refactor part of this loop into some kind of get_ram_chunk function
+	for (int i = 0; i < opts->gen.memmap_chunks; i++) {
+		if (address >= opts->gen.memmap[i].start && address < opts->gen.memmap[i].end) {
+			if ((opts->gen.memmap[i].flags & (MMAP_WRITE | MMAP_CODE)) == (MMAP_WRITE | MMAP_CODE)) {
+				uint32_t masked = (address & opts->gen.memmap[i].mask);
+				uint32_t final_off = masked + meta_off;
+				uint32_t ram_flags_off = final_off >> (opts->gen.ram_flags_shift + 3);
+				context->ram_code_flags[ram_flags_off] |= 1 << ((final_off >> opts->gen.ram_flags_shift) & 3);
+
+				uint32_t slot = final_off / 1024;
+				if (!opts->gen.ram_inst_sizes[slot]) {
+					opts->gen.ram_inst_sizes[slot] = malloc(sizeof(uint8_t) * 512);
+				}
+				opts->gen.ram_inst_sizes[slot][(final_off/2) & 511] = native_size;
+
+				//TODO: Deal with case in which end of instruction is in a different memory chunk
+				masked = (address + size - 1) & opts->gen.memmap[i].mask;
+				final_off = masked + meta_off;
+				ram_flags_off = final_off >> (opts->gen.ram_flags_shift + 3);
+				context->ram_code_flags[ram_flags_off] |= 1 << ((final_off >> opts->gen.ram_flags_shift) & 3);
+			}
+			break;
+		} else if ((opts->gen.memmap[i].flags & (MMAP_WRITE | MMAP_CODE)) == (MMAP_WRITE | MMAP_CODE)) {
+			uint32_t size = chunk_size(&opts->gen, opts->gen.memmap + i);
+			meta_off += size;
 		}
-		uint32_t slot = (address & 0xFFFF)/1024;
-		if (!opts->gen.ram_inst_sizes[slot]) {
-			opts->gen.ram_inst_sizes[slot] = malloc(sizeof(uint8_t) * 512);
-		}
-		opts->gen.ram_inst_sizes[slot][((address & 0xFFFF)/2)%512] = native_size;
 	}
 	address/= 2;
 	uint32_t chunk = address / NATIVE_CHUNK_SIZE;
@@ -630,11 +649,22 @@
 
 uint8_t get_native_inst_size(m68k_options * opts, uint32_t address)
 {
-	if (address < 0xE00000) {
-		return 0;
+	address &= opts->gen.address_mask;
+	uint32_t meta_off = 0;
+	for (int i = 0; i < opts->gen.memmap_chunks; i++) {
+		if (address >= opts->gen.memmap[i].start && address < opts->gen.memmap[i].end) {
+			if ((opts->gen.memmap[i].flags & (MMAP_WRITE | MMAP_CODE)) != (MMAP_WRITE | MMAP_CODE)) {
+				return 0;
+			}
+			meta_off += address & opts->gen.memmap[i].mask;
+			break;
+		} else if ((opts->gen.memmap[i].flags & (MMAP_WRITE | MMAP_CODE)) == (MMAP_WRITE | MMAP_CODE)) {
+			uint32_t size = chunk_size(&opts->gen, opts->gen.memmap + i);
+			meta_off += size;
+		}
 	}
-	uint32_t slot = (address & 0xFFFF)/1024;
-	return opts->gen.ram_inst_sizes[slot][((address & 0xFFFF)/2)%512];
+	uint32_t slot = meta_off/1024;
+	return opts->gen.ram_inst_sizes[slot][(meta_off/2)%512];
 }
 
 uint8_t m68k_is_terminal(m68kinst * inst)
@@ -926,6 +956,7 @@
 
 code_ptr get_native_address_trans(m68k_context * context, uint32_t address)
 {
+	//FIXME: Use opts->gen.address_mask
 	address &= 0xFFFFFF;
 	code_ptr ret = get_native_address(context->native_code_map, address);
 	if (!ret) {
@@ -962,11 +993,13 @@
 }
 
 
-void init_68k_context(m68k_context * context, native_map_slot * native_code_map, void * opts)
+m68k_context * init_68k_context(m68k_options * opts)
 {
+	m68k_context * context = malloc(sizeof(m68k_context) + ram_size(&opts->gen) / (1 << opts->gen.ram_flags_shift) / 8);
 	memset(context, 0, sizeof(m68k_context));
-	context->native_code_map = native_code_map;
+	context->native_code_map = opts->gen.native_code_map;
 	context->options = opts;
-	context->int_cycle = 0xFFFFFFFF;
+	context->int_cycle = CYCLE_NEVER;
 	context->status = 0x27;
+	return context;
 }
--- a/m68k_core.h	Thu Jan 08 23:20:41 2015 -0800
+++ b/m68k_core.h	Wed Jan 14 09:38:54 2015 -0800
@@ -60,15 +60,15 @@
 
 	native_map_slot *native_code_map;
 	m68k_options    *options;
-	uint8_t         ram_code_flags[32/8];
 	void            *system;
+	uint8_t         ram_code_flags[];
 } m68k_context;
 
 void translate_m68k(m68k_options * opts, struct m68kinst * inst);
 void translate_m68k_stream(uint32_t address, m68k_context * context);
 void start_68k_context(m68k_context * context, uint32_t address);
 void init_m68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chunks, uint32_t clock_divider);
-void init_68k_context(m68k_context * context, native_map_slot * native_code_map, void * opts);
+m68k_context * init_68k_context(m68k_options * opts);
 void m68k_reset(m68k_context * context);
 void insert_breakpoint(m68k_context * context, uint32_t address, uint8_t * bp_handler);
 void remove_breakpoint(m68k_context * context, uint32_t address);
--- a/m68k_core_x86.c	Thu Jan 08 23:20:41 2015 -0800
+++ b/m68k_core_x86.c	Wed Jan 14 09:38:54 2015 -0800
@@ -2202,8 +2202,10 @@
 	opts->gen.native_code_map = malloc(sizeof(native_map_slot) * NATIVE_MAP_CHUNKS);
 	memset(opts->gen.native_code_map, 0, sizeof(native_map_slot) * NATIVE_MAP_CHUNKS);
 	opts->gen.deferred = NULL;
-	opts->gen.ram_inst_sizes = malloc(sizeof(uint8_t *) * 64);
-	memset(opts->gen.ram_inst_sizes, 0, sizeof(uint8_t *) * 64);
+
+	uint32_t inst_size_size = sizeof(uint8_t *) * ram_size(&opts->gen) / 1024;
+	opts->gen.ram_inst_sizes = malloc(inst_size_size);
+	memset(opts->gen.ram_inst_sizes, 0, inst_size_size);
 
 	code_info *code = &opts->gen.code;
 	init_code_info(code);
@@ -2227,9 +2229,11 @@
 
 	opts->gen.load_context = code->cur;
 	for (int i = 0; i < 5; i++)
+	{
 		if (opts->flag_regs[i] >= 0) {
 			mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, flags) + i, opts->flag_regs[i], SZ_B);
 		}
+	}
 	for (int i = 0; i < 8; i++)
 	{
 		if (opts->dregs[i] >= 0) {