# HG changeset patch # User Michael Pavone # Date 1421257134 28800 # Node ID fc04781f4d28a9a71cd1ac906b3a950ae8602470 # Parent 858e31f977ae1636dda5d62238a975e2de5a1cde Removed hardcoded assumptions in M68K core about which parts of the memory map are RAM diff -r 858e31f977ae -r fc04781f4d28 backend.c --- a/backend.c Thu Jan 08 23:20:41 2015 -0800 +++ b/backend.c Wed Jan 14 09:38:54 2015 -0800 @@ -72,3 +72,28 @@ } return NULL; } + +uint32_t chunk_size(cpu_options *opts, memmap_chunk const *chunk) +{ + if (chunk->mask == opts->address_mask) { + return chunk->end - chunk->start; + } else { + return chunk->mask + 1; + } +} + +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].mask == opts->address_mask) { + size += opts->memmap[i].end - opts->memmap[i].start; + } else { + size += opts->memmap[i].mask + 1; + } + } + } + return size; +} diff -r 858e31f977ae -r fc04781f4d28 backend.h --- a/backend.h Thu Jan 08 23:20:41 2015 -0800 +++ b/backend.h Wed Jan 14 09:38:54 2015 -0800 @@ -116,6 +116,8 @@ 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); +uint32_t chunk_size(cpu_options *opts, memmap_chunk const *chunk); +uint32_t ram_size(cpu_options *opts); #endif //BACKEND_H_ diff -r 858e31f977ae -r fc04781f4d28 backend_x86.c --- a/backend_x86.c Thu Jan 08 23:20:41 2015 -0800 +++ b/backend_x86.c Wed Jan 14 09:38:54 2015 -0800 @@ -50,6 +50,7 @@ uint8_t adr_reg = is_write ? opts->scratch2 : opts->scratch1; uint16_t access_flag = is_write ? MMAP_WRITE : MMAP_READ; uint8_t size = (fun_type == READ_16 || fun_type == WRITE_16) ? SZ_W : SZ_B; + uint32_t ram_flags_off = opts->ram_flags_off; for (uint32_t chunk = 0; chunk < num_chunks; chunk++) { if (memmap[chunk].start > 0) { @@ -173,7 +174,12 @@ if (is_write && (memmap[chunk].flags & MMAP_CODE)) { 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, opts->ram_flags_off, opts->address_size); + bt_rrdisp(code, opts->scratch1, opts->context_reg, ram_flags_off, opts->address_size); + if (memmap[chunk].mask == opts->address_mask) { + ram_flags_off += memmap[chunk].end - memmap[chunk].start; + } else { + ram_flags_off += memmap[chunk].mask + 1; + } code_ptr not_code = code->cur + 1; jcc(code, CC_NC, code->cur + 2); call(code, opts->save_context); diff -r 858e31f977ae -r fc04781f4d28 blastem.c --- a/blastem.c Thu Jan 08 23:20:41 2015 -0800 +++ b/blastem.c Wed Jan 14 09:38:54 2015 -0800 @@ -901,9 +901,7 @@ void init_run_cpu(genesis_context * gen, FILE * address_log, char * statefile, uint8_t * debugger) { - m68k_context context; m68k_options opts; - gen->m68k = &context; memmap_chunk memmap[MAX_MAP_CHUNKS]; uint32_t num_chunks; void * initial_mapped = NULL; @@ -998,21 +996,22 @@ } init_m68k_opts(&opts, memmap, num_chunks, MCLKS_PER_68K); opts.address_log = address_log; - init_68k_context(&context, opts.gen.native_code_map, &opts); + m68k_context *context = init_68k_context(&opts); + gen->m68k = context; - context.video_context = gen->vdp; - context.system = gen; + context->video_context = gen->vdp; + context->system = gen; //cartridge ROM - context.mem_pointers[0] = cart; - context.target_cycle = context.sync_cycle = mclk_target; + context->mem_pointers[0] = cart; + context->target_cycle = context->sync_cycle = mclk_target; //work RAM - context.mem_pointers[1] = ram; + context->mem_pointers[1] = ram; //save RAM/map - context.mem_pointers[2] = initial_mapped; - context.mem_pointers[3] = (uint16_t *)gen->save_ram; + context->mem_pointers[2] = initial_mapped; + context->mem_pointers[3] = (uint16_t *)gen->save_ram; uint32_t address; address = cart[2] << 16 | cart[3]; - translate_m68k_stream(address, &context); + translate_m68k_stream(address, context); if (statefile) { uint32_t pc = load_gst(gen, statefile); if (!pc) { @@ -1021,15 +1020,15 @@ } printf("Loaded %s\n", statefile); if (debugger) { - insert_breakpoint(&context, pc, debugger); + insert_breakpoint(context, pc, debugger); } adjust_int_cycle(gen->m68k, gen->vdp); - start_68k_context(&context, pc); + start_68k_context(context, pc); } else { if (debugger) { - insert_breakpoint(&context, address, debugger); + insert_breakpoint(context, address, debugger); } - m68k_reset(&context); + m68k_reset(context); } } diff -r 858e31f977ae -r fc04781f4d28 m68k_core.c --- a/m68k_core.c Thu Jan 08 23:20:41 2015 -0800 +++ b/m68k_core.c Wed Jan 14 09:38:54 2015 -0800 @@ -553,6 +553,7 @@ code_ptr get_native_address(native_map_slot * native_code_map, uint32_t address) { + //FIXME: Use opts->gen.address_mask address &= 0xFFFFFF; address /= 2; uint32_t chunk = address / NATIVE_CHUNK_SIZE; @@ -573,6 +574,7 @@ uint32_t get_instruction_start(native_map_slot * native_code_map, uint32_t address) { + //FIXME: Use opts->gen.address_mask address &= 0xFFFFFF; address /= 2; uint32_t chunk = address / NATIVE_CHUNK_SIZE; @@ -595,17 +597,34 @@ { native_map_slot * native_code_map = context->native_code_map; m68k_options * opts = context->options; - address &= 0xFFFFFF; - if (address > 0xE00000) { - context->ram_code_flags[(address & 0xC000) >> 14] |= 1 << ((address & 0x3800) >> 11); - if (((address & 0x3FFF) + size) & 0xC000) { - context->ram_code_flags[((address+size) & 0xC000) >> 14] |= 1 << (((address+size) & 0x3800) >> 11); + 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) & 3); + + 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) & 3); + } + 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 slot = (address & 0xFFFF)/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][((address & 0xFFFF)/2)%512] = native_size; } address/= 2; uint32_t chunk = address / NATIVE_CHUNK_SIZE; @@ -630,11 +649,22 @@ uint8_t get_native_inst_size(m68k_options * opts, uint32_t address) { - if (address < 0xE00000) { - return 0; + 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 slot = (address & 0xFFFF)/1024; - return opts->gen.ram_inst_sizes[slot][((address & 0xFFFF)/2)%512]; + uint32_t slot = meta_off/1024; + return opts->gen.ram_inst_sizes[slot][(meta_off/2)%512]; } uint8_t m68k_is_terminal(m68kinst * inst) @@ -926,6 +956,7 @@ code_ptr get_native_address_trans(m68k_context * context, uint32_t address) { + //FIXME: Use opts->gen.address_mask address &= 0xFFFFFF; code_ptr ret = get_native_address(context->native_code_map, address); if (!ret) { @@ -962,11 +993,13 @@ } -void init_68k_context(m68k_context * context, native_map_slot * native_code_map, void * opts) +m68k_context * init_68k_context(m68k_options * opts) { + m68k_context * context = malloc(sizeof(m68k_context) + ram_size(&opts->gen) / (1 << opts->gen.ram_flags_shift) / 8); memset(context, 0, sizeof(m68k_context)); - context->native_code_map = native_code_map; + context->native_code_map = opts->gen.native_code_map; context->options = opts; - context->int_cycle = 0xFFFFFFFF; + context->int_cycle = CYCLE_NEVER; context->status = 0x27; + return context; } diff -r 858e31f977ae -r fc04781f4d28 m68k_core.h --- a/m68k_core.h Thu Jan 08 23:20:41 2015 -0800 +++ b/m68k_core.h Wed Jan 14 09:38:54 2015 -0800 @@ -60,15 +60,15 @@ native_map_slot *native_code_map; m68k_options *options; - uint8_t ram_code_flags[32/8]; void *system; + uint8_t ram_code_flags[]; } m68k_context; void translate_m68k(m68k_options * opts, struct m68kinst * inst); void translate_m68k_stream(uint32_t address, m68k_context * context); void start_68k_context(m68k_context * context, uint32_t address); void init_m68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chunks, uint32_t clock_divider); -void init_68k_context(m68k_context * context, native_map_slot * native_code_map, void * opts); +m68k_context * init_68k_context(m68k_options * opts); void m68k_reset(m68k_context * context); void insert_breakpoint(m68k_context * context, uint32_t address, uint8_t * bp_handler); void remove_breakpoint(m68k_context * context, uint32_t address); diff -r 858e31f977ae -r fc04781f4d28 m68k_core_x86.c --- a/m68k_core_x86.c Thu Jan 08 23:20:41 2015 -0800 +++ b/m68k_core_x86.c Wed Jan 14 09:38:54 2015 -0800 @@ -2202,8 +2202,10 @@ opts->gen.native_code_map = malloc(sizeof(native_map_slot) * NATIVE_MAP_CHUNKS); memset(opts->gen.native_code_map, 0, sizeof(native_map_slot) * NATIVE_MAP_CHUNKS); opts->gen.deferred = NULL; - opts->gen.ram_inst_sizes = malloc(sizeof(uint8_t *) * 64); - memset(opts->gen.ram_inst_sizes, 0, sizeof(uint8_t *) * 64); + + uint32_t inst_size_size = sizeof(uint8_t *) * ram_size(&opts->gen) / 1024; + opts->gen.ram_inst_sizes = malloc(inst_size_size); + memset(opts->gen.ram_inst_sizes, 0, inst_size_size); code_info *code = &opts->gen.code; init_code_info(code); @@ -2227,9 +2229,11 @@ opts->gen.load_context = code->cur; for (int i = 0; i < 5; i++) + { if (opts->flag_regs[i] >= 0) { mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, flags) + i, opts->flag_regs[i], SZ_B); } + } for (int i = 0; i < 8; i++) { if (opts->dregs[i] >= 0) {