Mercurial > repos > blastem
diff m68k_to_x86.c @ 343:467bfa17004a
Mostly working runtime generation of memory map read/write functions
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 18 May 2013 11:44:42 -0700 |
parents | 4f2711899866 |
children | b24556b45d1e |
line wrap: on
line diff
--- a/m68k_to_x86.c Thu May 16 09:37:53 2013 -0700 +++ b/m68k_to_x86.c Sat May 18 11:44:42 2013 -0700 @@ -24,13 +24,7 @@ char disasm_buf[1024]; void handle_cycle_limit_int(); -void m68k_read_word_scratch1(); -void m68k_read_long_scratch1(); -void m68k_read_byte_scratch1(); -void m68k_write_word(); -void m68k_write_long_lowfirst(); -void m68k_write_long_highfirst(); -void m68k_write_byte(); +void handle_cycle_limit(); void m68k_save_context(); void m68k_load_context(); void m68k_modified_ret_addr(); @@ -65,6 +59,16 @@ return dst; } +uint8_t * check_cycles(uint8_t * dst) +{ + dst = cmp_rr(dst, CYCLES, LIMIT, SZ_D); + uint8_t * jmp_off = dst+1; + dst = jcc(dst, CC_NC, dst + 7); + dst = call(dst, (uint8_t *)handle_cycle_limit); + *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) { @@ -155,13 +159,13 @@ switch (inst->extra.size) { case OPSIZE_BYTE: - out = call(out, (char *)m68k_read_byte_scratch1); + out = call(out, opts->read_8); break; case OPSIZE_WORD: - out = call(out, (char *)m68k_read_word_scratch1); + out = call(out, opts->read_16); break; case OPSIZE_LONG: - out = call(out, (char *)m68k_read_long_scratch1); + out = call(out, opts->read_32); break; } @@ -187,13 +191,13 @@ switch (inst->extra.size) { case OPSIZE_BYTE: - out = call(out, (char *)m68k_read_byte_scratch1); + out = call(out, opts->read_8); break; case OPSIZE_WORD: - out = call(out, (char *)m68k_read_word_scratch1); + out = call(out, opts->read_16); break; case OPSIZE_LONG: - out = call(out, (char *)m68k_read_long_scratch1); + out = call(out, opts->read_32); break; } ea->mode = MODE_REG_DIRECT; @@ -243,13 +247,13 @@ switch (inst->extra.size) { case OPSIZE_BYTE: - out = call(out, (char *)m68k_read_byte_scratch1); + out = call(out, opts->read_8); break; case OPSIZE_WORD: - out = call(out, (char *)m68k_read_word_scratch1); + out = call(out, opts->read_16); break; case OPSIZE_LONG: - out = call(out, (char *)m68k_read_long_scratch1); + out = call(out, opts->read_32); break; } ea->mode = MODE_REG_DIRECT; @@ -261,13 +265,13 @@ switch (inst->extra.size) { case OPSIZE_BYTE: - out = call(out, (char *)m68k_read_byte_scratch1); + out = call(out, opts->read_8); break; case OPSIZE_WORD: - out = call(out, (char *)m68k_read_word_scratch1); + out = call(out, opts->read_16); break; case OPSIZE_LONG: - out = call(out, (char *)m68k_read_long_scratch1); + out = call(out, opts->read_32); break; } ea->mode = MODE_REG_DIRECT; @@ -313,13 +317,13 @@ switch (inst->extra.size) { case OPSIZE_BYTE: - out = call(out, (char *)m68k_read_byte_scratch1); + out = call(out, opts->read_8); break; case OPSIZE_WORD: - out = call(out, (char *)m68k_read_word_scratch1); + out = call(out, opts->read_16); break; case OPSIZE_LONG: - out = call(out, (char *)m68k_read_long_scratch1); + out = call(out, opts->read_32); break; } ea->mode = MODE_REG_DIRECT; @@ -336,13 +340,13 @@ switch (inst->extra.size) { case OPSIZE_BYTE: - out = call(out, (char *)m68k_read_byte_scratch1); + out = call(out, opts->read_8); break; case OPSIZE_WORD: - out = call(out, (char *)m68k_read_word_scratch1); + out = call(out, opts->read_16); break; case OPSIZE_LONG: - out = call(out, (char *)m68k_read_long_scratch1); + out = call(out, opts->read_32); break; } ea->mode = MODE_REG_DIRECT; @@ -416,13 +420,13 @@ switch (inst->extra.size) { case OPSIZE_BYTE: - out = call(out, (char *)m68k_read_byte_scratch1); + out = call(out, opts->read_8); break; case OPSIZE_WORD: - out = call(out, (char *)m68k_read_word_scratch1); + out = call(out, opts->read_16); break; case OPSIZE_LONG: - out = call(out, (char *)m68k_read_long_scratch1); + out = call(out, opts->read_32); break; } } @@ -463,13 +467,13 @@ switch (inst->extra.size) { case OPSIZE_BYTE: - out = call(out, (char *)m68k_read_byte_scratch1); + out = call(out, opts->read_8); break; case OPSIZE_WORD: - out = call(out, (char *)m68k_read_word_scratch1); + out = call(out, opts->read_16); break; case OPSIZE_LONG: - out = call(out, (char *)m68k_read_long_scratch1); + out = call(out, opts->read_32); break; } out = pop_r(out, SCRATCH2); @@ -525,13 +529,13 @@ switch (inst->extra.size) { case OPSIZE_BYTE: - out = call(out, (char *)m68k_read_byte_scratch1); + out = call(out, opts->read_8); break; case OPSIZE_WORD: - out = call(out, (char *)m68k_read_word_scratch1); + out = call(out, opts->read_16); break; case OPSIZE_LONG: - out = call(out, (char *)m68k_read_long_scratch1); + out = call(out, opts->read_32); break; } out = pop_r(out, SCRATCH2); @@ -547,13 +551,13 @@ switch (inst->extra.size) { case OPSIZE_BYTE: - out = call(out, (char *)m68k_read_byte_scratch1); + out = call(out, opts->read_8); break; case OPSIZE_WORD: - out = call(out, (char *)m68k_read_word_scratch1); + out = call(out, opts->read_16); break; case OPSIZE_LONG: - out = call(out, (char *)m68k_read_long_scratch1); + out = call(out, opts->read_32); break; } out = pop_r(out, SCRATCH2); @@ -605,13 +609,13 @@ switch (inst->extra.size) { case OPSIZE_BYTE: - out = call(out, (char *)m68k_read_byte_scratch1); + out = call(out, opts->read_8); break; case OPSIZE_WORD: - out = call(out, (char *)m68k_read_word_scratch1); + out = call(out, opts->read_16); break; case OPSIZE_LONG: - out = call(out, (char *)m68k_read_long_scratch1); + out = call(out, opts->read_32); break; } out = pop_r(out, SCRATCH2); @@ -629,13 +633,13 @@ switch (inst->extra.size) { case OPSIZE_BYTE: - out = call(out, (char *)m68k_read_byte_scratch1); + out = call(out, opts->read_8); break; case OPSIZE_WORD: - out = call(out, (char *)m68k_read_word_scratch1); + out = call(out, opts->read_16); break; case OPSIZE_LONG: - out = call(out, (char *)m68k_read_long_scratch1); + out = call(out, opts->read_32); break; } out = pop_r(out, SCRATCH2); @@ -664,13 +668,13 @@ switch (inst->extra.size) { case OPSIZE_BYTE: - out = call(out, (char *)m68k_write_byte); + out = call(out, opts->write_8); break; case OPSIZE_WORD: - out = call(out, (char *)m68k_write_word); + out = call(out, opts->write_16); break; case OPSIZE_LONG: - out = call(out, (char *)m68k_write_long_lowfirst); + out = call(out, opts->write_32_lowfirst); break; } } @@ -851,13 +855,13 @@ switch (inst->extra.size) { case OPSIZE_BYTE: - dst = call(dst, (char *)m68k_write_byte); + dst = call(dst, opts->write_8); break; case OPSIZE_WORD: - dst = call(dst, (char *)m68k_write_word); + dst = call(dst, opts->write_16); break; case OPSIZE_LONG: - dst = call(dst, (char *)m68k_write_long_highfirst); + dst = call(dst, opts->write_32_highfirst); break; } if (inst->dst.addr_mode == MODE_AREG_POSTINC) { @@ -894,13 +898,13 @@ switch (inst->extra.size) { case OPSIZE_BYTE: - dst = call(dst, (char *)m68k_write_byte); + dst = call(dst, opts->write_8); break; case OPSIZE_WORD: - dst = call(dst, (char *)m68k_write_word); + dst = call(dst, opts->write_16); break; case OPSIZE_LONG: - dst = call(dst, (char *)m68k_write_long_highfirst); + dst = call(dst, opts->write_32_highfirst); break; } break; @@ -968,13 +972,13 @@ switch (inst->extra.size) { case OPSIZE_BYTE: - dst = call(dst, (char *)m68k_write_byte); + dst = call(dst, opts->write_8); break; case OPSIZE_WORD: - dst = call(dst, (char *)m68k_write_word); + dst = call(dst, opts->write_16); break; case OPSIZE_LONG: - dst = call(dst, (char *)m68k_write_long_highfirst); + dst = call(dst, opts->write_32_highfirst); break; } break; @@ -998,13 +1002,13 @@ switch (inst->extra.size) { case OPSIZE_BYTE: - dst = call(dst, (char *)m68k_write_byte); + dst = call(dst, opts->write_8); break; case OPSIZE_WORD: - dst = call(dst, (char *)m68k_write_word); + dst = call(dst, opts->write_16); break; case OPSIZE_LONG: - dst = call(dst, (char *)m68k_write_long_highfirst); + dst = call(dst, opts->write_32_highfirst); break; } break; @@ -1068,13 +1072,13 @@ switch (inst->extra.size) { case OPSIZE_BYTE: - dst = call(dst, (char *)m68k_write_byte); + dst = call(dst, opts->write_8); break; case OPSIZE_WORD: - dst = call(dst, (char *)m68k_write_word); + dst = call(dst, opts->write_16); break; case OPSIZE_LONG: - dst = call(dst, (char *)m68k_write_long_highfirst); + dst = call(dst, opts->write_32_highfirst); break; } break; @@ -1103,13 +1107,13 @@ switch (inst->extra.size) { case OPSIZE_BYTE: - dst = call(dst, (char *)m68k_write_byte); + dst = call(dst, opts->write_8); break; case OPSIZE_WORD: - dst = call(dst, (char *)m68k_write_word); + dst = call(dst, opts->write_16); break; case OPSIZE_LONG: - dst = call(dst, (char *)m68k_write_long_highfirst); + dst = call(dst, opts->write_32_highfirst); break; } break; @@ -1275,9 +1279,9 @@ } } if (inst->extra.size == OPSIZE_LONG) { - dst = call(dst, (uint8_t *)m68k_write_long_lowfirst); + dst = call(dst, opts->write_32_lowfirst); } else { - dst = call(dst, (uint8_t *)m68k_write_word); + dst = call(dst, opts->write_16); } dst = pop_r(dst, SCRATCH2); if (inst->dst.addr_mode != MODE_AREG_PREDEC) { @@ -1415,9 +1419,9 @@ if (inst->dst.params.immed & (1 << reg)) { dst = push_r(dst, SCRATCH1); if (inst->extra.size == OPSIZE_LONG) { - dst = call(dst, (uint8_t *)m68k_read_long_scratch1); + dst = call(dst, opts->read_32); } else { - dst = call(dst, (uint8_t *)m68k_read_word_scratch1); + dst = call(dst, opts->read_16); } if (inst->extra.size == OPSIZE_WORD) { dst = movsx_rr(dst, SCRATCH1, SCRATCH1, SZ_W, SZ_D); @@ -1737,7 +1741,7 @@ } dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); - dst = call(dst, (uint8_t *)m68k_write_long_lowfirst); + dst = call(dst, opts->write_32_lowfirst); return dst; } @@ -1753,7 +1757,7 @@ } dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); - dst = call(dst, (char *)m68k_write_long_highfirst); + dst = call(dst, opts->write_32_highfirst); uint8_t * dest_addr = get_native_address(opts->native_code_map, (inst->address+2) + disp); if (!dest_addr) { opts->deferred = defer_address(opts->deferred, (inst->address+2) + disp, dst + 1); @@ -2077,7 +2081,7 @@ } dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); - dst = call(dst, (char *)m68k_write_long_highfirst); + dst = call(dst, opts->write_32_highfirst); if (opts->aregs[inst->src.params.regs.pri] >= 0) { dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); } else { @@ -2100,7 +2104,7 @@ } dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); - dst = call(dst, (char *)m68k_write_long_highfirst); + dst = call(dst, opts->write_32_highfirst); if (opts->aregs[inst->src.params.regs.pri] >= 0) { dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); } else { @@ -2124,7 +2128,7 @@ } dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); - dst = call(dst, (char *)m68k_write_long_highfirst); + dst = call(dst, opts->write_32_highfirst); if (opts->aregs[inst->src.params.regs.pri] >= 0) { dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); } else { @@ -2182,7 +2186,7 @@ } dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); - dst = call(dst, (char *)m68k_write_long_highfirst); + dst = call(dst, opts->write_32_highfirst); m68k_addr = inst->src.params.regs.displacement + inst->address + 2; if ((m68k_addr & 0xFFFFFF) < 0x400000) { dest_addr = get_native_address(opts->native_code_map, m68k_addr); @@ -2218,7 +2222,7 @@ } dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); - dst = call(dst, (char *)m68k_write_long_highfirst); + dst = call(dst, opts->write_32_highfirst); dst = mov_ir(dst, inst->address+2, SCRATCH1, SZ_D); sec_reg = (inst->src.params.regs.sec >> 1) & 0x7; if (inst->src.params.regs.sec & 1) { @@ -2273,7 +2277,7 @@ } dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); - dst = call(dst, (char *)m68k_write_long_highfirst); + dst = call(dst, opts->write_32_highfirst); m68k_addr = inst->src.params.immed; if ((m68k_addr & 0xFFFFFF) < 0x400000) { dest_addr = get_native_address(opts->native_code_map, m68k_addr); @@ -2314,7 +2318,7 @@ //TODO: Add cycles dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D); dst = add_ir(dst, 4, opts->aregs[7], SZ_D); - dst = call(dst, (char *)m68k_read_long_scratch1); + dst = call(dst, opts->read_32); if (opts->flags & OPT_NATIVE_CALL_STACK) { dst = cmp_rdisp8r(dst, RSP, 8, SCRATCH1, SZ_D); dst = jcc(dst, CC_NZ, dst+3); @@ -2420,7 +2424,7 @@ } else { dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src)), SCRATCH1, SZ_D); } - dst = call(dst, (char *)m68k_write_long_highfirst); + dst = call(dst, opts->write_32_highfirst); if (reg >= 0) { dst = mov_rr(dst, opts->aregs[7], reg, SZ_D); } else { @@ -2451,7 +2455,7 @@ dst = mov_rr(dst, reg, SCRATCH1, SZ_D); dst = shr_ir(dst, 24, SCRATCH1, SZ_D); dst = push_r(dst, SCRATCH2); - dst = call(dst, (uint8_t *)m68k_write_byte); + dst = call(dst, opts->write_8); dst = pop_r(dst, SCRATCH2); dst = mov_rr(dst, reg, SCRATCH1, SZ_D); dst = shr_ir(dst, 16, SCRATCH1, SZ_D); @@ -2459,13 +2463,13 @@ } else { dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src))+3, SCRATCH1, SZ_B); dst = push_r(dst, SCRATCH2); - dst = call(dst, (uint8_t *)m68k_write_byte); + dst = call(dst, opts->write_8); dst = pop_r(dst, SCRATCH2); dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src))+2, SCRATCH1, SZ_B); } dst = add_ir(dst, 2, SCRATCH2, SZ_D); dst = push_r(dst, SCRATCH2); - dst = call(dst, (uint8_t *)m68k_write_byte); + dst = call(dst, opts->write_8); dst = pop_r(dst, SCRATCH2); dst = add_ir(dst, 2, SCRATCH2, SZ_D); } @@ -2473,18 +2477,18 @@ dst = mov_rr(dst, reg, SCRATCH1, SZ_W); dst = shr_ir(dst, 8, SCRATCH1, SZ_W); dst = push_r(dst, SCRATCH2); - dst = call(dst, (uint8_t *)m68k_write_byte); + dst = call(dst, opts->write_8); dst = pop_r(dst, SCRATCH2); dst = mov_rr(dst, reg, SCRATCH1, SZ_W); } else { dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src))+1, SCRATCH1, SZ_B); dst = push_r(dst, SCRATCH2); - dst = call(dst, (uint8_t *)m68k_write_byte); + dst = call(dst, opts->write_8); dst = pop_r(dst, SCRATCH2); dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src)), SCRATCH1, SZ_B); } dst = add_ir(dst, 2, SCRATCH2, SZ_D); - dst = call(dst, (uint8_t *)m68k_write_byte); + dst = call(dst, opts->write_8); } else { if (opts->aregs[inst->src.params.regs.pri] >= 0) { dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); @@ -2498,43 +2502,43 @@ if (inst->extra.size == OPSIZE_LONG) { if (reg >= 0) { dst = push_r(dst, SCRATCH1); - dst = call(dst, (uint8_t *)m68k_read_byte_scratch1); + dst = call(dst, opts->read_8); dst = shl_ir(dst, 24, SCRATCH1, SZ_D); dst = mov_rr(dst, SCRATCH1, reg, SZ_D); dst = pop_r(dst, SCRATCH1); dst = add_ir(dst, 2, SCRATCH1, SZ_D); dst = push_r(dst, SCRATCH1); - dst = call(dst, (uint8_t *)m68k_read_byte_scratch1); + dst = call(dst, opts->read_8); dst = shl_ir(dst, 16, SCRATCH1, SZ_D); dst = or_rr(dst, SCRATCH1, reg, SZ_D); } else { dst = push_r(dst, SCRATCH1); - dst = call(dst, (uint8_t *)m68k_read_byte_scratch1); + dst = call(dst, opts->read_8); dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, reg_offset(&(inst->dst))+3, SZ_B); dst = pop_r(dst, SCRATCH1); dst = add_ir(dst, 2, SCRATCH1, SZ_D); dst = push_r(dst, SCRATCH1); - dst = call(dst, (uint8_t *)m68k_read_byte_scratch1); + dst = call(dst, opts->read_8); dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, reg_offset(&(inst->dst))+2, SZ_B); } dst = pop_r(dst, SCRATCH1); dst = add_ir(dst, 2, SCRATCH1, SZ_D); } dst = push_r(dst, SCRATCH1); - dst = call(dst, (uint8_t *)m68k_read_byte_scratch1); + dst = call(dst, opts->read_8); if (reg >= 0) { dst = shl_ir(dst, 8, SCRATCH1, SZ_W); dst = mov_rr(dst, SCRATCH1, reg, SZ_W); dst = pop_r(dst, SCRATCH1); dst = add_ir(dst, 2, SCRATCH1, SZ_D); - dst = call(dst, (uint8_t *)m68k_read_byte_scratch1); + dst = call(dst, opts->read_8); dst = mov_rr(dst, SCRATCH1, reg, SZ_B); } else { dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, reg_offset(&(inst->dst))+1, SZ_B); dst = pop_r(dst, SCRATCH1); dst = add_ir(dst, 2, SCRATCH1, SZ_D); - dst = call(dst, (uint8_t *)m68k_read_byte_scratch1); + dst = call(dst, opts->read_8); dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, reg_offset(&(inst->dst)), SZ_B); } } @@ -3711,12 +3715,12 @@ //TODO: Trap if not in system mode //Read saved SR dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D); - dst = call(dst, (uint8_t *)m68k_read_word_scratch1); + dst = call(dst, opts->read_16); dst = add_ir(dst, 2, opts->aregs[7], SZ_D); dst = call(dst, (uint8_t *)set_sr); //Read saved PC dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D); - dst = call(dst, (uint8_t *)m68k_read_long_scratch1); + dst = call(dst, opts->read_32); dst = add_ir(dst, 4, opts->aregs[7], SZ_D); //Check if we've switched to user mode and swap stack pointers if needed dst = bt_irdisp8(dst, 5, CONTEXT, offsetof(m68k_context, status), SZ_B); @@ -3733,12 +3737,12 @@ case M68K_RTR: //Read saved CCR dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D); - dst = call(dst, (uint8_t *)m68k_read_word_scratch1); + dst = call(dst, opts->read_16); dst = add_ir(dst, 2, opts->aregs[7], SZ_D); dst = call(dst, (uint8_t *)set_ccr); //Read saved PC dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D); - dst = call(dst, (uint8_t *)m68k_read_long_scratch1); + dst = call(dst, opts->read_32); dst = add_ir(dst, 4, opts->aregs[7], SZ_D); //Get native address and jump to it dst = call(dst, (uint8_t *)m68k_native_addr); @@ -3871,7 +3875,7 @@ dst = mov_rdisp8r(dst, dst_op.base, dst_op.disp, opts->aregs[7], SZ_D); } dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D); - dst = call(dst, (uint8_t *)m68k_read_long_scratch1); + dst = call(dst, opts->read_32); if (dst_op.mode == MODE_REG_DIRECT) { dst = mov_rr(dst, SCRATCH1, dst_op.base, SZ_D); } else { @@ -4135,7 +4139,7 @@ start_68k_context(context, address); } -void init_x86_68k_opts(x86_68k_options * opts) +void init_x86_68k_opts(x86_68k_options * opts, memmap_chunk * memmap, uint32_t num_chunks) { opts->flags = 0; for (int i = 0; i < 8; i++) @@ -4154,6 +4158,317 @@ opts->code_end = opts->cur_code + size; opts->ram_inst_sizes = malloc(sizeof(uint8_t *) * 64); memset(opts->ram_inst_sizes, 0, sizeof(uint8_t *) * 64); + uint8_t * dst = opts->read_16 = opts->cur_code; + dst = check_cycles(dst); + dst = cycles(dst, BUS); + dst = and_ir(dst, 0xFFFFFF, SCRATCH1, SZ_D); + uint8_t *lb_jcc = NULL, *ub_jcc = NULL; + for (uint32_t chunk = 0; chunk < num_chunks; chunk++) + { + if (lb_jcc) { + *lb_jcc = dst - (lb_jcc+1); + lb_jcc = NULL; + } + if (ub_jcc) { + *ub_jcc = dst - (ub_jcc+1); + ub_jcc = NULL; + } + if (memmap[chunk].start > 0) { + dst = cmp_ir(dst, memmap[chunk].start, SCRATCH1, SZ_D); + lb_jcc = dst + 1; + dst = jcc(dst, CC_C, dst+2); + } + if (memmap[chunk].end < 0x1000000) { + dst = cmp_ir(dst, memmap[chunk].end, SCRATCH1, SZ_D); + ub_jcc = dst + 1; + dst = jcc(dst, CC_NC, dst+2); + } + + if (memmap[chunk].mask != 0xFFFFFF) { + dst = and_ir(dst, memmap[chunk].mask, SCRATCH1, SZ_D); + } + + if (memmap[chunk].read_16) { + dst = call(dst, (uint8_t *)m68k_save_context); + dst = push_r(dst, CONTEXT); + dst = mov_rr(dst, SCRATCH1, RDI, SZ_D); + dst = call(dst, (uint8_t *)memmap[chunk].read_16); + dst = pop_r(dst, CONTEXT); + dst = mov_rr(dst, RAX, SCRATCH1, SZ_W); + dst = jmp(dst, (uint8_t *)m68k_load_context); + } else if(memmap[chunk].buffer && memmap[chunk].flags & MMAP_READ) { + if ((int64_t)memmap[chunk].buffer <= 0x7FFFFFFF && (int64_t)memmap[chunk].buffer >= -2147483648) { + dst = mov_rdisp32r(dst, SCRATCH1, (int64_t)memmap[chunk].buffer, SCRATCH1, SZ_W); + } else { + dst = mov_ir(dst, (int64_t)memmap[chunk].buffer, SCRATCH2, SZ_Q); + dst = mov_rindexr(dst, SCRATCH2, SCRATCH1, 1, SCRATCH1, SZ_W); + } + dst = retn(dst); + } else { + //Not sure the best course of action here + dst = mov_ir(dst, 0xFFFF, SCRATCH1, SZ_W); + dst = retn(dst); + } + } + if (lb_jcc) { + *lb_jcc = dst - (lb_jcc+1); + lb_jcc = NULL; + } + if (ub_jcc) { + *ub_jcc = dst - (ub_jcc+1); + ub_jcc = NULL; + } + dst = mov_ir(dst, 0xFFFF, SCRATCH1, SZ_W); + dst = retn(dst); + + opts->write_16 = dst; + dst = check_cycles(dst); + dst = cycles(dst, BUS); + dst = and_ir(dst, 0xFFFFFF, SCRATCH2, SZ_D); + for (uint32_t chunk = 0; chunk < num_chunks; chunk++) + { + if (lb_jcc) { + *lb_jcc = dst - (lb_jcc+1); + lb_jcc = NULL; + } + if (ub_jcc) { + *ub_jcc = dst - (ub_jcc+1); + ub_jcc = NULL; + } + if (memmap[chunk].start > 0) { + dst = cmp_ir(dst, memmap[chunk].start, SCRATCH2, SZ_D); + lb_jcc = dst + 1; + dst = jcc(dst, CC_C, dst+2); + } + if (memmap[chunk].end < 0x1000000) { + dst = cmp_ir(dst, memmap[chunk].end, SCRATCH2, SZ_D); + ub_jcc = dst + 1; + dst = jcc(dst, CC_NC, dst+2); + } + + if (memmap[chunk].mask != 0xFFFFFF) { + dst = and_ir(dst, memmap[chunk].mask, SCRATCH2, SZ_D); + } + + if (memmap[chunk].write_16) { + dst = call(dst, (uint8_t *)m68k_save_context); + //SCRATCH2 is RDI, so no need to move it there + dst = mov_rr(dst, SCRATCH1, RDX, SZ_W); + dst = call(dst, (uint8_t *)memmap[chunk].write_16); + dst = mov_rr(dst, RAX, CONTEXT, SZ_Q); + dst = jmp(dst, (uint8_t *)m68k_load_context); + } else if(memmap[chunk].buffer && memmap[chunk].flags & MMAP_WRITE) { + if ((int64_t)memmap[chunk].buffer <= 0x7FFFFFFF && (int64_t)memmap[chunk].buffer >= -2147483648) { + dst = mov_rrdisp32(dst, SCRATCH1, SCRATCH2, (int64_t)memmap[chunk].buffer, SZ_W); + } else { + dst = push_r(dst, SCRATCH1); + dst = mov_ir(dst, (int64_t)memmap[chunk].buffer, SCRATCH1, SZ_Q); + dst = add_rr(dst, SCRATCH1, SCRATCH2, SZ_Q); + dst = pop_r(dst, SCRATCH1); + dst = mov_rrind(dst, SCRATCH1, SCRATCH2, SZ_W); + } + if (memmap[chunk].flags & MMAP_CODE) { + dst = mov_rr(dst, SCRATCH2, SCRATCH1, SZ_D); + dst = shr_ir(dst, 11, SCRATCH1, SZ_D); + dst = bt_rrdisp32(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, ram_code_flags), SZ_D); + uint8_t * not_code = dst+1; + dst = jcc(dst, CC_NC, dst+2); + dst = call(dst, (uint8_t *)m68k_save_context); + dst = call(dst, (uint8_t *)m68k_handle_code_write); + dst = mov_rr(dst, RAX, CONTEXT, SZ_Q); + dst = call(dst, (uint8_t *)m68k_load_context); + *not_code = dst - (not_code+1); + } + dst = retn(dst); + } else { + //Not sure the best course of action here + dst = retn(dst); + } + } + if (lb_jcc) { + *lb_jcc = dst - (lb_jcc+1); + lb_jcc = NULL; + } + if (ub_jcc) { + *ub_jcc = dst - (ub_jcc+1); + ub_jcc = NULL; + } + dst = retn(dst); + + opts->read_8 = dst; + dst = check_cycles(dst); + dst = cycles(dst, BUS); + dst = and_ir(dst, 0xFFFFFF, SCRATCH1, SZ_D); + for (uint32_t chunk = 0; chunk < num_chunks; chunk++) + { + if (lb_jcc) { + *lb_jcc = dst - (lb_jcc+1); + lb_jcc = NULL; + } + if (ub_jcc) { + *ub_jcc = dst - (ub_jcc+1); + ub_jcc = NULL; + } + if (memmap[chunk].start > 0) { + dst = cmp_ir(dst, memmap[chunk].start, SCRATCH1, SZ_D); + lb_jcc = dst + 1; + dst = jcc(dst, CC_C, dst+2); + } + if (memmap[chunk].end < 0x1000000) { + dst = cmp_ir(dst, memmap[chunk].end, SCRATCH1, SZ_D); + ub_jcc = dst + 1; + dst = jcc(dst, CC_NC, dst+2); + } + + if (memmap[chunk].mask != 0xFFFFFF) { + dst = and_ir(dst, memmap[chunk].mask, SCRATCH1, SZ_D); + } + + if (memmap[chunk].read_8) { + dst = call(dst, (uint8_t *)m68k_save_context); + dst = push_r(dst, CONTEXT); + dst = mov_rr(dst, SCRATCH1, RDI, SZ_D); + dst = call(dst, (uint8_t *)memmap[chunk].read_8); + dst = pop_r(dst, CONTEXT); + dst = mov_rr(dst, RAX, SCRATCH1, SZ_B); + dst = jmp(dst, (uint8_t *)m68k_load_context); + } else if(memmap[chunk].buffer && memmap[chunk].flags & MMAP_READ) { + dst = xor_ir(dst, 1, SCRATCH1, SZ_D); + if ((int64_t)memmap[chunk].buffer <= 0x7FFFFFFF && (int64_t)memmap[chunk].buffer >= -2147483648) { + dst = mov_rdisp32r(dst, SCRATCH1, (int64_t)memmap[chunk].buffer, SCRATCH1, SZ_B); + } else { + dst = mov_ir(dst, (int64_t)memmap[chunk].buffer, SCRATCH2, SZ_Q); + dst = mov_rindexr(dst, SCRATCH2, SCRATCH1, 1, SCRATCH1, SZ_B); + } + dst = retn(dst); + } else { + //Not sure the best course of action here + dst = mov_ir(dst, 0xFF, SCRATCH1, SZ_B); + dst = retn(dst); + } + } + if (lb_jcc) { + *lb_jcc = dst - (lb_jcc+1); + lb_jcc = NULL; + } + if (ub_jcc) { + *ub_jcc = dst - (ub_jcc+1); + ub_jcc = NULL; + } + dst = mov_ir(dst, 0xFFFF, SCRATCH1, SZ_W); + dst = retn(dst); + + opts->write_8 = dst; + dst = check_cycles(dst); + dst = cycles(dst, BUS); + dst = and_ir(dst, 0xFFFFFF, SCRATCH2, SZ_D); + for (uint32_t chunk = 0; chunk < num_chunks; chunk++) + { + if (lb_jcc) { + *lb_jcc = dst - (lb_jcc+1); + lb_jcc = NULL; + } + if (ub_jcc) { + *ub_jcc = dst - (ub_jcc+1); + ub_jcc = NULL; + } + if (memmap[chunk].start > 0) { + dst = cmp_ir(dst, memmap[chunk].start, SCRATCH2, SZ_D); + lb_jcc = dst + 1; + dst = jcc(dst, CC_C, dst+2); + } + if (memmap[chunk].end < 0x1000000) { + dst = cmp_ir(dst, memmap[chunk].end, SCRATCH2, SZ_D); + ub_jcc = dst + 1; + dst = jcc(dst, CC_NC, dst+2); + } + + if (memmap[chunk].mask != 0xFFFFFF) { + dst = and_ir(dst, memmap[chunk].mask, SCRATCH2, SZ_D); + } + + if (memmap[chunk].write_8) { + dst = call(dst, (uint8_t *)m68k_save_context); + //SCRATCH2 is RDI, so no need to move it there + dst = mov_rr(dst, SCRATCH1, RDX, SZ_B); + dst = call(dst, (uint8_t *)memmap[chunk].write_8); + dst = mov_rr(dst, RAX, CONTEXT, SZ_Q); + dst = jmp(dst, (uint8_t *)m68k_load_context); + } else if(memmap[chunk].buffer && memmap[chunk].flags & MMAP_WRITE) { + dst = xor_ir(dst, 1, SCRATCH2, SZ_D); + if ((int64_t)memmap[chunk].buffer <= 0x7FFFFFFF && (int64_t)memmap[chunk].buffer >= -2147483648) { + dst = mov_rrdisp32(dst, SCRATCH1, SCRATCH2, (int64_t)memmap[chunk].buffer, SZ_B); + } else { + dst = push_r(dst, SCRATCH1); + dst = mov_ir(dst, (int64_t)memmap[chunk].buffer, SCRATCH1, SZ_Q); + dst = add_rr(dst, SCRATCH1, SCRATCH2, SZ_Q); + dst = pop_r(dst, SCRATCH1); + dst = mov_rrind(dst, SCRATCH1, SCRATCH2, SZ_B); + } + if (memmap[chunk].flags & MMAP_CODE) { + dst = mov_rr(dst, SCRATCH2, SCRATCH1, SZ_D); + dst = shr_ir(dst, 11, SCRATCH1, SZ_D); + dst = bt_rrdisp32(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, ram_code_flags), SZ_D); + uint8_t * not_code = dst+1; + dst = jcc(dst, CC_NC, dst+2); + dst = xor_ir(dst, 1, SCRATCH2, SZ_D); + dst = call(dst, (uint8_t *)m68k_save_context); + dst = call(dst, (uint8_t *)m68k_handle_code_write); + dst = mov_rr(dst, RAX, CONTEXT, SZ_Q); + dst = call(dst, (uint8_t *)m68k_load_context); + *not_code = dst - (not_code+1); + } + dst = retn(dst); + } else { + //Not sure the best course of action here + dst = retn(dst); + } + } + if (lb_jcc) { + *lb_jcc = dst - (lb_jcc+1); + lb_jcc = NULL; + } + if (ub_jcc) { + *ub_jcc = dst - (ub_jcc+1); + ub_jcc = NULL; + } + dst = retn(dst); + + opts->read_32 = dst; + dst = push_r(dst, SCRATCH1); + dst = call(dst, opts->read_16); + dst = mov_rr(dst, SCRATCH1, SCRATCH2, SZ_W); + dst = pop_r(dst, SCRATCH1); + dst = push_r(dst, SCRATCH2); + dst = add_ir(dst, 2, SCRATCH1, SZ_D); + dst = call(dst, opts->read_16); + dst = pop_r(dst, SCRATCH2); + dst = movzx_rr(dst, SCRATCH1, SCRATCH1, SZ_W, SZ_D); + dst = shl_ir(dst, 16, SCRATCH2, SZ_D); + dst = or_rr(dst, SCRATCH2, SCRATCH1, SZ_D); + dst = retn(dst); + + opts->write_32_lowfirst = dst; + dst = push_r(dst, SCRATCH2); + dst = push_r(dst, SCRATCH1); + dst = add_ir(dst, 2, SCRATCH2, SZ_D); + dst = call(dst, opts->write_16); + dst = pop_r(dst, SCRATCH1); + dst = pop_r(dst, SCRATCH2); + dst = shr_ir(dst, 16, SCRATCH1, SZ_D); + dst = jmp(dst, opts->write_16); + + opts->write_32_highfirst = dst; + dst = push_r(dst, SCRATCH1); + dst = push_r(dst, SCRATCH2); + dst = shr_ir(dst, 16, SCRATCH1, SZ_D); + dst = call(dst, opts->write_16); + dst = pop_r(dst, SCRATCH2); + dst = pop_r(dst, SCRATCH1); + dst = add_ir(dst, 2, SCRATCH2, SZ_D); + dst = jmp(dst, opts->write_16); + + opts->cur_code = dst; } void init_68k_context(m68k_context * context, native_map_slot * native_code_map, void * opts)