Mercurial > repos > blastem
comparison m68k_core_x86.c @ 1461:aa945f1bdd71
Properly clear trace mode on interrupt or other exception. Fix NBCD with memory destination
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Wed, 06 Sep 2017 23:10:11 -0700 |
parents | 747c779fc137 |
children | 5d41d0574863 |
comparison
equal
deleted
inserted
replaced
1460:4929325c3ce0 | 1461:aa945f1bdd71 |
---|---|
1502 } else { | 1502 } else { |
1503 mov_rdispr(code, dst_op->base, dst_op->disp, opts->gen.scratch1, SZ_B); | 1503 mov_rdispr(code, dst_op->base, dst_op->disp, opts->gen.scratch1, SZ_B); |
1504 } | 1504 } |
1505 } | 1505 } |
1506 } | 1506 } |
1507 if (inst->dst.addr_mode != MODE_REG && inst->dst.addr_mode != MODE_AREG && inst->dst.addr_mode != MODE_AREG_PREDEC) { | |
1508 //destination is in memory so we need to preserve scratch2 for the write at the end | |
1509 push_r(code, opts->gen.scratch2); | |
1510 } | |
1507 uint8_t other_reg; | 1511 uint8_t other_reg; |
1508 //WARNING: This may need adjustment if register assignments change | 1512 //WARNING: This may need adjustment if register assignments change |
1509 if (opts->gen.scratch2 > RBX) { | 1513 if (opts->gen.scratch2 > RBX) { |
1510 other_reg = RAX; | 1514 other_reg = RAX; |
1511 xchg_rr(code, opts->gen.scratch2, RAX, SZ_D); | 1515 xchg_rr(code, opts->gen.scratch2, RAX, SZ_D); |
1589 if (dst_op->mode == MODE_REG_DIRECT) { | 1593 if (dst_op->mode == MODE_REG_DIRECT) { |
1590 mov_rr(code, opts->gen.scratch1, dst_op->base, SZ_B); | 1594 mov_rr(code, opts->gen.scratch1, dst_op->base, SZ_B); |
1591 } else { | 1595 } else { |
1592 mov_rrdisp(code, opts->gen.scratch1, dst_op->base, dst_op->disp, SZ_B); | 1596 mov_rrdisp(code, opts->gen.scratch1, dst_op->base, dst_op->disp, SZ_B); |
1593 } | 1597 } |
1598 } | |
1599 if (inst->dst.addr_mode != MODE_REG && inst->dst.addr_mode != MODE_AREG && inst->dst.addr_mode != MODE_AREG_PREDEC) { | |
1600 //destination is in memory so we need to restore scratch2 for the write at the end | |
1601 pop_r(code, opts->gen.scratch2); | |
1594 } | 1602 } |
1595 m68k_save_result(inst, opts); | 1603 m68k_save_result(inst, opts); |
1596 } | 1604 } |
1597 | 1605 |
1598 void translate_m68k_sl(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op) | 1606 void translate_m68k_sl(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op) |
3087 pop_r(code, RDX); | 3095 pop_r(code, RDX); |
3088 //add saved cycle count to result | 3096 //add saved cycle count to result |
3089 add_rr(code, opts->gen.scratch1, RAX, SZ_D); | 3097 add_rr(code, opts->gen.scratch1, RAX, SZ_D); |
3090 | 3098 |
3091 //update status register | 3099 //update status register |
3092 and_irdisp(code, 0xF8, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B); | 3100 and_irdisp(code, 0x78, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B); |
3093 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, int_num), opts->gen.scratch1, SZ_B); | 3101 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, int_num), opts->gen.scratch1, SZ_B); |
3102 //clear trace pending flag | |
3103 mov_irdisp(code, 0, opts->gen.context_reg, offsetof(m68k_context, trace_pending), SZ_B); | |
3094 //need to separate int priority and interrupt vector, but for now mask out large interrupt numbers | 3104 //need to separate int priority and interrupt vector, but for now mask out large interrupt numbers |
3095 and_ir(code, 0x7, opts->gen.scratch1, SZ_B); | 3105 and_ir(code, 0x7, opts->gen.scratch1, SZ_B); |
3096 or_ir(code, 0x20, opts->gen.scratch1, SZ_B); | 3106 or_ir(code, 0x20, opts->gen.scratch1, SZ_B); |
3097 or_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B); | 3107 or_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B); |
3098 | 3108 |
3156 call(code, opts->get_sr); | 3166 call(code, opts->get_sr); |
3157 areg_to_native(opts, 7, opts->gen.scratch2); | 3167 areg_to_native(opts, 7, opts->gen.scratch2); |
3158 call(code, opts->write_16); | 3168 call(code, opts->write_16); |
3159 //set supervisor bit | 3169 //set supervisor bit |
3160 or_irdisp(code, 0x20, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B); | 3170 or_irdisp(code, 0x20, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B); |
3171 //clear trace bit | |
3172 and_irdisp(code, 0x7F, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B); | |
3173 mov_irdisp(code, 0, opts->gen.context_reg, offsetof(m68k_context, trace_pending), SZ_B); | |
3161 //calculate vector address | 3174 //calculate vector address |
3162 pop_r(code, opts->gen.scratch1); | 3175 pop_r(code, opts->gen.scratch1); |
3163 shl_ir(code, 2, opts->gen.scratch1, SZ_D); | 3176 shl_ir(code, 2, opts->gen.scratch1, SZ_D); |
3164 call(code, opts->read_32); | 3177 call(code, opts->read_32); |
3165 call(code, opts->native_addr_and_sync); | 3178 call(code, opts->native_addr_and_sync); |