From e0ee03184517737bb5a01f98142ad713324bda7c Mon Sep 17 00:00:00 2001 From: Julian Blake Kongslie Date: Sat, 22 Oct 2022 23:31:04 -0700 Subject: Initial interrupt controller support --- io/model.cpp | 18 ++++++++-------- isa/decode.cpp | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ isa/isa.h | 1 + 3 files changed, 76 insertions(+), 9 deletions(-) diff --git a/io/model.cpp b/io/model.cpp index e1b59ea..d6e36f9 100644 --- a/io/model.cpp +++ b/io/model.cpp @@ -24,16 +24,16 @@ bool iomodel::interact(std::array &ctlregs) { } bool interrupt = false; - if (ctlregs[INT_ENABLE] & 1) { - if (ctlregs[TT_INPUT_INT_ENABLE]) { - if (ctlregs[TT_BITS] & TTI_FLAG) - interrupt = true; - } - if (ctlregs[TT_OUTPUT_INT_ENABLE]) { - if ((ctlregs[TT_BITS] & (TTO_FLAG|TTO_FLAG_OLD)) == TTO_FLAG) - interrupt = true; - } + if (ctlregs[TT_INPUT_INT_ENABLE]) { + if (ctlregs[TT_BITS] & TTI_FLAG) + interrupt = true; } + if (ctlregs[TT_OUTPUT_INT_ENABLE]) { + if ((ctlregs[TT_BITS] & (TTO_FLAG|TTO_FLAG_OLD)) == TTO_FLAG) + interrupt = true; + } + ctlregs[INT_PENDING] = interrupt; + interrupt = interrupt && (ctlregs[INT_ENABLE] & 1); if (interrupt) { ctlregs[DATA_INSTRUCTION_FIELD_SAVED] = ctlregs[DATA_INSTRUCTION_FIELD_BUFFER]; diff --git a/isa/decode.cpp b/isa/decode.cpp index 1ecb189..d709cf8 100644 --- a/isa/decode.cpp +++ b/isa/decode.cpp @@ -73,6 +73,72 @@ instruction_context decode(unsigned int dfifb, unsigned int pc, unsigned int bit break; case 6: // IOT switch ((bits >> 3) & 077) { + case 000: + // INTERRUPT CONTROLLER + switch (bits & 07) { + case 0: + // SKON skip if interrupts enabled + inst.read_ctlreg = INT_ENABLE; + inst.possibly_redirects = true; + inst.ef = [](auto &ctx) { + if (ctx.ctlval.value() & 1) + ctx.next_pc = (ctx.next_pc & 07777) | ((ctx.next_pc + 1) & 07777); + }; + break; + case 1: + // ION set int_enable_delay + inst.read_ctlreg = INT_ENABLE; + inst.write_ctlreg = INT_ENABLE; + inst.ef = [](auto &ctx) { + ctx.ctlval.value() |= 2; + }; + break; + case 2: + // IOFF clear int_enable and int_enable_delay + inst.write_ctlreg = INT_ENABLE; + inst.ef = [](auto &ctx) { + ctx.ctlval = 0; + }; + break; + case 3: + // SRQ skip if pending interrupt + inst.read_ctlreg = INT_PENDING; + inst.possibly_redirects = true; + inst.ef = [](auto &ctx) { + if (ctx.ctlval.value()) + ctx.next_pc = (ctx.next_pc & 07777) | ((ctx.next_pc + 1) & 07777); + }; + break; + case 4: + // GTF get flags + inst.ef = [](auto &ctx) { + assert(false); + }; + break; + case 5: + // RTF restore flags + inst.ef = [](auto &ctx) { + assert(false); + }; + break; + case 6: + // SGT skip if greater than + inst.ef = [](auto &ctx) { + assert(false); + }; + break; + case 7: + // CAF clear all flags + inst.ef = [](auto &ctx) { + assert(false); + }; + break; + default: + inst.ef = [](auto &ctx) { + assert(false); + }; + } + break; case 004: // TELETYPE TELEPRINTER/PUNCH switch (bits & 07) { diff --git a/isa/isa.h b/isa/isa.h index 24ed108..1ad5a77 100644 --- a/isa/isa.h +++ b/isa/isa.h @@ -8,6 +8,7 @@ enum ctlreg { DATA_INSTRUCTION_FIELD_SAVED, // (df_saved << 3) | if_saved HALTED, INT_ENABLE, // (int_enable_delay << 1) | int_enable + INT_PENDING, // only meaningful if interrupts disabled TT_BITS, // see below TT[IO]_* consts TT_INPUT_INT_ENABLE, TT_OUTPUT_INT_ENABLE, -- cgit v1.2.3