diff options
Diffstat (limited to 'isa')
| -rw-r--r-- | isa/decode.cpp | 76 |
1 files changed, 68 insertions, 8 deletions
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; |
