Mercurial > repos > blastem
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 |