# HG changeset patch # User Michael Pavone # Date 1483428940 28800 # Node ID 5c8b1c33ca104eae25f61036146e08a52d1f064d # Parent 7e199bebde2f8aebe04411a8b0ab3c047f96e03b Invalidate translated code on a cartridge bank change in SMS mode. Fix handling of bank 0 diff -r 7e199bebde2f -r 5c8b1c33ca10 backend.c --- a/backend.c Mon Jan 02 22:54:24 2017 -0800 +++ b/backend.c Mon Jan 02 23:35:40 2017 -0800 @@ -107,7 +107,7 @@ 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 -r 7e199bebde2f -r 5c8b1c33ca10 sms.c --- a/sms.c Mon Jan 02 22:54:24 2017 -0800 +++ b/sms.c Mon Jan 02 23:35:40 2017 -0800 @@ -101,24 +101,19 @@ { 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 @@ 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 -r 7e199bebde2f -r 5c8b1c33ca10 z80_to_x86.c --- a/z80_to_x86.c Mon Jan 02 22:54:24 2017 -0800 +++ b/z80_to_x86.c Mon Jan 02 23:35:40 2017 -0800 @@ -2905,7 +2905,7 @@ 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 @@ 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 @@ 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 -r 7e199bebde2f -r 5c8b1c33ca10 z80_to_x86.h --- a/z80_to_x86.h Mon Jan 02 22:54:24 2017 -0800 +++ b/z80_to_x86.h Mon Jan 02 23:35:40 2017 -0800 @@ -94,6 +94,7 @@ 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);