mirror of
https://github.com/MoleskiCoder/EightBit.git
synced 2025-01-14 06:29:58 +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;
|
int execute() noexcept final;
|
||||||
[[nodiscard]] int step() noexcept final;
|
[[nodiscard]] int step() noexcept final;
|
||||||
|
|
||||||
[[nodiscard]] constexpr auto& X() noexcept { return x; }
|
[[nodiscard]] constexpr auto& X() noexcept { return m_x; }
|
||||||
[[nodiscard]] constexpr auto& Y() noexcept { return y; }
|
[[nodiscard]] constexpr auto& Y() noexcept { return m_y; }
|
||||||
[[nodiscard]] constexpr auto& A() noexcept { return a; }
|
[[nodiscard]] constexpr auto& A() noexcept { return m_a; }
|
||||||
[[nodiscard]] constexpr auto& S() noexcept { return s; }
|
[[nodiscard]] constexpr auto& S() noexcept { return m_s; }
|
||||||
|
|
||||||
[[nodiscard]] constexpr auto& P() noexcept { return p; }
|
[[nodiscard]] constexpr auto& P() noexcept { return m_p; }
|
||||||
[[nodiscard]] constexpr const auto& P() const noexcept { return p; }
|
[[nodiscard]] constexpr const auto& P() const noexcept { return m_p; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void handleRESET() noexcept final;
|
void handleRESET() noexcept final;
|
||||||
@ -92,6 +92,7 @@ namespace EightBit {
|
|||||||
|
|
||||||
// Addressing modes
|
// Addressing modes
|
||||||
|
|
||||||
|
[[nodiscard]] register16_t Address_Immediate() noexcept;
|
||||||
[[nodiscard]] register16_t Address_Absolute() noexcept;
|
[[nodiscard]] register16_t Address_Absolute() noexcept;
|
||||||
[[nodiscard]] uint8_t Address_ZeroPage() noexcept;
|
[[nodiscard]] uint8_t Address_ZeroPage() noexcept;
|
||||||
[[nodiscard]] register16_t Address_ZeroPageIndirect() noexcept;
|
[[nodiscard]] register16_t Address_ZeroPageIndirect() noexcept;
|
||||||
@ -168,15 +169,17 @@ namespace EightBit {
|
|||||||
memoryWrite(data);
|
memoryWrite(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unconditional page fixup cycle required
|
bool maybe_fixup(register16_t address, uint8_t unfixed_page, bool always_fixup = false) noexcept {
|
||||||
void fixup(const register16_t address, const uint8_t unfixed_page) noexcept {
|
BUS().ADDRESS() = { address.low, unfixed_page };
|
||||||
getBytePaged(unfixed_page, address.low); // Possible fixup for page boundary crossing
|
const auto fixing = unfixed_page != address.high;
|
||||||
|
if (always_fixup || fixing)
|
||||||
|
memoryRead();
|
||||||
BUS().ADDRESS() = address;
|
BUS().ADDRESS() = address;
|
||||||
|
return fixing;
|
||||||
}
|
}
|
||||||
|
|
||||||
void maybe_fixup(const register16_t address, const uint8_t unfixed_page) noexcept {
|
void fixup(register16_t address, uint8_t unfixed_page) noexcept {
|
||||||
if (address.high != unfixed_page)
|
maybe_fixup(address, unfixed_page, true);
|
||||||
fixup(address, unfixed_page);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -327,11 +330,11 @@ namespace EightBit {
|
|||||||
// NOP
|
// NOP
|
||||||
void nop_AbsoluteX() noexcept;
|
void nop_AbsoluteX() noexcept;
|
||||||
|
|
||||||
uint8_t x = 0; // index register X
|
uint8_t m_x = 0; // index register X
|
||||||
uint8_t y = 0; // index register Y
|
uint8_t m_y = 0; // index register Y
|
||||||
uint8_t a = 0; // accumulator
|
uint8_t m_a = 0; // accumulator
|
||||||
uint8_t s = 0; // stack pointer
|
uint8_t m_s = 0; // stack pointer
|
||||||
uint8_t p = 0; // processor status
|
uint8_t m_p = 0; // processor status
|
||||||
|
|
||||||
register16_t m_intermediate;
|
register16_t m_intermediate;
|
||||||
|
|
||||||
|
@ -102,7 +102,8 @@ void EightBit::MOS6502::interrupt() noexcept {
|
|||||||
}
|
}
|
||||||
set_flag(IF); // Disable IRQ
|
set_flag(IF); // Disable IRQ
|
||||||
const uint8_t vector = reset ? RSTvector : (nmi ? NMIvector : IRQvector);
|
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;
|
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 {
|
EightBit::register16_t EightBit::MOS6502::Address_Absolute() noexcept {
|
||||||
return fetchWord();
|
return fetchWord();
|
||||||
}
|
}
|
||||||
@ -431,12 +436,13 @@ uint8_t EightBit::MOS6502::Address_ZeroPage() noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
EightBit::register16_t EightBit::MOS6502::Address_ZeroPageIndirect() 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 {
|
EightBit::register16_t EightBit::MOS6502::Address_Indirect() noexcept {
|
||||||
const auto address = Address_Absolute();
|
BUS().ADDRESS() = Address_Absolute();
|
||||||
return getWordPaged(address.high, address.low);
|
return getWordPaged();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EightBit::MOS6502::Address_ZeroPageX() noexcept {
|
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 {
|
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 {
|
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
|
// Addressing modes, read
|
||||||
|
|
||||||
uint8_t EightBit::MOS6502::AM_Immediate() noexcept {
|
uint8_t EightBit::MOS6502::AM_Immediate() noexcept {
|
||||||
return fetchByte();
|
return memoryRead(Address_Immediate());
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EightBit::MOS6502::AM_Absolute() noexcept {
|
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 {
|
uint8_t EightBit::MOS6502::AM_AbsoluteX(const PageCrossingBehavior behaviour) noexcept {
|
||||||
const auto [address, page] = Address_AbsoluteX();
|
const auto [address, page] = Address_AbsoluteX();
|
||||||
auto possible = getBytePaged(page, address.low);
|
maybe_fixup(address, page, behaviour == PageCrossingBehavior::AlwaysReadTwice);
|
||||||
if ((behaviour == PageCrossingBehavior::AlwaysReadTwice) || UNLIKELY(page != address.high))
|
return memoryRead();
|
||||||
possible = memoryRead(address);
|
|
||||||
return possible;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EightBit::MOS6502::AM_AbsoluteY() noexcept {
|
uint8_t EightBit::MOS6502::AM_AbsoluteY() noexcept {
|
||||||
const auto [address, page] = Address_AbsoluteY();
|
const auto [address, page] = Address_AbsoluteY();
|
||||||
auto possible = getBytePaged(page, address.low);
|
maybe_fixup(address, page);
|
||||||
if (UNLIKELY(page != address.high))
|
return memoryRead();
|
||||||
possible = memoryRead(address);
|
|
||||||
return possible;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EightBit::MOS6502::AM_ZeroPageX() noexcept {
|
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 {
|
uint8_t EightBit::MOS6502::AM_IndirectIndexedY() noexcept {
|
||||||
const auto [address, page] = Address_IndirectIndexedY();
|
const auto [address, page] = Address_IndirectIndexedY();
|
||||||
auto possible = getBytePaged(page, address.low);
|
maybe_fixup(address, page);
|
||||||
if (page != address.high)
|
return memoryRead();
|
||||||
possible = memoryRead(address);
|
|
||||||
return possible;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////
|
////
|
||||||
@ -535,8 +536,7 @@ void EightBit::MOS6502::branch(const int condition) noexcept {
|
|||||||
swallow();
|
swallow();
|
||||||
const auto page = PC().high;
|
const auto page = PC().high;
|
||||||
jump(destination);
|
jump(destination);
|
||||||
if (UNLIKELY(PC().high != page))
|
maybe_fixup(PC(), page);
|
||||||
getBytePaged(page, PC().low);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user