From 6b45e0f81267be6140f0f178579494ca6d24443b Mon Sep 17 00:00:00 2001 From: Julian Blake Kongslie Date: Mon, 31 Oct 2022 19:55:32 -0700 Subject: Restructure a lot of the control registers --- isa/checker.cpp | 4 ++-- isa/ctlreg.def | 10 ++++------ isa/decode.cpp | 45 ++++++++++++++++++++++++++++----------------- isa/isa.h | 20 ++++++++++++++++++-- 4 files changed, 52 insertions(+), 27 deletions(-) (limited to 'isa') diff --git a/isa/checker.cpp b/isa/checker.cpp index 6eaa15f..c6ab161 100644 --- a/isa/checker.cpp +++ b/isa/checker.cpp @@ -9,7 +9,7 @@ void checker::execute() { if (ctlregs[HALTED]) return; - inst = decode(ctlregs[DATA_INSTRUCTION_FIELD_BUFFER], + inst = decode(ctlregs[FLAGS], pc, mem.fetch(pc), interrupt); @@ -21,7 +21,7 @@ void checker::execute() { addr = (addr + 1) & 07777; mem.store(*inst.init_address, addr); } - auto df = ctlregs[DATA_INSTRUCTION_FIELD_BUFFER] >> 3; + auto df = (ctlregs[FLAGS] & FLAG_DF) >> FLAG_DF_SHIFT; inst.final_address = (df << 12) | addr; } else { assert(!inst.need_autoinc_store); diff --git a/isa/ctlreg.def b/isa/ctlreg.def index d490073..e379b21 100644 --- a/isa/ctlreg.def +++ b/isa/ctlreg.def @@ -1,7 +1,5 @@ -REG(DATA_INSTRUCTION_FIELD_BUFFER) // (df << 3) | if_buffer -REG(DATA_INSTRUCTION_FIELD_SAVED) // (df_saved << 3) | if_saved +REG(FLAGS) // see FLAG_* consts in isa/isa.h +REG(FLAGS_SAVED) // see FLAG_* consts in isa/isa.h REG(HALTED) -REG(INT_ENABLE) // (int_enable_delay << 1) | int_enable -REG(INT_PENDING) // only meaningful if interrupts disabled -REG(TT_BITS) // see TT[IO]_* consts in isa/isa.h -REG(TT_INT_ENABLE) // (status_enable << 1) | (int_enable) +REG(TT_BITS) // see TT[IO]_* consts in isa/isa.h +REG(TT_FLAGS) // see TTF_* consts in isa/isa.h diff --git a/isa/decode.cpp b/isa/decode.cpp index 1496364..201a684 100644 --- a/isa/decode.cpp +++ b/isa/decode.cpp @@ -1,12 +1,18 @@ #include +#include #include #include "isa/isa.h" -instruction_context decode(unsigned int dfifb, unsigned int pc, unsigned int bits, bool interrupt) +instruction_context decode(std::uint_fast32_t flags, unsigned int pc, unsigned int bits, bool interrupt) { - auto df = dfifb >> 3; - auto ifb = dfifb & 00007; + //bool gt = (flags >> 10) & 1; + //bool ir = (flags >> 9) & 1; + //bool ii = (flags >> 8) & 1; + //bool ie = (flags >> 7) & 1; + //bool u = (flags >> 6) & 1; + bool ifb = (flags >> 3) & 7; + bool df = flags & 7; instruction_context inst; inst.next_pc = (pc & ~07777) | ((pc + 1) & 07777); @@ -16,6 +22,7 @@ instruction_context decode(unsigned int dfifb, unsigned int pc, unsigned int bit assert(df == 0); assert(ifb == 0); inst.next_pc = pc; + pc = 0; } switch (bits >> 9) { @@ -79,42 +86,46 @@ instruction_context decode(unsigned int dfifb, unsigned int pc, unsigned int bit switch (bits & 07) { case 0: // SKON skip if interrupts enabled - inst.read_ctlreg = INT_ENABLE; + inst.read_ctlreg = FLAGS; inst.possibly_redirects = true; inst.ef = [](auto &ctx) { - if (ctx.ctlval.value() & 1) + if (ctx.ctlval.value() & FLAG_INT_ENABLE) 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.read_ctlreg = FLAGS; + inst.write_ctlreg = FLAGS; inst.ef = [](auto &ctx) { - ctx.ctlval.value() |= 2; + ctx.ctlval.value() |= FLAG_INT_ENABLE_DELAY; }; break; case 2: // IOFF clear int_enable and int_enable_delay - inst.write_ctlreg = INT_ENABLE; + inst.read_ctlreg = FLAGS; + inst.write_ctlreg = FLAGS; inst.ef = [](auto &ctx) { - ctx.ctlval = 0; + ctx.ctlval.value() &= ~FLAG_INT_ENABLE_DELAY & ~FLAG_INT_ENABLE; }; break; case 3: // SRQ skip if pending interrupt - inst.read_ctlreg = INT_PENDING; + inst.read_ctlreg = FLAGS; inst.possibly_redirects = true; inst.ef = [](auto &ctx) { - if (ctx.ctlval.value()) + if (ctx.ctlval.value() & FLAG_INT_REQUEST) ctx.next_pc = (ctx.next_pc & 07777) | ((ctx.next_pc + 1) & 07777); }; break; case 4: // GTF get flags + inst.read_ctlreg = FLAGS; + inst.need_read_link = true; inst.ef = [](auto &ctx) { - std::cerr << "unimplemented GTF\n"; - assert(false); + auto flags = ctx.ctlval.value(); + flags |= (unsigned int)ctx.link.value() << 11; + ctx.acc = flags; }; break; case 5: @@ -153,11 +164,11 @@ instruction_context decode(unsigned int dfifb, unsigned int pc, unsigned int bit }; break; case 5: - // KIE set TT_INT_ENABLE to the low bit of the accumulator + // KIE set TT_FLAGS from the accumulator inst.need_read_acc = true; - inst.write_ctlreg = TT_INT_ENABLE; + inst.write_ctlreg = TT_FLAGS; inst.ef = [](auto &ctx) { - ctx.ctlval = ctx.acc.value() & 3; + ctx.ctlval = ctx.acc.value(); }; break; case 6: diff --git a/isa/isa.h b/isa/isa.h index 69f8b2a..71f852e 100644 --- a/isa/isa.h +++ b/isa/isa.h @@ -26,15 +26,31 @@ const std::map ctlreg_map = { #undef REG }; +// FLAGS and FLAGS_SAVED +static constexpr unsigned int FLAG_DF_SHIFT = 0; +static constexpr std::uint_fast32_t FLAG_DF = 07 << FLAG_DF_SHIFT; +static constexpr unsigned int FLAG_IF_SHIFT = 3; +static constexpr std::uint_fast32_t FLAG_IF = 07 << FLAG_IF_SHIFT; // In FLAGS this is IFB, not IF +static constexpr std::uint_fast32_t FLAG_USER_MODE = 1 << 6; +static constexpr std::uint_fast32_t FLAG_INT_ENABLE = 1 << 7; +static constexpr std::uint_fast32_t FLAG_INT_INHIBIT = 1 << 8; +static constexpr std::uint_fast32_t FLAG_INT_REQUEST = 1 << 9; +static constexpr std::uint_fast32_t FLAG_GREATER_THAN = 1 << 10; +static constexpr std::uint_fast32_t FLAG_INT_ENABLE_DELAY = 1 << 12; + // TT_BITS static constexpr std::uint_fast32_t TTI_FLAG = 1 << 0; static constexpr std::uint_fast32_t TTO_TX = 1 << 1; static constexpr std::uint_fast32_t TTO_FLAG = 1 << 2; static constexpr unsigned int TTI_DATA_SHIFT = 8; -static constexpr unsigned int TTO_DATA_SHIFT = 16; static constexpr std::uint_fast32_t TTI_DATA = 0xff << TTI_DATA_SHIFT; +static constexpr unsigned int TTO_DATA_SHIFT = 16; static constexpr std::uint_fast32_t TTO_DATA = 0xff << TTO_DATA_SHIFT; +// TT_FLAGS +static constexpr std::uint_fast32_t TTF_INT_ENABLE = 1 << 0; +static constexpr std::uint_fast32_t TTF_STATUS_ENABLE = 1 << 1; + struct instruction_context { // Known statically at decode time bool need_indirect_load = false; // final_address = mem[init_address] @@ -65,4 +81,4 @@ struct instruction_context { std::optional mq; }; -instruction_context decode(unsigned int df, unsigned int pc, unsigned int bits, bool interrupt); +instruction_context decode(std::uint_fast32_t flags, unsigned int pc, unsigned int bits, bool interrupt); -- cgit v1.2.3