summaryrefslogtreecommitdiff
path: root/io
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--io/event.h18
-rw-r--r--io/model.cpp49
-rw-r--r--io/model.h15
3 files changed, 82 insertions, 0 deletions
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 @@
1#pragma once
2
3#include <map>
4
5#include "isa/isa.h"
6
7struct event {
8 ctlreg reg;
9 unsigned int mask;
10 unsigned int value;
11 event(ctlreg reg, unsigned int value, unsigned int mask=~0)
12 : reg(reg)
13 , mask(mask)
14 , value(value)
15 { }
16};
17
18typedef std::multimap<std::uint64_t, event> 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 @@
1#include <array>
2#include <cstdint>
3#include <iostream>
4#include <utility>
5
6#include "io/model.h"
7#include "isa/isa.h"
8
9bool iomodel::interact(std::array<unsigned int, NUM_CTLREGS> &ctlregs) {
10 auto [ebegin, eend] = log.equal_range(time);
11 for (auto e = ebegin; e != eend; ++e) {
12 auto &r = ctlregs[e->second.reg];
13 r &= ~e->second.mask;
14 r |= e->second.value;
15 }
16
17 ++time;
18
19 if (ctlregs[TT_OUTPUT] & 0x100) {
20 // PDP-8 doesn't really have support for 8-bit output, this is Jules' contribution
21 std::cout << (char)((ctlregs[TT_OUTPUT] & 0xff) ^ 0x80);
22 ctlregs[TT_OUTPUT] &= ~0x1ff;
23 log.emplace(time + TT_OUTPUT_DELAY, event(TT_OUTPUT, 0x200, 0));
24 }
25
26 bool interrupt = false;
27 if (ctlregs[INT_ENABLE] & 1) {
28 if (ctlregs[TT_INPUT_INT_ENABLE]) {
29 if (ctlregs[TT_INPUT] & 0x100)
30 interrupt = true;
31 }
32 if (ctlregs[TT_OUTPUT_INT_ENABLE]) {
33 if (!(ctlregs[TT_OUTPUT] & 0x400) && (ctlregs[TT_OUTPUT] & 0x200))
34 interrupt = true;
35 }
36 }
37
38 if (interrupt) {
39 ctlregs[DATA_INSTRUCTION_FIELD_SAVED] = ctlregs[DATA_INSTRUCTION_FIELD_BUFFER];
40 ctlregs[DATA_INSTRUCTION_FIELD_BUFFER] = 0;
41 ctlregs[HALTED] = 0;
42 ctlregs[INT_ENABLE] = 0;
43 ctlregs[TT_OUTPUT] = (ctlregs[TT_OUTPUT] & 0x200) * 3;
44 } else {
45 ctlregs[INT_ENABLE] = (ctlregs[INT_ENABLE] >> 1) * 3;
46 }
47
48 return interrupt;
49};
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 @@
1#pragma once
2
3#include <array>
4#include <cstdint>
5
6#include "io/event.h"
7#include "isa/isa.h"
8
9struct iomodel {
10 static constexpr unsigned int TT_OUTPUT_DELAY = 100;
11
12 event_log log;
13 std::uint64_t time = 0;
14 bool interact(std::array<unsigned int, NUM_CTLREGS> &ctlregs);
15};