| 484 | } |
| 485 | |
| 486 | static void cpu_execute_alu(int i, uint8_t v) { |
| 487 | uint8_t old; |
| 488 | eZ80registers_t *r = &cpu.registers; |
| 489 | switch (i) { |
| 490 | case 0: /* ADD A, v */ |
| 491 | old = r->A; |
| 492 | r->A += v; |
| 493 | r->F = cpuflag_sign_b(r->A) | cpuflag_zero(r->A) |
| 494 | | cpuflag_undef(r->F) | cpuflag_overflow_b_add(old, v, r->A) |
| 495 | | cpuflag_subtract(0) | cpuflag_carry_b(old + v) |
| 496 | | cpuflag_halfcarry_b_add(old, v, 0); |
| 497 | break; |
| 498 | case 1: /* ADC A, v */ |
| 499 | old = r->A; |
| 500 | r->A += v + r->flags.C; |
| 501 | r->F = cpuflag_sign_b(r->A) | cpuflag_zero(r->A) |
| 502 | | cpuflag_undef(r->F) | cpuflag_overflow_b_add(old, v, r->A) |
| 503 | | cpuflag_subtract(0) | cpuflag_carry_b(old + v + r->flags.C) |
| 504 | | cpuflag_halfcarry_b_add(old, v, r->flags.C); |
| 505 | break; |
| 506 | case 2: /* SUB v */ |
| 507 | old = r->A; |
| 508 | r->A -= v; |
| 509 | r->F = cpuflag_sign_b(r->A) | cpuflag_zero(r->A) |
| 510 | | cpuflag_undef(r->F) | cpuflag_overflow_b_sub(old, v, r->A) |
| 511 | | cpuflag_subtract(1) | cpuflag_carry_b(old - v) |
| 512 | | cpuflag_halfcarry_b_sub(old, v, 0); |
| 513 | break; |
| 514 | case 3: /* SBC v */ |
| 515 | old = r->A; |
| 516 | r->A -= v + r->flags.C; |
| 517 | r->F = cpuflag_sign_b(r->A) | cpuflag_zero(r->A) |
| 518 | | cpuflag_undef(r->F) | cpuflag_overflow_b_sub(old, v, r->A) |
| 519 | | cpuflag_subtract(1) | cpuflag_carry_b(old - v - r->flags.C) |
| 520 | | cpuflag_halfcarry_b_sub(old, v, r->flags.C); |
| 521 | break; |
| 522 | case 4: /* AND v */ |
| 523 | r->A &= v; |
| 524 | r->F = cpuflag_sign_b(r->A) | cpuflag_zero(r->A) |
| 525 | | cpuflag_undef(r->F) | cpuflag_parity(r->A) |
| 526 | | FLAG_H; |
| 527 | break; |
| 528 | case 5: /* XOR v */ |
| 529 | r->A ^= v; |
| 530 | r->F = cpuflag_sign_b(r->A) | cpuflag_zero(r->A) |
| 531 | | cpuflag_undef(r->F) | cpuflag_parity(r->A); |
| 532 | break; |
| 533 | case 6: /* OR v */ |
| 534 | r->A |= v; |
| 535 | r->F = cpuflag_sign_b(r->A) | cpuflag_zero(r->A) |
| 536 | | cpuflag_undef(r->F) | cpuflag_parity(r->A); |
| 537 | break; |
| 538 | case 7: /* CP v */ |
| 539 | old = r->A - v; |
| 540 | r->F = cpuflag_sign_b(old) | cpuflag_zero(old) |
| 541 | | cpuflag_undef(r->F) | cpuflag_subtract(1) |
| 542 | | cpuflag_carry_b(r->A - v) |
| 543 | | cpuflag_overflow_b_sub(r->A, v, old) |