comparison m68k_core_x86.c @ 579:0031cd308a31

Combine the implementation of ABCD and SBCD in the 68K core
author Michael Pavone <pavone@retrodev.com>
date Tue, 04 Mar 2014 22:35:01 -0800
parents ec1365fb2954
children 5157bc966c1a
comparison
equal deleted inserted replaced
578:ec1365fb2954 579:0031cd308a31
1544 } 1544 }
1545 uint8_t size; 1545 uint8_t size;
1546 switch(inst->op) 1546 switch(inst->op)
1547 { 1547 {
1548 case M68K_ABCD: 1548 case M68K_ABCD:
1549 case M68K_SBCD:
1549 if (src_op.base != opts->gen.scratch2) { 1550 if (src_op.base != opts->gen.scratch2) {
1550 if (src_op.mode == MODE_REG_DIRECT) { 1551 if (src_op.mode == MODE_REG_DIRECT) {
1551 mov_rr(code, src_op.base, opts->gen.scratch2, SZ_B); 1552 mov_rr(code, src_op.base, opts->gen.scratch2, SZ_B);
1552 } else { 1553 } else {
1553 mov_rdispr(code, src_op.base, src_op.disp, opts->gen.scratch2, SZ_B); 1554 mov_rdispr(code, src_op.base, src_op.disp, opts->gen.scratch2, SZ_B);
1560 mov_rdispr(code, dst_op.base, dst_op.disp, opts->gen.scratch1, SZ_B); 1561 mov_rdispr(code, dst_op.base, dst_op.disp, opts->gen.scratch1, SZ_B);
1561 } 1562 }
1562 } 1563 }
1563 flag_to_carry(opts, FLAG_X); 1564 flag_to_carry(opts, FLAG_X);
1564 jcc(code, CC_NC, code->cur + 5); 1565 jcc(code, CC_NC, code->cur + 5);
1565 add_ir(code, 1, opts->gen.scratch1, SZ_B); 1566 if (inst->op == M68K_ABCD) {
1566 call(code, (code_ptr)bcd_add); 1567 add_ir(code, 1, opts->gen.scratch1, SZ_B);
1568 } else {
1569 sub_ir(code, 1, opts->gen.scratch1, SZ_B);
1570 }
1571 call(code, (code_ptr) (inst->op == M68K_ABCD ? bcd_add : bcd_sub));
1567 reg_to_flag(opts, CH, FLAG_C); 1572 reg_to_flag(opts, CH, FLAG_C);
1568 reg_to_flag(opts, CH, FLAG_X); 1573 reg_to_flag(opts, CH, FLAG_X);
1569 cmp_ir(code, 0, opts->gen.scratch1, SZ_B); 1574 cmp_ir(code, 0, opts->gen.scratch1, SZ_B);
1570 jcc(code, CC_Z, code->cur + 4); 1575 jcc(code, CC_Z, code->cur + 4);
1571 set_flag(opts, 0, FLAG_Z); 1576 set_flag(opts, 0, FLAG_Z);
2256 jmp_r(code, opts->gen.scratch1); 2261 jmp_r(code, opts->gen.scratch1);
2257 break; 2262 break;
2258 case M68K_RTR: 2263 case M68K_RTR:
2259 translate_m68k_rtr(opts, inst); 2264 translate_m68k_rtr(opts, inst);
2260 break; 2265 break;
2261 case M68K_SBCD: {
2262 if (src_op.base != opts->gen.scratch2) {
2263 if (src_op.mode == MODE_REG_DIRECT) {
2264 mov_rr(code, src_op.base, opts->gen.scratch2, SZ_B);
2265 } else {
2266 mov_rdispr(code, src_op.base, src_op.disp, opts->gen.scratch2, SZ_B);
2267 }
2268 }
2269 if (dst_op.base != opts->gen.scratch1) {
2270 if (dst_op.mode == MODE_REG_DIRECT) {
2271 mov_rr(code, dst_op.base, opts->gen.scratch1, SZ_B);
2272 } else {
2273 mov_rdispr(code, dst_op.base, dst_op.disp, opts->gen.scratch1, SZ_B);
2274 }
2275 }
2276 flag_to_carry(opts, FLAG_X);
2277 jcc(code, CC_NC, code->cur + 5);
2278 sub_ir(code, 1, opts->gen.scratch1, SZ_B);
2279 call(code, (code_ptr)bcd_sub);
2280 reg_to_flag(opts, CH, FLAG_C);
2281 reg_to_flag(opts, CH, FLAG_X);
2282 cmp_ir(code, 0, opts->gen.scratch1, SZ_B);
2283 code_ptr after_flag_set = code->cur+1;
2284 jcc(code, CC_Z, code->cur + 2);
2285 set_flag(opts, 0, FLAG_Z);
2286 *after_flag_set = code->cur - (after_flag_set+1);
2287 if (dst_op.base != opts->gen.scratch1) {
2288 if (dst_op.mode == MODE_REG_DIRECT) {
2289 mov_rr(code, opts->gen.scratch1, dst_op.base, SZ_B);
2290 } else {
2291 mov_rrdisp(code, opts->gen.scratch1, dst_op.base, dst_op.disp, SZ_B);
2292 }
2293 }
2294 m68k_save_result(inst, opts);
2295 break;
2296 }
2297 case M68K_STOP: { 2266 case M68K_STOP: {
2298 //TODO: Trap if not in system mode 2267 //TODO: Trap if not in system mode
2299 //manual says 4 cycles, but it has to be at least 8 since it's a 2-word instruction 2268 //manual says 4 cycles, but it has to be at least 8 since it's a 2-word instruction
2300 //possibly even 12 since that's how long MOVE to SR takes 2269 //possibly even 12 since that's how long MOVE to SR takes
2301 cycles(&opts->gen, BUS*2); 2270 cycles(&opts->gen, BUS*2);