1
0
mirror of https://github.com/TomHarte/CLK.git synced 2026-04-21 02:17:08 +00:00

Eliminate 'addr' side effects.

This commit is contained in:
Thomas Harte
2025-10-27 22:14:48 -04:00
parent c8c4c99f09
commit 58e1880773
2 changed files with 54 additions and 64 deletions
+54 -61
View File
@@ -48,12 +48,12 @@ void Processor<model, Traits>::run_for(const Cycles cycles) {
#define restore_point() (__COUNTER__ + int(ResumePoint::Max) + int(AddressingMode::Max))
#define join(a, b) a##b
#define attach(a, b) join(a, b)
#define join(a, b) a##b
#define attach(a, b) join(a, b)
#define access_label() attach(repeat, __LINE__)
// TODO: find a way not to generate a restore point if pause precision and uses_ready_line/model allows it.
#define access(type, addr, value) { \
#define access(type, addr, value, ...) { \
static constexpr int location = restore_point(); \
[[fallthrough]]; case location: \
[[maybe_unused]] access_label(): \
@@ -80,11 +80,12 @@ void Processor<model, Traits>::run_for(const Cycles cycles) {
} else { \
Data::Writeable target; \
Storage::cycles_ -= Storage::bus_handler_.template perform<type>(addr, target); \
WriteableReader::assign(value, target); \
WriteableReader::assign(value, target); \
} \
} else { \
Storage::cycles_ -= Storage::bus_handler_.template perform<type>(addr, value); \
} \
__VA_ARGS__; \
}
#define access_program(name) int(ResumePoint::Max) + int(AddressingMode::name)
@@ -110,6 +111,12 @@ void Processor<model, Traits>::run_for(const Cycles cycles) {
Storage::decoded_.operation == Operation::SBC
) && registers.flags.decimal;
};
const auto set_interrupt_flag = [&] {
registers.flags.inverse_interrupt = 0;
if constexpr (is_65c02(model)) {
registers.flags.decimal = 0;
}
};
using Literal = Address::Literal;
using ZeroPage = Address::ZeroPage;
@@ -207,8 +214,8 @@ void Processor<model, Traits>::run_for(const Cycles cycles) {
access_absolute_65c02_decimal:
access(BusOperation::Read, Literal(Storage::address_.full), Storage::operand_);
perform_operation();
access(BusOperation::Read, Literal(Storage::address_.full), Storage::operand_);
perform_operation();
goto fetch_decode;
// MARK: - Fetch/decode.
@@ -226,8 +233,7 @@ void Processor<model, Traits>::run_for(const Cycles cycles) {
goto interrupt;
}
access(BusOperation::ReadOpcode, Literal(registers.pc.full), Storage::opcode_);
++registers.pc.full;
access(BusOperation::ReadOpcode, Literal(registers.pc.full), Storage::opcode_, ++registers.pc.full);
Storage::decoded_ = Decoder<model>::decode(Storage::opcode_);
// 65c02 special case: support single-cycle NOPs.
@@ -259,9 +265,7 @@ void Processor<model, Traits>::run_for(const Cycles cycles) {
goto fetch_decode;
immediate_65c02_decimal:
access(BusOperation::Read, Literal(registers.pc.full), Storage::operand_);
++registers.pc.full;
access(BusOperation::Read, Literal(registers.pc.full), Storage::operand_, ++registers.pc.full);
perform_operation();
goto fetch_decode;
@@ -277,14 +281,14 @@ void Processor<model, Traits>::run_for(const Cycles cycles) {
// MARK: - Stack.
case access_program(Pull):
access(BusOperation::Read, Stack(registers.s), Storage::operand_, ++registers.s);
access(BusOperation::Read, Stack(registers.s), Storage::operand_);
access(BusOperation::Read, Stack(registers.inc_s()), Storage::operand_);
perform_operation();
goto fetch_decode;
case access_program(Push):
perform_operation();
access(BusOperation::Write, Stack(registers.dec_s()), Storage::operand_);
access(BusOperation::Write, Stack(registers.s), Storage::operand_, --registers.s);
goto fetch_decode;
// MARK: - Relative, and BBR/BBS (for the 65c02).
@@ -314,9 +318,8 @@ void Processor<model, Traits>::run_for(const Cycles cycles) {
Storage::address_.halves.low = Storage::operand_;
access(BusOperation::Read, ZeroPage(Storage::address_.halves.low), Storage::operand_);
access(BusOperation::Read, ZeroPage(Storage::address_.halves.low), Storage::operand_);
access(BusOperation::Read, Literal(registers.pc.full), Storage::address_.halves.low);
access(BusOperation::Read, Literal(registers.pc.full), Storage::address_.halves.low, ++registers.pc.full);
++registers.pc.full;
if(!test_bbr_bbs(Storage::opcode_, Storage::operand_)) {
goto fetch_decode;
}
@@ -352,7 +355,7 @@ void Processor<model, Traits>::run_for(const Cycles cycles) {
// MARK: - Zero indirect (which is exclusive to the 65c02).
case access_program(ZeroIndirect):
access(BusOperation::Read, ZeroPage(Storage::operand_++), Storage::address_.halves.low);
access(BusOperation::Read, ZeroPage(Storage::operand_), Storage::address_.halves.low, ++Storage::operand_);
access(BusOperation::Read, ZeroPage(Storage::operand_), Storage::address_.halves.high);
goto access_absolute;
@@ -418,17 +421,14 @@ void Processor<model, Traits>::run_for(const Cycles cycles) {
case access_program(IndexedIndirect):
access(BusOperation::Read, ZeroPage(Storage::operand_), throwaway);
Storage::operand_ += registers.x;
access(BusOperation::Read, ZeroPage(Storage::operand_), Storage::address_.halves.low);
++Storage::operand_;
access(BusOperation::Read, ZeroPage(Storage::operand_), Storage::address_.halves.low, ++Storage::operand_);
access(BusOperation::Read, ZeroPage(Storage::operand_), Storage::address_.halves.high);
goto access_absolute;
// MARK: - Indirect indexed.
case access_program(IndirectIndexed):
access(BusOperation::Read, ZeroPage(Storage::operand_), Storage::address_.halves.low);
++Storage::operand_;
access(BusOperation::Read, ZeroPage(Storage::operand_), Storage::address_.halves.low, ++Storage::operand_);
access(BusOperation::Read, ZeroPage(Storage::operand_), Storage::address_.halves.high);
Storage::operand_ = Storage::address_.halves.high;
@@ -455,10 +455,8 @@ void Processor<model, Traits>::run_for(const Cycles cycles) {
case access_program(SHxAbsoluteXY):
++registers.pc.full;
Storage::address_.halves.low = Storage::operand_;
access(BusOperation::Read, Literal(registers.pc.full), Storage::address_.halves.high);
++registers.pc.full;
access(BusOperation::Read, Literal(registers.pc.full), Storage::address_.halves.high, ++registers.pc.full);
Storage::operand_ = Storage::address_.halves.high;
Storage::address_.full += (Storage::decoded_.operation == Operation::SHY) ? registers.x : registers.y;
@@ -490,10 +488,7 @@ void Processor<model, Traits>::run_for(const Cycles cycles) {
case access_program(SHxIndirectIndexed):
++registers.pc.full;
access(BusOperation::Read, ZeroPage(Storage::operand_), Storage::address_.halves.low);
++Storage::operand_;
access(BusOperation::Read, ZeroPage(Storage::operand_), Storage::address_.halves.low, ++Storage::operand_);
access(BusOperation::Read, ZeroPage(Storage::operand_), Storage::address_.halves.high);
Storage::operand_ = Storage::address_.halves.high;
@@ -534,31 +529,30 @@ void Processor<model, Traits>::run_for(const Cycles cycles) {
case access_program(JSR):
++registers.pc.full;
access(BusOperation::Read, Stack(registers.s), throwaway);
access(BusOperation::Write, Stack(registers.dec_s()), registers.pc.halves.high);
access(BusOperation::Write, Stack(registers.dec_s()), registers.pc.halves.low);
access(BusOperation::Write, Stack(registers.s), registers.pc.halves.high, --registers.s);
access(BusOperation::Write, Stack(registers.s), registers.pc.halves.low, --registers.s);
access(BusOperation::Read, Literal(registers.pc.full), registers.pc.halves.high);
registers.pc.halves.low = Storage::operand_;
goto fetch_decode;
case access_program(RTI):
access(BusOperation::Read, Stack(registers.s), Storage::operand_);
access(BusOperation::Read, Stack(registers.s), Storage::operand_, ++registers.s);
access(BusOperation::Read, Stack(registers.inc_s()), Storage::operand_);
access(BusOperation::Read, Stack(registers.s), Storage::operand_, ++registers.s);
registers.flags = Flags(Storage::operand_);
access(BusOperation::Read, Stack(registers.inc_s()), registers.pc.halves.low);
access(BusOperation::Read, Stack(registers.inc_s()), registers.pc.halves.high);
access(BusOperation::Read, Stack(registers.s), registers.pc.halves.low, ++registers.s);
access(BusOperation::Read, Stack(registers.s), registers.pc.halves.high);
goto fetch_decode;
case access_program(RTS):
access(BusOperation::Read, Stack(registers.s), Storage::operand_);
access(BusOperation::Read, Stack(registers.s), Storage::operand_, ++registers.s);
access(BusOperation::Read, Stack(registers.inc_s()), registers.pc.halves.low);
access(BusOperation::Read, Stack(registers.inc_s()), registers.pc.halves.high);
access(BusOperation::Read, Literal(registers.pc.full), throwaway);
++registers.pc.full;
access(BusOperation::Read, Stack(registers.s), registers.pc.halves.low, ++registers.s);
access(BusOperation::Read, Stack(registers.s), registers.pc.halves.high);
access(BusOperation::Read, Literal(registers.pc.full), throwaway, ++registers.pc.full);
goto fetch_decode;
@@ -595,7 +589,12 @@ void Processor<model, Traits>::run_for(const Cycles cycles) {
access(BusOperation::Read, Literal(registers.pc.full), throwaway);
Storage::address_.full += registers.x;
access(BusOperation::Read, Literal(Storage::address_.full++), registers.pc.halves.low);
access(
BusOperation::Read,
Literal(Storage::address_.full),
registers.pc.halves.low,
++Storage::address_.full
);
access(BusOperation::Read, Literal(Storage::address_.full), registers.pc.halves.high);
goto fetch_decode;
@@ -604,19 +603,16 @@ void Processor<model, Traits>::run_for(const Cycles cycles) {
case access_program(BRK):
++registers.pc.full;
access(BusOperation::Write, Stack(registers.dec_s()), registers.pc.halves.high);
access(BusOperation::Write, Stack(registers.dec_s()), registers.pc.halves.low);
access(BusOperation::Write, Stack(registers.s), registers.pc.halves.high, --registers.s);
access(BusOperation::Write, Stack(registers.s), registers.pc.halves.low, --registers.s);
access(
BusOperation::Write,
Stack(registers.dec_s()),
static_cast<uint8_t>(registers.flags) | Flag::Break
Stack(registers.s),
static_cast<uint8_t>(registers.flags) | Flag::Break,
--registers.s
);
registers.flags.inverse_interrupt = 0;
if constexpr (is_65c02(model)) {
registers.flags.decimal = 0;
}
set_interrupt_flag();
access(BusOperation::Read, Vector(0xfe), registers.pc.halves.low);
access(BusOperation::Read, Vector(0xff), registers.pc.halves.high);
goto fetch_decode;
@@ -630,17 +626,16 @@ void Processor<model, Traits>::run_for(const Cycles cycles) {
goto reset;
}
access(BusOperation::Write, Stack(registers.dec_s()), registers.pc.halves.high);
access(BusOperation::Write, Stack(registers.dec_s()), registers.pc.halves.low);
access(BusOperation::Write, Stack(registers.s), registers.pc.halves.high, --registers.s);
access(BusOperation::Write, Stack(registers.s), registers.pc.halves.low, --registers.s);
access(
BusOperation::Write,
Stack(registers.dec_s()),
static_cast<uint8_t>(registers.flags) & ~Flag::Break
Stack(registers.s),
static_cast<uint8_t>(registers.flags) & ~Flag::Break,
--registers.s
);
registers.flags.inverse_interrupt = 0;
if constexpr (is_65c02(model)) registers.flags.decimal = 0;
set_interrupt_flag();
if(Storage::captured_interrupt_requests_ & InterruptRequest::NMI) {
Storage::inputs_.interrupt_requests &= ~InterruptRequest::NMI;
goto nmi;
@@ -656,13 +651,11 @@ void Processor<model, Traits>::run_for(const Cycles cycles) {
goto fetch_decode;
reset:
access(BusOperation::Read, Stack(registers.dec_s()), Storage::operand_);
access(BusOperation::Read, Stack(registers.dec_s()), Storage::operand_);
access(BusOperation::Read, Stack(registers.dec_s()), Storage::operand_);
registers.flags.inverse_interrupt = 0;
if constexpr (is_65c02(model)) registers.flags.decimal = 0;
access(BusOperation::Read, Stack(registers.s), Storage::operand_, --registers.s);
access(BusOperation::Read, Stack(registers.s), Storage::operand_, --registers.s);
access(BusOperation::Read, Stack(registers.s), Storage::operand_, --registers.s);
set_interrupt_flag();
access(BusOperation::Read, Vector(0xfc), registers.pc.halves.low);
access(BusOperation::Read, Vector(0xfd), registers.pc.halves.high);
goto fetch_decode;
-3
View File
@@ -121,9 +121,6 @@ struct Registers {
Flags flags;
auto operator <=> (const Registers &) const = default;
uint8_t dec_s() { return s--; }
uint8_t inc_s() { return ++s; }
};
}