1
0
mirror of https://github.com/TomHarte/CLK.git synced 2026-04-25 11:17:26 +00:00

Add insurance against bus handler not writing.

This commit is contained in:
Thomas Harte
2025-10-27 12:37:14 -04:00
parent 6cf87e3aa9
commit f847a72696
2 changed files with 45 additions and 6 deletions
+31 -1
View File
@@ -15,6 +15,7 @@
#include "ClockReceiver/ClockReceiver.hpp"
#include <cassert>
#include <type_traits>
namespace CPU::MOS6502Mk2 {
@@ -109,9 +110,38 @@ struct NoValue {
constexpr NoValue(uint8_t) noexcept {}
};
/// A value that can be written only, not read. With a DEBUG build test that it is written before it is read.
class Writeable {
public:
uint8_t operator=(const uint8_t value) {
if constexpr (requires{did_write_;}) {
did_write_ = true;
}
return result_ = value;
}
operator uint8_t() const {
assert(did_write_);
return result_;
}
private:
uint8_t result_;
friend struct WriteableReader;
#ifndef NDEBUG
bool did_write_ = false;
#endif
};
struct WriteableReader {
static void assign(uint8_t &lhs, const Writeable rhs) {
lhs = rhs;
}
static void assign(const uint8_t &, const Writeable) {}
};
template <BusOperation, typename Enable = void> struct Value;
template <BusOperation operation> struct Value<operation, std::enable_if_t<is_read(operation)>> {
using type = uint8_t &;
using type = Writeable &;
};
template <BusOperation operation> struct Value<operation, std::enable_if_t<is_write(operation)>> {
using type = const uint8_t;
+14 -5
View File
@@ -56,7 +56,13 @@ void Processor<model, Traits>::run_for(const Cycles cycles) {
goto access_label(); \
} \
\
Storage::cycles_ -= Storage::bus_handler_.template perform<type>(addr, value); \
if constexpr (is_read(type)) { \
Data::Writeable target; \
Storage::cycles_ -= Storage::bus_handler_.template perform<type>(addr, target); \
Data::WriteableReader::assign(value, target); \
} else { \
Storage::cycles_ -= Storage::bus_handler_.template perform<type>(addr, value); \
} \
}
#define access_program(name) int(ResumePoint::Max) + int(AddressingMode::name)
@@ -536,10 +542,13 @@ void Processor<model, Traits>::run_for(const Cycles cycles) {
if(Storage::cycles_ <= Cycles(0)) {
return;
}
Storage::cycles_ -= Storage::bus_handler_.template perform<BusOperation::Read>(
Vector(0xff),
throwaway
);
{
Data::Writeable empty;
Storage::cycles_ -= Storage::bus_handler_.template perform<BusOperation::Read>(
Vector(0xff),
empty
);
}
goto jammed;
// MARK: - Flow control (other than BRK).