#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) ? (inst.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; }