mirror of
https://github.com/TomHarte/CLK.git
synced 2026-04-21 02:17:08 +00:00
Clarify set/get difference; make interrupt flag storage private.
This commit is contained in:
@@ -111,7 +111,7 @@ void Processor<model, Traits>::run_for(const Cycles cycles) {
|
||||
) && registers.flags.decimal;
|
||||
};
|
||||
const auto set_interrupt_flag = [&] {
|
||||
registers.flags.inverse_interrupt = 0;
|
||||
registers.flags.template set_per<Flag::InverseInterrupt>(0);
|
||||
if constexpr (is_65c02(model)) {
|
||||
registers.flags.decimal = 0;
|
||||
}
|
||||
|
||||
@@ -21,13 +21,13 @@ namespace Operations {
|
||||
template <typename RegistersT>
|
||||
void ane(RegistersT ®isters, const uint8_t operand) {
|
||||
registers.a = (registers.a | 0xee) & operand & registers.x;
|
||||
registers.flags.template set<Flag::NegativeZero>(registers.a);
|
||||
registers.flags.template set_per<Flag::NegativeZero>(registers.a);
|
||||
}
|
||||
|
||||
template <typename RegistersT>
|
||||
void anc(RegistersT ®isters, const uint8_t operand) {
|
||||
registers.a &= operand;
|
||||
registers.flags.template set<Flag::NegativeZero>(registers.a);
|
||||
registers.flags.template set_per<Flag::NegativeZero>(registers.a);
|
||||
registers.flags.carry = registers.a >> 7;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ void adc(RegistersT ®isters, const uint8_t operand) {
|
||||
|
||||
if(!has_decimal_mode(model) || !registers.flags.decimal) {
|
||||
registers.flags.set_overflow(result, registers.a, operand);
|
||||
registers.flags.template set<Flag::NegativeZero>(registers.a = result);
|
||||
registers.flags.template set_per<Flag::NegativeZero>(registers.a = result);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ void adc(RegistersT ®isters, const uint8_t operand) {
|
||||
|
||||
registers.a = result;
|
||||
if constexpr (is_65c02(model)) {
|
||||
registers.flags.template set<Flag::NegativeZero>(registers.a);
|
||||
registers.flags.template set_per<Flag::NegativeZero>(registers.a);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ void sbc(RegistersT ®isters, const uint8_t operand) {
|
||||
// All flags are set based only on the decimal result.
|
||||
registers.flags.carry = result < registers.a + registers.flags.carry;
|
||||
if constexpr (!is_65c02(model)) {
|
||||
registers.flags.template set<Flag::NegativeZero>(result);
|
||||
registers.flags.template set_per<Flag::NegativeZero>(result);
|
||||
}
|
||||
registers.flags.set_overflow(result, registers.a, operand_complement);
|
||||
|
||||
@@ -128,7 +128,7 @@ void sbc(RegistersT ®isters, const uint8_t operand) {
|
||||
|
||||
registers.a = result;
|
||||
if constexpr (is_65c02(model)) {
|
||||
registers.flags.template set<Flag::NegativeZero>(registers.a);
|
||||
registers.flags.template set_per<Flag::NegativeZero>(registers.a);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,7 +137,7 @@ void arr(RegistersT ®isters, const uint8_t operand) {
|
||||
registers.a &= operand;
|
||||
const uint8_t unshifted_a = registers.a;
|
||||
registers.a = uint8_t((registers.a >> 1) | (registers.flags.carry << 7));
|
||||
registers.flags.template set<Flag::NegativeZero>(registers.a);
|
||||
registers.flags.template set_per<Flag::NegativeZero>(registers.a);
|
||||
registers.flags.overflow = (registers.a^(registers.a << 1))&Flag::Overflow;
|
||||
|
||||
if(registers.flags.decimal && has_decimal_mode(model)) {
|
||||
@@ -154,14 +154,14 @@ void sbx(RegistersT ®isters, const uint8_t operand) {
|
||||
registers.x &= registers.a;
|
||||
registers.flags.carry = operand <= registers.x;
|
||||
registers.x -= operand;
|
||||
registers.flags.template set<Flag::NegativeZero>(registers.x);
|
||||
registers.flags.template set_per<Flag::NegativeZero>(registers.x);
|
||||
}
|
||||
|
||||
template <typename RegistersT>
|
||||
void asl(RegistersT ®isters, uint8_t &operand) {
|
||||
registers.flags.carry = operand >> 7;
|
||||
operand <<= 1;
|
||||
registers.flags.template set<Flag::NegativeZero>(operand);
|
||||
registers.flags.template set_per<Flag::NegativeZero>(operand);
|
||||
}
|
||||
|
||||
template <typename RegistersT>
|
||||
@@ -169,14 +169,14 @@ void aso(RegistersT ®isters, uint8_t &operand) {
|
||||
registers.flags.carry = operand >> 7;
|
||||
operand <<= 1;
|
||||
registers.a |= operand;
|
||||
registers.flags.template set<Flag::NegativeZero>(registers.a);
|
||||
registers.flags.template set_per<Flag::NegativeZero>(registers.a);
|
||||
}
|
||||
|
||||
template <typename RegistersT>
|
||||
void rol(RegistersT ®isters, uint8_t &operand) {
|
||||
const uint8_t temp8 = uint8_t((operand << 1) | registers.flags.carry);
|
||||
registers.flags.carry = operand >> 7;
|
||||
registers.flags.template set<Flag::NegativeZero>(operand = temp8);
|
||||
registers.flags.template set_per<Flag::NegativeZero>(operand = temp8);
|
||||
}
|
||||
|
||||
template <typename RegistersT>
|
||||
@@ -185,14 +185,14 @@ void rla(RegistersT ®isters, uint8_t &operand) {
|
||||
registers.flags.carry = operand >> 7;
|
||||
operand = temp8;
|
||||
registers.a &= operand;
|
||||
registers.flags.template set<Flag::NegativeZero>(registers.a);
|
||||
registers.flags.template set_per<Flag::NegativeZero>(registers.a);
|
||||
}
|
||||
|
||||
template <typename RegistersT>
|
||||
void lsr(RegistersT ®isters, uint8_t &operand) {
|
||||
registers.flags.carry = operand & 1;
|
||||
operand >>= 1;
|
||||
registers.flags.template set<Flag::NegativeZero>(operand);
|
||||
registers.flags.template set_per<Flag::NegativeZero>(operand);
|
||||
}
|
||||
|
||||
template <typename RegistersT>
|
||||
@@ -200,7 +200,7 @@ void lse(RegistersT ®isters, uint8_t &operand) {
|
||||
registers.flags.carry = operand & 1;
|
||||
operand >>= 1;
|
||||
registers.a ^= operand;
|
||||
registers.flags.template set<Flag::NegativeZero>(registers.a);
|
||||
registers.flags.template set_per<Flag::NegativeZero>(registers.a);
|
||||
}
|
||||
|
||||
template <typename RegistersT>
|
||||
@@ -208,14 +208,14 @@ void asr(RegistersT ®isters, uint8_t &operand) {
|
||||
registers.a &= operand;
|
||||
registers.flags.carry = registers.a & 1;
|
||||
registers.a >>= 1;
|
||||
registers.flags.template set<Flag::NegativeZero>(registers.a);
|
||||
registers.flags.template set_per<Flag::NegativeZero>(registers.a);
|
||||
}
|
||||
|
||||
template <typename RegistersT>
|
||||
void ror(RegistersT ®isters, uint8_t &operand) {
|
||||
const uint8_t temp8 = uint8_t((operand >> 1) | (registers.flags.carry << 7));
|
||||
registers.flags.carry = operand & 1;
|
||||
registers.flags.template set<Flag::NegativeZero>(operand = temp8);
|
||||
registers.flags.template set_per<Flag::NegativeZero>(operand = temp8);
|
||||
}
|
||||
|
||||
template <Model model, typename RegistersT>
|
||||
@@ -229,7 +229,7 @@ void rra(RegistersT ®isters, uint8_t &operand) {
|
||||
template <typename RegistersT>
|
||||
void compare(RegistersT ®isters, const uint8_t lhs, const uint8_t rhs) {
|
||||
registers.flags.carry = rhs <= lhs;
|
||||
registers.flags.template set<Flag::NegativeZero>(lhs - rhs);
|
||||
registers.flags.template set_per<Flag::NegativeZero>(lhs - rhs);
|
||||
}
|
||||
|
||||
template <typename RegistersT>
|
||||
@@ -342,19 +342,19 @@ void perform(
|
||||
|
||||
// MARK: - Bitwise logic.
|
||||
|
||||
case Operation::ORA: registers.flags.template set<Flag::NegativeZero>(registers.a |= operand); break;
|
||||
case Operation::AND: registers.flags.template set<Flag::NegativeZero>(registers.a &= operand); break;
|
||||
case Operation::EOR: registers.flags.template set<Flag::NegativeZero>(registers.a ^= operand); break;
|
||||
case Operation::ORA: registers.flags.template set_per<Flag::NegativeZero>(registers.a |= operand); break;
|
||||
case Operation::AND: registers.flags.template set_per<Flag::NegativeZero>(registers.a &= operand); break;
|
||||
case Operation::EOR: registers.flags.template set_per<Flag::NegativeZero>(registers.a ^= operand); break;
|
||||
|
||||
// MARK: - Loads and stores.
|
||||
|
||||
case Operation::LDA: registers.flags.template set<Flag::NegativeZero>(registers.a = operand); break;
|
||||
case Operation::LDX: registers.flags.template set<Flag::NegativeZero>(registers.x = operand); break;
|
||||
case Operation::LDY: registers.flags.template set<Flag::NegativeZero>(registers.y = operand); break;
|
||||
case Operation::LAX: registers.flags.template set<Flag::NegativeZero>(registers.a = registers.x = operand); break;
|
||||
case Operation::LDA: registers.flags.template set_per<Flag::NegativeZero>(registers.a = operand); break;
|
||||
case Operation::LDX: registers.flags.template set_per<Flag::NegativeZero>(registers.x = operand); break;
|
||||
case Operation::LDY: registers.flags.template set_per<Flag::NegativeZero>(registers.y = operand); break;
|
||||
case Operation::LAX: registers.flags.template set_per<Flag::NegativeZero>(registers.a = registers.x = operand); break;
|
||||
case Operation::LXA:
|
||||
registers.a = registers.x = (registers.a | 0xee) & operand;
|
||||
registers.flags.template set<Flag::NegativeZero>(registers.a);
|
||||
registers.flags.template set_per<Flag::NegativeZero>(registers.a);
|
||||
break;
|
||||
case Operation::PLP: registers.flags = Flags(operand); break;
|
||||
|
||||
@@ -365,40 +365,40 @@ void perform(
|
||||
case Operation::SAX: operand = registers.a & registers.x; break;
|
||||
case Operation::PHP: operand = static_cast<uint8_t>(registers.flags) | Flag::Break; break;
|
||||
|
||||
case Operation::CLC: registers.flags.carry = 0; break;
|
||||
case Operation::CLI: registers.flags.inverse_interrupt = Flag::Interrupt; break;
|
||||
case Operation::CLV: registers.flags.overflow = 0; break;
|
||||
case Operation::CLD: registers.flags.decimal = 0; break;
|
||||
case Operation::SEC: registers.flags.carry = Flag::Carry; break;
|
||||
case Operation::SEI: registers.flags.inverse_interrupt = 0; break;
|
||||
case Operation::SED: registers.flags.decimal = Flag::Decimal; break;
|
||||
case Operation::CLC: registers.flags.carry = 0; break;
|
||||
case Operation::CLI: registers.flags.template set_per<Flag::Interrupt>(0); break;
|
||||
case Operation::CLV: registers.flags.overflow = 0; break;
|
||||
case Operation::CLD: registers.flags.decimal = 0; break;
|
||||
case Operation::SEC: registers.flags.carry = Flag::Carry; break;
|
||||
case Operation::SEI: registers.flags.template set_per<Flag::Interrupt>(Flag::Interrupt); break;
|
||||
case Operation::SED: registers.flags.decimal = Flag::Decimal; break;
|
||||
|
||||
case Operation::ANE: Operations::ane(registers, operand); break;
|
||||
case Operation::ANC: Operations::anc(registers, operand); break;
|
||||
case Operation::LAS:
|
||||
registers.a = registers.x = registers.s = registers.s & operand;
|
||||
registers.flags.template set<Flag::NegativeZero>(registers.a);
|
||||
registers.flags.template set_per<Flag::NegativeZero>(registers.a);
|
||||
break;
|
||||
|
||||
// MARK: - Transfers.
|
||||
|
||||
case Operation::TXA: registers.flags.template set<Flag::NegativeZero>(registers.a = registers.x); break;
|
||||
case Operation::TYA: registers.flags.template set<Flag::NegativeZero>(registers.a = registers.y); break;
|
||||
case Operation::TXA: registers.flags.template set_per<Flag::NegativeZero>(registers.a = registers.x); break;
|
||||
case Operation::TYA: registers.flags.template set_per<Flag::NegativeZero>(registers.a = registers.y); break;
|
||||
case Operation::TXS: registers.s = registers.x; break;
|
||||
case Operation::TAY: registers.flags.template set<Flag::NegativeZero>(registers.y = registers.a); break;
|
||||
case Operation::TAX: registers.flags.template set<Flag::NegativeZero>(registers.x = registers.a); break;
|
||||
case Operation::TSX: registers.flags.template set<Flag::NegativeZero>(registers.x = registers.s); break;
|
||||
case Operation::TAY: registers.flags.template set_per<Flag::NegativeZero>(registers.y = registers.a); break;
|
||||
case Operation::TAX: registers.flags.template set_per<Flag::NegativeZero>(registers.x = registers.a); break;
|
||||
case Operation::TSX: registers.flags.template set_per<Flag::NegativeZero>(registers.x = registers.s); break;
|
||||
|
||||
// MARK: - Increments and decrements.
|
||||
|
||||
case Operation::INC: registers.flags.template set<Flag::NegativeZero>(++operand); break;
|
||||
case Operation::DEC: registers.flags.template set<Flag::NegativeZero>(--operand); break;
|
||||
case Operation::INA: registers.flags.template set<Flag::NegativeZero>(++registers.a); break;
|
||||
case Operation::DEA: registers.flags.template set<Flag::NegativeZero>(--registers.a); break;
|
||||
case Operation::INX: registers.flags.template set<Flag::NegativeZero>(++registers.x); break;
|
||||
case Operation::DEX: registers.flags.template set<Flag::NegativeZero>(--registers.x); break;
|
||||
case Operation::INY: registers.flags.template set<Flag::NegativeZero>(++registers.y); break;
|
||||
case Operation::DEY: registers.flags.template set<Flag::NegativeZero>(--registers.y); break;
|
||||
case Operation::INC: registers.flags.template set_per<Flag::NegativeZero>(++operand); break;
|
||||
case Operation::DEC: registers.flags.template set_per<Flag::NegativeZero>(--operand); break;
|
||||
case Operation::INA: registers.flags.template set_per<Flag::NegativeZero>(++registers.a); break;
|
||||
case Operation::DEA: registers.flags.template set_per<Flag::NegativeZero>(--registers.a); break;
|
||||
case Operation::INX: registers.flags.template set_per<Flag::NegativeZero>(++registers.x); break;
|
||||
case Operation::DEX: registers.flags.template set_per<Flag::NegativeZero>(--registers.x); break;
|
||||
case Operation::INY: registers.flags.template set_per<Flag::NegativeZero>(++registers.y); break;
|
||||
case Operation::DEY: registers.flags.template set_per<Flag::NegativeZero>(--registers.y); break;
|
||||
|
||||
// MARK: - Shifts and rolls.
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@ struct Flags {
|
||||
/// Sets a flag based on an 8-bit ALU result.
|
||||
template <Flag flag>
|
||||
requires(is_settable(flag))
|
||||
void set(const uint8_t result) {
|
||||
void set_per(const uint8_t result) {
|
||||
switch(flag) {
|
||||
default: __builtin_unreachable();
|
||||
|
||||
@@ -117,6 +117,12 @@ struct Flags {
|
||||
}
|
||||
}
|
||||
|
||||
template <Flag flag>
|
||||
requires(is_settable(flag))
|
||||
void set(const bool result) {
|
||||
set_per<flag>(result ? 0xff : 0x00);
|
||||
}
|
||||
|
||||
uint8_t carry_value() const {
|
||||
return carry;
|
||||
}
|
||||
@@ -145,12 +151,12 @@ struct Flags {
|
||||
}
|
||||
|
||||
Flags(const uint8_t flags) {
|
||||
set<Flag::Carry>(flags);
|
||||
set<Flag::Negative>(flags);
|
||||
set<Flag::Zero>((~flags) & Flag::Zero);
|
||||
set<Flag::Overflow>(flags);
|
||||
set<Flag::Interrupt>(flags);
|
||||
set<Flag::Decimal>(flags);
|
||||
set_per<Flag::Carry>(flags);
|
||||
set_per<Flag::Negative>(flags);
|
||||
set_per<Flag::Zero>((~flags) & Flag::Zero);
|
||||
set_per<Flag::Overflow>(flags);
|
||||
set_per<Flag::Interrupt>(flags);
|
||||
set_per<Flag::Decimal>(flags);
|
||||
|
||||
assert((flags | Flag::Always | Flag::Break) == static_cast<uint8_t>(*this));
|
||||
}
|
||||
@@ -164,6 +170,7 @@ struct Flags {
|
||||
uint8_t carry = 0; /// Contains Flag::Carry.
|
||||
uint8_t decimal = 0; /// Contains Flag::Decimal.
|
||||
uint8_t overflow = 0; /// Contains Flag::Overflow.
|
||||
private:
|
||||
uint8_t inverse_interrupt = 0; /// Contains Flag::Interrupt, complemented.
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user