Mercurial > repos > blastem
comparison 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 |
comparison
equal
deleted
inserted
replaced
60:6ffea8607730 | 61:918468c623e9 |
---|---|
173 } | 173 } |
174 ea->mode = MODE_REG_DIRECT; | 174 ea->mode = MODE_REG_DIRECT; |
175 ea->base = SCRATCH1; | 175 ea->base = SCRATCH1; |
176 break; | 176 break; |
177 case MODE_IMMEDIATE: | 177 case MODE_IMMEDIATE: |
178 case MODE_IMMEDIATE_WORD: | |
178 if (inst->variant != VAR_QUICK) { | 179 if (inst->variant != VAR_QUICK) { |
179 if (inst->extra.size == OPSIZE_LONG) { | 180 if (inst->extra.size == OPSIZE_LONG && inst->src.addr_mode == MODE_IMMEDIATE) { |
180 out = cycles(out, BUS); | 181 out = cycles(out, BUS); |
181 out = check_cycles(out); | 182 out = check_cycles(out); |
182 } | 183 } |
183 out = cycles(out, BUS); | 184 out = cycles(out, BUS); |
184 out = check_cycles(out); | 185 out = check_cycles(out); |
249 out = add_ir(out, inc_amount, opts->aregs[inst->dst.params.regs.pri], SZ_D); | 250 out = add_ir(out, inc_amount, opts->aregs[inst->dst.params.regs.pri], SZ_D); |
250 } else { | 251 } else { |
251 out = add_irdisp8(out, inc_amount, CONTEXT, reg_offset(&(inst->dst)), SZ_D); | 252 out = add_irdisp8(out, inc_amount, CONTEXT, reg_offset(&(inst->dst)), SZ_D); |
252 } | 253 } |
253 } | 254 } |
255 ea->mode = MODE_REG_DIRECT; | |
256 ea->base = SCRATCH1; | |
257 break; | |
258 case MODE_ABSOLUTE: | |
259 case MODE_ABSOLUTE_SHORT: | |
260 //Add cycles for reading address from instruction stream | |
261 if (inst->dst.addr_mode == MODE_ABSOLUTE) { | |
262 out = cycles(out, BUS*2); | |
263 } else { | |
264 out = cycles(out, BUS); | |
265 } | |
266 out = mov_ir(out, inst->dst.params.immed, SCRATCH1, SZ_D); | |
267 out = push_r(out, SCRATCH1); | |
268 switch (inst->extra.size) | |
269 { | |
270 case OPSIZE_BYTE: | |
271 out = call(out, (char *)m68k_read_byte_scratch1); | |
272 break; | |
273 case OPSIZE_WORD: | |
274 out = call(out, (char *)m68k_read_word_scratch1); | |
275 break; | |
276 case OPSIZE_LONG: | |
277 out = call(out, (char *)m68k_read_long_scratch1); | |
278 break; | |
279 } | |
280 out = pop_r(out, SCRATCH2); | |
254 ea->mode = MODE_REG_DIRECT; | 281 ea->mode = MODE_REG_DIRECT; |
255 ea->base = SCRATCH1; | 282 ea->base = SCRATCH1; |
256 break; | 283 break; |
257 default: | 284 default: |
258 printf("address mode %d not implemented (dst)\n", inst->dst.addr_mode); | 285 printf("address mode %d not implemented (dst)\n", inst->dst.addr_mode); |
1008 dst = translate_shift(dst, inst, &src_op, &dst_op, opts, shr_ir, shr_irdisp8, shr_clr, shr_clrdisp8, shl_ir, shl_irdisp8); | 1035 dst = translate_shift(dst, inst, &src_op, &dst_op, opts, shr_ir, shr_irdisp8, shr_clr, shr_clrdisp8, shl_ir, shl_irdisp8); |
1009 break; | 1036 break; |
1010 case M68K_BCHG: | 1037 case M68K_BCHG: |
1011 case M68K_BCLR: | 1038 case M68K_BCLR: |
1012 case M68K_BSET: | 1039 case M68K_BSET: |
1040 break; | |
1013 case M68K_BTST: | 1041 case M68K_BTST: |
1042 dst = cycles(dst, inst->extra.size == OPSIZE_BYTE ? 4 : 6); | |
1043 if (src_op.mode == MODE_IMMEDIATE) { | |
1044 if (inst->extra.size == OPSIZE_BYTE) { | |
1045 src_op.disp &= 0x7; | |
1046 } | |
1047 if (dst_op.mode == MODE_REG_DIRECT) { | |
1048 dst = bt_ir(dst, src_op.disp, dst_op.base, SZ_D); | |
1049 } else { | |
1050 dst = bt_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, SZ_D); | |
1051 } | |
1052 } else { | |
1053 if (src_op.mode == MODE_REG_DISPLACE8) { | |
1054 if (dst_op.base == SCRATCH1) { | |
1055 dst = push_r(dst, SCRATCH2); | |
1056 dst = mov_rdisp8r(dst, src_op.base, src_op.disp, SCRATCH2, SZ_B); | |
1057 src_op.base = SCRATCH1; | |
1058 } else { | |
1059 dst = mov_rdisp8r(dst, src_op.base, src_op.disp, SCRATCH1, SZ_B); | |
1060 src_op.base = SCRATCH1; | |
1061 } | |
1062 } | |
1063 if (inst->extra.size == OPSIZE_BYTE) { | |
1064 dst = and_ir(dst, 0x7, src_op.base, SZ_B); | |
1065 } | |
1066 if (dst_op.mode == MODE_REG_DIRECT) { | |
1067 dst = bt_rr(dst, src_op.base, dst_op.base, SZ_D); | |
1068 } else { | |
1069 dst = bt_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, SZ_D); | |
1070 } | |
1071 } | |
1072 //x86 sets the carry flag to the value of the bit tested | |
1073 //68K sets the zero flag to the complement of the bit tested | |
1074 dst = setcc_r(dst, CC_NC, FLAG_Z); | |
1075 if (src_op.base == SCRATCH2) { | |
1076 dst = pop_r(dst, SCRATCH2); | |
1077 } | |
1078 dst = m68k_save_result(inst, dst, opts); | |
1079 break; | |
1014 case M68K_CHK: | 1080 case M68K_CHK: |
1015 break; | 1081 break; |
1016 case M68K_CMP: | 1082 case M68K_CMP: |
1017 dst = cycles(dst, BUS); | 1083 dst = cycles(dst, BUS); |
1018 if (src_op.mode == MODE_REG_DIRECT) { | 1084 if (src_op.mode == MODE_REG_DIRECT) { |
1094 case M68K_ILLEGAL: | 1160 case M68K_ILLEGAL: |
1095 dst = call(dst, (uint8_t *)m68k_save_context); | 1161 dst = call(dst, (uint8_t *)m68k_save_context); |
1096 dst = mov_rr(dst, CONTEXT, RDI, SZ_Q); | 1162 dst = mov_rr(dst, CONTEXT, RDI, SZ_Q); |
1097 dst = call(dst, (uint8_t *)print_regs_exit); | 1163 dst = call(dst, (uint8_t *)print_regs_exit); |
1098 break; | 1164 break; |
1099 case M68K_JMP: | |
1100 case M68K_JSR: | 1165 case M68K_JSR: |
1101 case M68K_LEA: | 1166 case M68K_LEA: |
1102 case M68K_LINK: | 1167 case M68K_LINK: |
1103 case M68K_MOVE_CCR: | 1168 case M68K_MOVE_CCR: |
1104 case M68K_MOVE_FROM_SR: | 1169 case M68K_MOVE_FROM_SR: |