summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Blake Kongslie2022-10-22 22:53:26 -0700
committerJulian Blake Kongslie2022-10-22 22:53:26 -0700
commit763beb022c799598ef4eaa9750ad259497bd2e84 (patch)
tree3e436e523f3270aa8040d192b993c5bf85298186
parentFix rotate left to not drop the highest bit (diff)
downloadbiggolf-763beb022c799598ef4eaa9750ad259497bd2e84.tar.xz
Merge TT_INPUT and TT_OUTPUT into TT_BITS
Diffstat (limited to '')
-rw-r--r--io/model.cpp14
-rw-r--r--isa/decode.cpp48
-rw-r--r--isa/isa.h13
3 files changed, 48 insertions, 27 deletions
diff --git a/io/model.cpp b/io/model.cpp
index eaa6ca8..e1b59ea 100644
--- a/io/model.cpp
+++ b/io/model.cpp
@@ -16,21 +16,21 @@ bool iomodel::interact(std::array<unsigned int, NUM_CTLREGS> &ctlregs) {
16 16
17 ++time; 17 ++time;
18 18
19 if (ctlregs[TT_OUTPUT] & 0x100) { 19 if (ctlregs[TT_BITS] & TTO_TX) {
20 // PDP-8 doesn't really have support for 8-bit output, this is Jules' contribution 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) << std::flush; 21 std::cout << (char)(((ctlregs[TT_BITS] & TTO_DATA) >> TTO_DATA_SHIFT) ^ 0x80) << std::flush;
22 ctlregs[TT_OUTPUT] &= ~0x1ff; 22 ctlregs[TT_BITS] &= ~TTO_TX & ~TTO_DATA;
23 log.emplace(time + TT_OUTPUT_DELAY, event(TT_OUTPUT, 0x200, 0)); 23 log.emplace(time + TT_OUTPUT_DELAY, event(TT_BITS, TTO_FLAG, 0));
24 } 24 }
25 25
26 bool interrupt = false; 26 bool interrupt = false;
27 if (ctlregs[INT_ENABLE] & 1) { 27 if (ctlregs[INT_ENABLE] & 1) {
28 if (ctlregs[TT_INPUT_INT_ENABLE]) { 28 if (ctlregs[TT_INPUT_INT_ENABLE]) {
29 if (ctlregs[TT_INPUT] & 0x100) 29 if (ctlregs[TT_BITS] & TTI_FLAG)
30 interrupt = true; 30 interrupt = true;
31 } 31 }
32 if (ctlregs[TT_OUTPUT_INT_ENABLE]) { 32 if (ctlregs[TT_OUTPUT_INT_ENABLE]) {
33 if (!(ctlregs[TT_OUTPUT] & 0x400) && (ctlregs[TT_OUTPUT] & 0x200)) 33 if ((ctlregs[TT_BITS] & (TTO_FLAG|TTO_FLAG_OLD)) == TTO_FLAG)
34 interrupt = true; 34 interrupt = true;
35 } 35 }
36 } 36 }
@@ -40,7 +40,7 @@ bool iomodel::interact(std::array<unsigned int, NUM_CTLREGS> &ctlregs) {
40 ctlregs[DATA_INSTRUCTION_FIELD_BUFFER] = 0; 40 ctlregs[DATA_INSTRUCTION_FIELD_BUFFER] = 0;
41 ctlregs[HALTED] = 0; 41 ctlregs[HALTED] = 0;
42 ctlregs[INT_ENABLE] = 0; 42 ctlregs[INT_ENABLE] = 0;
43 ctlregs[TT_OUTPUT] = (ctlregs[TT_OUTPUT] & 0x200) * 3; 43 ctlregs[TT_BITS] |= (ctlregs[TT_BITS] & TTO_FLAG) ? TTO_FLAG_OLD : 0;
44 } else { 44 } else {
45 ctlregs[INT_ENABLE] = (ctlregs[INT_ENABLE] >> 1) * 3; 45 ctlregs[INT_ENABLE] = (ctlregs[INT_ENABLE] >> 1) * 3;
46 } 46 }
diff --git a/isa/decode.cpp b/isa/decode.cpp
index dde5b74..41d125d 100644
--- a/isa/decode.cpp
+++ b/isa/decode.cpp
@@ -74,54 +74,66 @@ instruction_context decode(unsigned int dfifb, unsigned int pc, unsigned int bit
74 case 6: // IOT 74 case 6: // IOT
75 switch ((bits >> 3) & 077) { 75 switch ((bits >> 3) & 077) {
76 case 004: 76 case 004:
77 // TELETYPE TELEPRINTER/PUNCH
77 switch (bits & 07) { 78 switch (bits & 07) {
78 case 0: 79 case 0:
79 inst.write_ctlreg = TT_OUTPUT; 80 // Set TTO flag
81 inst.read_ctlreg = TT_BITS;
82 inst.write_ctlreg = TT_BITS;
80 inst.ef = [](auto &ctx) { 83 inst.ef = [](auto &ctx) {
81 ctx.ctlval = 0x600; 84 ctx.ctlval.value() |= TTO_FLAG | TTO_FLAG_OLD;
82 }; 85 };
83 break; 86 break;
84 case 1: 87 case 1:
85 inst.read_ctlreg = TT_OUTPUT; 88 // Skip if TTO flag is set
89 inst.read_ctlreg = TT_BITS;
86 inst.possibly_redirects = true; 90 inst.possibly_redirects = true;
87 inst.ef = [](auto &ctx) { 91 inst.ef = [](auto &ctx) {
88 if (ctx.ctlval.value() & 0x200) 92 if (ctx.ctlval.value() & TTO_FLAG)
89 ctx.next_pc = (ctx.next_pc & ~07777) | ((ctx.next_pc + 1) & 07777); 93 ctx.next_pc = (ctx.next_pc & ~07777) | ((ctx.next_pc + 1) & 07777);
90 }; 94 };
91 break; 95 break;
92 case 2: 96 case 2:
93 inst.write_ctlreg = TT_OUTPUT; 97 // Clear TTO flag
98 inst.read_ctlreg = TT_BITS;
99 inst.write_ctlreg = TT_BITS;
94 inst.ef = [](auto &ctx) { 100 inst.ef = [](auto &ctx) {
95 ctx.ctlval = 0; 101 ctx.ctlval.value() &= ~TTO_FLAG & ~TTO_FLAG_OLD;
96 }; 102 };
97 break; 103 break;
98 case 4: 104 case 4:
105 // Print to TTO
99 inst.need_read_acc = true; 106 inst.need_read_acc = true;
100 inst.read_ctlreg = TT_OUTPUT; 107 inst.read_ctlreg = TT_BITS;
101 inst.write_ctlreg = TT_OUTPUT; 108 inst.write_ctlreg = TT_BITS;
102 inst.ef = [](auto &ctx) { 109 inst.ef = [](auto &ctx) {
103 auto &x = ctx.ctlval.value(); 110 auto &x = ctx.ctlval.value();
104 x &= ~0x1ff; 111 auto chr = ctx.acc.value() ^ 0x80;
105 x |= (ctx.acc.value() & 0xff) ^ 0x80; // 0x7f instead of 0xff for real PDP-8 IO 112 x &= ~TTO_DATA;
106 x |= 0x100; 113 x |= (chr << TTO_DATA_SHIFT) & TTO_DATA;
114 x |= TTO_TX;
107 }; 115 };
108 break; 116 break;
109 case 5: 117 case 5:
118 // Skip if TTO flag is set or TTI flag is set
119 inst.read_ctlreg = TT_BITS;
110 inst.possibly_redirects = true; 120 inst.possibly_redirects = true;
111 // FIXME this instruction wants to read both TT_OUTPUT and TT_INPUT
112 inst.ef = [](auto &ctx) { 121 inst.ef = [](auto &ctx) {
113 assert(false); 122 if (ctx.ctlval.value() & (TTI_FLAG | TTO_FLAG))
123 ctx.next_pc = (ctx.next_pc & ~07777) | ((ctx.next_pc + 1) & 07777);
114 }; 124 };
115 break; 125 break;
116 case 6: 126 case 6:
127 // Print to TTO and clear TTO flag
117 inst.need_read_acc = true; 128 inst.need_read_acc = true;
118 inst.read_ctlreg = TT_OUTPUT; 129 inst.read_ctlreg = TT_BITS;
119 inst.write_ctlreg = TT_OUTPUT; 130 inst.write_ctlreg = TT_BITS;
120 inst.ef = [](auto &ctx) { 131 inst.ef = [](auto &ctx) {
121 auto &x = ctx.ctlval.value(); 132 auto &x = ctx.ctlval.value();
122 x &= ~0x7ff; 133 auto chr = ctx.acc.value() ^ 0x80;
123 x |= (ctx.acc.value() & 0xff) ^ 0x80; 134 x &= ~TTO_FLAG & ~TTO_FLAG_OLD & ~TTO_DATA;
124 x |= 0x100; 135 x |= (chr << TTO_DATA_SHIFT) & TTO_DATA;
136 x |= TTO_TX;
125 }; 137 };
126 break; 138 break;
127 default: 139 default:
diff --git a/isa/isa.h b/isa/isa.h
index bea484e..24ed108 100644
--- a/isa/isa.h
+++ b/isa/isa.h
@@ -8,14 +8,23 @@ enum ctlreg {
8 DATA_INSTRUCTION_FIELD_SAVED, // (df_saved << 3) | if_saved 8 DATA_INSTRUCTION_FIELD_SAVED, // (df_saved << 3) | if_saved
9 HALTED, 9 HALTED,
10 INT_ENABLE, // (int_enable_delay << 1) | int_enable 10 INT_ENABLE, // (int_enable_delay << 1) | int_enable
11 TT_INPUT, // (tti_flag << 8) | tti_buffer 11 TT_BITS, // see below TT[IO]_* consts
12 TT_INPUT_INT_ENABLE, 12 TT_INPUT_INT_ENABLE,
13 TT_OUTPUT, // {tto_flag_old, tto_flag, tto_tx, tto_data}
14 TT_OUTPUT_INT_ENABLE, 13 TT_OUTPUT_INT_ENABLE,
15 14
16 NUM_CTLREGS, 15 NUM_CTLREGS,
17}; 16};
18 17
18// TT_BITS
19static constexpr unsigned int TTI_FLAG = 1 << 0;
20static constexpr unsigned int TTO_TX = 1 << 1;
21static constexpr unsigned int TTO_FLAG = 1 << 2;
22static constexpr unsigned int TTO_FLAG_OLD = 1 << 3;
23static constexpr unsigned int TTI_DATA_SHIFT = 8;
24static constexpr unsigned int TTO_DATA_SHIFT = 16;
25static constexpr unsigned int TTI_DATA = 0xff << TTI_DATA_SHIFT;
26static constexpr unsigned int TTO_DATA = 0xff << TTO_DATA_SHIFT;
27
19struct instruction_context { 28struct instruction_context {
20 // Known statically at decode time 29 // Known statically at decode time
21 bool need_indirect_load = false; // final_address = mem[init_address] 30 bool need_indirect_load = false; // final_address = mem[init_address]