Tidy up of the M6502 page fixup code

This commit is contained in:
Adrian Conlon 2024-03-01 23:18:24 +00:00
parent f3c694303d
commit 2e29233b3b
2 changed files with 40 additions and 37 deletions

View File

@ -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;

View File

@ -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::register16_t, uint8_t> 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::register16_t, uint8_t> 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);
}
}