1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-02-16 18:30:32 +00:00

Demacroise set_shift_flags, reduce casting.

This commit is contained in:
Thomas Harte 2024-01-16 13:51:16 -05:00
parent ea4cc4c9b3
commit fe34083ab8

View File

@ -86,7 +86,7 @@ template < class T,
set_did_compute_flags(); set_did_compute_flags();
}; };
/// Sets flags as expected at the end of a rotate operation. /// Sets flags as expected at the end of an 8080-style rotate operation (i.e. RRA, RRCA, RLA or RLCA).
/// Specifically: /// Specifically:
/// * N and H are set to 0; /// * N and H are set to 0;
/// * C is set to whatever is supplied as new_carry; and /// * C is set to whatever is supplied as new_carry; and
@ -98,6 +98,19 @@ template < class T,
set_did_compute_flags(); set_did_compute_flags();
}; };
/// Sets flags as expected at the end of a shift or post-8080-style rotate operation.
/// Specifically:
/// * N, Z, 5 and 3 are set according to the value of source;
/// * P is set according to the parity of the source; and
/// * H and N are reset.
const auto set_shift_flags = [&](uint8_t source) {
sign_result_ = zero_result_ = bit53_result_ = source;
set_parity(source);
half_carry_result_ = 0;
subtract_flag_ = 0;
set_did_compute_flags();
};
/// Takes appropriate action for an untaken conditional branch; this might mean just skipping to the next instruction or it might mean taking /// Takes appropriate action for an untaken conditional branch; this might mean just skipping to the next instruction or it might mean taking
/// some other alternative follow-up action. /// some other alternative follow-up action.
const auto decline_conditional = [&](const MicroOp *operation) { const auto decline_conditional = [&](const MicroOp *operation) {
@ -712,64 +725,63 @@ template < class T,
set_rotate_flags(new_carry); set_rotate_flags(new_carry);
} break; } break;
#define set_shift_flags() \ case MicroOp::RLC: {
sign_result_ = zero_result_ = bit53_result_ = *static_cast<uint8_t *>(operation->source); \ uint8_t &source = *static_cast<uint8_t *>(operation->source);
set_parity(sign_result_); \ carry_result_ = source >> 7;
half_carry_result_ = 0; \ source = uint8_t((source << 1) | carry_result_);
subtract_flag_ = 0; \ set_shift_flags(source);
set_did_compute_flags(); } break;
case MicroOp::RLC: case MicroOp::RRC: {
carry_result_ = *static_cast<uint8_t *>(operation->source) >> 7; uint8_t &source = *static_cast<uint8_t *>(operation->source);
*static_cast<uint8_t *>(operation->source) = uint8_t((*static_cast<uint8_t *>(operation->source) << 1) | carry_result_); carry_result_ = source;
set_shift_flags(); source = uint8_t((source >> 1) | (carry_result_ << 7));
break; set_shift_flags(source);
} break;
case MicroOp::RRC:
carry_result_ = *static_cast<uint8_t *>(operation->source);
*static_cast<uint8_t *>(operation->source) = uint8_t((*static_cast<uint8_t *>(operation->source) >> 1) | (carry_result_ << 7));
set_shift_flags();
break;
case MicroOp::RL: { case MicroOp::RL: {
const uint8_t next_carry = *static_cast<uint8_t *>(operation->source) >> 7; uint8_t &source = *static_cast<uint8_t *>(operation->source);
*static_cast<uint8_t *>(operation->source) = uint8_t((*static_cast<uint8_t *>(operation->source) << 1) | (carry_result_ & Flag::Carry)); const uint8_t next_carry = source >> 7;
source = uint8_t((source << 1) | (carry_result_ & Flag::Carry));
carry_result_ = next_carry; carry_result_ = next_carry;
set_shift_flags(); set_shift_flags(source);
} break; } break;
case MicroOp::RR: { case MicroOp::RR: {
const uint8_t next_carry = *static_cast<uint8_t *>(operation->source); uint8_t &source = *static_cast<uint8_t *>(operation->source);
*static_cast<uint8_t *>(operation->source) = uint8_t((*static_cast<uint8_t *>(operation->source) >> 1) | (carry_result_ << 7)); const uint8_t next_carry = source;
source = uint8_t((source >> 1) | (carry_result_ << 7));
carry_result_ = next_carry; carry_result_ = next_carry;
set_shift_flags(); set_shift_flags(source);
} break; } break;
case MicroOp::SLA: case MicroOp::SLA: {
carry_result_ = *static_cast<uint8_t *>(operation->source) >> 7; uint8_t &source = *static_cast<uint8_t *>(operation->source);
*static_cast<uint8_t *>(operation->source) = uint8_t(*static_cast<uint8_t *>(operation->source) << 1); carry_result_ = source >> 7;
set_shift_flags(); source <<= 1;
break; set_shift_flags(source);
} break;
case MicroOp::SRA: case MicroOp::SRA: {
carry_result_ = *static_cast<uint8_t *>(operation->source); uint8_t &source = *static_cast<uint8_t *>(operation->source);
*static_cast<uint8_t *>(operation->source) = uint8_t((*static_cast<uint8_t *>(operation->source) >> 1) | (*static_cast<uint8_t *>(operation->source) & 0x80)); carry_result_ = source;
set_shift_flags(); source = uint8_t((source >> 1) | (source & 0x80));
break; set_shift_flags(source);
} break;
case MicroOp::SLL: case MicroOp::SLL: {
carry_result_ = *static_cast<uint8_t *>(operation->source) >> 7; uint8_t &source = *static_cast<uint8_t *>(operation->source);
*static_cast<uint8_t *>(operation->source) = uint8_t(*static_cast<uint8_t *>(operation->source) << 1) | 1; carry_result_ = source >> 7;
set_shift_flags(); source = uint8_t(source << 1) | 1;
break; set_shift_flags(source);
} break;
case MicroOp::SRL: case MicroOp::SRL: {
carry_result_ = *static_cast<uint8_t *>(operation->source); uint8_t &source = *static_cast<uint8_t *>(operation->source);
*static_cast<uint8_t *>(operation->source) = uint8_t((*static_cast<uint8_t *>(operation->source) >> 1)); carry_result_ = source;
set_shift_flags(); source >>= 1;
break; set_shift_flags(source);
} break;
#undef set_shift_flags
#define set_decimal_rotate_flags() \ #define set_decimal_rotate_flags() \
subtract_flag_ = 0; \ subtract_flag_ = 0; \