summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backend.c2
-rw-r--r--sms.c39
-rw-r--r--z80_to_x86.c41
-rw-r--r--z80_to_x86.h1
4 files changed, 57 insertions, 26 deletions
diff --git a/backend.c b/backend.c
index 00a2d03..7967aa0 100644
--- a/backend.c
+++ b/backend.c
@@ -107,7 +107,7 @@ 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].flags & MMAP_CODE) {
if (opts->memmap[i].mask == opts->address_mask) {
size += opts->memmap[i].end - opts->memmap[i].start;
} else {
diff --git a/sms.c b/sms.c
index 345f85c..cb1805b 100644
--- a/sms.c
+++ b/sms.c
@@ -101,24 +101,19 @@ static void *mapper_write(uint32_t location, void *vcontext, uint8_t value)
{
z80_context *z80 = vcontext;
sms_context *sms = z80->system;
+ void *old_value;
sms->ram[location & (sizeof(sms->ram)-1)] = value;
- switch (location & 3)
- {
- case 0:
+ location &= 3;
+ if (location) {
+ uint32_t idx = location - 1;
+ old_value = z80->mem_pointers[idx];
+ z80->mem_pointers[idx] = sms->rom + (value << 14 & (sms->rom_size-1));
+ if (old_value != z80->mem_pointers[idx]) {
+ //invalidate any code we translated for the relevant bank
+ z80_invalidate_code_range(z80, idx ? idx * 0x4000 : 0x400, idx * 0x4000 + 0x4000);
+ }
+ } else {
//TODO: implement me
- break;
- case 1:
- z80->mem_pointers[0] = sms->rom + (value << 14 & (sms->rom_size-1)) + 0x400;
- //TODO: invalidate translated code in range 0x400-0x4000
- break;
- case 2:
- z80->mem_pointers[1] = sms->rom + (value << 14 & (sms->rom_size-1));
- //TODO: invalidate translated code in range 0x4000-0x8000
- break;
- case 3:
- z80->mem_pointers[2] = sms->rom + (value << 14 & (sms->rom_size-1));
- //TODO: invalidate translated code in range 0x8000-0xC000
- break;
}
return vcontext;
}
@@ -234,12 +229,12 @@ sms_context *alloc_configure_sms(void *rom, uint32_t rom_size, void *extra_rom,
if (orig_size > 0xC000) {
info_out->map_chunks = 6;
uint8_t *ram_reg_overlap = sms->ram + sizeof(sms->ram) - 4;
- memory_map[0] = (memmap_chunk){0x0000, 0x0400, 0xFFFF, 0, 0, MMAP_READ, rom, NULL, NULL, NULL, NULL};
- memory_map[1] = (memmap_chunk){0x0400, 0x4000, 0xFFFF, 0, 0, MMAP_READ|MMAP_PTR_IDX, NULL, NULL, NULL, NULL, NULL};
- memory_map[2] = (memmap_chunk){0x4000, 0x8000, 0x3FFF, 0, 1, MMAP_READ|MMAP_PTR_IDX, NULL, NULL, NULL, NULL, NULL};
- memory_map[3] = (memmap_chunk){0x8000, 0xC000, 0x3FFF, 0, 2, MMAP_READ|MMAP_PTR_IDX, NULL, NULL, NULL, NULL, NULL};
- memory_map[4] = (memmap_chunk){0xC000, 0xFFFC, sizeof(sms->ram)-1, 0, 0, MMAP_READ|MMAP_WRITE|MMAP_CODE, sms->ram, NULL, NULL, NULL, NULL};
- memory_map[5] = (memmap_chunk){0xFFFC, 0x10000, 0xFFFF, 0, 0, MMAP_READ, ram_reg_overlap, NULL, NULL, NULL, mapper_write};
+ memory_map[0] = (memmap_chunk){0x0000, 0x0400, 0xFFFF, 0, 0, MMAP_READ, rom, NULL, NULL, NULL, NULL};
+ memory_map[1] = (memmap_chunk){0x0400, 0x4000, 0xFFFF, 0, 0, MMAP_READ|MMAP_PTR_IDX|MMAP_CODE, NULL, NULL, NULL, NULL, NULL};
+ memory_map[2] = (memmap_chunk){0x4000, 0x8000, 0x3FFF, 0, 1, MMAP_READ|MMAP_PTR_IDX|MMAP_CODE, NULL, NULL, NULL, NULL, NULL};
+ memory_map[3] = (memmap_chunk){0x8000, 0xC000, 0x3FFF, 0, 2, MMAP_READ|MMAP_PTR_IDX|MMAP_CODE, NULL, NULL, NULL, NULL, NULL};
+ memory_map[4] = (memmap_chunk){0xC000, 0xFFFC, sizeof(sms->ram)-1, 0, 0, MMAP_READ|MMAP_WRITE|MMAP_CODE, sms->ram, NULL, NULL, NULL, NULL};
+ memory_map[5] = (memmap_chunk){0xFFFC, 0x10000, 0xFFFF, 0, 0, MMAP_READ, ram_reg_overlap, NULL, NULL, NULL, mapper_write};
} else {
info_out->map_chunks = 2;
memory_map[0] = (memmap_chunk){0x0000, 0xC000, rom_size-1, 0, 0, MMAP_READ, rom, NULL, NULL, NULL, NULL};
diff --git a/z80_to_x86.c b/z80_to_x86.c
index 6149d22..34ad2f5 100644
--- a/z80_to_x86.c
+++ b/z80_to_x86.c
@@ -2905,7 +2905,7 @@ uint8_t * z80_get_native_address(z80_context * context, uint32_t address)
uint8_t z80_get_native_inst_size(z80_options * opts, uint32_t address)
{
uint32_t meta_off;
- memmap_chunk const *chunk = find_map_chunk(address, &opts->gen, MMAP_WRITE | MMAP_CODE, &meta_off);
+ memmap_chunk const *chunk = find_map_chunk(address, &opts->gen, MMAP_CODE, &meta_off);
if (chunk) {
meta_off += (address - chunk->start) & chunk->mask;
}
@@ -2919,9 +2919,9 @@ void z80_map_native_address(z80_context * context, uint32_t address, uint8_t * n
z80_options * opts = context->options;
uint32_t meta_off;
- memmap_chunk const *mem_chunk = find_map_chunk(address, &opts->gen, MMAP_WRITE | MMAP_CODE, &meta_off);
+ memmap_chunk const *mem_chunk = find_map_chunk(address, &opts->gen, MMAP_CODE, &meta_off);
if (mem_chunk) {
- if ((mem_chunk->flags & (MMAP_WRITE | MMAP_CODE)) == (MMAP_WRITE | MMAP_CODE)) {
+ if (mem_chunk->flags & MMAP_CODE) {
uint32_t masked = (address & mem_chunk->mask);
uint32_t final_off = masked + meta_off;
uint32_t ram_flags_off = final_off >> (opts->gen.ram_flags_shift + 3);
@@ -3008,6 +3008,41 @@ z80_context * z80_handle_code_write(uint32_t address, z80_context * context)
return context;
}
+void z80_invalidate_code_range(z80_context *context, uint32_t start, uint32_t end)
+{
+ z80_options *opts = context->options;
+ native_map_slot * native_code_map = opts->gen.native_code_map;
+ memmap_chunk const *mem_chunk = find_map_chunk(start, &opts->gen, 0, NULL);
+ if (mem_chunk) {
+ //calculate the lowest alias for this address
+ start = mem_chunk->start + ((start - mem_chunk->start) & mem_chunk->mask);
+ }
+ mem_chunk = find_map_chunk(end, &opts->gen, 0, NULL);
+ if (mem_chunk) {
+ //calculate the lowest alias for this address
+ end = mem_chunk->start + ((end - mem_chunk->start) & mem_chunk->mask);
+ }
+ uint32_t start_chunk = start / NATIVE_CHUNK_SIZE, end_chunk = end / NATIVE_CHUNK_SIZE;
+ for (uint32_t chunk = start_chunk; chunk <= end_chunk; chunk++)
+ {
+ if (native_code_map[chunk].base) {
+ uint32_t start_offset = chunk == start_chunk ? start % NATIVE_CHUNK_SIZE : 0;
+ uint32_t end_offset = chunk == end_chunk ? end % NATIVE_CHUNK_SIZE : NATIVE_CHUNK_SIZE;
+ for (uint32_t offset = start_offset; offset < end_offset; offset++)
+ {
+ if (native_code_map[chunk].offsets[offset] != INVALID_OFFSET && native_code_map[chunk].offsets[offset] != EXTENSION_WORD) {
+ code_info code;
+ code.cur = native_code_map[chunk].base + native_code_map[chunk].offsets[offset];
+ code.last = code.cur + 32;
+ code.stack_off = 0;
+ mov_ir(&code, chunk * NATIVE_CHUNK_SIZE + offset, opts->gen.scratch1, SZ_D);
+ call(&code, opts->retrans_stub);
+ }
+ }
+ }
+ }
+}
+
uint8_t * z80_get_native_address_trans(z80_context * context, uint32_t address)
{
uint8_t * addr = z80_get_native_address(context, address);
diff --git a/z80_to_x86.h b/z80_to_x86.h
index 4dcfdc3..e26777c 100644
--- a/z80_to_x86.h
+++ b/z80_to_x86.h
@@ -94,6 +94,7 @@ z80_context * init_z80_context(z80_options * options);
code_ptr z80_get_native_address(z80_context * context, uint32_t address);
code_ptr z80_get_native_address_trans(z80_context * context, uint32_t address);
z80_context * z80_handle_code_write(uint32_t address, z80_context * context);
+void z80_invalidate_code_range(z80_context *context, uint32_t start, uint32_t end);
void z80_reset(z80_context * context);
void zinsert_breakpoint(z80_context * context, uint16_t address, uint8_t * bp_handler);
void zremove_breakpoint(z80_context * context, uint16_t address);