Mercurial > repos > blastem
comparison m68k_core_x86.c @ 833:841e44c5af83
Fix for abcd/sbcd. Hopefully got it 100% right this time.
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Mon, 19 Oct 2015 19:16:57 -0700 |
parents | 724bbec47f86 |
children | 65f9041b5f17 |
comparison
equal
deleted
inserted
replaced
832:0433fdd9ba66 | 833:841e44c5af83 |
---|---|
1395 } else { | 1395 } else { |
1396 other_reg = opts->gen.scratch2; | 1396 other_reg = opts->gen.scratch2; |
1397 } | 1397 } |
1398 mov_rr(code, opts->gen.scratch1, opts->gen.scratch1 + (AH-RAX), SZ_B); | 1398 mov_rr(code, opts->gen.scratch1, opts->gen.scratch1 + (AH-RAX), SZ_B); |
1399 mov_rr(code, other_reg, other_reg + (AH-RAX), SZ_B); | 1399 mov_rr(code, other_reg, other_reg + (AH-RAX), SZ_B); |
1400 and_ir(code, 0xF0, opts->gen.scratch1, SZ_B); | |
1401 and_ir(code, 0xF0, other_reg, SZ_B); | |
1402 and_ir(code, 0xF, opts->gen.scratch1 + (AH-RAX), SZ_B); | 1400 and_ir(code, 0xF, opts->gen.scratch1 + (AH-RAX), SZ_B); |
1403 and_ir(code, 0xF, other_reg + (AH-RAX), SZ_B); | 1401 and_ir(code, 0xF, other_reg + (AH-RAX), SZ_B); |
1404 //do op on low nibble | 1402 //do op on low nibble so we can determine if an adjustment is necessary |
1405 flag_to_carry(opts, FLAG_X); | 1403 flag_to_carry(opts, FLAG_X); |
1406 if (inst->op == M68K_ABCD) { | 1404 if (inst->op == M68K_ABCD) { |
1407 adc_rr(code, other_reg + (AH-RAX), opts->gen.scratch1 + (AH-RAX), SZ_B); | 1405 adc_rr(code, other_reg + (AH-RAX), opts->gen.scratch1 + (AH-RAX), SZ_B); |
1408 } else { | 1406 } else { |
1409 sbb_rr(code, other_reg + (AH-RAX), opts->gen.scratch1 + (AH-RAX), SZ_B); | 1407 sbb_rr(code, other_reg + (AH-RAX), opts->gen.scratch1 + (AH-RAX), SZ_B); |
1410 } | 1408 } |
1411 cmp_ir(code, 0xA, opts->gen.scratch1 + (AH-RAX), SZ_B); | 1409 cmp_ir(code, 0xA, opts->gen.scratch1 + (AH-RAX), SZ_B); |
1410 mov_ir(code, 0xA0, other_reg + (AH-RAX), SZ_B); | |
1412 code_ptr no_adjust = code->cur+1; | 1411 code_ptr no_adjust = code->cur+1; |
1413 //add correction factor if necessary | 1412 //add correction factor if necessary |
1414 jcc(code, CC_B, no_adjust); | 1413 jcc(code, CC_B, no_adjust); |
1414 mov_ir(code, 6, opts->gen.scratch1 + (AH-RAX), SZ_B); | |
1415 mov_ir(code, inst->op == M68K_ABCD ? 0x9A : 0xA6, other_reg + (AH-RAX), SZ_B); | |
1416 code_ptr after_adjust = code->cur+1; | |
1417 jmp(code, after_adjust); | |
1418 | |
1419 *no_adjust = code->cur - (no_adjust+1); | |
1420 xor_rr(code, opts->gen.scratch1 + (AH-RAX), opts->gen.scratch1 + (AH-RAX), SZ_B); | |
1421 *after_adjust = code->cur - (after_adjust+1); | |
1422 | |
1423 //do op on full byte | |
1424 flag_to_carry(opts, FLAG_X); | |
1415 if (inst->op == M68K_ABCD) { | 1425 if (inst->op == M68K_ABCD) { |
1416 add_ir(code, 6, opts->gen.scratch1 + (AH-RAX), SZ_B); | 1426 adc_rr(code, other_reg, opts->gen.scratch1, SZ_B); |
1417 } else { | 1427 } else { |
1418 sub_ir(code, 6, opts->gen.scratch1 + (AH-RAX), SZ_B); | 1428 sbb_rr(code, other_reg, opts->gen.scratch1, SZ_B); |
1419 } | |
1420 *no_adjust = code->cur - (no_adjust+1); | |
1421 //add low nibble result to one of the high nibble operands | |
1422 add_rr(code, opts->gen.scratch1 + (AH-RAX), opts->gen.scratch1, SZ_B); | |
1423 if (inst->op == M68K_ABCD) { | |
1424 add_rr(code, other_reg, opts->gen.scratch1, SZ_B); | |
1425 } else { | |
1426 sub_rr(code, other_reg, opts->gen.scratch1, SZ_B); | |
1427 } | |
1428 if (opts->gen.scratch2 > RBX) { | |
1429 mov_rr(code, opts->gen.scratch2, RAX, SZ_D); | |
1430 } | 1429 } |
1431 set_flag(opts, 0, FLAG_C); | 1430 set_flag(opts, 0, FLAG_C); |
1432 set_flag(opts, 0, FLAG_V); | 1431 //determine if we need a correction on the upper nibble |
1433 code_ptr def_adjust = code->cur+1; | 1432 code_ptr def_adjust = code->cur+1; |
1434 jcc(code, CC_C, def_adjust); | 1433 jcc(code, CC_C, def_adjust); |
1435 cmp_ir(code, 0xA0, opts->gen.scratch1, SZ_B); | 1434 cmp_rr(code, other_reg + (AH-RAX), opts->gen.scratch1, SZ_B); |
1436 no_adjust = code->cur+1; | 1435 no_adjust = code->cur+1; |
1437 jcc(code, CC_B, no_adjust); | 1436 jcc(code, CC_B, no_adjust); |
1438 *def_adjust = code->cur - (def_adjust + 1); | 1437 *def_adjust = code->cur - (def_adjust + 1); |
1439 set_flag(opts, 1, FLAG_C); | 1438 set_flag(opts, 1, FLAG_C); |
1439 or_ir(code, 0x60, opts->gen.scratch1 + (AH-RAX), SZ_B); | |
1440 *no_adjust = code->cur - (no_adjust+1); | |
1440 if (inst->op == M68K_ABCD) { | 1441 if (inst->op == M68K_ABCD) { |
1441 add_ir(code, 0x60, opts->gen.scratch1, SZ_B); | 1442 add_rr(code, opts->gen.scratch1 + (AH-RAX), opts->gen.scratch1, SZ_B); |
1442 } else { | 1443 } else { |
1443 sub_ir(code, 0x60, opts->gen.scratch1, SZ_B); | 1444 sub_rr(code, opts->gen.scratch1 + (AH-RAX), opts->gen.scratch1, SZ_B); |
1444 } | 1445 } |
1445 //V flag is set based on the result of the addition of the | 1446 code_ptr no_ensure_carry = code->cur+1; |
1447 jcc(code, CC_NC, no_ensure_carry); | |
1448 set_flag(opts, 1, FLAG_C); | |
1449 *no_ensure_carry = code->cur - (no_ensure_carry+1); | |
1450 //restore RAX if necessary | |
1451 if (opts->gen.scratch2 > RBX) { | |
1452 mov_rr(code, opts->gen.scratch2, RAX, SZ_D); | |
1453 } | |
1454 //V flag is set based on the result of the addition/subtraction of the | |
1446 //result and the correction factor | 1455 //result and the correction factor |
1447 set_flag_cond(opts, CC_O, FLAG_V); | 1456 set_flag_cond(opts, CC_O, FLAG_V); |
1448 *no_adjust = code->cur - (no_adjust+1); | 1457 |
1449 flag_to_flag(opts, FLAG_C, FLAG_X); | 1458 flag_to_flag(opts, FLAG_C, FLAG_X); |
1450 | 1459 |
1451 cmp_ir(code, 0, opts->gen.scratch1, SZ_B); | 1460 cmp_ir(code, 0, opts->gen.scratch1, SZ_B); |
1452 set_flag_cond(opts, CC_S, FLAG_N); | 1461 set_flag_cond(opts, CC_S, FLAG_N); |
1453 code_ptr no_setz = code->cur+1; | 1462 code_ptr no_setz = code->cur+1; |
2483 shl_ir(code, 2, opts->gen.scratch1, SZ_D); | 2492 shl_ir(code, 2, opts->gen.scratch1, SZ_D); |
2484 call(code, opts->read_32); | 2493 call(code, opts->read_32); |
2485 call(code, opts->native_addr_and_sync); | 2494 call(code, opts->native_addr_and_sync); |
2486 cycles(&opts->gen, 18); | 2495 cycles(&opts->gen, 18); |
2487 jmp_r(code, opts->gen.scratch1); | 2496 jmp_r(code, opts->gen.scratch1); |
2488 | 2497 |
2489 opts->odd_address = code->cur; | 2498 opts->odd_address = code->cur; |
2490 mov_ir(code, (int64_t)stderr, RDI, SZ_PTR); | 2499 mov_ir(code, (int64_t)stderr, RDI, SZ_PTR); |
2491 mov_ir(code, (int64_t)"Attempt to execute code at odd address\n", RSI, SZ_PTR); | 2500 mov_ir(code, (int64_t)"Attempt to execute code at odd address\n", RSI, SZ_PTR); |
2492 call_args_abi(code, (code_ptr)fprintf, 2, RDI, RSI, RDX); | 2501 call_args_abi(code, (code_ptr)fprintf, 2, RDI, RSI, RDX); |
2493 xor_rr(code, RDI, RDI, SZ_D); | 2502 xor_rr(code, RDI, RDI, SZ_D); |