Mercurial > repos > blastem
diff m68k_to_x86.c @ 61:918468c623e9
Add support for BTST instruction (untested), absolute addressing mode for instructions other than move (untested) and fix decoding of MOVEM.
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Wed, 19 Dec 2012 20:23:59 -0800 |
parents | 32650c77008a |
children | 2b1a65f4b85d |
line wrap: on
line diff
--- a/m68k_to_x86.c Tue Dec 18 23:55:10 2012 -0800 +++ b/m68k_to_x86.c Wed Dec 19 20:23:59 2012 -0800 @@ -175,8 +175,9 @@ ea->base = SCRATCH1; break; case MODE_IMMEDIATE: + case MODE_IMMEDIATE_WORD: if (inst->variant != VAR_QUICK) { - if (inst->extra.size == OPSIZE_LONG) { + if (inst->extra.size == OPSIZE_LONG && inst->src.addr_mode == MODE_IMMEDIATE) { out = cycles(out, BUS); out = check_cycles(out); } @@ -254,6 +255,32 @@ ea->mode = MODE_REG_DIRECT; ea->base = SCRATCH1; break; + case MODE_ABSOLUTE: + case MODE_ABSOLUTE_SHORT: + //Add cycles for reading address from instruction stream + if (inst->dst.addr_mode == MODE_ABSOLUTE) { + out = cycles(out, BUS*2); + } else { + out = cycles(out, BUS); + } + out = mov_ir(out, inst->dst.params.immed, SCRATCH1, SZ_D); + out = push_r(out, SCRATCH1); + switch (inst->extra.size) + { + case OPSIZE_BYTE: + out = call(out, (char *)m68k_read_byte_scratch1); + break; + case OPSIZE_WORD: + out = call(out, (char *)m68k_read_word_scratch1); + break; + case OPSIZE_LONG: + out = call(out, (char *)m68k_read_long_scratch1); + break; + } + out = pop_r(out, SCRATCH2); + ea->mode = MODE_REG_DIRECT; + ea->base = SCRATCH1; + break; default: printf("address mode %d not implemented (dst)\n", inst->dst.addr_mode); exit(1); @@ -1010,7 +1037,46 @@ case M68K_BCHG: case M68K_BCLR: case M68K_BSET: + break; case M68K_BTST: + dst = cycles(dst, inst->extra.size == OPSIZE_BYTE ? 4 : 6); + if (src_op.mode == MODE_IMMEDIATE) { + if (inst->extra.size == OPSIZE_BYTE) { + src_op.disp &= 0x7; + } + if (dst_op.mode == MODE_REG_DIRECT) { + dst = bt_ir(dst, src_op.disp, dst_op.base, SZ_D); + } else { + dst = bt_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, SZ_D); + } + } else { + if (src_op.mode == MODE_REG_DISPLACE8) { + if (dst_op.base == SCRATCH1) { + dst = push_r(dst, SCRATCH2); + dst = mov_rdisp8r(dst, src_op.base, src_op.disp, SCRATCH2, SZ_B); + src_op.base = SCRATCH1; + } else { + dst = mov_rdisp8r(dst, src_op.base, src_op.disp, SCRATCH1, SZ_B); + src_op.base = SCRATCH1; + } + } + if (inst->extra.size == OPSIZE_BYTE) { + dst = and_ir(dst, 0x7, src_op.base, SZ_B); + } + if (dst_op.mode == MODE_REG_DIRECT) { + dst = bt_rr(dst, src_op.base, dst_op.base, SZ_D); + } else { + dst = bt_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, SZ_D); + } + } + //x86 sets the carry flag to the value of the bit tested + //68K sets the zero flag to the complement of the bit tested + dst = setcc_r(dst, CC_NC, FLAG_Z); + if (src_op.base == SCRATCH2) { + dst = pop_r(dst, SCRATCH2); + } + dst = m68k_save_result(inst, dst, opts); + break; case M68K_CHK: break; case M68K_CMP: @@ -1096,7 +1162,6 @@ dst = mov_rr(dst, CONTEXT, RDI, SZ_Q); dst = call(dst, (uint8_t *)print_regs_exit); break; - case M68K_JMP: case M68K_JSR: case M68K_LEA: case M68K_LINK: