diff --git a/CMakeLists.txt b/CMakeLists.txt index ad215c2..32b5926 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,6 +15,7 @@ add_executable( cpu.cpp debugger.cpp error.cpp + kw11-l.cpp main.cpp memory.cpp rk05.cpp diff --git a/bus.cpp b/bus.cpp index 06e8570..e08e8c8 100644 --- a/bus.cpp +++ b/bus.cpp @@ -80,8 +80,7 @@ uint16_t bus::read(const uint16_t a, const bool word_mode, const bool use_prev, if (a == 0177546) { // line frequency clock and status register D(fprintf(stderr, "read line freq clock\n");) - CSR |= 128; - return CSR; + return lf_csr; } if (a == 0177514) { // printer, CSR register, LP11 @@ -533,8 +532,8 @@ uint16_t bus::write(const uint16_t a, const bool word_mode, uint16_t value, cons if (a == 0177546) { // line frequency clock and status register D(fprintf(stderr, "write set LFC/SR: %o\n", value);) - CSR = value; - return CSR; + lf_csr = value; + return lf_csr; } if (tm11 && a >= TM_11_BASE && a < TM_11_END) { @@ -721,3 +720,13 @@ void bus::writeUnibusByte(const uint16_t a, const uint8_t v) { m->writeByte(a, v); } + +void bus::set_lf_crs_b7() +{ + lf_csr |= 128; +} + +uint8_t bus::get_lf_crs() +{ + return lf_csr; +} diff --git a/bus.h b/bus.h index ad593f7..0ce7138 100644 --- a/bus.h +++ b/bus.h @@ -36,6 +36,8 @@ private: uint16_t switch_register { 0 }; + uint16_t lf_csr { 0 }; + bool debug_mode { false }; public: @@ -58,6 +60,9 @@ public: void init(); // invoked by 'RESET' command + void set_lf_crs_b7(); + uint8_t get_lf_crs(); + uint16_t read(const uint16_t a, const bool word_mode, const bool use_prev, const bool peek_only=false); uint16_t readByte(const uint16_t a) { return read(a, true, false); } uint16_t readWord(const uint16_t a); diff --git a/cpu.cpp b/cpu.cpp index d58f2fd..d520a34 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -247,6 +247,8 @@ void cpu::setPSW(const uint16_t v, const bool limited) bool cpu::check_queued_interrupts() { + std::unique_lock lck(qi_lock); + uint8_t current_level = getPSW_spl(); // uint8_t start_level = current_level <= 3 ? 0 : current_level + 1; @@ -273,6 +275,8 @@ bool cpu::check_queued_interrupts() void cpu::queue_interrupt(const uint8_t level, const uint8_t vector) { + std::unique_lock lck(qi_lock); + auto it = queued_interrupts.find(level); it->second.insert(vector); diff --git a/cpu.h b/cpu.h index ecb2f77..0d27c11 100644 --- a/cpu.h +++ b/cpu.h @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -27,6 +28,7 @@ private: // level, vector std::map > queued_interrupts; + std::mutex qi_lock; std::set breakpoints; diff --git a/kw11-l.cpp b/kw11-l.cpp new file mode 100644 index 0000000..18637b6 --- /dev/null +++ b/kw11-l.cpp @@ -0,0 +1,31 @@ +#include + +#include "cpu.h" +#include "kw11-l.h" + + +kw11_l::kw11_l(bus *const b) : b(b) +{ + th = new std::thread(std::ref(*this)); +} + +kw11_l::~kw11_l() +{ + stop_flag = true; + + th->join(); + + delete th; +} + +void kw11_l::operator()() +{ + while(!stop_flag) { + b->set_lf_crs_b7(); + + if (b->get_lf_crs() & 64) + b->getCpu()->queue_interrupt(6, 0100); + + usleep(1000000 / 50); + } +} diff --git a/kw11-l.h b/kw11-l.h new file mode 100644 index 0000000..88158db --- /dev/null +++ b/kw11-l.h @@ -0,0 +1,19 @@ +#include +#include + +#include "bus.h" + + +class kw11_l +{ +private: + bus *const b { nullptr }; + std::thread * th { nullptr }; + std::atomic_bool stop_flag { false }; + +public: + kw11_l(bus *const b); + virtual ~kw11_l(); + + void operator()(); +}; diff --git a/main.cpp b/main.cpp index c3fc893..4a4ff9f 100644 --- a/main.cpp +++ b/main.cpp @@ -13,6 +13,7 @@ #include "cpu.h" #include "debugger.h" #include "gen.h" +#include "kw11-l.h" #include "memory.h" #include "terminal.h" #include "tests.h" @@ -160,9 +161,12 @@ int main(int argc, char *argv[]) //setlocale(LC_ALL, ""); bus *b = new bus(); + cpu *c = new cpu(b, &event); b->add_cpu(c); + kw11_l *lf = new kw11_l(b); + c -> setEmulateMFPT(true); std::vector rk05_files;