Mercurial > repos > blastem
comparison m68k_to_x86.c @ 347:b24556b45d1e
Generate handle_cycle_limit_int at runtime so it can refer to the runtime generated memory map functions
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Tue, 21 May 2013 00:56:56 -0700 |
parents | 467bfa17004a |
children | 3923dbc2dcc4 |
comparison
equal
deleted
inserted
replaced
346:aff29d50afd5 | 347:b24556b45d1e |
---|---|
21 #define FLAG_Z RDX | 21 #define FLAG_Z RDX |
22 #define FLAG_C DH | 22 #define FLAG_C DH |
23 | 23 |
24 char disasm_buf[1024]; | 24 char disasm_buf[1024]; |
25 | 25 |
26 void handle_cycle_limit_int(); | 26 m68k_context * sync_components(m68k_context * context, uint32_t address); |
27 | |
27 void handle_cycle_limit(); | 28 void handle_cycle_limit(); |
28 void m68k_save_context(); | 29 void m68k_save_context(); |
29 void m68k_load_context(); | 30 void m68k_load_context(); |
30 void m68k_modified_ret_addr(); | 31 void m68k_modified_ret_addr(); |
31 void m68k_native_addr(); | 32 void m68k_native_addr(); |
46 { | 47 { |
47 dst = add_ir(dst, num, CYCLES, SZ_D); | 48 dst = add_ir(dst, num, CYCLES, SZ_D); |
48 return dst; | 49 return dst; |
49 } | 50 } |
50 | 51 |
51 uint8_t * check_cycles_int(uint8_t * dst, uint32_t address) | 52 uint8_t * check_cycles_int(uint8_t * dst, uint32_t address, x86_68k_options * opts) |
52 { | 53 { |
53 dst = cmp_rr(dst, CYCLES, LIMIT, SZ_D); | 54 dst = cmp_rr(dst, CYCLES, LIMIT, SZ_D); |
54 uint8_t * jmp_off = dst+1; | 55 uint8_t * jmp_off = dst+1; |
55 dst = jcc(dst, CC_NC, dst + 7); | 56 dst = jcc(dst, CC_NC, dst + 7); |
56 dst = mov_ir(dst, address, SCRATCH1, SZ_D); | 57 dst = mov_ir(dst, address, SCRATCH1, SZ_D); |
57 dst = call(dst, (uint8_t *)handle_cycle_limit_int); | 58 dst = call(dst, opts->handle_cycle_limit_int); |
58 *jmp_off = dst - (jmp_off+1); | 59 *jmp_off = dst - (jmp_off+1); |
59 return dst; | 60 return dst; |
60 } | 61 } |
61 | 62 |
62 uint8_t * check_cycles(uint8_t * dst) | 63 uint8_t * check_cycles(uint8_t * dst) |
2744 | 2745 |
2745 uint8_t * translate_m68k(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) | 2746 uint8_t * translate_m68k(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) |
2746 { | 2747 { |
2747 uint8_t * end_off, *zero_off, *norm_off; | 2748 uint8_t * end_off, *zero_off, *norm_off; |
2748 uint8_t dst_reg; | 2749 uint8_t dst_reg; |
2749 dst = check_cycles_int(dst, inst->address); | 2750 dst = check_cycles_int(dst, inst->address, opts); |
2750 if (inst->op == M68K_MOVE) { | 2751 if (inst->op == M68K_MOVE) { |
2751 return translate_m68k_move(dst, inst, opts); | 2752 return translate_m68k_move(dst, inst, opts); |
2752 } else if(inst->op == M68K_LEA) { | 2753 } else if(inst->op == M68K_LEA) { |
2753 return translate_m68k_lea(dst, inst, opts); | 2754 return translate_m68k_lea(dst, inst, opts); |
2754 } else if(inst->op == M68K_PEA) { | 2755 } else if(inst->op == M68K_PEA) { |
4087 } | 4088 } |
4088 bp_stub = dst; | 4089 bp_stub = dst; |
4089 native = call(native, bp_stub); | 4090 native = call(native, bp_stub); |
4090 | 4091 |
4091 //Calculate length of prologue | 4092 //Calculate length of prologue |
4092 dst = check_cycles_int(dst, address); | 4093 dst = check_cycles_int(dst, address, opts); |
4093 int check_int_size = dst-bp_stub; | 4094 int check_int_size = dst-bp_stub; |
4094 dst = bp_stub; | 4095 dst = bp_stub; |
4095 | 4096 |
4096 //Save context and call breakpoint handler | 4097 //Save context and call breakpoint handler |
4097 dst = call(dst, (uint8_t *)m68k_save_context); | 4098 dst = call(dst, (uint8_t *)m68k_save_context); |
4105 dst = pop_r(dst, SCRATCH1); | 4106 dst = pop_r(dst, SCRATCH1); |
4106 //do prologue stuff | 4107 //do prologue stuff |
4107 dst = cmp_rr(dst, CYCLES, LIMIT, SZ_D); | 4108 dst = cmp_rr(dst, CYCLES, LIMIT, SZ_D); |
4108 uint8_t * jmp_off = dst+1; | 4109 uint8_t * jmp_off = dst+1; |
4109 dst = jcc(dst, CC_NC, dst + 7); | 4110 dst = jcc(dst, CC_NC, dst + 7); |
4110 dst = call(dst, (uint8_t *)handle_cycle_limit_int); | 4111 dst = call(dst, opts->handle_cycle_limit_int); |
4111 *jmp_off = dst - (jmp_off+1); | 4112 *jmp_off = dst - (jmp_off+1); |
4112 //jump back to body of translated instruction | 4113 //jump back to body of translated instruction |
4113 dst = pop_r(dst, SCRATCH1); | 4114 dst = pop_r(dst, SCRATCH1); |
4114 dst = add_ir(dst, check_int_size - (native-start_native), SCRATCH1, SZ_Q); | 4115 dst = add_ir(dst, check_int_size - (native-start_native), SCRATCH1, SZ_Q); |
4115 dst = jmp_r(dst, SCRATCH1); | 4116 dst = jmp_r(dst, SCRATCH1); |
4120 } | 4121 } |
4121 | 4122 |
4122 void remove_breakpoint(m68k_context * context, uint32_t address) | 4123 void remove_breakpoint(m68k_context * context, uint32_t address) |
4123 { | 4124 { |
4124 uint8_t * native = get_native_address(context->native_code_map, address); | 4125 uint8_t * native = get_native_address(context->native_code_map, address); |
4125 check_cycles_int(native, address); | 4126 check_cycles_int(native, address, context->options); |
4126 } | 4127 } |
4127 | 4128 |
4128 void start_68k_context(m68k_context * context, uint32_t address) | 4129 void start_68k_context(m68k_context * context, uint32_t address) |
4129 { | 4130 { |
4130 uint8_t * addr = get_native_address(context->native_code_map, address); | 4131 uint8_t * addr = get_native_address(context->native_code_map, address); |
4466 dst = pop_r(dst, SCRATCH2); | 4467 dst = pop_r(dst, SCRATCH2); |
4467 dst = pop_r(dst, SCRATCH1); | 4468 dst = pop_r(dst, SCRATCH1); |
4468 dst = add_ir(dst, 2, SCRATCH2, SZ_D); | 4469 dst = add_ir(dst, 2, SCRATCH2, SZ_D); |
4469 dst = jmp(dst, opts->write_16); | 4470 dst = jmp(dst, opts->write_16); |
4470 | 4471 |
4472 opts->handle_cycle_limit_int = dst; | |
4473 dst = cmp_rdisp8r(dst, CONTEXT, offsetof(m68k_context, int_cycle), CYCLES, SZ_D); | |
4474 uint8_t * do_int = dst+1; | |
4475 dst = jcc(dst, CC_NC, dst+2); | |
4476 dst = cmp_rdisp8r(dst, CONTEXT, offsetof(m68k_context, sync_cycle), CYCLES, SZ_D); | |
4477 uint8_t * skip_sync = dst+1; | |
4478 dst = jcc(dst, CC_C, dst+2); | |
4479 dst = call(dst, (uint8_t *)m68k_save_context); | |
4480 dst = mov_rr(dst, CONTEXT, RDI, SZ_Q); | |
4481 dst = mov_rr(dst, SCRATCH1, RSI, SZ_D); | |
4482 dst = call(dst, (uint8_t *)sync_components); | |
4483 dst = mov_rr(dst, RAX, CONTEXT, SZ_Q); | |
4484 dst = jmp(dst, (uint8_t *)m68k_load_context); | |
4485 *skip_sync = dst - (skip_sync+1); | |
4486 dst = retn(dst); | |
4487 *do_int = dst - (do_int+1); | |
4488 //set target cycle to sync cycle | |
4489 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, sync_cycle), LIMIT, SZ_D); | |
4490 //swap USP and SSP if not already in supervisor mode | |
4491 dst = bt_irdisp8(dst, 5, CONTEXT, offsetof(m68k_context, status), SZ_B); | |
4492 uint8_t *already_supervisor = dst+1; | |
4493 dst = jcc(dst, CC_C, dst+2); | |
4494 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SCRATCH2, SZ_D); | |
4495 dst = mov_rrdisp8(dst, opts->aregs[7], CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_D); | |
4496 dst = mov_rr(dst, SCRATCH2, opts->aregs[7], SZ_D); | |
4497 *already_supervisor = dst - (already_supervisor+1); | |
4498 //save PC | |
4499 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); | |
4500 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); | |
4501 dst = call(dst, opts->write_32_lowfirst); | |
4502 //save status register | |
4503 dst = sub_ir(dst, 2, opts->aregs[7], SZ_D); | |
4504 dst = call(dst, (uint8_t *)get_sr); | |
4505 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); | |
4506 dst = call(dst, opts->write_16); | |
4507 //update status register | |
4508 dst = and_irdisp8(dst, 0xF8, CONTEXT, offsetof(m68k_context, status), SZ_B); | |
4509 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, int_num), SCRATCH1, SZ_B); | |
4510 dst = or_ir(dst, 0x20, SCRATCH1, SZ_B); | |
4511 dst = or_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, status), SZ_B); | |
4512 //calculate interrupt vector address | |
4513 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, int_num), SCRATCH1, SZ_D); | |
4514 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, int_ack), SZ_W); | |
4515 dst = shl_ir(dst, 2, SCRATCH1, SZ_D); | |
4516 dst = add_ir(dst, 0x60, SCRATCH1, SZ_D); | |
4517 dst = call(dst, opts->read_32); | |
4518 dst = call(dst, (uint8_t *)m68k_native_addr_and_sync); | |
4519 dst = cycles(dst, 24); | |
4520 //discard function return address | |
4521 dst = pop_r(dst, SCRATCH2); | |
4522 dst = jmp_r(dst, SCRATCH1); | |
4523 | |
4471 opts->cur_code = dst; | 4524 opts->cur_code = dst; |
4472 } | 4525 } |
4473 | 4526 |
4474 void init_68k_context(m68k_context * context, native_map_slot * native_code_map, void * opts) | 4527 void init_68k_context(m68k_context * context, native_map_slot * native_code_map, void * opts) |
4475 { | 4528 { |