changeset 985:751280fb4494

Fix interrupt latency from STOP instruction status reg changes. Fix modified code patching when non-standard aliases are used. This fixes the demo MDEM's First
author Michael Pavone <pavone@retrodev.com>
date Sun, 24 Apr 2016 21:23:28 -0700
parents bd4d698d995b
children f680fe746a7d
files debug.c m68k_core.c m68k_core.h m68k_core_x86.c
diffstat 4 files changed, 37 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/debug.c	Sun Apr 24 14:30:15 2016 -0700
+++ b/debug.c	Sun Apr 24 21:23:28 2016 -0700
@@ -572,7 +572,7 @@
 					uint8_t non_adr_count = 0;
 					do {
 						uint32_t bt_address = ram[stack/2] << 16 | ram[stack/2+1];
-						bt_address = get_instruction_start(context->native_code_map, bt_address - 2);
+						bt_address = get_instruction_start(context->options, context->native_code_map, bt_address - 2);
 						if (bt_address) {
 							stack += 4;
 							non_adr_count = 0;
--- a/m68k_core.c	Sun Apr 24 14:30:15 2016 -0700
+++ b/m68k_core.c	Sun Apr 24 21:23:28 2016 -0700
@@ -547,6 +547,13 @@
 	if (address & 1) {
 		return opts->odd_address;
 	}
+	//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) {
+			//calculate the lowest alias for this address
+			address = opts->gen.memmap[i].start + ((address - opts->gen.memmap[i].start) & opts->gen.memmap[i].mask);
+		}
+	}
 	address /= 2;
 	uint32_t chunk = address / NATIVE_CHUNK_SIZE;
 	if (!native_code_map[chunk].base) {
@@ -564,10 +571,17 @@
 	return get_native_address(context->options, address);
 }
 
-uint32_t get_instruction_start(native_map_slot * native_code_map, uint32_t address)
+uint32_t get_instruction_start(m68k_options *opts, native_map_slot * native_code_map, uint32_t address)
 {
-	//FIXME: Use opts->gen.address_mask
-	address &= 0xFFFFFF;
+	address &= opts->gen.address_mask;
+	//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) {
+			//calculate the lowest alias for this address
+			address = opts->gen.memmap[i].start + ((address - opts->gen.memmap[i].start) & opts->gen.memmap[i].mask);
+		}
+	}
+	
 	address /= 2;
 	uint32_t chunk = address / NATIVE_CHUNK_SIZE;
 	if (!native_code_map[chunk].base) {
@@ -612,6 +626,8 @@
 				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) & 7);
 			}
+			//calculate the lowest alias for this address
+			address = opts->gen.memmap[i].start + ((address - opts->gen.memmap[i].start) & 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);
--- a/m68k_core.h	Sun Apr 24 14:30:15 2016 -0700
+++ b/m68k_core.h	Sun Apr 24 21:23:28 2016 -0700
@@ -79,7 +79,7 @@
 void insert_breakpoint(m68k_context * context, uint32_t address, uint8_t * bp_handler);
 void remove_breakpoint(m68k_context * context, uint32_t address);
 m68k_context * m68k_handle_code_write(uint32_t address, m68k_context * context);
-uint32_t get_instruction_start(native_map_slot * native_code_map, uint32_t address);
+uint32_t get_instruction_start(m68k_options *opts, native_map_slot * native_code_map, uint32_t address);
 
 #endif //M68K_CORE_H_
 
--- a/m68k_core_x86.c	Sun Apr 24 14:30:15 2016 -0700
+++ b/m68k_core_x86.c	Sun Apr 24 21:23:28 2016 -0700
@@ -2121,18 +2121,20 @@
 		swap_ssp_usp(opts);
 	}
 	code_ptr loop_top = code->cur;
-	call(code, opts->do_sync);
-	cmp_rr(code, opts->gen.limit, opts->gen.cycles, SZ_D);
-	code_ptr normal_cycle_up = code->cur + 1;
-	jcc(code, CC_A, code->cur + 2);
-	cycles(&opts->gen, BUS);
-	code_ptr after_cycle_up = code->cur + 1;
-	jmp(code, code->cur + 2);
-	*normal_cycle_up = code->cur - (normal_cycle_up + 1);
-	mov_rr(code, opts->gen.limit, opts->gen.cycles, SZ_D);
-	*after_cycle_up = code->cur - (after_cycle_up+1);
-	cmp_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, int_cycle), opts->gen.cycles, SZ_D);
+		call(code, opts->do_sync);
+		cmp_rr(code, opts->gen.limit, opts->gen.cycles, SZ_D);
+		code_ptr normal_cycle_up = code->cur + 1;
+		jcc(code, CC_A, code->cur + 2);
+			cycles(&opts->gen, BUS);
+			code_ptr after_cycle_up = code->cur + 1;
+			jmp(code, code->cur + 2);
+		*normal_cycle_up = code->cur - (normal_cycle_up + 1);
+			mov_rr(code, opts->gen.limit, opts->gen.cycles, SZ_D);
+		*after_cycle_up = code->cur - (after_cycle_up+1);
+		cmp_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, int_cycle), opts->gen.cycles, SZ_D);
 	jcc(code, CC_C, loop_top);
+	//set int pending flag so interrupt fires immediately after stop is done
+	mov_irdisp(code, 1, opts->gen.context_reg, offsetof(m68k_context, int_pending), SZ_B);
 }
 
 void translate_m68k_trapv(m68k_options *opts, m68kinst *inst)
@@ -2185,9 +2187,10 @@
 
 m68k_context * m68k_handle_code_write(uint32_t address, m68k_context * context)
 {
-	uint32_t inst_start = get_instruction_start(context->native_code_map, address | 0xFF0000);
+	m68k_options * options = context->options;
+	//TODO: Modify gen_mem_fun so that it passes the raw address instead of the masked one, then remove the OR below
+	uint32_t inst_start = get_instruction_start(options, context->native_code_map, address | 0xE00000);
 	if (inst_start) {
-		m68k_options * options = context->options;
 		code_info *code = &options->gen.code;
 		code_ptr dst = get_native_address(context->options, inst_start);
 		code_info orig = {dst, dst + 128, 0};