# HG changeset patch # User Michael Pavone # Date 1482986367 28800 # Node ID 8f14767661fa7fe8f8f82f31ddb56c4deb4ebf0c # Parent 6b5c92b6205cfde2d68c91d99c5ee9b117ff9643 Remove memory map assumptions from Z80 core and move a little bit of logic to the generic backend.c so it can be shared between CPU cores diff -r 6b5c92b6205c -r 8f14767661fa backend.c --- a/backend.c Wed Dec 28 12:28:52 2016 -0800 +++ b/backend.c Wed Dec 28 20:39:27 2016 -0800 @@ -51,6 +51,23 @@ } } +memmap_chunk const *find_map_chunk(uint32_t address, cpu_options *opts, uint16_t flags, uint32_t *size_sum) +{ + if (size_sum) { + *size_sum = 0; + } + address &= opts->address_mask; + for (memmap_chunk const *cur = opts->memmap, *end = opts->memmap + opts->memmap_chunks; cur != end; cur++) + { + if (address >= cur->start && address < cur->end) { + return cur; + } else if (size_sum && (cur->flags & flags) == flags) { + *size_sum += chunk_size(opts, cur); + } + } + return NULL; +} + void * get_native_pointer(uint32_t address, void ** mem_pointers, cpu_options * opts) { memmap_chunk const * memmap = opts->memmap; diff -r 6b5c92b6205c -r 8f14767661fa backend.h --- a/backend.h Wed Dec 28 12:28:52 2016 -0800 +++ b/backend.h Wed Dec 28 20:39:27 2016 -0800 @@ -122,6 +122,7 @@ code_ptr gen_mem_fun(cpu_options * opts, memmap_chunk const * memmap, uint32_t num_chunks, ftype fun_type, code_ptr *after_inc); void * get_native_pointer(uint32_t address, void ** mem_pointers, cpu_options * opts); +memmap_chunk const *find_map_chunk(uint32_t address, cpu_options *opts, uint16_t flags, uint32_t *size_sum); uint32_t chunk_size(cpu_options *opts, memmap_chunk const *chunk); uint32_t ram_size(cpu_options *opts); diff -r 6b5c92b6205c -r 8f14767661fa blastcpm.c --- a/blastcpm.c Wed Dec 28 12:28:52 2016 -0800 +++ b/blastcpm.c Wed Dec 28 20:39:27 2016 -0800 @@ -62,13 +62,13 @@ } const memmap_chunk z80_map[] = { - { 0x0000, 0x10000, 0xFFFF, 0, MMAP_READ | MMAP_WRITE | MMAP_CODE, ram, NULL, NULL, NULL, NULL}, + { 0x0000, 0x10000, 0xFFFF, 0, 0, MMAP_READ | MMAP_WRITE | MMAP_CODE, ram, NULL, NULL, NULL, NULL}, }; const memmap_chunk io_map[] = { - { 0x0, 0x1, 0xFFFF, 0, 0, NULL, NULL, NULL, console_read, console_write}, - { 0x1, 0x2, 0xFFFF, 0, 0, NULL, NULL, NULL, console_status_read, console_flush_write}, - { 0x2, 0x3, 0xFFFF, 0, 0, NULL, NULL, NULL, NULL, exit_write}, + { 0x0, 0x1, 0xFFFF, 0, 0, 0, NULL, NULL, NULL, console_read, console_write}, + { 0x1, 0x2, 0xFFFF, 0, 0, 0, NULL, NULL, NULL, console_status_read, console_flush_write}, + { 0x2, 0x3, 0xFFFF, 0, 0, 0, NULL, NULL, NULL, NULL, exit_write}, }; int main(int argc, char **argv) @@ -100,13 +100,13 @@ ram[7] = OS_START >> 8; z80_options opts; - z80_context context; + z80_context *context; init_z80_opts(&opts, z80_map, 1, io_map, 3, 1, 0xFF); - init_z80_context(&context, &opts); + context = init_z80_context(&opts); for(;;) { - z80_run(&context, 1000000); - context.current_cycle = 0; + z80_run(context, 1000000); + context->current_cycle = 0; } return 0; } \ No newline at end of file diff -r 6b5c92b6205c -r 8f14767661fa debug.c --- a/debug.c Wed Dec 28 12:28:52 2016 -0800 +++ b/debug.c Wed Dec 28 20:39:27 2016 -0800 @@ -591,7 +591,7 @@ uint8_t non_adr_count = 0; do { uint32_t bt_address = system->work_ram[stack/2] << 16 | system->work_ram[stack/2+1]; - bt_address = get_instruction_start(context->options, context->native_code_map, bt_address - 2); + bt_address = get_instruction_start(context->options, bt_address - 2); if (bt_address) { stack += 4; non_adr_count = 0; diff -r 6b5c92b6205c -r 8f14767661fa genesis.c --- a/genesis.c Wed Dec 28 12:28:52 2016 -0800 +++ b/genesis.c Wed Dec 28 20:39:27 2016 -0800 @@ -925,15 +925,16 @@ gen->psg = malloc(sizeof(psg_context)); psg_init(gen->psg, render_sample_rate(), gen->master_clock, MCLKS_PER_PSG, render_audio_buffer(), lowpass_cutoff); - gen->z80 = calloc(1, sizeof(z80_context)); gen->zram = calloc(1, Z80_RAM_BYTES); z80_map[0].buffer = gen->zram = calloc(1, Z80_RAM_BYTES); #ifndef NO_Z80 z80_options *z_opts = malloc(sizeof(z80_options)); init_z80_opts(z_opts, z80_map, 5, NULL, 0, MCLKS_PER_Z80, 0xFFFF); - init_z80_context(gen->z80, z_opts); + gen->z80 = init_z80_context(z_opts); gen->z80->next_int_pulse = z80_next_int_pulse; z80_assert_reset(gen->z80, 0); +#else + gen->z80 = calloc(1, sizeof(z80_context)); #endif gen->z80->system = gen; diff -r 6b5c92b6205c -r 8f14767661fa m68k_core.c --- a/m68k_core.c Wed Dec 28 12:28:52 2016 -0800 +++ b/m68k_core.c Wed Dec 28 20:39:27 2016 -0800 @@ -560,16 +560,12 @@ code_ptr get_native_address(m68k_options *opts, uint32_t address) { native_map_slot * native_code_map = opts->gen.native_code_map; - 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); - } + memmap_chunk const *mem_chunk = find_map_chunk(address, &opts->gen, 0, NULL); + if (mem_chunk) { + //calculate the lowest alias for this address + address = mem_chunk->start + ((address - mem_chunk->start) & mem_chunk->mask); } - uint32_t chunk = address / NATIVE_CHUNK_SIZE; if (!native_code_map[chunk].base) { return NULL; @@ -586,16 +582,13 @@ return get_native_address(context->options, address); } -uint32_t get_instruction_start(m68k_options *opts, native_map_slot * native_code_map, uint32_t address) +uint32_t get_instruction_start(m68k_options *opts, uint32_t address) { - 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); - break; - } + native_map_slot * native_code_map = opts->gen.native_code_map; + memmap_chunk const *mem_chunk = find_map_chunk(address, &opts->gen, 0, NULL); + if (mem_chunk) { + //calculate the lowest alias for this address + address = mem_chunk->start + ((address - mem_chunk->start) & mem_chunk->mask); } uint32_t chunk = address / NATIVE_CHUNK_SIZE; @@ -606,7 +599,8 @@ if (native_code_map[chunk].offsets[offset] == INVALID_OFFSET) { return 0; } - while (native_code_map[chunk].offsets[offset] == EXTENSION_WORD) { + while (native_code_map[chunk].offsets[offset] == EXTENSION_WORD) + { --address; chunk = address / NATIVE_CHUNK_SIZE; offset = address % NATIVE_CHUNK_SIZE; @@ -616,38 +610,31 @@ static void map_native_address(m68k_context * context, uint32_t address, code_ptr native_addr, uint8_t size, uint8_t native_size) { - native_map_slot * native_code_map = context->native_code_map; m68k_options * opts = context->options; - address &= opts->gen.address_mask; - uint32_t meta_off = 0; - //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) { - if ((opts->gen.memmap[i].flags & (MMAP_WRITE | MMAP_CODE)) == (MMAP_WRITE | MMAP_CODE)) { - uint32_t masked = (address & opts->gen.memmap[i].mask); - uint32_t final_off = masked + meta_off; - uint32_t 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); + native_map_slot * native_code_map = opts->gen.native_code_map; + uint32_t meta_off; + memmap_chunk const *mem_chunk = find_map_chunk(address, &opts->gen, MMAP_WRITE | MMAP_CODE, &meta_off); + if (mem_chunk) { + if ((mem_chunk->flags & (MMAP_WRITE | MMAP_CODE)) == (MMAP_WRITE | 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); + context->ram_code_flags[ram_flags_off] |= 1 << ((final_off >> opts->gen.ram_flags_shift) & 7); - uint32_t slot = final_off / 1024; - if (!opts->gen.ram_inst_sizes[slot]) { - opts->gen.ram_inst_sizes[slot] = malloc(sizeof(uint8_t) * 512); - } - opts->gen.ram_inst_sizes[slot][(final_off/2) & 511] = native_size; + uint32_t slot = final_off / 1024; + if (!opts->gen.ram_inst_sizes[slot]) { + opts->gen.ram_inst_sizes[slot] = malloc(sizeof(uint8_t) * 512); + } + opts->gen.ram_inst_sizes[slot][(final_off/2) & 511] = native_size; - //TODO: Deal with case in which end of instruction is in a different memory chunk - masked = (address + size - 1) & opts->gen.memmap[i].mask; - final_off = masked + meta_off; - 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); - meta_off += size; + //TODO: Deal with case in which end of instruction is in a different memory chunk + masked = (address + size - 1) & mem_chunk->mask; + final_off = masked + meta_off; + 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 = mem_chunk->start + ((address - mem_chunk->start) & mem_chunk->mask); } uint32_t chunk = address / NATIVE_CHUNK_SIZE; @@ -676,19 +663,10 @@ static uint8_t get_native_inst_size(m68k_options * opts, uint32_t address) { - address &= opts->gen.address_mask; - uint32_t meta_off = 0; - for (int i = 0; i < opts->gen.memmap_chunks; i++) { - if (address >= opts->gen.memmap[i].start && address < opts->gen.memmap[i].end) { - if ((opts->gen.memmap[i].flags & (MMAP_WRITE | MMAP_CODE)) != (MMAP_WRITE | MMAP_CODE)) { - return 0; - } - meta_off += address & 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); - meta_off += size; - } + uint32_t meta_off; + memmap_chunk const *chunk = find_map_chunk(address, &opts->gen, MMAP_WRITE | MMAP_CODE, &meta_off); + if (chunk) { + meta_off += (address - chunk->start) & chunk->mask; } uint32_t slot = meta_off/1024; return opts->gen.ram_inst_sizes[slot][(meta_off/2)%512]; @@ -712,7 +690,7 @@ uint16_t m68k_get_ir(m68k_context *context) { - uint32_t inst_addr = get_instruction_start(context->options, context->native_code_map, context->last_prefetch_address-2); + uint32_t inst_addr = get_instruction_start(context->options, context->last_prefetch_address-2); uint16_t *native_addr = get_native_pointer(inst_addr, (void **)context->mem_pointers, &context->options->gen); if (native_addr) { return *native_addr; @@ -1065,7 +1043,6 @@ size_t ctx_size = sizeof(m68k_context) + ram_size(&opts->gen) / (1 << opts->gen.ram_flags_shift) / 8; m68k_context * context = malloc(ctx_size); memset(context, 0, ctx_size); - context->native_code_map = opts->gen.native_code_map; context->options = opts; context->int_cycle = CYCLE_NEVER; context->status = 0x27; diff -r 6b5c92b6205c -r 8f14767661fa m68k_core.h --- a/m68k_core.h Wed Dec 28 12:28:52 2016 -0800 +++ b/m68k_core.h Wed Dec 28 20:39:27 2016 -0800 @@ -63,7 +63,6 @@ uint16_t *mem_pointers[NUM_MEM_AREAS]; code_ptr resume_pc; code_ptr reset_handler; - native_map_slot *native_code_map; m68k_options *options; void *system; uint8_t int_pending; @@ -84,7 +83,7 @@ void insert_breakpoint(m68k_context * context, uint32_t address, m68k_debug_handler 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(m68k_options *opts, native_map_slot * native_code_map, uint32_t address); +uint32_t get_instruction_start(m68k_options *opts, uint32_t address); uint16_t m68k_get_ir(m68k_context *context); void m68k_print_regs(m68k_context * context); diff -r 6b5c92b6205c -r 8f14767661fa m68k_core_x86.c --- a/m68k_core_x86.c Wed Dec 28 12:28:52 2016 -0800 +++ b/m68k_core_x86.c Wed Dec 28 20:39:27 2016 -0800 @@ -2266,8 +2266,7 @@ m68k_context * m68k_handle_code_write(uint32_t address, m68k_context * context) { 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); + uint32_t inst_start = get_instruction_start(options, address); if (inst_start) { code_info *code = &options->gen.code; code_ptr dst = get_native_address(context->options, inst_start); diff -r 6b5c92b6205c -r 8f14767661fa sms.c --- a/sms.c Wed Dec 28 12:28:52 2016 -0800 +++ b/sms.c Wed Dec 28 20:39:27 2016 -0800 @@ -212,8 +212,7 @@ memcpy(info_out->map, memory_map, sizeof(memory_map)); z80_options *zopts = malloc(sizeof(z80_options)); init_z80_opts(zopts, info_out->map, 2, io_map, 4, 15, 0xFF); - sms->z80 = malloc(sizeof(z80_context)); - init_z80_context(sms->z80, zopts); + sms->z80 = init_z80_context(zopts); sms->z80->system = sms; char * lowpass_cutoff_str = tern_find_path(config, "audio\0lowpass_cutoff\0").ptrval; diff -r 6b5c92b6205c -r 8f14767661fa transz80.c --- a/transz80.c Wed Dec 28 12:28:52 2016 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,94 +0,0 @@ -/* - Copyright 2013 Michael Pavone - This file is part of BlastEm. - BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text. -*/ -#include "z80inst.h" -#include "z80_to_x86.h" -#include "mem.h" -#include "vdp.h" -#include -#include - -uint8_t z80_ram[0x2000]; -uint16_t cart[0x200000]; - -#define MCLKS_PER_Z80 15 -//TODO: Figure out the exact value for this -#define MCLKS_PER_FRAME (MCLKS_LINE*262) -#define VINT_CYCLE ((MCLKS_LINE * 226)/MCLKS_PER_Z80) -#define CYCLE_NEVER 0xFFFFFFFF - -uint8_t z80_read_ym(uint16_t location, z80_context * context) -{ - return 0xFF; -} - -z80_context * z80_write_ym(uint16_t location, z80_context * context, uint8_t value) -{ - return context; -} - -z80_context * z80_vdp_port_write(uint16_t location, z80_context * context, uint8_t value) -{ - return context; -} - -int main(int argc, char ** argv) -{ - long filesize; - uint8_t *filebuf; - z80_options opts; - z80_context context; - if (argc < 2) { - fputs("usage: transz80 zrom [cartrom]\n", stderr); - exit(1); - } - FILE * f = fopen(argv[1], "rb"); - if (!f) { - fprintf(stderr, "unable to open file %s\n", argv[2]); - exit(1); - } - fseek(f, 0, SEEK_END); - filesize = ftell(f); - fseek(f, 0, SEEK_SET); - fread(z80_ram, 1, filesize < sizeof(z80_ram) ? filesize : sizeof(z80_ram), f); - fclose(f); - if (argc > 2) { - f = fopen(argv[2], "rb"); - if (!f) { - fprintf(stderr, "unable to open file %s\n", argv[2]); - exit(1); - } - fseek(f, 0, SEEK_END); - filesize = ftell(f); - fseek(f, 0, SEEK_SET); - fread(cart, 1, filesize < sizeof(cart) ? filesize : sizeof(cart), f); - fclose(f); - for(unsigned short * cur = cart; cur - cart < (filesize/2); ++cur) - { - *cur = (*cur >> 8) | (*cur << 8); - } - } - init_z80_opts(&opts); - init_z80_context(&context, &opts); - //Z80 RAM - context.mem_pointers[0] = z80_ram; - context.sync_cycle = context.target_cycle = MCLKS_PER_FRAME/MCLKS_PER_Z80; - context.int_cycle = CYCLE_NEVER; - //cartridge/bank - context.mem_pointers[1] = context.mem_pointers[2] = (uint8_t *)cart; - z80_reset(&context); - for(;;) - { - z80_run(&context); - if (context.current_cycle >= MCLKS_PER_FRAME/MCLKS_PER_Z80) { - context.current_cycle -= MCLKS_PER_FRAME/MCLKS_PER_Z80; - } - if (context.current_cycle < VINT_CYCLE && context.iff1) { - context.int_cycle = VINT_CYCLE; - } - context.target_cycle = context.sync_cycle < context.int_cycle ? context.sync_cycle : context.int_cycle; - } - return 0; -} diff -r 6b5c92b6205c -r 8f14767661fa z80_to_x86.c --- a/z80_to_x86.c Wed Dec 28 12:28:52 2016 -0800 +++ b/z80_to_x86.c Wed Dec 28 20:39:27 2016 -0800 @@ -15,6 +15,8 @@ #define MODE_UNUSED (MODE_IMMED-1) #define MAX_MCYCLE_LENGTH 6 +#define NATIVE_CHUNK_SIZE 1024 +#define NATIVE_MAP_CHUNKS (0x10000 / NATIVE_CHUNK_SIZE) //#define DO_DEBUG_PRINT @@ -2881,94 +2883,120 @@ uint8_t * z80_get_native_address(z80_context * context, uint32_t address) { - native_map_slot *map; - if (address < 0x4000) { - address &= 0x1FFF; - map = context->static_code_map; - } else { - address -= 0x4000; - map = context->banked_code_map; + z80_options *opts = context->options; + native_map_slot * native_code_map = opts->gen.native_code_map; + + memmap_chunk const *mem_chunk = find_map_chunk(address, &opts->gen, 0, NULL); + if (mem_chunk) { + //calculate the lowest alias for this address + address = mem_chunk->start + ((address - mem_chunk->start) & mem_chunk->mask); } - if (!map->base || !map->offsets || map->offsets[address] == INVALID_OFFSET || map->offsets[address] == EXTENSION_WORD) { - //dprintf("z80_get_native_address: %X NULL\n", address); + uint32_t chunk = address / NATIVE_CHUNK_SIZE; + if (!native_code_map[chunk].base) { return NULL; } - //dprintf("z80_get_native_address: %X %p\n", address, map->base + map->offsets[address]); - return map->base + map->offsets[address]; + uint32_t offset = address % NATIVE_CHUNK_SIZE; + if (native_code_map[chunk].offsets[offset] == INVALID_OFFSET || native_code_map[chunk].offsets[offset] == EXTENSION_WORD) { + return NULL; + } + return native_code_map[chunk].base + native_code_map[chunk].offsets[offset]; } uint8_t z80_get_native_inst_size(z80_options * opts, uint32_t address) { - //TODO: Fix for addresses >= 0x4000 - if (address >= 0x4000) { - return 0; + uint32_t meta_off; + memmap_chunk const *chunk = find_map_chunk(address, &opts->gen, MMAP_WRITE | MMAP_CODE, &meta_off); + if (chunk) { + meta_off += (address - chunk->start) & chunk->mask; } - return opts->gen.ram_inst_sizes[0][address & 0x1FFF]; + uint32_t slot = meta_off/1024; + return opts->gen.ram_inst_sizes[slot][meta_off%1024]; } void z80_map_native_address(z80_context * context, uint32_t address, uint8_t * native_address, uint8_t size, uint8_t native_size) { uint32_t orig_address = address; - native_map_slot *map; + z80_options * opts = context->options; - if (address < 0x4000) { - address &= 0x1FFF; - map = context->static_code_map; - opts->gen.ram_inst_sizes[0][address] = native_size; - context->ram_code_flags[(address & 0x1C00) >> 10] |= 1 << ((address & 0x380) >> 7); - context->ram_code_flags[((address + size) & 0x1C00) >> 10] |= 1 << (((address + size) & 0x380) >> 7); - } else { - //HERE - address -= 0x4000; - map = context->banked_code_map; - if (!map->offsets) { - map->offsets = malloc(sizeof(int32_t) * 0xC000); - memset(map->offsets, 0xFF, sizeof(int32_t) * 0xC000); + uint32_t meta_off; + memmap_chunk const *mem_chunk = find_map_chunk(address, &opts->gen, MMAP_WRITE | MMAP_CODE, &meta_off); + if (mem_chunk) { + if ((mem_chunk->flags & (MMAP_WRITE | MMAP_CODE)) == (MMAP_WRITE | 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); + context->ram_code_flags[ram_flags_off] |= 1 << ((final_off >> opts->gen.ram_flags_shift) & 7); + + uint32_t slot = final_off / 1024; + if (!opts->gen.ram_inst_sizes[slot]) { + opts->gen.ram_inst_sizes[slot] = malloc(sizeof(uint8_t) * 1024); + } + opts->gen.ram_inst_sizes[slot][final_off % 1024] = native_size; + + //TODO: Deal with case in which end of instruction is in a different memory chunk + masked = (address + size - 1) & mem_chunk->mask; + final_off = masked + meta_off; + 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 = mem_chunk->start + ((address - mem_chunk->start) & mem_chunk->mask); } + + native_map_slot *map = opts->gen.native_code_map + address / NATIVE_CHUNK_SIZE; if (!map->base) { map->base = native_address; + map->offsets = malloc(sizeof(int32_t) * NATIVE_CHUNK_SIZE); + memset(map->offsets, 0xFF, sizeof(int32_t) * NATIVE_CHUNK_SIZE); } - map->offsets[address] = native_address - map->base; - for(--size, orig_address++; size; --size, orig_address++) { - address = orig_address; - if (address < 0x4000) { - address &= 0x1FFF; - map = context->static_code_map; - } else { - address -= 0x4000; - map = context->banked_code_map; + map->offsets[address % NATIVE_CHUNK_SIZE] = native_address - map->base; + for(--size, address++; size; --size, orig_address++) { + address &= opts->gen.address_mask; + map = opts->gen.native_code_map + address / NATIVE_CHUNK_SIZE; + if (!map->base) { + map->base = native_address; + map->offsets = malloc(sizeof(int32_t) * NATIVE_CHUNK_SIZE); + memset(map->offsets, 0xFF, sizeof(int32_t) * NATIVE_CHUNK_SIZE); } - if (!map->offsets) { - map->offsets = malloc(sizeof(int32_t) * 0xC000); - memset(map->offsets, 0xFF, sizeof(int32_t) * 0xC000); + + if (map->offsets[address % NATIVE_CHUNK_SIZE] == INVALID_OFFSET) { + map->offsets[address % NATIVE_CHUNK_SIZE] = EXTENSION_WORD; } - map->offsets[address] = EXTENSION_WORD; } } #define INVALID_INSTRUCTION_START 0xFEEDFEED -uint32_t z80_get_instruction_start(native_map_slot * static_code_map, uint32_t address) -{ - //TODO: Fixme for address >= 0x4000 - if (!static_code_map->base || address >= 0x4000) { +uint32_t z80_get_instruction_start(z80_context *context, uint32_t address) +{ + z80_options *opts = context->options; + native_map_slot * native_code_map = opts->gen.native_code_map; + memmap_chunk const *mem_chunk = find_map_chunk(address, &opts->gen, 0, NULL); + if (mem_chunk) { + //calculate the lowest alias for this address + address = mem_chunk->start + ((address - mem_chunk->start) & mem_chunk->mask); + } + + uint32_t chunk = address / NATIVE_CHUNK_SIZE; + if (!native_code_map[chunk].base) { return INVALID_INSTRUCTION_START; } - address &= 0x1FFF; - if (static_code_map->offsets[address] == INVALID_OFFSET) { + uint32_t offset = address % NATIVE_CHUNK_SIZE; + if (native_code_map[chunk].offsets[offset] == INVALID_OFFSET) { return INVALID_INSTRUCTION_START; } - while (static_code_map->offsets[address] == EXTENSION_WORD) { + while (native_code_map[chunk].offsets[offset] == EXTENSION_WORD) + { --address; - address &= 0x1FFF; + chunk = address / NATIVE_CHUNK_SIZE; + offset = address % NATIVE_CHUNK_SIZE; } return address; } z80_context * z80_handle_code_write(uint32_t address, z80_context * context) { - uint32_t inst_start = z80_get_instruction_start(context->static_code_map, address); + uint32_t inst_start = z80_get_instruction_start(context, address); if (inst_start != INVALID_INSTRUCTION_START) { code_ptr dst = z80_get_native_address(context, inst_start); code_info code = {dst, dst+32, 0}; @@ -3178,12 +3206,12 @@ options->gen.cycles = RBP; options->gen.limit = -1; - options->gen.native_code_map = malloc(sizeof(native_map_slot)); - memset(options->gen.native_code_map, 0, sizeof(native_map_slot)); + options->gen.native_code_map = malloc(sizeof(native_map_slot) * NATIVE_MAP_CHUNKS); + memset(options->gen.native_code_map, 0, sizeof(native_map_slot) * NATIVE_MAP_CHUNKS); options->gen.deferred = NULL; - options->gen.ram_inst_sizes = malloc(sizeof(uint8_t) * 0x2000 + sizeof(uint8_t *)); - options->gen.ram_inst_sizes[0] = (uint8_t *)(options->gen.ram_inst_sizes + 1); - memset(options->gen.ram_inst_sizes[0], 0, sizeof(uint8_t) * 0x2000); + uint32_t inst_size_size = sizeof(uint8_t *) * ram_size(&options->gen) / 1024; + options->gen.ram_inst_sizes = malloc(inst_size_size); + memset(options->gen.ram_inst_sizes, 0, inst_size_size); code_info *code = &options->gen.code; init_code_info(code); @@ -3476,7 +3504,7 @@ call(code, options->gen.load_context); jmp_r(code, options->gen.scratch1); - options->run = code->cur; + options->run = (z80_ctx_fun)code->cur; tmp_stack_off = code->stack_off; save_callee_save_regs(code); #ifdef X86_64 @@ -3496,19 +3524,16 @@ code->stack_off = tmp_stack_off; } -void init_z80_context(z80_context * context, z80_options * options) +z80_context *init_z80_context(z80_options * options) { - memset(context, 0, sizeof(*context)); - context->static_code_map = malloc(sizeof(*context->static_code_map)); - context->static_code_map->base = NULL; - context->static_code_map->offsets = malloc(sizeof(int32_t) * 0x2000); - memset(context->static_code_map->offsets, 0xFF, sizeof(int32_t) * 0x2000); - context->banked_code_map = malloc(sizeof(native_map_slot)); - memset(context->banked_code_map, 0, sizeof(native_map_slot)); + size_t ctx_size = sizeof(z80_context) + ram_size(&options->gen) / (1 << options->gen.ram_flags_shift) / 8; + z80_context *context = calloc(1, ctx_size); context->options = options; context->int_cycle = CYCLE_NEVER; context->int_pulse_start = CYCLE_NEVER; context->int_pulse_end = CYCLE_NEVER; + + return context; } void z80_run(z80_context * context, uint32_t target_cycle) diff -r 6b5c92b6205c -r 8f14767661fa z80_to_x86.h --- a/z80_to_x86.h Wed Dec 28 12:28:52 2016 -0800 +++ b/z80_to_x86.h Wed Dec 28 20:39:27 2016 -0800 @@ -70,11 +70,8 @@ void * extra_pc; uint32_t sync_cycle; uint32_t int_cycle; - native_map_slot * static_code_map; - native_map_slot * banked_code_map; z80_options * options; void * system; - uint8_t ram_code_flags[(8 * 1024)/128/8]; uint32_t int_enable_cycle; uint16_t pc; uint32_t int_pulse_start; @@ -87,12 +84,13 @@ uint8_t reset; uint8_t busreq; uint8_t busack; + uint8_t ram_code_flags[]; }; void translate_z80_stream(z80_context * context, uint32_t address); void init_z80_opts(z80_options * options, memmap_chunk const * chunks, uint32_t num_chunks, memmap_chunk const * io_chunks, uint32_t num_io_chunks, uint32_t clock_divider, uint32_t io_address_mask); void z80_options_free(z80_options *opts); -void init_z80_context(z80_context * context, z80_options * options); +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); diff -r 6b5c92b6205c -r 8f14767661fa ztestrun.c --- a/ztestrun.c Wed Dec 28 12:28:52 2016 -0800 +++ b/ztestrun.c Wed Dec 28 20:39:27 2016 -0800 @@ -34,12 +34,12 @@ } const memmap_chunk z80_map[] = { - { 0x0000, 0x4000, 0x1FFF, 0, MMAP_READ | MMAP_WRITE | MMAP_CODE, z80_ram, NULL, NULL, NULL, NULL }, - { 0x4000, 0x10000, 0xFFFF, 0, 0, NULL, NULL, NULL, z80_unmapped_read, z80_unmapped_write} + { 0x0000, 0x4000, 0x1FFF, 0, 0, MMAP_READ | MMAP_WRITE | MMAP_CODE, z80_ram, NULL, NULL, NULL, NULL }, + { 0x4000, 0x10000, 0xFFFF, 0, 0, 0, NULL, NULL, NULL, z80_unmapped_read, z80_unmapped_write} }; const memmap_chunk port_map[] = { - { 0x0000, 0x100, 0xFF, 0, 0, NULL, NULL, NULL, z80_unmapped_read, z80_unmapped_write} + { 0x0000, 0x100, 0xFF, 0, 0, 0, NULL, NULL, NULL, z80_unmapped_read, z80_unmapped_write} }; void z80_next_int_pulse(z80_context * context) @@ -52,7 +52,7 @@ long filesize; uint8_t *filebuf; z80_options opts; - z80_context context; + z80_context *context; char *fname = NULL; uint8_t retranslate = 0; for (int i = 1; i < argc; i++) @@ -90,37 +90,37 @@ } fclose(f); init_z80_opts(&opts, z80_map, 2, port_map, 1, 1, 0xFF); - init_z80_context(&context, &opts); + context = init_z80_context(&opts); //Z80 RAM - context.mem_pointers[0] = z80_ram; + context->mem_pointers[0] = z80_ram; if (retranslate) { //run core long enough to translate code - z80_run(&context, 1); + z80_run(context, 1); for (int i = 0; i < filesize; i++) { - z80_handle_code_write(i, &context); + z80_handle_code_write(i, context); } - z80_assert_reset(&context, context.current_cycle); - z80_clear_reset(&context, context.current_cycle + 3); - z80_adjust_cycles(&context, context.current_cycle); + z80_assert_reset(context, context->current_cycle); + z80_clear_reset(context, context->current_cycle + 3); + z80_adjust_cycles(context, context->current_cycle); } - z80_run(&context, 1000); + z80_run(context, 1000); printf("A: %X\nB: %X\nC: %X\nD: %X\nE: %X\nHL: %X\nIX: %X\nIY: %X\nSP: %X\n\nIM: %d, IFF1: %d, IFF2: %d\n", - context.regs[Z80_A], context.regs[Z80_B], context.regs[Z80_C], - context.regs[Z80_D], context.regs[Z80_E], - (context.regs[Z80_H] << 8) | context.regs[Z80_L], - (context.regs[Z80_IXH] << 8) | context.regs[Z80_IXL], - (context.regs[Z80_IYH] << 8) | context.regs[Z80_IYL], - context.sp, context.im, context.iff1, context.iff2); + context->regs[Z80_A], context->regs[Z80_B], context->regs[Z80_C], + context->regs[Z80_D], context->regs[Z80_E], + (context->regs[Z80_H] << 8) | context->regs[Z80_L], + (context->regs[Z80_IXH] << 8) | context->regs[Z80_IXL], + (context->regs[Z80_IYH] << 8) | context->regs[Z80_IYL], + context->sp, context->im, context->iff1, context->iff2); printf("Flags: SZYHXVNC\n" " %d%d%d%d%d%d%d%d\n", - context.flags[ZF_S], context.flags[ZF_Z], context.flags[ZF_XY] >> 5 & 1, context.flags[ZF_H], - context.flags[ZF_XY] >> 3 & 1, context.flags[ZF_PV], context.flags[ZF_N], context.flags[ZF_C] + context->flags[ZF_S], context->flags[ZF_Z], context->flags[ZF_XY] >> 5 & 1, context->flags[ZF_H], + context->flags[ZF_XY] >> 3 & 1, context->flags[ZF_PV], context->flags[ZF_N], context->flags[ZF_C] ); puts("--Alternate Regs--"); printf("A: %X\nB: %X\nC: %X\nD: %X\nE: %X\nHL: %X\n", - context.alt_regs[Z80_A], context.alt_regs[Z80_B], context.alt_regs[Z80_C], - context.alt_regs[Z80_D], context.alt_regs[Z80_E], - (context.alt_regs[Z80_H] << 8) | context.alt_regs[Z80_L]); + context->alt_regs[Z80_A], context->alt_regs[Z80_B], context->alt_regs[Z80_C], + context->alt_regs[Z80_D], context->alt_regs[Z80_E], + (context->alt_regs[Z80_H] << 8) | context->alt_regs[Z80_L]); return 0; }