changeset 2237:f82c090c1e89

Implement MMAP_ONLY_ODD/EVEN in combination with MMAP_PTR_IDX. Fixes games that have SRAM when a system with TMSS is selected
author Michael Pavone <pavone@retrodev.com>
date Sat, 17 Sep 2022 15:38:40 -0700
parents c149c929361c
children 0a107b2d5837
files backend_x86.c
diffstat 1 files changed, 31 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/backend_x86.c	Tue Sep 13 20:18:03 2022 -0700
+++ b/backend_x86.c	Sat Sep 17 15:38:40 2022 -0700
@@ -220,6 +220,7 @@
 			cfun = NULL;
 		}
 		if(memmap[chunk].flags & access_flag) {
+			uint8_t tmp_size = size;
 			if (memmap[chunk].flags & MMAP_PTR_IDX) {
 				if (memmap[chunk].flags & MMAP_FUNC_NULL) {
 					cmp_irdisp(code, 0, opts->context_reg, opts->mem_ptr_off + sizeof(void*) * memmap[chunk].ptr_index, SZ_PTR);
@@ -239,8 +240,26 @@
 
 					*not_null = code->cur - (not_null + 1);
 				}
-				if ((opts->byte_swap || memmap[chunk].flags & MMAP_BYTESWAP) && size == SZ_B) {
-					xor_ir(code, 1, adr_reg, opts->address_size);
+				if (size == SZ_B) {
+					if ((memmap[chunk].flags & MMAP_ONLY_ODD) || (memmap[chunk].flags & MMAP_ONLY_EVEN)) {
+						bt_ir(code, 0, adr_reg, opts->address_size);
+						code_ptr good_addr = code->cur + 1;
+						jcc(code, (memmap[chunk].flags & MMAP_ONLY_ODD) ? CC_C : CC_NC, code->cur + 2);
+						if (!is_write) {
+							mov_ir(code, 0xFF, opts->scratch1, SZ_B);
+						}
+						retn(code);
+						*good_addr = code->cur - (good_addr + 1);
+						shr_ir(code, 1, adr_reg, opts->address_size);
+					} else if (opts->byte_swap || memmap[chunk].flags & MMAP_BYTESWAP) {
+						xor_ir(code, 1, adr_reg, opts->address_size);
+					}
+				} else if ((memmap[chunk].flags & MMAP_ONLY_ODD) || (memmap[chunk].flags & MMAP_ONLY_EVEN)) {
+					tmp_size = SZ_B;
+					shr_ir(code, 1, adr_reg, opts->address_size);
+					if ((memmap[chunk].flags & MMAP_ONLY_EVEN) && is_write) {
+						shr_ir(code, 8, opts->scratch1, SZ_W);
+					}
 				}
 				if (opts->address_size != SZ_D) {
 					movzx_rr(code, adr_reg, adr_reg, opts->address_size, SZ_D);
@@ -251,12 +270,19 @@
 				}
 				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);
+					mov_rrind(code, opts->scratch1, opts->scratch2, tmp_size);
 				} else {
-					mov_rindr(code, opts->scratch1, opts->scratch1, size);
+					mov_rindr(code, opts->scratch1, opts->scratch1, tmp_size);
+				}
+				if (size != tmp_size && !is_write) {
+					if (memmap[chunk].flags & MMAP_ONLY_EVEN) {
+						shl_ir(code, 8, opts->scratch1, SZ_W);
+						mov_ir(code, 0xFF, opts->scratch1, SZ_B);
+					} else {
+						or_ir(code, 0xFF00, opts->scratch1, SZ_W);
+					}
 				}
 			} else {
-				uint8_t tmp_size = size;
 				if (size == SZ_B) {
 					if ((memmap[chunk].flags & MMAP_ONLY_ODD) || (memmap[chunk].flags & MMAP_ONLY_EVEN)) {
 						bt_ir(code, 0, adr_reg, opts->address_size);