changeset 2138:b6338e18787e

Fix some dynarec code invalidation issues
author Michael Pavone <pavone@retrodev.com>
date Sat, 19 Mar 2022 15:50:45 -0700
parents 3ef9456b76cf
children 11a3d5b00a66
files backend_x86.c segacd.c
diffstat 2 files changed, 25 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/backend_x86.c	Sat Mar 19 00:42:05 2022 -0700
+++ b/backend_x86.c	Sat Mar 19 15:50:45 2022 -0700
@@ -166,7 +166,12 @@
 			and_ir(code, memmap[chunk].mask, adr_reg, opts->address_size);
 		}
 		code_ptr after_normal = NULL;
+		uint8_t need_addr_pop = 0;
 		if (size == SZ_B && memmap[chunk].shift != 0) {
+			if (is_write && (memmap[chunk].flags & MMAP_CODE)) {
+				push_r(code, adr_reg);
+				need_addr_pop = 1;
+			}
 			btr_ir(code, 0, adr_reg, opts->address_size);
 			code_ptr normal = code->cur+1;
 			jcc(code, CC_NC, normal);
@@ -181,8 +186,16 @@
 			*normal = code->cur - (normal + 1);
 		}
 		if (memmap[chunk].shift > 0) {
+			if (!need_addr_pop && is_write && (memmap[chunk].flags & MMAP_CODE)) {
+				push_r(code, adr_reg);
+				need_addr_pop = 1;
+			}
 			shl_ir(code, memmap[chunk].shift, adr_reg, opts->address_size);
 		} else if (memmap[chunk].shift < 0) {
+			if (!need_addr_pop && is_write && (memmap[chunk].flags & MMAP_CODE)) {
+				push_r(code, adr_reg);
+				need_addr_pop = 1;
+			}
 			shr_ir(code, -memmap[chunk].shift, adr_reg, opts->address_size);
 		}
 		if (after_normal) {
@@ -232,15 +245,13 @@
 				if (opts->address_size != SZ_D) {
 					movzx_rr(code, adr_reg, adr_reg, opts->address_size, SZ_D);
 				}
-				if (is_write && (memmap[chunk].flags & MMAP_CODE)) {
+				if (!need_addr_pop && is_write && (memmap[chunk].flags & MMAP_CODE)) {
 					push_r(code, adr_reg);
+					need_addr_pop = 1;
 				}
 				add_rdispr(code, opts->context_reg, opts->mem_ptr_off + sizeof(void*) * memmap[chunk].ptr_index, adr_reg, SZ_PTR);
 				if (is_write) {
 					mov_rrind(code, opts->scratch1, opts->scratch2, size);
-					if (memmap[chunk].flags & MMAP_CODE) {
-						pop_r(code, adr_reg);
-					}
 				} else {
 					mov_rindr(code, opts->scratch1, opts->scratch1, size);
 				}
@@ -283,7 +294,7 @@
 						add_rdispr(code, RSP, 0, opts->scratch2, SZ_PTR);
 						mov_rrind(code, opts->scratch1, opts->scratch2, tmp_size);
 						if (is_write && (memmap[chunk].flags & MMAP_CODE)) {
-							pop_r(code, opts->scratch2);
+							need_addr_pop = 1;
 						} else {
 							add_ir(code, sizeof(void*), RSP, SZ_PTR);
 							code->stack_off -= sizeof(void *);
@@ -305,6 +316,9 @@
 				}
 			}
 			if (is_write && (memmap[chunk].flags & MMAP_CODE)) {
+				if (need_addr_pop) {
+					pop_r(code, adr_reg);
+				}
 				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, ram_flags_off, opts->address_size);
--- a/segacd.c	Sat Mar 19 00:42:05 2022 -0700
+++ b/segacd.c	Sat Mar 19 15:50:45 2022 -0700
@@ -157,6 +157,7 @@
 	m68k_context *m68k = vcontext;
 	segacd_context *cd = m68k->system;
 	if (!(cd->gate_array[GA_MEM_MODE] & BIT_MEM_MODE)) {
+		//TODO: Confirm this first write goes through (seemed like it in initial testing)
 		if (address & 1) {
 			address >>= 1;
 			cd->word_ram[address] &= 0xFF00;
@@ -166,6 +167,7 @@
 			cd->word_ram[address] &= 0x00FF;
 			cd->word_ram[address] |= value << 8;
 		}
+		m68k_invalidate_code_range(cd->genesis->m68k, cd->base + 0x200000 + (address & ~1), cd->base + 0x200000 + (address & ~1) + 1);
 		cd->sub_paused_wordram = 1;
 		m68k->sync_cycle = m68k->target_cycle = m68k->current_cycle;
 		m68k->should_return = 1;
@@ -207,6 +209,7 @@
 
 static uint16_t word_ram_1M_read16(uint32_t address, void *vcontext)
 {
+	//TODO: check behavior for these on hardware
 	return 0;
 }
 
@@ -300,7 +303,7 @@
 			cd->word_ram[address + cd->bank_toggle] &= 0xFF;
 			cd->word_ram[address + cd->bank_toggle] |= value << 8;
 		}
-		m68k_invalidate_code_range(m68k, cd->base + 0x200000 + (address & ~1), cd->base + 0x200000 + address + 1);
+		m68k_invalidate_code_range(m68k, cd->base + 0x200000 + (address & ~1), cd->base + 0x200000 + (address & ~1) + 1);
 	}
 	return vcontext;
 }
@@ -362,6 +365,7 @@
 	if (cd->gate_array[GA_MEM_MODE] & BIT_MEM_MODE) {
 		address = cell_image_translate_address(address);
 		cd->word_ram[address + cd->bank_toggle] = value;
+		m68k_invalidate_code_range(m68k, cd->base + 0x200000 + address, cd->base + 0x200000 + address + 1);
 	}
 	return vcontext;
 }
@@ -381,6 +385,7 @@
 			cd->word_ram[address + cd->bank_toggle] &= 0x00FF;
 			cd->word_ram[address + cd->bank_toggle] |= value << 8;
 		}
+		m68k_invalidate_code_range(m68k, cd->base + 0x200000 + address, cd->base + 0x200000 + address + 1);
 	}
 	return vcontext;
 }