summaryrefslogtreecommitdiff
path: root/isa/decode.cpp
diff options
context:
space:
mode:
authorJulian Blake Kongslie2022-10-02 15:32:49 -0700
committerJulian Blake Kongslie2022-10-02 15:32:49 -0700
commit82cc71261d3d32012d33d3bebe56ca5e3b0bcdbd (patch)
treef1358a38d244e27d9740e914c54328d753cb0b4f /isa/decode.cpp
downloadbiggolf-82cc71261d3d32012d33d3bebe56ca5e3b0bcdbd.tar.xz
Initial commit.
Diffstat (limited to '')
-rw-r--r--isa/decode.cpp96
1 files changed, 96 insertions, 0 deletions
diff --git a/isa/decode.cpp b/isa/decode.cpp
new file mode 100644
index 0000000..8a85d41
--- /dev/null
+++ b/isa/decode.cpp
@@ -0,0 +1,96 @@
1#include <cassert>
2
3#include "isa/isa.h"
4
5instruction_context decode(unsigned int dfifb, unsigned int pc, unsigned int bits)
6{
7 instruction_context inst;
8
9 auto df = dfifb >> 3;
10 auto ifb = dfifb & 00007;
11
12 inst.next_pc = (pc & ~07777) | ((pc + 1) & 07777);
13
14 switch (bits >> 9) {
15 case 0: // AND
16 inst.need_exec_load = true;
17 inst.need_read_acc = true;
18 inst.need_write_acc = true;
19 inst.ef = [](auto &ctx) {
20 ctx.acc = ctx.acc.value() & ctx.data.value();
21 };
22 break;
23 case 1: // TAD
24 inst.need_exec_load = true;
25 inst.need_read_acc = true;
26 inst.need_read_link = true;
27 inst.need_write_acc = true;
28 inst.need_write_link = true;
29 inst.ef = [](auto &ctx) {
30 unsigned int sum = (ctx.link.value() << 12) + ctx.acc.value() + ctx.data.value();
31 ctx.link = (sum >> 12) & 1;
32 ctx.acc = sum & 07777;
33 };
34 break;
35 case 2: // ISZ
36 inst.need_exec_load = true;
37 inst.need_exec_store = true;
38 inst.possibly_redirects = true;
39 inst.ef = [](auto &ctx) {
40 ctx.data = (ctx.data.value() + 1) & 07777;
41 if (*ctx.data)
42 ctx.next_pc = (ctx.next_pc & ~07777) | ((ctx.next_pc + 1) & 07777);
43 };
44 break;
45 case 3: // DCA
46 inst.need_read_acc = true;
47 inst.need_write_acc = true;
48 inst.need_exec_store = true;
49 inst.ef = [](auto &ctx) {
50 ctx.data = ctx.acc.value();
51 ctx.acc = 0;
52 };
53 break;
54 case 4: // JMS
55 inst.need_exec_store = true;
56 inst.possibly_redirects = true;
57 inst.ef = [ifb](auto &ctx) {
58 ctx.data = ctx.next_pc;
59 ctx.next_pc = (ifb << 12) | ((ctx.final_address.value() + 1) & 07777);
60 };
61 break;
62 case 5: // JMP
63 inst.possibly_redirects = true;
64 inst.ef = [ifb](auto &ctx) {
65 ctx.next_pc = (ifb << 12) | (ctx.final_address.value() & 07777);
66 };
67 break;
68 case 6: // IOT
69 inst.ef = [bits](auto &ctx) {
70 assert(false);
71 };
72 break;
73 case 7: // OPR
74 inst.ef = [bits](auto &ctx) {
75 assert(false);
76 };
77 break;
78 }
79
80 // Instructions with memory operands may be direct or indirect
81 if (inst.need_exec_load || inst.need_exec_store || inst.possibly_redirects) {
82 auto addr = (df << 12) | ((bits & 00200) ? (next_pc & 07600) : 0) | (bits & 00177);
83 if (bits & 00400) {
84 inst.need_indirect_load = true;
85 inst.init_address = addr;
86 } else {
87 inst.final_address = addr;
88 }
89 }
90
91 // Non-jump indirect memory operands may be autoincrementing depending on operand bits
92 if (!inst.possibly_redirects && inst.need_indirect_load && ((bits & 00170) == 00010))
93 inst.need_autoinc_store = true;
94
95 return inst;
96}