From 763beb022c799598ef4eaa9750ad259497bd2e84 Mon Sep 17 00:00:00 2001 From: Julian Blake Kongslie Date: Sat, 22 Oct 2022 22:53:26 -0700 Subject: Merge TT_INPUT and TT_OUTPUT into TT_BITS --- io/model.cpp | 14 +++++++------- isa/decode.cpp | 48 ++++++++++++++++++++++++++++++------------------ isa/isa.h | 13 +++++++++++-- 3 files changed, 48 insertions(+), 27 deletions(-) diff --git a/io/model.cpp b/io/model.cpp index eaa6ca8..e1b59ea 100644 --- a/io/model.cpp +++ b/io/model.cpp @@ -16,21 +16,21 @@ bool iomodel::interact(std::array &ctlregs) { ++time; - if (ctlregs[TT_OUTPUT] & 0x100) { + if (ctlregs[TT_BITS] & TTO_TX) { // PDP-8 doesn't really have support for 8-bit output, this is Jules' contribution - std::cout << (char)((ctlregs[TT_OUTPUT] & 0xff) ^ 0x80) << std::flush; - ctlregs[TT_OUTPUT] &= ~0x1ff; - log.emplace(time + TT_OUTPUT_DELAY, event(TT_OUTPUT, 0x200, 0)); + std::cout << (char)(((ctlregs[TT_BITS] & TTO_DATA) >> TTO_DATA_SHIFT) ^ 0x80) << std::flush; + ctlregs[TT_BITS] &= ~TTO_TX & ~TTO_DATA; + log.emplace(time + TT_OUTPUT_DELAY, event(TT_BITS, TTO_FLAG, 0)); } bool interrupt = false; if (ctlregs[INT_ENABLE] & 1) { if (ctlregs[TT_INPUT_INT_ENABLE]) { - if (ctlregs[TT_INPUT] & 0x100) + if (ctlregs[TT_BITS] & TTI_FLAG) interrupt = true; } if (ctlregs[TT_OUTPUT_INT_ENABLE]) { - if (!(ctlregs[TT_OUTPUT] & 0x400) && (ctlregs[TT_OUTPUT] & 0x200)) + if ((ctlregs[TT_BITS] & (TTO_FLAG|TTO_FLAG_OLD)) == TTO_FLAG) interrupt = true; } } @@ -40,7 +40,7 @@ bool iomodel::interact(std::array &ctlregs) { ctlregs[DATA_INSTRUCTION_FIELD_BUFFER] = 0; ctlregs[HALTED] = 0; ctlregs[INT_ENABLE] = 0; - ctlregs[TT_OUTPUT] = (ctlregs[TT_OUTPUT] & 0x200) * 3; + ctlregs[TT_BITS] |= (ctlregs[TT_BITS] & TTO_FLAG) ? TTO_FLAG_OLD : 0; } else { ctlregs[INT_ENABLE] = (ctlregs[INT_ENABLE] >> 1) * 3; } diff --git a/isa/decode.cpp b/isa/decode.cpp index dde5b74..41d125d 100644 --- a/isa/decode.cpp +++ b/isa/decode.cpp @@ -74,54 +74,66 @@ instruction_context decode(unsigned int dfifb, unsigned int pc, unsigned int bit case 6: // IOT switch ((bits >> 3) & 077) { case 004: + // TELETYPE TELEPRINTER/PUNCH switch (bits & 07) { case 0: - inst.write_ctlreg = TT_OUTPUT; + // Set TTO flag + inst.read_ctlreg = TT_BITS; + inst.write_ctlreg = TT_BITS; inst.ef = [](auto &ctx) { - ctx.ctlval = 0x600; + ctx.ctlval.value() |= TTO_FLAG | TTO_FLAG_OLD; }; break; case 1: - inst.read_ctlreg = TT_OUTPUT; + // Skip if TTO flag is set + inst.read_ctlreg = TT_BITS; inst.possibly_redirects = true; inst.ef = [](auto &ctx) { - if (ctx.ctlval.value() & 0x200) + if (ctx.ctlval.value() & TTO_FLAG) ctx.next_pc = (ctx.next_pc & ~07777) | ((ctx.next_pc + 1) & 07777); }; break; case 2: - inst.write_ctlreg = TT_OUTPUT; + // Clear TTO flag + inst.read_ctlreg = TT_BITS; + inst.write_ctlreg = TT_BITS; inst.ef = [](auto &ctx) { - ctx.ctlval = 0; + ctx.ctlval.value() &= ~TTO_FLAG & ~TTO_FLAG_OLD; }; break; case 4: + // Print to TTO inst.need_read_acc = true; - inst.read_ctlreg = TT_OUTPUT; - inst.write_ctlreg = TT_OUTPUT; + inst.read_ctlreg = TT_BITS; + inst.write_ctlreg = TT_BITS; inst.ef = [](auto &ctx) { auto &x = ctx.ctlval.value(); - x &= ~0x1ff; - x |= (ctx.acc.value() & 0xff) ^ 0x80; // 0x7f instead of 0xff for real PDP-8 IO - x |= 0x100; + auto chr = ctx.acc.value() ^ 0x80; + x &= ~TTO_DATA; + x |= (chr << TTO_DATA_SHIFT) & TTO_DATA; + x |= TTO_TX; }; break; case 5: + // Skip if TTO flag is set or TTI flag is set + inst.read_ctlreg = TT_BITS; inst.possibly_redirects = true; - // FIXME this instruction wants to read both TT_OUTPUT and TT_INPUT inst.ef = [](auto &ctx) { - assert(false); + if (ctx.ctlval.value() & (TTI_FLAG | TTO_FLAG)) + ctx.next_pc = (ctx.next_pc & ~07777) | ((ctx.next_pc + 1) & 07777); }; break; case 6: + // Print to TTO and clear TTO flag inst.need_read_acc = true; - inst.read_ctlreg = TT_OUTPUT; - inst.write_ctlreg = TT_OUTPUT; + inst.read_ctlreg = TT_BITS; + inst.write_ctlreg = TT_BITS; inst.ef = [](auto &ctx) { auto &x = ctx.ctlval.value(); - x &= ~0x7ff; - x |= (ctx.acc.value() & 0xff) ^ 0x80; - x |= 0x100; + auto chr = ctx.acc.value() ^ 0x80; + x &= ~TTO_FLAG & ~TTO_FLAG_OLD & ~TTO_DATA; + x |= (chr << TTO_DATA_SHIFT) & TTO_DATA; + x |= TTO_TX; }; break; default: diff --git a/isa/isa.h b/isa/isa.h index bea484e..24ed108 100644 --- a/isa/isa.h +++ b/isa/isa.h @@ -8,14 +8,23 @@ enum ctlreg { DATA_INSTRUCTION_FIELD_SAVED, // (df_saved << 3) | if_saved HALTED, INT_ENABLE, // (int_enable_delay << 1) | int_enable - TT_INPUT, // (tti_flag << 8) | tti_buffer + TT_BITS, // see below TT[IO]_* consts TT_INPUT_INT_ENABLE, - TT_OUTPUT, // {tto_flag_old, tto_flag, tto_tx, tto_data} TT_OUTPUT_INT_ENABLE, NUM_CTLREGS, }; +// TT_BITS +static constexpr unsigned int TTI_FLAG = 1 << 0; +static constexpr unsigned int TTO_TX = 1 << 1; +static constexpr unsigned int TTO_FLAG = 1 << 2; +static constexpr unsigned int TTO_FLAG_OLD = 1 << 3; +static constexpr unsigned int TTI_DATA_SHIFT = 8; +static constexpr unsigned int TTO_DATA_SHIFT = 16; +static constexpr unsigned int TTI_DATA = 0xff << TTI_DATA_SHIFT; +static constexpr unsigned int TTO_DATA = 0xff << TTO_DATA_SHIFT; + struct instruction_context { // Known statically at decode time bool need_indirect_load = false; // final_address = mem[init_address] -- cgit v1.2.3