# HG changeset patch # User Michael Pavone # Date 1461558208 25200 # Node ID 751280fb44944063c7bb974885dd6640981d069b # Parent bd4d698d995bae116c4c5f11937dd3cbc1f082b1 Fix interrupt latency from STOP instruction status reg changes. Fix modified code patching when non-standard aliases are used. This fixes the demo MDEM's First diff -r bd4d698d995b -r 751280fb4494 debug.c --- a/debug.c Sun Apr 24 14:30:15 2016 -0700 +++ b/debug.c Sun Apr 24 21:23:28 2016 -0700 @@ -572,7 +572,7 @@ uint8_t non_adr_count = 0; do { uint32_t bt_address = ram[stack/2] << 16 | ram[stack/2+1]; - bt_address = get_instruction_start(context->native_code_map, bt_address - 2); + bt_address = get_instruction_start(context->options, context->native_code_map, bt_address - 2); if (bt_address) { stack += 4; non_adr_count = 0; diff -r bd4d698d995b -r 751280fb4494 m68k_core.c --- a/m68k_core.c Sun Apr 24 14:30:15 2016 -0700 +++ b/m68k_core.c Sun Apr 24 21:23:28 2016 -0700 @@ -547,6 +547,13 @@ if (address & 1) { return opts->odd_address; } + //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); + } + } address /= 2; uint32_t chunk = address / NATIVE_CHUNK_SIZE; if (!native_code_map[chunk].base) { @@ -564,10 +571,17 @@ return get_native_address(context->options, address); } -uint32_t get_instruction_start(native_map_slot * native_code_map, uint32_t address) +uint32_t get_instruction_start(m68k_options *opts, native_map_slot * native_code_map, uint32_t address) { - //FIXME: Use opts->gen.address_mask - address &= 0xFFFFFF; + 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); + } + } + address /= 2; uint32_t chunk = address / NATIVE_CHUNK_SIZE; if (!native_code_map[chunk].base) { @@ -612,6 +626,8 @@ 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); diff -r bd4d698d995b -r 751280fb4494 m68k_core.h --- a/m68k_core.h Sun Apr 24 14:30:15 2016 -0700 +++ b/m68k_core.h Sun Apr 24 21:23:28 2016 -0700 @@ -79,7 +79,7 @@ void insert_breakpoint(m68k_context * context, uint32_t address, uint8_t * 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(native_map_slot * native_code_map, uint32_t address); +uint32_t get_instruction_start(m68k_options *opts, native_map_slot * native_code_map, uint32_t address); #endif //M68K_CORE_H_ diff -r bd4d698d995b -r 751280fb4494 m68k_core_x86.c --- a/m68k_core_x86.c Sun Apr 24 14:30:15 2016 -0700 +++ b/m68k_core_x86.c Sun Apr 24 21:23:28 2016 -0700 @@ -2121,18 +2121,20 @@ swap_ssp_usp(opts); } code_ptr loop_top = code->cur; - call(code, opts->do_sync); - cmp_rr(code, opts->gen.limit, opts->gen.cycles, SZ_D); - code_ptr normal_cycle_up = code->cur + 1; - jcc(code, CC_A, code->cur + 2); - cycles(&opts->gen, BUS); - code_ptr after_cycle_up = code->cur + 1; - jmp(code, code->cur + 2); - *normal_cycle_up = code->cur - (normal_cycle_up + 1); - mov_rr(code, opts->gen.limit, opts->gen.cycles, SZ_D); - *after_cycle_up = code->cur - (after_cycle_up+1); - cmp_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, int_cycle), opts->gen.cycles, SZ_D); + call(code, opts->do_sync); + cmp_rr(code, opts->gen.limit, opts->gen.cycles, SZ_D); + code_ptr normal_cycle_up = code->cur + 1; + jcc(code, CC_A, code->cur + 2); + cycles(&opts->gen, BUS); + code_ptr after_cycle_up = code->cur + 1; + jmp(code, code->cur + 2); + *normal_cycle_up = code->cur - (normal_cycle_up + 1); + mov_rr(code, opts->gen.limit, opts->gen.cycles, SZ_D); + *after_cycle_up = code->cur - (after_cycle_up+1); + cmp_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, int_cycle), opts->gen.cycles, SZ_D); jcc(code, CC_C, loop_top); + //set int pending flag so interrupt fires immediately after stop is done + mov_irdisp(code, 1, opts->gen.context_reg, offsetof(m68k_context, int_pending), SZ_B); } void translate_m68k_trapv(m68k_options *opts, m68kinst *inst) @@ -2185,9 +2187,10 @@ m68k_context * m68k_handle_code_write(uint32_t address, m68k_context * context) { - uint32_t inst_start = get_instruction_start(context->native_code_map, address | 0xFF0000); + 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 | 0xE00000); if (inst_start) { - m68k_options * options = context->options; code_info *code = &options->gen.code; code_ptr dst = get_native_address(context->options, inst_start); code_info orig = {dst, dst + 128, 0};