diff options
| -rw-r--r-- | io/model.cpp | 2 | ||||
| -rw-r--r-- | isa/decode.cpp | 76 | ||||
| -rw-r--r-- | main.cpp | 2 | ||||
| -rw-r--r-- | programs/count.pal | 2 | ||||
| -rw-r--r-- | programs/mike_fib.pal | 117 |
5 files changed, 188 insertions, 11 deletions
diff --git a/io/model.cpp b/io/model.cpp index dd55ce6..eaa6ca8 100644 --- a/io/model.cpp +++ b/io/model.cpp | |||
| @@ -18,7 +18,7 @@ bool iomodel::interact(std::array<unsigned int, NUM_CTLREGS> &ctlregs) { | |||
| 18 | 18 | ||
| 19 | if (ctlregs[TT_OUTPUT] & 0x100) { | 19 | if (ctlregs[TT_OUTPUT] & 0x100) { |
| 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); | 21 | std::cout << (char)((ctlregs[TT_OUTPUT] & 0xff) ^ 0x80) << std::flush; |
| 22 | ctlregs[TT_OUTPUT] &= ~0x1ff; | 22 | ctlregs[TT_OUTPUT] &= ~0x1ff; |
| 23 | log.emplace(time + TT_OUTPUT_DELAY, event(TT_OUTPUT, 0x200, 0)); | 23 | log.emplace(time + TT_OUTPUT_DELAY, event(TT_OUTPUT, 0x200, 0)); |
| 24 | } | 24 | } |
diff --git a/isa/decode.cpp b/isa/decode.cpp index d24632b..cb6a694 100644 --- a/isa/decode.cpp +++ b/isa/decode.cpp | |||
| @@ -23,7 +23,7 @@ instruction_context decode(unsigned int dfifb, unsigned int pc, unsigned int bit | |||
| 23 | inst.need_read_acc = true; | 23 | inst.need_read_acc = true; |
| 24 | inst.need_write_acc = true; | 24 | inst.need_write_acc = true; |
| 25 | inst.ef = [](auto &ctx) { | 25 | inst.ef = [](auto &ctx) { |
| 26 | ctx.acc = ctx.acc.value() & ctx.data.value(); | 26 | ctx.acc = ctx.acc.value() & ctx.data.value() & 07777; |
| 27 | }; | 27 | }; |
| 28 | break; | 28 | break; |
| 29 | case 1: // TAD | 29 | case 1: // TAD |
| @@ -44,7 +44,7 @@ instruction_context decode(unsigned int dfifb, unsigned int pc, unsigned int bit | |||
| 44 | inst.possibly_redirects = true; | 44 | inst.possibly_redirects = true; |
| 45 | inst.ef = [](auto &ctx) { | 45 | inst.ef = [](auto &ctx) { |
| 46 | ctx.data = (ctx.data.value() + 1) & 07777; | 46 | ctx.data = (ctx.data.value() + 1) & 07777; |
| 47 | if (*ctx.data) | 47 | if (*ctx.data == 0) |
| 48 | ctx.next_pc = (ctx.next_pc & ~07777) | ((ctx.next_pc + 1) & 07777); | 48 | ctx.next_pc = (ctx.next_pc & ~07777) | ((ctx.next_pc + 1) & 07777); |
| 49 | }; | 49 | }; |
| 50 | break; | 50 | break; |
| @@ -72,9 +72,69 @@ instruction_context decode(unsigned int dfifb, unsigned int pc, unsigned int bit | |||
| 72 | }; | 72 | }; |
| 73 | break; | 73 | break; |
| 74 | case 6: // IOT | 74 | case 6: // IOT |
| 75 | inst.ef = [](auto &ctx) { | 75 | switch ((bits >> 3) & 077) { |
| 76 | assert(false); | 76 | case 004: |
| 77 | }; | 77 | switch (bits & 07) { |
| 78 | case 0: | ||
| 79 | inst.write_ctlreg = TT_OUTPUT; | ||
| 80 | inst.ef = [](auto &ctx) { | ||
| 81 | ctx.ctlval = 0x600; | ||
| 82 | }; | ||
| 83 | break; | ||
| 84 | case 1: | ||
| 85 | inst.read_ctlreg = TT_OUTPUT; | ||
| 86 | inst.possibly_redirects = true; | ||
| 87 | inst.ef = [](auto &ctx) { | ||
| 88 | if (ctx.ctlval.value() & 0x200) | ||
| 89 | ctx.next_pc = (ctx.next_pc & ~07777) | ((ctx.next_pc + 1) & 07777); | ||
| 90 | }; | ||
| 91 | break; | ||
| 92 | case 2: | ||
| 93 | inst.write_ctlreg = TT_OUTPUT; | ||
| 94 | inst.ef = [](auto &ctx) { | ||
| 95 | ctx.ctlval = 0; | ||
| 96 | }; | ||
| 97 | break; | ||
| 98 | case 4: | ||
| 99 | inst.need_read_acc = true; | ||
| 100 | inst.read_ctlreg = TT_OUTPUT; | ||
| 101 | inst.write_ctlreg = TT_OUTPUT; | ||
| 102 | inst.ef = [](auto &ctx) { | ||
| 103 | auto &x = ctx.ctlval.value(); | ||
| 104 | x &= ~0x1ff; | ||
| 105 | x |= (ctx.acc.value() & 0xff) ^ 0x80; // 0x7f instead of 0xff for real PDP-8 IO | ||
| 106 | x |= 0x100; | ||
| 107 | }; | ||
| 108 | break; | ||
| 109 | case 5: | ||
| 110 | inst.possibly_redirects = true; | ||
| 111 | // FIXME this instruction wants to read both TT_OUTPUT and TT_INPUT | ||
| 112 | inst.ef = [](auto &ctx) { | ||
| 113 | assert(false); | ||
| 114 | }; | ||
| 115 | break; | ||
| 116 | case 6: | ||
| 117 | inst.need_read_acc = true; | ||
| 118 | inst.read_ctlreg = TT_OUTPUT; | ||
| 119 | inst.write_ctlreg = TT_OUTPUT; | ||
| 120 | inst.ef = [](auto &ctx) { | ||
| 121 | auto &x = ctx.ctlval.value(); | ||
| 122 | x &= ~0x7ff; | ||
| 123 | x |= (ctx.acc.value() & 0xff) ^ 0x80; | ||
| 124 | x |= 0x100; | ||
| 125 | }; | ||
| 126 | break; | ||
| 127 | default: | ||
| 128 | inst.ef = [](auto &ctx) { | ||
| 129 | assert(false); | ||
| 130 | }; | ||
| 131 | } | ||
| 132 | break; | ||
| 133 | default: | ||
| 134 | inst.ef = [](auto &ctx) { | ||
| 135 | assert(false); | ||
| 136 | }; | ||
| 137 | } | ||
| 78 | break; | 138 | break; |
| 79 | case 7: // OPR | 139 | case 7: // OPR |
| 80 | if ((bits & 0400) == 0000) { | 140 | if ((bits & 0400) == 0000) { |
| @@ -93,7 +153,7 @@ instruction_context decode(unsigned int dfifb, unsigned int pc, unsigned int bit | |||
| 93 | inst.ef = [cla, cll, cma, cml, rar, ral, bsw, iac](auto &ctx) { | 153 | inst.ef = [cla, cll, cma, cml, rar, ral, bsw, iac](auto &ctx) { |
| 94 | if (cla) ctx.acc = 0; | 154 | if (cla) ctx.acc = 0; |
| 95 | if (cll) ctx.link = 0; | 155 | if (cll) ctx.link = 0; |
| 96 | if (cma) ctx.acc = ~ctx.acc.value(); | 156 | if (cma) ctx.acc = ~ctx.acc.value() & 07777; |
| 97 | if (cml) ctx.link = !ctx.link.value(); | 157 | if (cml) ctx.link = !ctx.link.value(); |
| 98 | if (iac) { | 158 | if (iac) { |
| 99 | if (++ctx.acc.value() == 0) ctx.link = !ctx.link.value(); | 159 | if (++ctx.acc.value() == 0) ctx.link = !ctx.link.value(); |
| @@ -139,7 +199,7 @@ instruction_context decode(unsigned int dfifb, unsigned int pc, unsigned int bit | |||
| 139 | assert(!osr); | 199 | assert(!osr); |
| 140 | if (hlt) ctx.ctlval = 1; | 200 | if (hlt) ctx.ctlval = 1; |
| 141 | if (skip) | 201 | if (skip) |
| 142 | ctx.next_pc = (ctx.next_pc & 070000) | ((ctx.next_pc + 1) & 007777); | 202 | ctx.next_pc = (ctx.next_pc & ~07777) | ((ctx.next_pc + 1) & 07777); |
| 143 | }; | 203 | }; |
| 144 | } else if ((bits & 0411) == 0410) { | 204 | } else if ((bits & 0411) == 0410) { |
| 145 | bool cla = bits & 0200; | 205 | bool cla = bits & 0200; |
| @@ -163,7 +223,7 @@ instruction_context decode(unsigned int dfifb, unsigned int pc, unsigned int bit | |||
| 163 | assert(!osr); | 223 | assert(!osr); |
| 164 | if (hlt) ctx.ctlval = 1; | 224 | if (hlt) ctx.ctlval = 1; |
| 165 | if (skip) | 225 | if (skip) |
| 166 | ctx.next_pc = (ctx.next_pc & 070000) | ((ctx.next_pc + 1) & 007777); | 226 | ctx.next_pc = (ctx.next_pc & ~07777) | ((ctx.next_pc + 1) & 07777); |
| 167 | }; | 227 | }; |
| 168 | } else if ((bits & 0401) == 0401) { | 228 | } else if ((bits & 0401) == 0401) { |
| 169 | bool cla = bits & 0200; | 229 | bool cla = bits & 0200; |
| @@ -66,7 +66,7 @@ int main(int argc, const char *argv[]) { | |||
| 66 | } | 66 | } |
| 67 | 67 | ||
| 68 | while (true) { | 68 | while (true) { |
| 69 | std::cout << fmt::format("{:9} @{:04o} {:01o}:{:04o}:{:04o}\n", system.time, checker.pc, checker.link, checker.acc, checker.mq); | 69 | //std::cout << fmt::format("{:9} @{:04o} {:01o}:{:04o}:{:04o} TTO={:x}\n", system.time, checker.pc, checker.link, checker.acc, checker.mq, checker.ctlregs[TT_OUTPUT]); |
| 70 | checker.execute(); | 70 | checker.execute(); |
| 71 | } | 71 | } |
| 72 | 72 | ||
diff --git a/programs/count.pal b/programs/count.pal index 2e96759..aa34be6 100644 --- a/programs/count.pal +++ b/programs/count.pal | |||
| @@ -2,5 +2,5 @@ | |||
| 2 | 2 | ||
| 3 | *200 | 3 | *200 |
| 4 | 4 | ||
| 5 | LOOP, TAD [1] | 5 | LOOP, TAD (1) |
| 6 | JMP LOOP | 6 | JMP LOOP |
diff --git a/programs/mike_fib.pal b/programs/mike_fib.pal new file mode 100644 index 0000000..6f56109 --- /dev/null +++ b/programs/mike_fib.pal | |||
| @@ -0,0 +1,117 @@ | |||
| 1 | *200 | ||
| 2 | MAIN, CLA | ||
| 3 | TAD (-26) | ||
| 4 | DCA FIBN | ||
| 5 | DCA FIB0 | ||
| 6 | IAC | ||
| 7 | DCA FIB1 | ||
| 8 | LOOP, CLA | ||
| 9 | TAD FIB0 | ||
| 10 | JMS PUTN | ||
| 11 | CLA | ||
| 12 | TAD (054) | ||
| 13 | JMS PUTC | ||
| 14 | CLA | ||
| 15 | TAD FIB0 | ||
| 16 | TAD FIB1 | ||
| 17 | DCA FIB2 | ||
| 18 | TAD FIB1 | ||
| 19 | DCA FIB0 | ||
| 20 | TAD FIB2 | ||
| 21 | DCA FIB1 | ||
| 22 | ISZ FIBN | ||
| 23 | JMP LOOP | ||
| 24 | EXIT, HLT | ||
| 25 | CLA IAC | ||
| 26 | DCA FIB1 | ||
| 27 | DCA FIB0 | ||
| 28 | JMP MAIN | ||
| 29 | PUTN, 0 | ||
| 30 | JMS ITOA | ||
| 31 | CMA IAC | ||
| 32 | IAC | ||
| 33 | CMA IAC | ||
| 34 | DCA 10 | ||
| 35 | PUTNL, CLA | ||
| 36 | TAD I 10 | ||
| 37 | SPA | ||
| 38 | JMP I PUTN | ||
| 39 | TAD (60) | ||
| 40 | JMS PUTC | ||
| 41 | JMP PUTNL | ||
| 42 | PUTC, 0 | ||
| 43 | TLS | ||
| 44 | TSF | ||
| 45 | JMP .-1 | ||
| 46 | JMP I PUTC | ||
| 47 | ITOA, 0 | ||
| 48 | DCA ITOAV | ||
| 49 | DCA ITOAD | ||
| 50 | DCA ITOAD+1 | ||
| 51 | DCA ITOAD+2 | ||
| 52 | DCA ITOAD+3 | ||
| 53 | TAD (-14) | ||
| 54 | DCA ITOAN | ||
| 55 | ITOAL, CLL / LOOP OVER BINARY INPUT BITS | ||
| 56 | TAD ITOAD+3 | ||
| 57 | JMS ITOA2X | ||
| 58 | DCA ITOAD+3 | ||
| 59 | TAD ITOAD+2 | ||
| 60 | JMS ITOA2X | ||
| 61 | DCA ITOAD+2 | ||
| 62 | TAD ITOAD+1 | ||
| 63 | JMS ITOA2X | ||
| 64 | DCA ITOAD+1 | ||
| 65 | TAD ITOAD | ||
| 66 | JMS ITOA2X | ||
| 67 | DCA ITOAD | ||
| 68 | CLL | ||
| 69 | TAD ITOAV / SHIFT MSB OUT OF INPUT VALUE | ||
| 70 | RAL | ||
| 71 | DCA ITOAV | ||
| 72 | RAL | ||
| 73 | TAD ITOAD+3 / ADD SHIFTED-OUT MSB TO DECIMAL LSD | ||
| 74 | DCA ITOAD+3 | ||
| 75 | ISZ ITOAN | ||
| 76 | JMP ITOAL / NEXT LOOP ITERATION | ||
| 77 | TAD (ITOAD) | ||
| 78 | DCA ITOAR | ||
| 79 | ITOAJ, TAD I ITOAR | ||
| 80 | SZA | ||
| 81 | JMP ITOAX | ||
| 82 | ISZ ITOAR | ||
| 83 | TAD I ITOAR | ||
| 84 | SZA | ||
| 85 | JMP ITOAX | ||
| 86 | ISZ ITOAR | ||
| 87 | TAD I ITOAR | ||
| 88 | SZA | ||
| 89 | JMP ITOAX | ||
| 90 | ISZ ITOAR | ||
| 91 | ITOAX, CLA | ||
| 92 | TAD ITOAR | ||
| 93 | JMP I ITOA | ||
| 94 | ITOA2X, 0 | ||
| 95 | RAL / PUTS 0 IN LINK | ||
| 96 | DCA ITOAT | ||
| 97 | TAD (-12) | ||
| 98 | TAD ITOAT / PUTS 1 IN LINK IF WRAPPED | ||
| 99 | SMA | ||
| 100 | DCA ITOAT | ||
| 101 | CLA | ||
| 102 | TAD ITOAT | ||
| 103 | JMP I ITOA2X | ||
| 104 | FIB0, 0 | ||
| 105 | FIB1, 1 | ||
| 106 | FIB2, 0 | ||
| 107 | FIBN, -27 | ||
| 108 | ITOAD, 0 / OUTPUT DIGITS (MSD FIRST) | ||
| 109 | 0 | ||
| 110 | 0 | ||
| 111 | 0 | ||
| 112 | 4000 / OUTPUT SENTINEL | ||
| 113 | ITOAN, 0 / INPUT BITS LOOP COUNTER | ||
| 114 | ITOAR, 0 / POINTER TO FIRST NONZERO DIGIT | ||
| 115 | ITOAT, 0 / SCRATCHPAD FOR ITOA2X | ||
| 116 | ITOAV, 0 / VALUE BEING CONVERTED (TEMPORARY) | ||
| 117 | $ | ||
