diff --git a/M6502/inc/mos6502.h b/M6502/inc/mos6502.h index 876a795..d4aa96e 100644 --- a/M6502/inc/mos6502.h +++ b/M6502/inc/mos6502.h @@ -41,13 +41,13 @@ namespace EightBit { int execute() noexcept final; [[nodiscard]] int step() noexcept final; - [[nodiscard]] constexpr auto& X() noexcept { return x; } - [[nodiscard]] constexpr auto& Y() noexcept { return y; } - [[nodiscard]] constexpr auto& A() noexcept { return a; } - [[nodiscard]] constexpr auto& S() noexcept { return s; } + [[nodiscard]] constexpr auto& X() noexcept { return m_x; } + [[nodiscard]] constexpr auto& Y() noexcept { return m_y; } + [[nodiscard]] constexpr auto& A() noexcept { return m_a; } + [[nodiscard]] constexpr auto& S() noexcept { return m_s; } - [[nodiscard]] constexpr auto& P() noexcept { return p; } - [[nodiscard]] constexpr const auto& P() const noexcept { return p; } + [[nodiscard]] constexpr auto& P() noexcept { return m_p; } + [[nodiscard]] constexpr const auto& P() const noexcept { return m_p; } protected: void handleRESET() noexcept final; @@ -92,6 +92,7 @@ namespace EightBit { // Addressing modes + [[nodiscard]] register16_t Address_Immediate() noexcept; [[nodiscard]] register16_t Address_Absolute() noexcept; [[nodiscard]] uint8_t Address_ZeroPage() noexcept; [[nodiscard]] register16_t Address_ZeroPageIndirect() noexcept; @@ -168,15 +169,17 @@ namespace EightBit { memoryWrite(data); } - // Unconditional page fixup cycle required - void fixup(const register16_t address, const uint8_t unfixed_page) noexcept { - getBytePaged(unfixed_page, address.low); // Possible fixup for page boundary crossing + bool maybe_fixup(register16_t address, uint8_t unfixed_page, bool always_fixup = false) noexcept { + BUS().ADDRESS() = { address.low, unfixed_page }; + const auto fixing = unfixed_page != address.high; + if (always_fixup || fixing) + memoryRead(); BUS().ADDRESS() = address; + return fixing; } - void maybe_fixup(const register16_t address, const uint8_t unfixed_page) noexcept { - if (address.high != unfixed_page) - fixup(address, unfixed_page); + void fixup(register16_t address, uint8_t unfixed_page) noexcept { + maybe_fixup(address, unfixed_page, true); } @@ -327,11 +330,11 @@ namespace EightBit { // NOP void nop_AbsoluteX() noexcept; - uint8_t x = 0; // index register X - uint8_t y = 0; // index register Y - uint8_t a = 0; // accumulator - uint8_t s = 0; // stack pointer - uint8_t p = 0; // processor status + uint8_t m_x = 0; // index register X + uint8_t m_y = 0; // index register Y + uint8_t m_a = 0; // accumulator + uint8_t m_s = 0; // stack pointer + uint8_t m_p = 0; // processor status register16_t m_intermediate; diff --git a/M6502/src/mos6502.cpp b/M6502/src/mos6502.cpp index 2140faa..cf7b6de 100644 --- a/M6502/src/mos6502.cpp +++ b/M6502/src/mos6502.cpp @@ -102,7 +102,8 @@ void EightBit::MOS6502::interrupt() noexcept { } set_flag(IF); // Disable IRQ const uint8_t vector = reset ? RSTvector : (nmi ? NMIvector : IRQvector); - jump(getWordPaged(0xff, vector)); + BUS().ADDRESS() = { vector, 0xff }; + jump(getWordPaged()); m_handlingRESET = m_handlingNMI = m_handlingINT = false; } @@ -422,6 +423,10 @@ void EightBit::MOS6502::dummyPush(const uint8_t value) noexcept { //// +EightBit::register16_t EightBit::MOS6502::Address_Immediate() noexcept { + return PC()++; +} + EightBit::register16_t EightBit::MOS6502::Address_Absolute() noexcept { return fetchWord(); } @@ -431,12 +436,13 @@ uint8_t EightBit::MOS6502::Address_ZeroPage() noexcept { } EightBit::register16_t EightBit::MOS6502::Address_ZeroPageIndirect() noexcept { - return getWordPaged(0, Address_ZeroPage()); + BUS().ADDRESS() = { Address_ZeroPage(), 0 }; + return getWordPaged(); } EightBit::register16_t EightBit::MOS6502::Address_Indirect() noexcept { - const auto address = Address_Absolute(); - return getWordPaged(address.high, address.low); + BUS().ADDRESS() = Address_Absolute(); + return getWordPaged(); } uint8_t EightBit::MOS6502::Address_ZeroPageX() noexcept { @@ -464,7 +470,8 @@ std::pair EightBit::MOS6502::Address_AbsoluteY( } EightBit::register16_t EightBit::MOS6502::Address_IndexedIndirectX() noexcept { - return getWordPaged(0, Address_ZeroPageX()); + BUS().ADDRESS() = { Address_ZeroPageX(), 0 }; + return getWordPaged(); } std::pair EightBit::MOS6502::Address_IndirectIndexedY() noexcept { @@ -480,7 +487,7 @@ EightBit::register16_t EightBit::MOS6502::Address_relative_byte() noexcept { // Addressing modes, read uint8_t EightBit::MOS6502::AM_Immediate() noexcept { - return fetchByte(); + return memoryRead(Address_Immediate()); } uint8_t EightBit::MOS6502::AM_Absolute() noexcept { @@ -493,18 +500,14 @@ uint8_t EightBit::MOS6502::AM_ZeroPage() noexcept { uint8_t EightBit::MOS6502::AM_AbsoluteX(const PageCrossingBehavior behaviour) noexcept { const auto [address, page] = Address_AbsoluteX(); - auto possible = getBytePaged(page, address.low); - if ((behaviour == PageCrossingBehavior::AlwaysReadTwice) || UNLIKELY(page != address.high)) - possible = memoryRead(address); - return possible; + maybe_fixup(address, page, behaviour == PageCrossingBehavior::AlwaysReadTwice); + return memoryRead(); } uint8_t EightBit::MOS6502::AM_AbsoluteY() noexcept { const auto [address, page] = Address_AbsoluteY(); - auto possible = getBytePaged(page, address.low); - if (UNLIKELY(page != address.high)) - possible = memoryRead(address); - return possible; + maybe_fixup(address, page); + return memoryRead(); } uint8_t EightBit::MOS6502::AM_ZeroPageX() noexcept { @@ -521,10 +524,8 @@ uint8_t EightBit::MOS6502::AM_IndexedIndirectX() noexcept { uint8_t EightBit::MOS6502::AM_IndirectIndexedY() noexcept { const auto [address, page] = Address_IndirectIndexedY(); - auto possible = getBytePaged(page, address.low); - if (page != address.high) - possible = memoryRead(address); - return possible; + maybe_fixup(address, page); + return memoryRead(); } //// @@ -535,8 +536,7 @@ void EightBit::MOS6502::branch(const int condition) noexcept { swallow(); const auto page = PC().high; jump(destination); - if (UNLIKELY(PC().high != page)) - getBytePaged(page, PC().low); + maybe_fixup(PC(), page); } }