diff --git a/M6502/inc/Disassembly.h b/M6502/inc/Disassembly.h index 28792c6..814b272 100644 --- a/M6502/inc/Disassembly.h +++ b/M6502/inc/Disassembly.h @@ -19,6 +19,7 @@ namespace EightBit { Disassembly(MOS6502& processor, const Symbols& symbols); + std::string Dump_Flags(uint8_t value) const; std::string Dump_ByteValue(uint8_t value) const; std::string Dump_WordValue(uint16_t value) const; diff --git a/M6502/inc/StatusFlags.h b/M6502/inc/StatusFlags.h deleted file mode 100644 index e0fe727..0000000 --- a/M6502/inc/StatusFlags.h +++ /dev/null @@ -1,84 +0,0 @@ -#pragma once - -#include -#include - -namespace EightBit { - struct StatusFlags { - - bool negative; - bool overflow; - bool reserved; - bool brk; - bool decimal; - bool interrupt; - bool zero; - bool carry; - - enum StatusBits { - Negative = 0x80, // N - Overflow = 0x40, // V - Reserved = 0x20, // ignored - Break = 0x10, // B - Decimal = 0x08, // D (use BCD for arithmetic) - Interrupt = 0x04, // I (IRQ disable) - Zero = 0x02, // Z - Carry = 0x01, // C - }; - - StatusFlags(uint8_t value) { - negative = (value & StatusBits::Negative) != 0; - overflow = (value & StatusBits::Overflow) != 0; - reserved = (value & StatusBits::Reserved) != 0; - brk = (value & StatusBits::Break) != 0; - decimal = (value & StatusBits::Decimal) != 0; - interrupt = (value & StatusBits::Interrupt) != 0; - zero = (value & StatusBits::Zero) != 0; - carry = (value & StatusBits::Carry) != 0; - } - - operator uint8_t() const { - - uint8_t flags = 0; - - if (negative) - flags |= StatusBits::Negative; - - if (overflow) - flags |= StatusBits::Overflow; - - if (reserved) - flags |= StatusBits::Reserved; - - if (brk) - flags |= StatusBits::Break; - - if (decimal) - flags |= StatusBits::Decimal; - - if (interrupt) - flags |= StatusBits::Interrupt; - - if (zero) - flags |= StatusBits::Zero; - - if (carry) - flags |= StatusBits::Carry; - - return flags; - } - - operator std::string() const { - std::string returned; - returned += negative ? "N" : "-"; - returned += overflow ? "O" : "-"; - returned += reserved ? "R" : "-"; - returned += brk ? "B" : "-"; - returned += decimal ? "D" : "-"; - returned += interrupt ? "I" : "-"; - returned += zero ? "Z" : "-"; - returned += carry ? "C" : "-"; - return returned; - } - }; -} \ No newline at end of file diff --git a/M6502/inc/mos6502.h b/M6502/inc/mos6502.h index 2ebafc8..1b0ff2f 100644 --- a/M6502/inc/mos6502.h +++ b/M6502/inc/mos6502.h @@ -8,13 +8,23 @@ #include "Memory.h" #include "Processor.h" #include "ProcessorType.h" -#include "StatusFlags.h" #include "AddressingMode.h" #include "Signal.h" namespace EightBit { class MOS6502 : public Processor { public: + enum StatusBits { + NF = 0x80, // Negative + VF = 0x40, // Overflow + RF = 0x20, // reserved + BF = 0x10, // Brk + DF = 0x08, // D (use BCD for arithmetic) + IF = 0x04, // I (IRQ disable) + ZF = 0x02, // Zero + CF = 0x01, // Carry + }; + typedef std::function instruction_t; struct Instruction { @@ -35,8 +45,7 @@ namespace EightBit { uint8_t& Y() { return y; } uint8_t& A() { return a; } uint8_t& S() { return s; } - - StatusFlags& P() { return p; } + uint8_t& P() { return p; } const Instruction& getInstruction(uint8_t code) const { return instructions[code]; @@ -78,8 +87,8 @@ namespace EightBit { void OverlayInstructionSet(const std::array& overlay); void OverlayInstructionSet(const std::array& overlay, bool includeIllegal); - void UpdateZeroFlag(uint8_t datum) { p.zero = datum == 0; } - void UpdateNegativeFlag(uint8_t datum) { p.negative = (datum & StatusFlags::Negative) != 0; } + void UpdateZeroFlag(uint8_t datum) { clearFlag(P(), ZF, datum); } + void UpdateNegativeFlag(uint8_t datum) { setFlag(P(), NF, datum & NF); } void UpdateZeroNegativeFlags(uint8_t datum) { UpdateZeroFlag(datum); @@ -444,8 +453,7 @@ namespace EightBit { uint8_t y; // index register Y uint8_t a; // accumulator uint8_t s; // stack pointer - - StatusFlags p = 0; // processor status + uint8_t p; // processor status std::array instructions; diff --git a/M6502/src/Disassembly.cpp b/M6502/src/Disassembly.cpp index c5d3663..bfb0901 100644 --- a/M6502/src/Disassembly.cpp +++ b/M6502/src/Disassembly.cpp @@ -31,6 +31,19 @@ EightBit::Disassembly::Disassembly(MOS6502& targetProcessor, const Symbols& targ }; } +std::string EightBit::Disassembly::Dump_Flags(uint8_t value) const { + std::string returned; + returned += (value & MOS6502::NF) ? "N" : "-"; + returned += (value & MOS6502::VF) ? "O" : "-"; + returned += (value & MOS6502::RF) ? "R" : "-"; + returned += (value & MOS6502::BF) ? "B" : "-"; + returned += (value & MOS6502::DF) ? "D" : "-"; + returned += (value & MOS6502::IF) ? "I" : "-"; + returned += (value & MOS6502::ZF) ? "Z" : "-"; + returned += (value & MOS6502::CF) ? "C" : "-"; + return returned; +} + std::string EightBit::Disassembly::Dump_ByteValue(uint8_t value) const { std::ostringstream output; output << std::hex << std::setw(2) << std::setfill('0') << (int)value; diff --git a/M6502/src/M6502.vcxproj b/M6502/src/M6502.vcxproj index 3dec772..44cdb03 100644 --- a/M6502/src/M6502.vcxproj +++ b/M6502/src/M6502.vcxproj @@ -146,7 +146,6 @@ - diff --git a/M6502/src/M6502.vcxproj.filters b/M6502/src/M6502.vcxproj.filters index e1cdfac..a743055 100644 --- a/M6502/src/M6502.vcxproj.filters +++ b/M6502/src/M6502.vcxproj.filters @@ -44,9 +44,6 @@ Header Files - - Header Files - Header Files diff --git a/M6502/src/mos6502.cpp b/M6502/src/mos6502.cpp index c8f73c4..fa65768 100644 --- a/M6502/src/mos6502.cpp +++ b/M6502/src/mos6502.cpp @@ -19,7 +19,7 @@ void EightBit::MOS6502::initialise() { a = 0; p = 0; - p.reserved = true; + setFlag(P(), RF); s = 0xff; } @@ -57,7 +57,7 @@ void EightBit::MOS6502::GetWord(uint16_t offset, register16_t& output) { void EightBit::MOS6502::Interrupt(uint16_t vector) { PushWord(PC()); PushByte(p); - p.interrupt = true; + setFlag(P(), IF); GetWord(vector, PC()); } @@ -426,13 +426,9 @@ void EightBit::MOS6502::DEC(uint16_t offset) { } uint8_t EightBit::MOS6502::ROR(uint8_t data) { - auto carry = p.carry; + auto result = (data >> 1) | ((P() & CF) << 7); - p.carry = (data & 1) != 0; - - auto result = (uint8_t)(data >> 1); - if (carry) - result |= 0x80; + setFlag(P(), CF, data & CF); UpdateZeroNegativeFlags(result); @@ -444,9 +440,9 @@ void EightBit::MOS6502::ROR(uint16_t offset) { } uint8_t EightBit::MOS6502::LSR(uint8_t data) { - p.carry = (data & 1) != 0; + auto result = data >> 1; - auto result = (uint8_t)(data >> 1); + setFlag(P(), CF, data & CF); UpdateZeroNegativeFlags(result); @@ -464,22 +460,20 @@ void EightBit::MOS6502::BIT_immediate(uint8_t data) { void EightBit::MOS6502::BIT(uint8_t data) { BIT_immediate(data); - p.negative = (data & 0x80) != 0; - p.overflow = (data & 0x40) != 0; + UpdateNegativeFlag(data); + setFlag(P(), VF, data & VF); } void EightBit::MOS6502::TSB(uint16_t address) { auto content = GetByte(address); BIT_immediate(content); - uint8_t result = content | a; - SetByte(address, result); + SetByte(address, content | a); } void EightBit::MOS6502::TRB(uint16_t address) { auto content = GetByte(address); BIT_immediate(content); - uint8_t result = content & ~a; - SetByte(address, result); + SetByte(address, content & ~a); } void EightBit::MOS6502::INC(uint16_t offset) { @@ -493,14 +487,9 @@ void EightBit::MOS6502::ROL(uint16_t offset) { } uint8_t EightBit::MOS6502::ROL(uint8_t data) { - auto carry = p.carry; + uint8_t result = (data << 1) | (P() & CF); - p.carry = (data & 0x80) != 0; - - uint8_t result = data << 1; - - if (carry) - result |= 1; + setFlag(P(), CF, data & Bit7); UpdateZeroNegativeFlags(result); @@ -514,42 +503,38 @@ void EightBit::MOS6502::ASL(uint16_t offset) { uint8_t EightBit::MOS6502::ASL(uint8_t data) { uint8_t result = data << 1; UpdateZeroNegativeFlags(result); - p.carry = (data & 0x80) != 0; + setFlag(P(), CF, (data & 0x80) >> 7); return result; } void EightBit::MOS6502::ORA(uint8_t data) { - a |= data; - UpdateZeroNegativeFlags(a); + UpdateZeroNegativeFlags(a |= data); } void EightBit::MOS6502::AND(uint8_t data) { - a &= data; - UpdateZeroNegativeFlags(a); + UpdateZeroNegativeFlags(a &= data); } void EightBit::MOS6502::SBC(uint8_t data) { - if (p.decimal) + if (P() & DF) SBC_d(data); else SBC_b(data); } void EightBit::MOS6502::SBC_b(uint8_t data) { - auto carry = p.carry ? 0 : 1; - register16_t difference; - difference.word = a - data - carry; + difference.word = a - data - (~P() & CF); UpdateZeroNegativeFlags(difference.low); - p.overflow = ((a ^ data) & (a ^ difference.low) & 0x80) != 0; - p.carry = difference.high == 0; + setFlag(P(), VF, (a ^ data) & (a ^ difference.low) & 0x80); + clearFlag(P(), CF, difference.high); a = difference.low; } void EightBit::MOS6502::SBC_d(uint8_t data) { - auto carry = p.carry ? 0 : 1; + auto carry = ~P() & CF; register16_t difference; difference.word = a - data - carry; @@ -557,8 +542,8 @@ void EightBit::MOS6502::SBC_d(uint8_t data) { if (level < ProcessorType::Cpu65SC02) UpdateZeroNegativeFlags(difference.low); - p.overflow = ((a ^ data) & (a ^ difference.low) & 0x80) != 0; - p.carry = difference.high == 0; + setFlag(P(), VF, (a ^ data) & (a ^ difference.low) & 0x80); + clearFlag(P(), CF, difference.high); auto low = (uint8_t)(lowNibble(a) - lowNibble(data) - carry); @@ -597,46 +582,42 @@ void EightBit::MOS6502::CMP(uint8_t first, uint8_t second) { register16_t result; result.word = first - second; UpdateZeroNegativeFlags(result.low); - p.carry = result.high == 0; + clearFlag(P(), CF, result.high); } void EightBit::MOS6502::LDA(uint8_t data) { - a = data; - UpdateZeroNegativeFlags(a); + UpdateZeroNegativeFlags(a = data); } void EightBit::MOS6502::LDY(uint8_t data) { - y = data; - UpdateZeroNegativeFlags(y); + UpdateZeroNegativeFlags(y = data); } void EightBit::MOS6502::LDX(uint8_t data) { - x = data; - UpdateZeroNegativeFlags(x); + UpdateZeroNegativeFlags(x = data); } void EightBit::MOS6502::ADC(uint8_t data) { - if (p.decimal) + if (P() & DF) ADC_d(data); else ADC_b(data); } void EightBit::MOS6502::ADC_b(uint8_t data) { - auto carry = (uint8_t)(p.carry ? 1 : 0); register16_t sum; - sum.word = a + data + carry; + sum.word = a + data + (P() & CF); UpdateZeroNegativeFlags(sum.low); - p.overflow = (~(a ^ data) & (a ^ sum.low) & 0x80) != 0; - p.carry = sum.high != 0; + setFlag(P(), VF, ~(a ^ data) & (a ^ sum.low) & 0x80); + setFlag(P(), CF, sum.high & CF); a = sum.low; } void EightBit::MOS6502::ADC_d(uint8_t data) { - auto carry = (uint8_t)(p.carry ? 1 : 0); + auto carry = P() & CF; register16_t sum; sum.word = a + data + carry; @@ -649,12 +630,12 @@ void EightBit::MOS6502::ADC_d(uint8_t data) { low += 6; auto high = (uint8_t)(highNibble(a) + highNibble(data) + (low > 0xf ? 1 : 0)); - p.overflow = (~(a ^ data) & (a ^ promoteNibble(high)) & 0x80) != 0; + setFlag(P(), VF, ~(a ^ data) & (a ^ promoteNibble(high)) & 0x80); if (high > 9) high += 6; - p.carry = high > 0xf; + setFlag(P(), CF, high > 0xf); a = (uint8_t)(promoteNibble(high) | lowNibble(low)); if (level >= ProcessorType::Cpu65SC02) @@ -1281,13 +1262,13 @@ void EightBit::MOS6502::TXA_imp() { // void EightBit::MOS6502::PHP_imp() { - p.brk = true; + setFlag(P(), BF); PushByte(p); } void EightBit::MOS6502::PLP_imp() { p = PopByte(); - p.reserved = true; + setFlag(P(), RF); } void EightBit::MOS6502::PLA_imp() { @@ -1607,9 +1588,9 @@ void EightBit::MOS6502::BRK_imp() { PC().word++; PushWord(PC()); PHP_imp(); - p.interrupt = true; + setFlag(P(), IF); if (level >= ProcessorType::Cpu65SC02) - p.decimal = false; + clearFlag(P(), DF); GetWord(IRQvector, PC()); } @@ -1627,65 +1608,65 @@ void EightBit::MOS6502::STP_imp() { // void EightBit::MOS6502::SED_imp() { - p.decimal = true; + setFlag(P(), DF); } void EightBit::MOS6502::CLD_imp() { - p.decimal = false; + clearFlag(P(), DF); } void EightBit::MOS6502::CLV_imp() { - p.overflow = false; + clearFlag(P(), VF); } void EightBit::MOS6502::SEI_imp() { - p.interrupt = true; + setFlag(P(), IF); } void EightBit::MOS6502::CLI_imp() { - p.interrupt = false; + clearFlag(P(), IF); } void EightBit::MOS6502::CLC_imp() { - p.carry = false; + clearFlag(P(), CF); } void EightBit::MOS6502::SEC_imp() { - p.carry = true; + setFlag(P(), CF); } // void EightBit::MOS6502::BMI_rel() { - Branch(p.negative); + Branch((P() & NF) != 0); } void EightBit::MOS6502::BPL_rel() { - Branch(!p.negative); + Branch(!(P() & NF)); } void EightBit::MOS6502::BVC_rel() { - Branch(!p.overflow); + Branch(!(P() & VF)); } void EightBit::MOS6502::BVS_rel() { - Branch(p.overflow); + Branch((P() & VF) != 0); } void EightBit::MOS6502::BCC_rel() { - Branch(!p.carry); + Branch(!(P() & CF)); } void EightBit::MOS6502::BCS_rel() { - Branch(p.carry); + Branch((P() & CF) != 0); } void EightBit::MOS6502::BNE_rel() { - Branch(!p.zero); + Branch(!(P() & ZF)); } void EightBit::MOS6502::BEQ_rel() { - Branch(p.zero); + Branch((P() & ZF) != 0); } void EightBit::MOS6502::BRA_rel() { diff --git a/M6502/test_M6502/Board.cpp b/M6502/test_M6502/Board.cpp index 9fe1a98..c9aeaf6 100644 --- a/M6502/test_M6502/Board.cpp +++ b/M6502/test_M6502/Board.cpp @@ -82,7 +82,7 @@ void Board::Cpu_ExecutingInstruction_Debug(const EightBit::MOS6502& cpu) { std::cout << std::hex; std::cout << "PC=" << std::setw(4) << std::setfill('0') << address << ":"; - std::cout << "P=" << (std::string)m_cpu.P() << ", "; + std::cout << "P=" << m_disassembler.Dump_Flags(m_cpu.P()) << ", "; std::cout << std::setw(2) << std::setfill('0'); std::cout << "A=" << (int)m_cpu.A() << ", "; std::cout << "X=" << (int)m_cpu.X() << ", ";