From 82cc71261d3d32012d33d3bebe56ca5e3b0bcdbd Mon Sep 17 00:00:00 2001 From: Julian Blake Kongslie Date: Sun, 2 Oct 2022 15:32:49 -0700 Subject: Initial commit. --- isa/decode.cpp | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 isa/decode.cpp (limited to 'isa/decode.cpp') 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 @@ +#include + +#include "isa/isa.h" + +instruction_context decode(unsigned int dfifb, unsigned int pc, unsigned int bits) +{ + instruction_context inst; + + auto df = dfifb >> 3; + auto ifb = dfifb & 00007; + + inst.next_pc = (pc & ~07777) | ((pc + 1) & 07777); + + switch (bits >> 9) { + case 0: // AND + inst.need_exec_load = true; + inst.need_read_acc = true; + inst.need_write_acc = true; + inst.ef = [](auto &ctx) { + ctx.acc = ctx.acc.value() & ctx.data.value(); + }; + break; + case 1: // TAD + inst.need_exec_load = true; + inst.need_read_acc = true; + inst.need_read_link = true; + inst.need_write_acc = true; + inst.need_write_link = true; + inst.ef = [](auto &ctx) { + unsigned int sum = (ctx.link.value() << 12) + ctx.acc.value() + ctx.data.value(); + ctx.link = (sum >> 12) & 1; + ctx.acc = sum & 07777; + }; + break; + case 2: // ISZ + inst.need_exec_load = true; + inst.need_exec_store = true; + inst.possibly_redirects = true; + inst.ef = [](auto &ctx) { + ctx.data = (ctx.data.value() + 1) & 07777; + if (*ctx.data) + ctx.next_pc = (ctx.next_pc & ~07777) | ((ctx.next_pc + 1) & 07777); + }; + break; + case 3: // DCA + inst.need_read_acc = true; + inst.need_write_acc = true; + inst.need_exec_store = true; + inst.ef = [](auto &ctx) { + ctx.data = ctx.acc.value(); + ctx.acc = 0; + }; + break; + case 4: // JMS + inst.need_exec_store = true; + inst.possibly_redirects = true; + inst.ef = [ifb](auto &ctx) { + ctx.data = ctx.next_pc; + ctx.next_pc = (ifb << 12) | ((ctx.final_address.value() + 1) & 07777); + }; + break; + case 5: // JMP + inst.possibly_redirects = true; + inst.ef = [ifb](auto &ctx) { + ctx.next_pc = (ifb << 12) | (ctx.final_address.value() & 07777); + }; + break; + case 6: // IOT + inst.ef = [bits](auto &ctx) { + assert(false); + }; + break; + case 7: // OPR + inst.ef = [bits](auto &ctx) { + assert(false); + }; + break; + } + + // Instructions with memory operands may be direct or indirect + if (inst.need_exec_load || inst.need_exec_store || inst.possibly_redirects) { + auto addr = (df << 12) | ((bits & 00200) ? (next_pc & 07600) : 0) | (bits & 00177); + if (bits & 00400) { + inst.need_indirect_load = true; + inst.init_address = addr; + } else { + inst.final_address = addr; + } + } + + // Non-jump indirect memory operands may be autoincrementing depending on operand bits + if (!inst.possibly_redirects && inst.need_indirect_load && ((bits & 00170) == 00010)) + inst.need_autoinc_store = true; + + return inst; +} -- cgit v1.2.3