Make the flag manipulations in the 6502 implementatin a little more comprehensible

This commit is contained in:
Adrian Conlon 2021-12-08 19:47:35 +00:00
parent e7d3c2ecb7
commit 5522fde9a7
2 changed files with 38 additions and 30 deletions

View File

@ -14,6 +14,13 @@ namespace EightBit {
class Bus;
class MOS6502 : public LittleEndianProcessor {
public:
DECLARE_PIN_INPUT(NMI)
DECLARE_PIN_INPUT(SO)
DECLARE_PIN_OUTPUT(SYNC)
DECLARE_PIN_INPUT(RDY)
DECLARE_PIN_OUTPUT(RW)
public:
enum StatusBits {
NF = Bit7, // Negative
@ -42,12 +49,6 @@ namespace EightBit {
[[nodiscard]] constexpr auto& P() noexcept { return p; }
[[nodiscard]] constexpr const auto& P() const noexcept { return p; }
DECLARE_PIN_INPUT(NMI)
DECLARE_PIN_INPUT(SO)
DECLARE_PIN_OUTPUT(SYNC)
DECLARE_PIN_INPUT(RDY)
DECLARE_PIN_OUTPUT(RW)
protected:
void handleRESET() final;
void handleINT() final;
@ -109,25 +110,32 @@ namespace EightBit {
uint8_t AM_IndexedIndirectX();
uint8_t AM_IndirectIndexedY();
// Flag adjustment
constexpr void adjustZero(const uint8_t datum) noexcept { P() = clearBit(P(), ZF, datum); }
constexpr void adjustNegative(const uint8_t datum) noexcept { P() = setBit(P(), NF, datum & NF); }
constexpr void adjustNZ(const uint8_t datum) noexcept {
adjustZero(datum);
adjustNegative(datum);
}
// Flag checking
[[nodiscard]] constexpr auto interruptMasked() const noexcept { return P() & IF; }
[[nodiscard]] constexpr auto decimal() const noexcept { return P() & DF; }
[[nodiscard]] constexpr auto negative() const noexcept { return P() & NF; }
[[nodiscard]] constexpr auto zero() const noexcept { return P() & ZF; }
[[nodiscard]] constexpr auto overflow() const noexcept { return P() & VF; }
[[nodiscard]] constexpr auto carry() const noexcept { return P() & CF; }
[[nodiscard]] static constexpr auto negative(uint8_t data) noexcept { return data & NF; }
[[nodiscard]] constexpr auto negative() const noexcept { return negative(P()); }
[[nodiscard]] static constexpr auto zero(uint8_t data) noexcept { return data & ZF; }
[[nodiscard]] constexpr auto zero() const noexcept { return zero(P()); }
[[nodiscard]] static constexpr auto overflow(uint8_t data) noexcept { return data & VF; }
[[nodiscard]] constexpr auto overflow() const noexcept { return overflow(P()); }
[[nodiscard]] static constexpr auto carry(uint8_t data) noexcept { return data & CF; }
[[nodiscard]] constexpr auto carry() const noexcept { return carry(P()); }
// Flag adjustment
constexpr void adjustZero(const uint8_t datum) noexcept { P() = clearBit(P(), ZF, datum); }
constexpr void adjustNegative(const uint8_t datum) noexcept { P() = setBit(P(), NF, negative(datum)); }
constexpr void adjustNZ(const uint8_t datum) noexcept {
adjustZero(datum);
adjustNegative(datum);
}
// Miscellaneous

View File

@ -529,7 +529,7 @@ void EightBit::MOS6502::branch(const int condition) {
uint8_t EightBit::MOS6502::sbc(const uint8_t operand, const uint8_t data) noexcept {
const auto returned = sub(operand, data, ~P() & CF);
const auto returned = sub(operand, data, carry(~P()));
const auto difference = m_intermediate;
adjustNZ(difference.low);
@ -552,12 +552,12 @@ uint8_t EightBit::MOS6502::sub_d(const uint8_t operand, const uint8_t data, cons
m_intermediate.word = operand - data - borrow;
uint8_t low = lowNibble(operand) - lowNibble(data) - borrow;
const auto lowNegative = low & NF;
const auto lowNegative = negative(low);
if (lowNegative)
low -= 6;
uint8_t high = highNibble(operand) - highNibble(data) - (lowNegative >> 7);
const auto highNegative = high & NF;
const auto highNegative = negative(high);
if (highNegative)
high -= 6;
@ -568,15 +568,15 @@ uint8_t EightBit::MOS6502::adc(const uint8_t operand, const uint8_t data) noexce
return add(operand, data, carry());
}
uint8_t EightBit::MOS6502::add(uint8_t operand, uint8_t data, int carry) noexcept {
return decimal() ? add_d(operand, data, carry) : add_b(operand, data, carry);
uint8_t EightBit::MOS6502::add(uint8_t operand, uint8_t data, int carrying) noexcept {
return decimal() ? add_d(operand, data, carrying) : add_b(operand, data, carrying);
}
uint8_t EightBit::MOS6502::add_b(uint8_t operand, uint8_t data, int carry) noexcept {
m_intermediate.word = operand + data + carry;
uint8_t EightBit::MOS6502::add_b(uint8_t operand, uint8_t data, int carrying) noexcept {
m_intermediate.word = operand + data + carrying;
P() = setBit(P(), VF, ~(operand ^ data) & (operand ^ m_intermediate.low) & NF);
P() = setBit(P(), CF, m_intermediate.high & CF);
P() = setBit(P(), CF, carry(m_intermediate.high));
adjustNZ(m_intermediate.low);
@ -595,7 +595,7 @@ uint8_t EightBit::MOS6502::add_d(uint8_t operand, uint8_t data, int carry) noexc
low += 0x06;
}
P() = setBit(P(), NF, high.low & NF);
adjustNegative(high.low);
P() = setBit(P(), VF, ~(operand ^ data) & (operand ^ high.low) & NF);
if (high.word > 0x90)
@ -616,7 +616,7 @@ uint8_t EightBit::MOS6502::asl(const uint8_t value) noexcept {
}
void EightBit::MOS6502::bit(const uint8_t operand, const uint8_t data) noexcept {
P() = setBit(P(), VF, data & VF);
P() = setBit(P(), VF, overflow(data));
adjustZero(operand & data);
adjustNegative(data);
}