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 {