mirror of
https://github.com/MoleskiCoder/EightBit.git
synced 2024-12-26 03:32:51 +00:00
Tidy up of the M6502 page fixup code
This commit is contained in:
parent
f3c694303d
commit
2e29233b3b
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user