diff options
| author | Julian Blake Kongslie | 2022-10-22 22:53:26 -0700 |
|---|---|---|
| committer | Julian Blake Kongslie | 2022-10-22 22:53:26 -0700 |
| commit | 763beb022c799598ef4eaa9750ad259497bd2e84 (patch) | |
| tree | 3e436e523f3270aa8040d192b993c5bf85298186 /isa | |
| parent | Fix rotate left to not drop the highest bit (diff) | |
| download | biggolf-763beb022c799598ef4eaa9750ad259497bd2e84.tar.xz | |
Merge TT_INPUT and TT_OUTPUT into TT_BITS
Diffstat (limited to 'isa')
| -rw-r--r-- | isa/decode.cpp | 48 | ||||
| -rw-r--r-- | isa/isa.h | 13 |
2 files changed, 41 insertions, 20 deletions
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: |
| @@ -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 | ||
| 19 | static constexpr unsigned int TTI_FLAG = 1 << 0; | ||
| 20 | static constexpr unsigned int TTO_TX = 1 << 1; | ||
| 21 | static constexpr unsigned int TTO_FLAG = 1 << 2; | ||
| 22 | static constexpr unsigned int TTO_FLAG_OLD = 1 << 3; | ||
| 23 | static constexpr unsigned int TTI_DATA_SHIFT = 8; | ||
| 24 | static constexpr unsigned int TTO_DATA_SHIFT = 16; | ||
| 25 | static constexpr unsigned int TTI_DATA = 0xff << TTI_DATA_SHIFT; | ||
| 26 | static constexpr unsigned int TTO_DATA = 0xff << TTO_DATA_SHIFT; | ||
| 27 | |||
| 19 | struct instruction_context { | 28 | struct 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] |
