From a59407a215d6112c2e20b1a746b33742209e5f87 Mon Sep 17 00:00:00 2001 From: Julian Blake Kongslie Date: Sun, 16 Oct 2022 16:24:49 -0700 Subject: Support for log-based event model --- io/event.h | 18 ++++++++++++++++++ io/model.cpp | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ io/model.h | 15 +++++++++++++++ 3 files changed, 82 insertions(+) create mode 100644 io/event.h create mode 100644 io/model.cpp create mode 100644 io/model.h (limited to 'io') diff --git a/io/event.h b/io/event.h new file mode 100644 index 0000000..02f3fab --- /dev/null +++ b/io/event.h @@ -0,0 +1,18 @@ +#pragma once + +#include + +#include "isa/isa.h" + +struct event { + ctlreg reg; + unsigned int mask; + unsigned int value; + event(ctlreg reg, unsigned int value, unsigned int mask=~0) + : reg(reg) + , mask(mask) + , value(value) + { } +}; + +typedef std::multimap event_log; diff --git a/io/model.cpp b/io/model.cpp new file mode 100644 index 0000000..dd55ce6 --- /dev/null +++ b/io/model.cpp @@ -0,0 +1,49 @@ +#include +#include +#include +#include + +#include "io/model.h" +#include "isa/isa.h" + +bool iomodel::interact(std::array &ctlregs) { + auto [ebegin, eend] = log.equal_range(time); + for (auto e = ebegin; e != eend; ++e) { + auto &r = ctlregs[e->second.reg]; + r &= ~e->second.mask; + r |= e->second.value; + } + + ++time; + + if (ctlregs[TT_OUTPUT] & 0x100) { + // PDP-8 doesn't really have support for 8-bit output, this is Jules' contribution + std::cout << (char)((ctlregs[TT_OUTPUT] & 0xff) ^ 0x80); + ctlregs[TT_OUTPUT] &= ~0x1ff; + log.emplace(time + TT_OUTPUT_DELAY, event(TT_OUTPUT, 0x200, 0)); + } + + bool interrupt = false; + if (ctlregs[INT_ENABLE] & 1) { + if (ctlregs[TT_INPUT_INT_ENABLE]) { + if (ctlregs[TT_INPUT] & 0x100) + interrupt = true; + } + if (ctlregs[TT_OUTPUT_INT_ENABLE]) { + if (!(ctlregs[TT_OUTPUT] & 0x400) && (ctlregs[TT_OUTPUT] & 0x200)) + interrupt = true; + } + } + + if (interrupt) { + ctlregs[DATA_INSTRUCTION_FIELD_SAVED] = ctlregs[DATA_INSTRUCTION_FIELD_BUFFER]; + ctlregs[DATA_INSTRUCTION_FIELD_BUFFER] = 0; + ctlregs[HALTED] = 0; + ctlregs[INT_ENABLE] = 0; + ctlregs[TT_OUTPUT] = (ctlregs[TT_OUTPUT] & 0x200) * 3; + } else { + ctlregs[INT_ENABLE] = (ctlregs[INT_ENABLE] >> 1) * 3; + } + + return interrupt; +}; diff --git a/io/model.h b/io/model.h new file mode 100644 index 0000000..86fb086 --- /dev/null +++ b/io/model.h @@ -0,0 +1,15 @@ +#pragma once + +#include +#include + +#include "io/event.h" +#include "isa/isa.h" + +struct iomodel { + static constexpr unsigned int TT_OUTPUT_DELAY = 100; + + event_log log; + std::uint64_t time = 0; + bool interact(std::array &ctlregs); +}; -- cgit v1.2.3