Mercurial > repos > blastem
diff m68k_to_x86.c @ 82:6331ddec228f
Initial stab at interrupt support. Make native code offsets bigger so I don't have to worry about overflowing the offset. Implement neg and not (untested).
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Wed, 26 Dec 2012 11:09:04 -0800 |
parents | 6d231dbe75ab |
children | 3d3966c254b2 |
line wrap: on
line diff
--- a/m68k_to_x86.c Sat Dec 22 21:37:25 2012 -0800 +++ b/m68k_to_x86.c Wed Dec 26 11:09:04 2012 -0800 @@ -26,7 +26,7 @@ uint8_t cycles; } x86_ea; -void handle_cycle_limit(); +void handle_cycle_limit_int(); void m68k_read_word_scratch1(); void m68k_read_long_scratch1(); void m68k_read_byte_scratch1(); @@ -37,6 +37,10 @@ void m68k_save_context(); void m68k_modified_ret_addr(); void m68k_native_addr(); +void m68k_native_addr_and_sync(); +void set_sr(); +void set_ccr(); +void get_sr(); void m68k_start_context(uint8_t * addr, m68k_context * context); uint8_t * cycles(uint8_t * dst, uint32_t num) @@ -44,6 +48,17 @@ dst = add_ir(dst, num, CYCLES, SZ_D); } +uint8_t * check_cycles_int(uint8_t * dst, uint32_t address) +{ + dst = cmp_rr(dst, LIMIT, CYCLES, SZ_D); + uint8_t * jmp_off = dst+1; + dst = jcc(dst, CC_NC, dst + 7); + dst = mov_ir(dst, address, SCRATCH1, SZ_D); + dst = call(dst, (uint8_t *)handle_cycle_limit_int); + *jmp_off = dst - (jmp_off+1); + return dst; +} + int8_t native_reg(m68k_op_info * op, x86_68k_options * opts) { if (op->addr_mode == MODE_REG) { @@ -513,14 +528,12 @@ void map_native_address(native_map_slot * native_code_map, uint32_t address, uint8_t * native_addr) { - //FIXME: This probably isn't going to work with real code in a lot of cases, no guarantee that - //all the code in 1KB block is going to be translated at the same time address &= 0xFFFFFF; uint32_t chunk = address / NATIVE_CHUNK_SIZE; if (!native_code_map[chunk].base) { native_code_map[chunk].base = native_addr; - native_code_map[chunk].offsets = malloc(sizeof(uint16_t) * NATIVE_CHUNK_SIZE); - memset(native_code_map[chunk].offsets, 0xFF, sizeof(uint16_t) * NATIVE_CHUNK_SIZE); + native_code_map[chunk].offsets = malloc(sizeof(int32_t) * NATIVE_CHUNK_SIZE); + memset(native_code_map[chunk].offsets, 0xFF, sizeof(int32_t) * NATIVE_CHUNK_SIZE); } uint32_t offset = address % NATIVE_CHUNK_SIZE; native_code_map[chunk].offsets[offset] = native_addr-native_code_map[chunk].base; @@ -1407,6 +1420,7 @@ { uint8_t * end_off; map_native_address(opts->native_code_map, inst->address, dst); + dst = check_cycles_int(dst, inst->address); if (inst->op == M68K_MOVE) { return translate_m68k_move(dst, inst, opts); } else if(inst->op == M68K_LEA) { @@ -1653,9 +1667,7 @@ dst = mov_rr(dst, CONTEXT, RDI, SZ_Q); dst = call(dst, (uint8_t *)print_regs_exit); break; - /*case M68K_JSR: - case M68K_LEA: - case M68K_MOVE_FROM_SR: + /*case M68K_MOVE_FROM_SR: break;*/ case M68K_MOVE_CCR: case M68K_MOVE_SR: @@ -1677,34 +1689,16 @@ } dst = cycles(dst, 12); } else { - if (src_op.mode == MODE_REG_DIRECT) { - dst = mov_rr(dst, src_op.base, FLAG_C, SZ_B); - } else { - dst = mov_rdisp8r(dst, src_op.base, src_op.disp, FLAG_C, SZ_B); - } - dst = mov_rr(dst, FLAG_C, FLAG_V, SZ_B); - dst = and_ir(dst, 1, FLAG_C, SZ_B); - dst = shr_ir(dst, 1, FLAG_V, SZ_B); - dst = mov_rr(dst, FLAG_V, FLAG_Z, SZ_B); - dst = and_ir(dst, 1, FLAG_V, SZ_B); - dst = shr_ir(dst, 1, FLAG_Z, SZ_B); - dst = mov_rr(dst, FLAG_Z, FLAG_N, SZ_B); - dst = and_ir(dst, 1, FLAG_Z, SZ_B); - dst = shr_ir(dst, 1, FLAG_N, SZ_B); - dst = mov_rr(dst, 1, SCRATCH2, SZ_B); - dst = shr_ir(dst, 1, SCRATCH2, SZ_B); - dst = and_ir(dst, 1, SCRATCH2, SZ_B); - dst = mov_rrind(dst, SCRATCH2, CONTEXT, SZ_B); - dst = cycles(dst, 12); - if (inst->op == M68K_MOVE_SR) { + if (src_op.base != SCRATCH1) { if (src_op.mode == MODE_REG_DIRECT) { - dst = mov_rr(dst, src_op.base, SCRATCH2, SZ_W); + dst = mov_rr(dst, src_op.base, SCRATCH1, SZ_W); } else { - dst = mov_rdisp8r(dst, src_op.base, src_op.disp, SCRATCH2, SZ_W); + dst = mov_rdisp8r(dst, src_op.base, src_op.disp, SCRATCH1, SZ_W); } } - dst = shr_ir(dst, 8, SCRATCH2, SZ_B); - dst = mov_rrdisp8(dst, SCRATCH2, CONTEXT, offsetof(m68k_context, status), SZ_B); + dst = call(dst, (uint8_t *)(inst->op == M68K_MOVE_SR ? set_sr : set_ccr)); + dst = cycles(dst, 12); + } break; case M68K_MOVE_USP: @@ -1730,15 +1724,36 @@ /*case M68K_MOVEP: case M68K_MULS: case M68K_MULU: - case M68K_NBCD: + case M68K_NBCD:*/ case M68K_NEG: - case M68K_NEGX: + if (dst_op.mode == MODE_REG_DIRECT) { + dst = neg_r(dst, dst_op.base, inst->extra.size); + } else { + dst = not_rdisp8(dst, dst_op.base, dst_op.disp, inst->extra.size); + } + dst = mov_ir(dst, 0, FLAG_C, SZ_B); + dst = setcc_r(dst, CC_Z, FLAG_Z); + dst = setcc_r(dst, CC_S, FLAG_N); + dst = mov_ir(dst, 0, FLAG_V, SZ_B); + dst = m68k_save_result(inst, dst, opts); + break; + /*case M68K_NEGX: break;*/ case M68K_NOP: dst = cycles(dst, BUS); break; - //case M68K_NOT: - // break; + case M68K_NOT: + if (dst_op.mode == MODE_REG_DIRECT) { + dst = not_r(dst, dst_op.base, inst->extra.size); + } else { + dst = not_rdisp8(dst, dst_op.base, dst_op.disp, inst->extra.size); + } + dst = mov_ir(dst, 0, FLAG_C, SZ_B); + dst = setcc_r(dst, CC_Z, FLAG_Z); + dst = setcc_r(dst, CC_S, FLAG_N); + dst = mov_ir(dst, 0, FLAG_V, SZ_B); + dst = m68k_save_result(inst, dst, opts); + break; case M68K_OR: dst = cycles(dst, BUS); if (src_op.mode == MODE_REG_DIRECT) { @@ -1769,9 +1784,28 @@ case M68K_ROL: case M68K_ROR: case M68K_ROXL: - case M68K_ROXR: + case M68K_ROXR:*/ case M68K_RTE: - case M68K_RTR: + dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D); + dst = call(dst, (uint8_t *)m68k_read_long_scratch1); + dst = push_r(dst, SCRATCH1); + dst = add_ir(dst, 4, opts->aregs[7], SZ_D); + dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D); + dst = call(dst, (uint8_t *)m68k_read_word_scratch1); + dst = add_ir(dst, 2, opts->aregs[7], SZ_D); + dst = call(dst, (uint8_t *)set_sr); + dst = pop_r(dst, SCRATCH1); + dst = bt_irdisp8(dst, 5, CONTEXT, offsetof(m68k_context, status), SZ_B); + end_off = dst+1; + dst = jcc(dst, CC_NC, dst+2); + dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); + dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, opts->aregs[7], SZ_D); + dst = mov_rrdisp8(dst, SCRATCH2, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_D); + *end_off = dst - (end_off+1); + dst = call(dst, (uint8_t *)m68k_native_addr_and_sync); + dst = jmp_r(dst, SCRATCH1); + break; + /*case M68K_RTR: case M68K_SBCD: case M68K_SCC: case M68K_STOP: @@ -1857,6 +1891,9 @@ { m68kinst instbuf; x86_68k_options * opts = context->options; + if(get_native_address(opts->native_code_map, address)) { + return dst; + } char disbuf[1024]; uint16_t *encoded = context->mem_pointers[0] + address/2, *next; do { @@ -1918,5 +1955,6 @@ memset(context, 0, sizeof(m68k_context)); context->native_code_map = native_code_map; context->options = opts; + context->int_cycle = 0xFFFFFFFF; }