comparison m68k_to_x86.c @ 547:3090d016c9e9

Generate get_sr, set_sr and set_ccr at runtime so they can respect the flag_regs setting
author Michael Pavone <pavone@retrodev.com>
date Tue, 18 Feb 2014 20:32:10 -0800
parents 90aca661542b
children a3afee2271ce
comparison
equal deleted inserted replaced
546:90aca661542b 547:3090d016c9e9
38 char disasm_buf[1024]; 38 char disasm_buf[1024];
39 39
40 m68k_context * sync_components(m68k_context * context, uint32_t address); 40 m68k_context * sync_components(m68k_context * context, uint32_t address);
41 41
42 void m68k_invalid(); 42 void m68k_invalid();
43 void set_sr();
44 void set_ccr();
45 void get_sr();
46 void bcd_add(); 43 void bcd_add();
47 void bcd_sub(); 44 void bcd_sub();
48 45
49 uint8_t * cycles(uint8_t * dst, uint32_t num) 46 uint8_t * cycles(uint8_t * dst, uint32_t num)
50 { 47 {
3377 dst = mov_rr(dst, CONTEXT, RDI, SZ_Q); 3374 dst = mov_rr(dst, CONTEXT, RDI, SZ_Q);
3378 dst = call(dst, (uint8_t *)print_regs_exit); 3375 dst = call(dst, (uint8_t *)print_regs_exit);
3379 break; 3376 break;
3380 case M68K_MOVE_FROM_SR: 3377 case M68K_MOVE_FROM_SR:
3381 //TODO: Trap if not in system mode 3378 //TODO: Trap if not in system mode
3382 dst = call(dst, (uint8_t *)get_sr); 3379 dst = call(dst, opts->get_sr);
3383 if (dst_op.mode == MODE_REG_DIRECT) { 3380 if (dst_op.mode == MODE_REG_DIRECT) {
3384 dst = mov_rr(dst, SCRATCH1, dst_op.base, SZ_W); 3381 dst = mov_rr(dst, SCRATCH1, dst_op.base, SZ_W);
3385 } else { 3382 } else {
3386 dst = mov_rrdisp8(dst, SCRATCH1, dst_op.base, dst_op.disp, SZ_W); 3383 dst = mov_rrdisp8(dst, SCRATCH1, dst_op.base, dst_op.disp, SZ_W);
3387 } 3384 }
3413 dst = mov_rr(dst, src_op.base, SCRATCH1, SZ_W); 3410 dst = mov_rr(dst, src_op.base, SCRATCH1, SZ_W);
3414 } else { 3411 } else {
3415 dst = mov_rdisp8r(dst, src_op.base, src_op.disp, SCRATCH1, SZ_W); 3412 dst = mov_rdisp8r(dst, src_op.base, src_op.disp, SCRATCH1, SZ_W);
3416 } 3413 }
3417 } 3414 }
3418 dst = call(dst, (uint8_t *)(inst->op == M68K_MOVE_SR ? set_sr : set_ccr)); 3415 dst = call(dst, inst->op == M68K_MOVE_SR ? opts->set_sr : opts->set_ccr);
3419 dst = cycles(dst, 12); 3416 dst = cycles(dst, 12);
3420 3417
3421 } 3418 }
3422 break; 3419 break;
3423 case M68K_MOVE_USP: 3420 case M68K_MOVE_USP:
3832 //TODO: Trap if not in system mode 3829 //TODO: Trap if not in system mode
3833 //Read saved SR 3830 //Read saved SR
3834 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D); 3831 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D);
3835 dst = call(dst, opts->read_16); 3832 dst = call(dst, opts->read_16);
3836 dst = add_ir(dst, 2, opts->aregs[7], SZ_D); 3833 dst = add_ir(dst, 2, opts->aregs[7], SZ_D);
3837 dst = call(dst, (uint8_t *)set_sr); 3834 dst = call(dst, opts->set_sr);
3838 //Read saved PC 3835 //Read saved PC
3839 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D); 3836 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D);
3840 dst = call(dst, opts->read_32); 3837 dst = call(dst, opts->read_32);
3841 dst = add_ir(dst, 4, opts->aregs[7], SZ_D); 3838 dst = add_ir(dst, 4, opts->aregs[7], SZ_D);
3842 //Check if we've switched to user mode and swap stack pointers if needed 3839 //Check if we've switched to user mode and swap stack pointers if needed
3854 case M68K_RTR: 3851 case M68K_RTR:
3855 //Read saved CCR 3852 //Read saved CCR
3856 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D); 3853 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D);
3857 dst = call(dst, opts->read_16); 3854 dst = call(dst, opts->read_16);
3858 dst = add_ir(dst, 2, opts->aregs[7], SZ_D); 3855 dst = add_ir(dst, 2, opts->aregs[7], SZ_D);
3859 dst = call(dst, (uint8_t *)set_ccr); 3856 dst = call(dst, opts->set_ccr);
3860 //Read saved PC 3857 //Read saved PC
3861 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D); 3858 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D);
3862 dst = call(dst, opts->read_32); 3859 dst = call(dst, opts->read_32);
3863 dst = add_ir(dst, 4, opts->aregs[7], SZ_D); 3860 dst = add_ir(dst, 4, opts->aregs[7], SZ_D);
3864 //Get native address and jump to it 3861 //Get native address and jump to it
4721 dst = call(dst, opts->write_16); 4718 dst = call(dst, opts->write_16);
4722 dst = pop_r(dst, SCRATCH2); 4719 dst = pop_r(dst, SCRATCH2);
4723 dst = pop_r(dst, SCRATCH1); 4720 dst = pop_r(dst, SCRATCH1);
4724 dst = add_ir(dst, 2, SCRATCH2, SZ_D); 4721 dst = add_ir(dst, 2, SCRATCH2, SZ_D);
4725 dst = jmp(dst, opts->write_16); 4722 dst = jmp(dst, opts->write_16);
4723
4724 opts->get_sr = dst;
4725 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, status), SCRATCH1, SZ_B);
4726 dst = shl_ir(dst, 8, SCRATCH1, SZ_W);
4727 if (opts->flag_regs[FLAG_X] >= 0) {
4728 dst = mov_rr(dst, opts->flag_regs[FLAG_X], SCRATCH1, SZ_B);
4729 } else {
4730 int8_t offset = offsetof(m68k_context, flags);
4731 if (offset) {
4732 dst = mov_rdisp8r(dst, CONTEXT, offset, SCRATCH1, SZ_B);
4733 } else {
4734 dst = mov_rindr(dst, CONTEXT, SCRATCH1, SZ_B);
4735 }
4736 }
4737 for (int flag = FLAG_N; flag <= FLAG_C; flag++)
4738 {
4739 dst = shl_ir(dst, 1, SCRATCH1, SZ_B);
4740 if (opts->flag_regs[flag] >= 0) {
4741 dst = or_rr(dst, opts->flag_regs[flag], SCRATCH1, SZ_B);
4742 } else {
4743 dst = or_rdisp8r(dst, CONTEXT, offsetof(m68k_context, flags) + flag, SCRATCH1, SZ_B);
4744 }
4745 }
4746 dst = retn(dst);
4747
4748 opts->set_sr = dst;
4749 for (int flag = FLAG_C; flag >= FLAG_X; flag--)
4750 {
4751 dst = rcr_ir(dst, 1, SCRATCH1, SZ_B);
4752 if (opts->flag_regs[flag] >= 0) {
4753 dst = setcc_r(dst, CC_C, opts->flag_regs[flag]);
4754 } else {
4755 int8_t offset = offsetof(m68k_context, flags) + flag;
4756 if (offset) {
4757 dst = setcc_rdisp8(dst, CC_C, CONTEXT, offset);
4758 } else {
4759 dst = setcc_rind(dst, CC_C, CONTEXT);
4760 }
4761 }
4762 }
4763 dst = shr_ir(dst, 8, SCRATCH1, SZ_W);
4764 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, status), SZ_B);
4765 dst = retn(dst);
4766
4767 opts->set_ccr = dst;
4768 for (int flag = FLAG_C; flag >= FLAG_X; flag--)
4769 {
4770 dst = rcr_ir(dst, 1, SCRATCH1, SZ_B);
4771 if (opts->flag_regs[flag] >= 0) {
4772 dst = setcc_r(dst, CC_C, opts->flag_regs[flag]);
4773 } else {
4774 int8_t offset = offsetof(m68k_context, flags) + flag;
4775 if (offset) {
4776 dst = setcc_rdisp8(dst, CC_C, CONTEXT, offset);
4777 } else {
4778 dst = setcc_rind(dst, CC_C, CONTEXT);
4779 }
4780 }
4781 }
4782 dst = retn(dst);
4726 4783
4727 opts->handle_cycle_limit_int = dst; 4784 opts->handle_cycle_limit_int = dst;
4728 dst = cmp_rdisp8r(dst, CONTEXT, offsetof(m68k_context, int_cycle), CYCLES, SZ_D); 4785 dst = cmp_rdisp8r(dst, CONTEXT, offsetof(m68k_context, int_cycle), CYCLES, SZ_D);
4729 uint8_t * do_int = dst+1; 4786 uint8_t * do_int = dst+1;
4730 dst = jcc(dst, CC_NC, dst+2); 4787 dst = jcc(dst, CC_NC, dst+2);
4764 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); 4821 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D);
4765 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); 4822 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
4766 dst = call(dst, opts->write_32_lowfirst); 4823 dst = call(dst, opts->write_32_lowfirst);
4767 //save status register 4824 //save status register
4768 dst = sub_ir(dst, 2, opts->aregs[7], SZ_D); 4825 dst = sub_ir(dst, 2, opts->aregs[7], SZ_D);
4769 dst = call(dst, (uint8_t *)get_sr); 4826 dst = call(dst, opts->get_sr);
4770 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); 4827 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
4771 dst = call(dst, opts->write_16); 4828 dst = call(dst, opts->write_16);
4772 //update status register 4829 //update status register
4773 dst = and_irdisp8(dst, 0xF8, CONTEXT, offsetof(m68k_context, status), SZ_B); 4830 dst = and_irdisp8(dst, 0xF8, CONTEXT, offsetof(m68k_context, status), SZ_B);
4774 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, int_num), SCRATCH1, SZ_B); 4831 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, int_num), SCRATCH1, SZ_B);
4800 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); 4857 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D);
4801 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); 4858 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
4802 dst = call(dst, opts->write_32_lowfirst); 4859 dst = call(dst, opts->write_32_lowfirst);
4803 //save status register 4860 //save status register
4804 dst = sub_ir(dst, 2, opts->aregs[7], SZ_D); 4861 dst = sub_ir(dst, 2, opts->aregs[7], SZ_D);
4805 dst = call(dst, (uint8_t *)get_sr); 4862 dst = call(dst, opts->get_sr);
4806 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); 4863 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
4807 dst = call(dst, opts->write_16); 4864 dst = call(dst, opts->write_16);
4808 //set supervisor bit 4865 //set supervisor bit
4809 dst = or_irdisp8(dst, 0x20, CONTEXT, offsetof(m68k_context, status), SZ_B); 4866 dst = or_irdisp8(dst, 0x20, CONTEXT, offsetof(m68k_context, status), SZ_B);
4810 //calculate vector address 4867 //calculate vector address