From 269e803f5e3adf54b46bf711380e970f8a75f369 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sun, 26 Mar 2023 14:26:16 +0200 Subject: [PATCH] tty fixes --- tty.cpp | 58 ++++++++++++++++++++++++++++++++++++++++++--------------- tty.h | 12 ++++++++++-- 2 files changed, 53 insertions(+), 17 deletions(-) diff --git a/tty.cpp b/tty.cpp index 5aeacef..3e3f112 100644 --- a/tty.cpp +++ b/tty.cpp @@ -23,10 +23,15 @@ tty::tty(console *const c, bus *const b) : c(c), b(b) { + th = new std::thread(std::ref(*this)); } tty::~tty() { + stop_flag = true; + + th->join(); + delete th; } uint8_t tty::readByte(const uint16_t addr) @@ -44,27 +49,31 @@ uint16_t tty::readWord(const uint16_t addr) const int reg = (addr - PDP11TTY_BASE) / 2; uint16_t vtemp = registers[reg]; - if (have_char_1) { - have_char_1 = false; - have_char_2 = true; - } - else if (have_char_2 == false) { - have_char_1 = c->poll_char(); - } - if (addr == PDP11TTY_TKS) { - vtemp = (have_char_2 ? 1 << 7 : 0) | (have_char_1 ? 1 << 11 : 0); + std::unique_lock lck(chars_lock); + + bool have_char = chars.empty() == false; + + vtemp &= ~128; + vtemp |= have_char ? 128 : 0; } else if (addr == PDP11TTY_TKB) { - if (have_char_2) { - uint8_t ch = c->get_char(); + std::unique_lock lck(chars_lock); + + if (chars.empty()) + vtemp = 0; + else { + uint8_t ch = chars.front(); + chars.erase(chars.begin()); vtemp = ch | (parity(ch) << 7); - have_char_2 = false; - } - else { - vtemp = 0; + if (chars.empty() == false) { + registers[(PDP11TTY_TKS - PDP11TTY_BASE) / 2] |= 128; + + if (registers[(PDP11TTY_TKS - PDP11TTY_BASE) / 2] & 64) + b->getCpu()->queue_interrupt(4, 060); + } } } else if (addr == PDP11TTY_TPS) { @@ -78,6 +87,25 @@ uint16_t tty::readWord(const uint16_t addr) return vtemp; } +void tty::operator()() +{ + while(!stop_flag) { + if (c->poll_char()) { + std::unique_lock lck(chars_lock); + + chars.push_back(c->get_char()); + + registers[(PDP11TTY_TKS - PDP11TTY_BASE) / 2] |= 128; + + if (registers[(PDP11TTY_TKS - PDP11TTY_BASE) / 2] & 64) + b->getCpu()->queue_interrupt(4, 060); + } + else { + myusleep(100000); + } + } +} + void tty::writeByte(const uint16_t addr, const uint8_t v) { uint16_t vtemp = registers[(addr - PDP11TTY_BASE) / 2]; diff --git a/tty.h b/tty.h index 33f230f..ec4d217 100644 --- a/tty.h +++ b/tty.h @@ -2,9 +2,13 @@ // Released under Apache License v2.0 #pragma once +#include +#include #include #include #include +#include +#include #include "bus.h" #include "console.h" @@ -24,9 +28,11 @@ class tty private: console *const c { nullptr }; bus *const b { nullptr }; - bool have_char_1 { false }; // RCVR BUSY bit high (11) - bool have_char_2 { false }; // RCVR DONE bit high (7) + std::mutex chars_lock; + std::vector chars; uint16_t registers[4] { 0 }; + std::thread *th { nullptr }; + std::atomic_bool stop_flag { false }; public: tty(console *const c, bus *const b); @@ -37,4 +43,6 @@ public: void writeByte(const uint16_t addr, const uint8_t v); void writeWord(const uint16_t addr, uint16_t v); + + void operator()(); };