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: