From 06b5c027d38401234e9198aec44a78d4f33a7a5c Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Tue, 21 Mar 2023 15:07:51 +0100 Subject: [PATCH 01/19] do not run trap when 4 upper bits of MMR0 are set (any of them), also set bit 12 when there is a case for traping --- bus.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bus.cpp b/bus.cpp index 81b0818..a4d07e5 100644 --- a/bus.cpp +++ b/bus.cpp @@ -435,9 +435,11 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c if (do_trap) { DOLOG(debug, true, "TRAP(0250) (throw 1) for access_control %d on address %06o", access_control, a); - if (MMR0 & (1 << 9)) + if ((MMR0 & (1 << 9)) && (MMR0 & 0xf000) == 0) c->schedule_trap(0250); // invalid address + MMR0 |= 1 << 12; // set trap-flag + if (is_write) pages[run_mode][d][apf].pdr |= 1 << 7; From 10ce535813487abbe342a5e4dd11c69c9a558793 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Tue, 21 Mar 2023 16:20:06 +0100 Subject: [PATCH 02/19] explicit logging of schedule_trap --- cpu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpu.cpp b/cpu.cpp index d035a60..eaa9c23 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -1591,7 +1591,7 @@ bool cpu::misc_operations(const uint16_t instr) void cpu::schedule_trap(const uint16_t vector) { - DOLOG(debug, false, "schedule_trap @ %06o", pc); + DOLOG(debug, true, "schedule_trap @ %06o", pc); scheduled_trap = vector; } From 7ea2fa0033c603dc4855f7d5d7806a508b4bc1ec Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Tue, 21 Mar 2023 18:09:36 +0100 Subject: [PATCH 03/19] only execute trap when MRR0_bit_9 AND MMR0_&_0xf000 == 0 --- bus.cpp | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/bus.cpp b/bus.cpp index a4d07e5..2c53d54 100644 --- a/bus.cpp +++ b/bus.cpp @@ -433,12 +433,19 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c } if (do_trap) { - DOLOG(debug, true, "TRAP(0250) (throw 1) for access_control %d on address %06o", access_control, a); + bool do_trap_250 = false; - if ((MMR0 & (1 << 9)) && (MMR0 & 0xf000) == 0) - c->schedule_trap(0250); // invalid address + if ((MMR0 & (1 << 9)) && (MMR0 & 0xf000) == 0) { + DOLOG(debug, true, "TRAP(0250) (throw 1) for access_control %d on address %06o", access_control, a); - MMR0 |= 1 << 12; // set trap-flag + do_trap_250 = true; + } + else { + DOLOG(debug, true, "A.C.F. triggger for %d on address %06o", access_control, a); + } + + if (access_control == 1 || access_control == 4 || access_control == 5) + MMR0 |= 1 << 12; // set trap-flag if (is_write) pages[run_mode][d][apf].pdr |= 1 << 7; @@ -459,7 +466,11 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c DOLOG(debug, true, "MMR0: %06o", MMR0); - throw 1; + if (do_trap_250) { + c->schedule_trap(0250); // invalid address + + throw 1; + } } } From 253d8437ebb0bad375f9b86c6bc7951bb835e7d4 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Tue, 21 Mar 2023 19:34:58 +0100 Subject: [PATCH 04/19] throw exception when scheduling trap 004 for non existing pages --- bus.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/bus.cpp b/bus.cpp index 2c53d54..4309dc5 100644 --- a/bus.cpp +++ b/bus.cpp @@ -17,7 +17,7 @@ // see also https://github.com/espressif/esp-idf/issues/1934 constexpr int n_pages = 12; #else -constexpr int n_pages = 128; // 1MB +constexpr int n_pages = 32; // 32=256kB (for EKBEEx.BIC) #endif constexpr uint16_t di_ena_mask[4] = { 4, 2, 0, 1 }; @@ -309,8 +309,11 @@ uint16_t bus::read(const uint16_t a, const bool word_mode, const bool use_prev, uint32_t m_offset = calculate_physical_address(run_mode, a, !peek_only, false, peek_only, space == d_space); if (peek_only == false && m_offset >= n_pages * 8192) { - if (!peek_only) DOLOG(debug, false, "Read non existing mapped memory (%o >= %o)", m_offset, n_pages * 8192); + if (!peek_only) DOLOG(debug, true, "Read non existing mapped memory (%o >= %o)", m_offset, n_pages * 8192); + c->schedule_trap(004); // no such memory + + throw 6; } if (word_mode) From 5bad90a820aba663cb8c1294b78e487b3eca769c Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Tue, 21 Mar 2023 19:40:32 +0100 Subject: [PATCH 05/19] lock MMR2 when upper 3 bits of MMR0 are set (any of them) --- bus.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bus.cpp b/bus.cpp index 4309dc5..e167834 100644 --- a/bus.cpp +++ b/bus.cpp @@ -361,7 +361,8 @@ void bus::clearMMR0Bit(const int bit) void bus::setMMR2(const uint16_t value) { - MMR2 = value; + if ((MMR0 & 0xe000) == 0) + MMR2 = value; } void bus::check_odd_addressing(const uint16_t a, const int run_mode, const d_i_space_t space, const bool is_write) From a9b42ff1d723926b1a8e70a691e2be8223589080 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Tue, 21 Mar 2023 20:31:55 +0100 Subject: [PATCH 06/19] MFPT is no longer switchable --- ESP32/main.ino | 2 -- 1 file changed, 2 deletions(-) diff --git a/ESP32/main.ino b/ESP32/main.ino index 9ae4471..e3197c5 100644 --- a/ESP32/main.ino +++ b/ESP32/main.ino @@ -181,8 +181,6 @@ void setup() { Serial.println(F("Connect CPU to BUS")); b->add_cpu(c); - c->setEmulateMFPT(true); - Serial.println(F("Init console")); cnsl = new console_esp32(&stop_event, b); From cf420ca726efed6f19d1eae937a2676d269a67cf Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Tue, 21 Mar 2023 21:07:36 +0100 Subject: [PATCH 07/19] d/i index 0 for i is more logical? because it is default mode. --- bus.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bus.h b/bus.h index f60921d..3aa583e 100644 --- a/bus.h +++ b/bus.h @@ -56,7 +56,7 @@ class cpu; class memory; class tty; -typedef enum { d_space, i_space } d_i_space_t; +typedef enum { i_space, d_space } d_i_space_t; typedef struct { uint16_t virtual_address; From a6728418657672ad67960d49921e03b588bc38c1 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Tue, 21 Mar 2023 21:16:41 +0100 Subject: [PATCH 08/19] clean-up --- bus.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/bus.cpp b/bus.cpp index e167834..d9b1830 100644 --- a/bus.cpp +++ b/bus.cpp @@ -428,11 +428,9 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c bool do_trap = false; - if (access_control == 0) + if (is_write && access_control != 6) // write do_trap = true; - else if (is_write && access_control != 6) // write - do_trap = true; - else if (!is_write && (access_control == 0 || access_control == 1 || access_control == 3 || access_control == 4 || access_control == 7)) { + else if (!is_write && (access_control == 0 || access_control == 1 || access_control == 3 || access_control == 4 || access_control == 7)) { // read do_trap = true; } From 6236d96b8328b9923fe8661f5d1190a5725de243 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Tue, 21 Mar 2023 21:45:25 +0100 Subject: [PATCH 09/19] disk backend --- CMakeLists.txt | 2 ++ disk_backend.cpp | 9 +++++ disk_backend.h | 16 +++++++++ disk_backend_file.cpp | 30 ++++++++++++++++ disk_backend_file.h | 18 ++++++++++ main.cpp | 10 +++--- rk05.cpp | 82 +++++++------------------------------------ rk05.h | 21 +++++------ rl02.cpp | 75 ++++++--------------------------------- rl02.h | 16 +++------ 10 files changed, 117 insertions(+), 162 deletions(-) create mode 100644 disk_backend.cpp create mode 100644 disk_backend.h create mode 100644 disk_backend_file.cpp create mode 100644 disk_backend_file.h diff --git a/CMakeLists.txt b/CMakeLists.txt index c81070e..e3bdc7c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,8 @@ add_executable( console_posix.cpp cpu.cpp debugger.cpp + disk_backend.cpp + disk_backend_file.cpp error.cpp kw11-l.cpp loaders.cpp diff --git a/disk_backend.cpp b/disk_backend.cpp new file mode 100644 index 0000000..b516e61 --- /dev/null +++ b/disk_backend.cpp @@ -0,0 +1,9 @@ +#include "disk_backend.h" + +disk_backend::disk_backend() +{ +} + +disk_backend::~disk_backend() +{ +} diff --git a/disk_backend.h b/disk_backend.h new file mode 100644 index 0000000..080c472 --- /dev/null +++ b/disk_backend.h @@ -0,0 +1,16 @@ +#pragma once + +#include +#include + + +class disk_backend +{ +public: + disk_backend(); + virtual ~disk_backend(); + + virtual bool read(const off_t offset, const size_t n, uint8_t *const target) = 0; + + virtual bool write(const off_t offset, const size_t n, const uint8_t *const from) = 0; +}; diff --git a/disk_backend_file.cpp b/disk_backend_file.cpp new file mode 100644 index 0000000..ed9a7db --- /dev/null +++ b/disk_backend_file.cpp @@ -0,0 +1,30 @@ +#include +#include + +#include "disk_backend_file.h" +#include "log.h" + + +disk_backend_file::disk_backend_file(const std::string & filename) : + fd(open(filename.c_str(), O_RDWR)) +{ +} + +disk_backend_file::~disk_backend_file() +{ + close(fd); +} + +bool disk_backend_file::read(const off_t offset, const size_t n, uint8_t *const target) +{ + DOLOG(debug, false, "disk_backend_file::read: read %zu bytes from offset %zu", n, offset); + + return pread(fd, target, n, offset) == ssize_t(n); +} + +bool disk_backend_file::write(const off_t offset, const size_t n, const uint8_t *const from) +{ + DOLOG(debug, false, "disk_backend_file::write: write %zu bytes to offset %zu", n, offset); + + return pwrite(fd, from, n, offset) == ssize_t(n); +} diff --git a/disk_backend_file.h b/disk_backend_file.h new file mode 100644 index 0000000..9f13227 --- /dev/null +++ b/disk_backend_file.h @@ -0,0 +1,18 @@ +#include + +#include "disk_backend.h" + + +class disk_backend_file : public disk_backend +{ +private: + const int fd { -1 }; + +public: + disk_backend_file(const std::string & filename); + virtual ~disk_backend_file(); + + bool read(const off_t offset, const size_t n, uint8_t *const target); + + bool write(const off_t offset, const size_t n, const uint8_t *const from); +}; diff --git a/main.cpp b/main.cpp index a640920..1c38638 100644 --- a/main.cpp +++ b/main.cpp @@ -12,6 +12,8 @@ #include "console_posix.h" #include "cpu.h" #include "debugger.h" +#include "disk_backend.h" +#include "disk_backend_file.h" #include "gen.h" #include "kw11-l.h" #include "loaders.h" @@ -59,8 +61,8 @@ int main(int argc, char *argv[]) { //setlocale(LC_ALL, ""); - std::vector rk05_files; - std::vector rl02_files; + std::vector rk05_files; + std::vector rl02_files; bool run_debugger = false; bool tracing = false; @@ -132,11 +134,11 @@ int main(int argc, char *argv[]) break; case 'R': - rk05_files.push_back(optarg); + rk05_files.push_back(new disk_backend_file(optarg)); break; case 'r': - rl02_files.push_back(optarg); + rl02_files.push_back(new disk_backend_file(optarg)); break; case 'p': diff --git a/rk05.cpp b/rk05.cpp index 4d07db9..9b3fd51 100644 --- a/rk05.cpp +++ b/rk05.cpp @@ -22,42 +22,21 @@ static const char * const regnames[] = { "RK05_DATABUF " }; -rk05::rk05(const std::vector & files, bus *const b, std::atomic_bool *const disk_read_acitivity, std::atomic_bool *const disk_write_acitivity) : +rk05::rk05(const std::vector & files, bus *const b, std::atomic_bool *const disk_read_acitivity, std::atomic_bool *const disk_write_acitivity) : b(b), disk_read_acitivity(disk_read_acitivity), disk_write_acitivity(disk_write_acitivity) { - memset(registers, 0x00, sizeof registers); + memset(registers, 0x00, sizeof registers ); memset(xfer_buffer, 0x00, sizeof xfer_buffer); - for(auto file : files) { -#if defined(ESP32) - File32 *fh = new File32(); - - if (!fh->open(file.c_str(), O_RDWR)) { - delete fh; - error_exit(true, "rk05: cannot open \"%s\"", file.c_str()); - } -#else - FILE *fh = fopen(file.c_str(), "rb"); - if (!fh) - error_exit(true, "rk05: cannot open \"%s\"", file.c_str()); -#endif - - fhs.push_back(fh); - } + fhs = files; } rk05::~rk05() { - for(auto fh : fhs) { -#if defined(ESP32) - fh->close(); + for(auto fh : fhs) delete fh; -#else - fclose(fh); -#endif - } } uint8_t rk05::readByte(const uint16_t addr) @@ -158,19 +137,8 @@ void rk05::writeWord(const uint16_t addr, uint16_t v) for(size_t i=0; ireadUnibusByte(memoff + i); -#if defined(ESP32) - File32 *fh = fhs.at(device); - if (!fh->seek(diskoffb)) - DOLOG(ll_error, true, "RK05 seek error %s", strerror(errno)); - if (fh->write(xfer_buffer, reclen) != reclen) - DOLOG(ll_error, true, "RK05 fwrite error %s", strerror(errno)); -#else - FILE *fh = fhs.at(device); - if (fseek(fh, diskoffb, SEEK_SET) == -1) - DOLOG(ll_error, true, "RK05 seek error %s", strerror(errno)); - if (fwrite(xfer_buffer, 1, reclen, fh) != reclen) - DOLOG(ll_error, true, "RK05 fwrite error %s", strerror(errno)); -#endif + if (!fhs.at(device)->write(diskoffb, reclen, xfer_buffer)) + DOLOG(ll_error, true, "RK05 pwrite error %s", strerror(errno)); if (v & 2048) DOLOG(debug, true, "RK05 inhibit BA increase"); @@ -194,43 +162,19 @@ void rk05::writeWord(const uint16_t addr, uint16_t v) DOLOG(debug, true, "RK05 drive %d position sec %d surf %d cyl %d, reclen %zo, READ from %o, mem: %o", device, sector, surface, cylinder, reclen, diskoffb, memoff); - bool proceed = true; - -#if defined(ESP32) - File32 *fh = fhs.at(device); - if (!fh->seek(diskoffb)) { - DOLOG(ll_error, true, "RK05 seek error %s", strerror(errno)); - proceed = false; - } -#else - FILE *fh = nullptr; - - if (device >= fhs.size()) - proceed = false; - else { - fh = fhs.at(device); - - if (fseek(fh, diskoffb, SEEK_SET) == -1) { - DOLOG(ll_error, true, "RK05 seek error %s", strerror(errno)); - proceed = false; - } - } -#endif + int temp_diskoffb = diskoffb; uint32_t temp = reclen; uint32_t p = memoff; - while(proceed && temp > 0) { + while(temp > 0) { uint32_t cur = std::min(uint32_t(sizeof xfer_buffer), temp); -#if defined(ESP32) - yield(); + if (!fhs.at(device)->read(temp_diskoffb, cur, xfer_buffer)) { + DOLOG(ll_error, true, "RK05 read error %s", strerror(errno)); + break; + } - if (fh->read(xfer_buffer, cur) != size_t(cur)) - DOLOG(debug, true, "RK05 fread error: %s", strerror(errno)); -#else - if (fread(xfer_buffer, 1, cur, fh) != size_t(cur)) - DOLOG(debug, true, "RK05 fread error: %s", strerror(errno)); -#endif + temp_diskoffb += cur; for(uint32_t i=0; i #include -#if defined(ESP32) -#include "esp32.h" -#endif +#include "disk_backend.h" #define RK05_DS 0177400 // drive status @@ -28,19 +26,16 @@ class bus; class rk05 { private: - bus *const b; - uint16_t registers[7]; - uint8_t xfer_buffer[512]; -#if defined(ESP32) - std::vector fhs; -#else - std::vector fhs; -#endif + bus *const b { nullptr }; + uint16_t registers [ 7]; + uint8_t xfer_buffer[512]; + std::vector fhs; + std::atomic_bool *const disk_read_acitivity { nullptr }; std::atomic_bool *const disk_write_acitivity { nullptr }; public: - rk05(const std::vector & files, bus *const b, std::atomic_bool *const disk_read_acitivity, std::atomic_bool *const disk_write_acitivity); + rk05(const std::vector & files, bus *const b, std::atomic_bool *const disk_read_acitivity, std::atomic_bool *const disk_write_acitivity); virtual ~rk05(); uint8_t readByte(const uint16_t addr); diff --git a/rl02.cpp b/rl02.cpp index 63a2642..ed81d21 100644 --- a/rl02.cpp +++ b/rl02.cpp @@ -22,7 +22,7 @@ static const char * const regnames[] = { "multipurpose " }; -rl02::rl02(const std::vector & files, bus *const b, std::atomic_bool *const disk_read_acitivity, std::atomic_bool *const disk_write_acitivity) : +rl02::rl02(const std::vector & files, bus *const b, std::atomic_bool *const disk_read_acitivity, std::atomic_bool *const disk_write_acitivity) : b(b), disk_read_acitivity(disk_read_acitivity), disk_write_acitivity(disk_write_acitivity) @@ -30,34 +30,13 @@ rl02::rl02(const std::vector & files, bus *const b, std::atomic_boo memset(registers, 0x00, sizeof registers); memset(xfer_buffer, 0x00, sizeof xfer_buffer); - for(auto file : files) { -#if defined(ESP32) - File32 *fh = new File32(); - - if (!fh->open(file.c_str(), O_RDWR)) { - delete fh; - error_exit(true, "rl02: cannot open \"%s\"", file.c_str()); - } -#else - FILE *fh = fopen(file.c_str(), "rb"); - if (!fh) - error_exit(true, "rl02: cannot open \"%s\"", file.c_str()); -#endif - - fhs.push_back(fh); - } + fhs = files; } rl02::~rl02() { - for(auto fh : fhs) { -#if defined(ESP32) - fh->close(); + for(auto fh : fhs) delete fh; -#else - fclose(fh); -#endif - } } uint8_t rl02::readByte(const uint16_t addr) @@ -138,44 +117,13 @@ void rl02::writeWord(const uint16_t addr, uint16_t v) if (command == 2) { // get status registers[(RL02_MPR - RL02_BASE) / 2] = 0; -#if 0 - if (registers[(RL02_DAR - RL02_BASE) / 2] & 2) { // get status -> load status word in MPR - registers[(RL02_MPR - RL02_BASE) / 2] = 5 | // lock on - (1 << 3) | // brushes are home - (1 << 7) | // this is an RL02 - 0; - - DOLOG(debug, true, "RL02 set MPR for status to %06o", registers[(RL02_MPR - RL02_BASE) / 2]); - } -#endif } else if (command == 6 || command == 7) { // read data / read data without header check *disk_read_acitivity = true; bool proceed = true; -#if defined(ESP32) - File32 *fh = fhs.at(device); - - if (!fh->seek(disk_offset)) { - DOLOG(ll_error, true, "RL02 seek to %d error %s", disk_offset, strerror(errno)); - - proceed = false; - } -#else - FILE *fh = nullptr; - - if (size_t(device) >= fhs.size()) - proceed = false; - else { - fh = fhs.at(device); - - if (fseek(fh, disk_offset, SEEK_SET) == -1) { - DOLOG(ll_error, true, "RL02 seek error %s", strerror(errno)); - proceed = false; - } - } -#endif + uint32_t temp_disk_offset = disk_offset; uint32_t memory_address = registers[(RL02_BAR - RL02_BASE) / 2]; @@ -187,19 +135,16 @@ void rl02::writeWord(const uint16_t addr, uint16_t v) while(proceed && count > 0) { uint32_t cur = std::min(uint32_t(sizeof xfer_buffer), count); -#if defined(ESP32) - yield(); - - if (fh->read(xfer_buffer, cur) != size_t(cur)) - DOLOG(info, true, "RL02 fread error: %s", strerror(errno)); -#else - if (fread(xfer_buffer, 1, cur, fh) != size_t(cur)) - DOLOG(info, true, "RL02 fread error: %s", strerror(errno)); -#endif + if (!fhs.at(device)->read(temp_disk_offset, cur, xfer_buffer)) { + DOLOG(ll_error, true, "RL02 read error %s", strerror(errno)); + break; + } for(uint32_t i=0; iwriteByte(p, xfer_buffer[i]); + temp_disk_offset += cur; + count -= cur; } diff --git a/rl02.h b/rl02.h index d0da43e..770a85a 100644 --- a/rl02.h +++ b/rl02.h @@ -1,4 +1,4 @@ -// (C) 2022 by Folkert van Heusden +// (C) 2023 by Folkert van Heusden // Released under Apache License v2.0 #pragma once @@ -8,9 +8,8 @@ #include #include -#if defined(ESP32) -#include "esp32.h" -#endif +#include "disk_backend.h" + #define RL02_CSR 0174400 // control status register #define RL02_BAR 0174402 // bus address register @@ -27,12 +26,7 @@ private: bus *const b; uint16_t registers[4]; uint8_t xfer_buffer[512]; - -#if defined(ESP32) - std::vector fhs; -#else - std::vector fhs; -#endif + std::vector fhs; std::atomic_bool *const disk_read_acitivity { nullptr }; std::atomic_bool *const disk_write_acitivity { nullptr }; @@ -40,7 +34,7 @@ private: uint32_t calcOffset(uint16_t); public: - rl02(const std::vector & files, bus *const b, std::atomic_bool *const disk_read_acitivity, std::atomic_bool *const disk_write_acitivity); + rl02(const std::vector & files, bus *const b, std::atomic_bool *const disk_read_acitivity, std::atomic_bool *const disk_write_acitivity); virtual ~rl02(); uint8_t readByte(const uint16_t addr); From 8278c8d308c16151ee3964d42575245813e3ea08 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Tue, 21 Mar 2023 22:02:15 +0100 Subject: [PATCH 10/19] ESP32 --- ESP32/disk_backend.cpp | 1 + ESP32/disk_backend.h | 1 + ESP32/disk_backend_esp32.cpp | 83 ++++++++++++++++++++++++++++++++++++ ESP32/disk_backend_esp32.h | 19 +++++++++ ESP32/esp32.h | 3 ++ ESP32/main.ino | 8 ++-- debugger.cpp | 2 + kw11-l.cpp | 5 +++ rk05.cpp | 8 ---- rl02.cpp | 8 ---- 10 files changed, 119 insertions(+), 19 deletions(-) create mode 120000 ESP32/disk_backend.cpp create mode 120000 ESP32/disk_backend.h create mode 100644 ESP32/disk_backend_esp32.cpp create mode 100644 ESP32/disk_backend_esp32.h diff --git a/ESP32/disk_backend.cpp b/ESP32/disk_backend.cpp new file mode 120000 index 0000000..6acc92c --- /dev/null +++ b/ESP32/disk_backend.cpp @@ -0,0 +1 @@ +../disk_backend.cpp \ No newline at end of file diff --git a/ESP32/disk_backend.h b/ESP32/disk_backend.h new file mode 120000 index 0000000..288f0e0 --- /dev/null +++ b/ESP32/disk_backend.h @@ -0,0 +1 @@ +../disk_backend.h \ No newline at end of file diff --git a/ESP32/disk_backend_esp32.cpp b/ESP32/disk_backend_esp32.cpp new file mode 100644 index 0000000..e0aa2fc --- /dev/null +++ b/ESP32/disk_backend_esp32.cpp @@ -0,0 +1,83 @@ +#include +#include + +#include "disk_backend_esp32.h" +#include "error.h" +#include "log.h" + + +disk_backend_esp32::disk_backend_esp32(const std::string & filename) : + fh(new File32()) +{ + if (!fh->open(filename.c_str(), O_RDWR)) + error_exit(true, "rk05: cannot open \"%s\"", filename.c_str()); +} + +disk_backend_esp32::~disk_backend_esp32() +{ + fh->close(); + + delete fh; +} + +bool disk_backend_esp32::read(const off_t offset, const size_t n, uint8_t *const target) +{ + DOLOG(debug, false, "disk_backend_esp32::read: read %zu bytes from offset %zu", n, offset); + +#if defined(ESP32) + digitalWrite(LED_BUILTIN, LOW); +#endif + + if (!fh->seek(offset)) + DOLOG(ll_error, true, "seek error %s", strerror(errno)); + + yield(); + + if (fh->read(target, n) != size_t(n)) { + DOLOG(debug, true, "fread error: %s", strerror(errno)); + +#if defined(ESP32) + digitalWrite(LED_BUILTIN, HIGH); +#endif + return false; + } + + yield(); + +#if defined(ESP32) + digitalWrite(LED_BUILTIN, HIGH); +#endif + + return true; +} + +bool disk_backend_esp32::write(const off_t offset, const size_t n, const uint8_t *const from) +{ + DOLOG(debug, false, "disk_backend_esp32::write: write %zu bytes to offset %zu", n, offset); + +#if defined(ESP32) + digitalWrite(LED_BUILTIN, LOW); +#endif + + if (!fh->seek(offset)) + DOLOG(ll_error, true, "seek error %s", strerror(errno)); + + yield(); + + if (fh->write(from, n) != n) { + DOLOG(ll_error, true, "RK05 fwrite error %s", strerror(errno)); + +#if defined(ESP32) + digitalWrite(LED_BUILTIN, HIGH); +#endif + return false; + } + + yield(); + +#if defined(ESP32) + digitalWrite(LED_BUILTIN, HIGH); +#endif + + return true; +} diff --git a/ESP32/disk_backend_esp32.h b/ESP32/disk_backend_esp32.h new file mode 100644 index 0000000..a33136a --- /dev/null +++ b/ESP32/disk_backend_esp32.h @@ -0,0 +1,19 @@ +#include + +#include "disk_backend.h" +#include "esp32.h" + + +class disk_backend_esp32 : public disk_backend +{ +private: + File32 *const fh { nullptr }; + +public: + disk_backend_esp32(const std::string & filename); + virtual ~disk_backend_esp32(); + + bool read(const off_t offset, const size_t n, uint8_t *const target); + + bool write(const off_t offset, const size_t n, const uint8_t *const from); +}; diff --git a/ESP32/esp32.h b/ESP32/esp32.h index 6d8dbf0..4deb38a 100644 --- a/ESP32/esp32.h +++ b/ESP32/esp32.h @@ -1,7 +1,10 @@ #pragma once #if defined(ESP32) +#include + #include + #define USE_SDFAT #define SD_FAT_TYPE 1 #include diff --git a/ESP32/main.ino b/ESP32/main.ino index e3197c5..d0ea153 100644 --- a/ESP32/main.ino +++ b/ESP32/main.ino @@ -12,6 +12,8 @@ #include "console_esp32.h" #include "cpu.h" #include "debugger.h" +#include "disk_backend.h" +#include "disk_backend_esp32.h" #include "error.h" #include "esp32.h" #include "gen.h" @@ -104,7 +106,7 @@ void setup_wifi_stations() } // RK05, RL02 files -std::pair, std::vector > select_disk_files(console *const c) +std::pair, std::vector > select_disk_files(console *const c) { c->debug("MISO: %d", int(MISO)); c->debug("MOSI: %d", int(MOSI)); @@ -146,10 +148,10 @@ std::pair, std::vector > select_disk_files fh.close(); if (ch == '1') - return { { selected_file }, { } }; + return { { new disk_backend_esp32(selected_file) }, { } }; if (ch == '2') - return { { }, { selected_file } }; + return { { }, { new disk_backend_esp32(selected_file) } }; } c->put_string_lf("open failed"); diff --git a/debugger.cpp b/debugger.cpp index f0bb155..743e292 100644 --- a/debugger.cpp +++ b/debugger.cpp @@ -7,6 +7,8 @@ #if defined(ESP32) +#include "esp32.h" + void setBootLoader(bus *const b); #endif diff --git a/kw11-l.cpp b/kw11-l.cpp index 2f73bd7..19aa531 100644 --- a/kw11-l.cpp +++ b/kw11-l.cpp @@ -5,6 +5,11 @@ #include "kw11-l.h" #include "utils.h" +#if defined(ESP32) +#include "esp32.h" +#endif + + #if defined(ESP32) void thread_wrapper_kw11(void *p) { diff --git a/rk05.cpp b/rk05.cpp index 9b3fd51..a2d0b06 100644 --- a/rk05.cpp +++ b/rk05.cpp @@ -96,10 +96,6 @@ void rk05::writeByte(const uint16_t addr, const uint8_t v) void rk05::writeWord(const uint16_t addr, uint16_t v) { -#if defined(ESP32) - digitalWrite(LED_BUILTIN, LOW); -#endif - const int reg = (addr - RK05_BASE) / 2; registers[reg] = v; @@ -228,8 +224,4 @@ void rk05::writeWord(const uint16_t addr, uint16_t v) } } } - -#if defined(ESP32) - digitalWrite(LED_BUILTIN, HIGH); -#endif } diff --git a/rl02.cpp b/rl02.cpp index ed81d21..b0a0355 100644 --- a/rl02.cpp +++ b/rl02.cpp @@ -95,10 +95,6 @@ uint32_t rl02::calcOffset(const uint16_t da) void rl02::writeWord(const uint16_t addr, uint16_t v) { -#if defined(ESP32) - digitalWrite(LED_BUILTIN, LOW); -#endif - DOLOG(debug, true, "RL02 write %06o: %06o", addr, v); const int reg = (addr - RL02_BASE) / 2; @@ -157,8 +153,4 @@ void rl02::writeWord(const uint16_t addr, uint16_t v) *disk_read_acitivity = false; } } - -#if defined(ESP32) - digitalWrite(LED_BUILTIN, HIGH); -#endif } From 553688a983877c20615a4255c1f4c60938b6f744 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Tue, 21 Mar 2023 22:15:27 +0100 Subject: [PATCH 11/19] wip --- CMakeLists.txt | 1 + disk_backend_nbd.cpp | 44 ++++++++++++++++++++++++++++++++++++++++++++ disk_backend_nbd.h | 18 ++++++++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 disk_backend_nbd.cpp create mode 100644 disk_backend_nbd.h diff --git a/CMakeLists.txt b/CMakeLists.txt index e3bdc7c..55e709f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,6 +16,7 @@ add_executable( debugger.cpp disk_backend.cpp disk_backend_file.cpp + disk_backend_nbd.cpp error.cpp kw11-l.cpp loaders.cpp diff --git a/disk_backend_nbd.cpp b/disk_backend_nbd.cpp new file mode 100644 index 0000000..3d5d3e9 --- /dev/null +++ b/disk_backend_nbd.cpp @@ -0,0 +1,44 @@ +#include +#include + +#include "disk_backend_nbd.h" +#include "log.h" + +#ifdef ESP32 +#include +#else +#include +#endif + + +disk_backend_nbd::disk_backend_nbd(const std::string & host, const int port) : + fd(socket(AF_INET, SOCK_STREAM, 0)) +{ + struct addrinfo hints, *res; + int status; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + char *host = "esp-942daf.local"; + char *port = "5556"; + status = getaddrinfo(host, port, &hints, &res) +} + +disk_backend_nbd::~disk_backend_nbd() +{ + close(fd); +} + +bool disk_backend_nbd::read(const off_t offset, const size_t n, uint8_t *const target) +{ + DOLOG(debug, false, "disk_backend_nbd::read: read %zu bytes from offset %zu", n, offset); + + return pread(fd, target, n, offset) == ssize_t(n); +} + +bool disk_backend_nbd::write(const off_t offset, const size_t n, const uint8_t *const from) +{ + DOLOG(debug, false, "disk_backend_nbd::write: write %zu bytes to offset %zu", n, offset); + + return pwrite(fd, from, n, offset) == ssize_t(n); +} diff --git a/disk_backend_nbd.h b/disk_backend_nbd.h new file mode 100644 index 0000000..0fe8678 --- /dev/null +++ b/disk_backend_nbd.h @@ -0,0 +1,18 @@ +#include + +#include "disk_backend.h" + + +class disk_backend_nbd : public disk_backend +{ +private: + const int fd { -1 }; + +public: + disk_backend_nbd(const std::string & host, const int port); + virtual ~disk_backend_nbd(); + + bool read(const off_t offset, const size_t n, uint8_t *const target); + + bool write(const off_t offset, const size_t n, const uint8_t *const from); +}; From 4a4448e7b09d9e61508724f038d68c48bf9f0bf8 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Tue, 21 Mar 2023 22:28:43 +0100 Subject: [PATCH 12/19] disk_backend::begin() --- ESP32/disk_backend_esp32.cpp | 14 ++++++++++++-- ESP32/disk_backend_esp32.h | 5 ++++- ESP32/main.ino | 15 +++++++++++++-- disk_backend.h | 2 ++ disk_backend_file.cpp | 16 +++++++++++++++- disk_backend_file.h | 6 +++++- main.cpp | 12 ++++++++++-- 7 files changed, 61 insertions(+), 9 deletions(-) diff --git a/ESP32/disk_backend_esp32.cpp b/ESP32/disk_backend_esp32.cpp index e0aa2fc..3934c10 100644 --- a/ESP32/disk_backend_esp32.cpp +++ b/ESP32/disk_backend_esp32.cpp @@ -7,10 +7,9 @@ disk_backend_esp32::disk_backend_esp32(const std::string & filename) : + filename(filename), fh(new File32()) { - if (!fh->open(filename.c_str(), O_RDWR)) - error_exit(true, "rk05: cannot open \"%s\"", filename.c_str()); } disk_backend_esp32::~disk_backend_esp32() @@ -20,6 +19,17 @@ disk_backend_esp32::~disk_backend_esp32() delete fh; } +bool disk_backend_esp32::begin() +{ + if (!fh->open(filename.c_str(), O_RDWR)) { + DOLOG(ll_error, true, "rk05: cannot open \"%s\"", filename.c_str()); + + return false; + } + + return true; +} + bool disk_backend_esp32::read(const off_t offset, const size_t n, uint8_t *const target) { DOLOG(debug, false, "disk_backend_esp32::read: read %zu bytes from offset %zu", n, offset); diff --git a/ESP32/disk_backend_esp32.h b/ESP32/disk_backend_esp32.h index a33136a..383eccf 100644 --- a/ESP32/disk_backend_esp32.h +++ b/ESP32/disk_backend_esp32.h @@ -7,12 +7,15 @@ class disk_backend_esp32 : public disk_backend { private: - File32 *const fh { nullptr }; + const std::string filename; + File32 *const fh { nullptr }; public: disk_backend_esp32(const std::string & filename); virtual ~disk_backend_esp32(); + bool begin(); + bool read(const off_t offset, const size_t n, uint8_t *const target); bool write(const off_t offset, const size_t n, const uint8_t *const from); diff --git a/ESP32/main.ino b/ESP32/main.ino index d0ea153..985ac0e 100644 --- a/ESP32/main.ino +++ b/ESP32/main.ino @@ -147,11 +147,22 @@ std::pair, std::vector > select_disk if (fh.open(selected_file.c_str(), O_RDWR)) { fh.close(); + disk_backend *temp = new disk_backend_esp32(selected_file); + + if (!temp->begin()) { + c->put_string("Cannot use: "); + c->put_string_lf(selected_file.c_str()); + + delete temp; + + continue; + } + if (ch == '1') - return { { new disk_backend_esp32(selected_file) }, { } }; + return { { temp }, { } }; if (ch == '2') - return { { }, { new disk_backend_esp32(selected_file) } }; + return { { }, { temp } }; } c->put_string_lf("open failed"); diff --git a/disk_backend.h b/disk_backend.h index 080c472..e0d44f2 100644 --- a/disk_backend.h +++ b/disk_backend.h @@ -10,6 +10,8 @@ public: disk_backend(); virtual ~disk_backend(); + virtual bool begin() = 0; + virtual bool read(const off_t offset, const size_t n, uint8_t *const target) = 0; virtual bool write(const off_t offset, const size_t n, const uint8_t *const from) = 0; diff --git a/disk_backend_file.cpp b/disk_backend_file.cpp index ed9a7db..ee33021 100644 --- a/disk_backend_file.cpp +++ b/disk_backend_file.cpp @@ -1,4 +1,5 @@ #include +#include #include #include "disk_backend_file.h" @@ -6,7 +7,7 @@ disk_backend_file::disk_backend_file(const std::string & filename) : - fd(open(filename.c_str(), O_RDWR)) + filename(filename) { } @@ -15,6 +16,19 @@ disk_backend_file::~disk_backend_file() close(fd); } +bool disk_backend_file::begin() +{ + fd = open(filename.c_str(), O_RDWR); + + if (fd == -1) { + DOLOG(ll_error, true, "disk_backend_file: cannot open \"%s\": %s", filename.c_str(), strerror(errno)); + + return false; + } + + return true; +} + bool disk_backend_file::read(const off_t offset, const size_t n, uint8_t *const target) { DOLOG(debug, false, "disk_backend_file::read: read %zu bytes from offset %zu", n, offset); diff --git a/disk_backend_file.h b/disk_backend_file.h index 9f13227..bf1bd6d 100644 --- a/disk_backend_file.h +++ b/disk_backend_file.h @@ -6,12 +6,16 @@ class disk_backend_file : public disk_backend { private: - const int fd { -1 }; + const std::string filename; + + int fd { -1 }; public: disk_backend_file(const std::string & filename); virtual ~disk_backend_file(); + bool begin(); + bool read(const off_t offset, const size_t n, uint8_t *const target); bool write(const off_t offset, const size_t n, const uint8_t *const from); diff --git a/main.cpp b/main.cpp index 1c38638..8746e82 100644 --- a/main.cpp +++ b/main.cpp @@ -82,6 +82,8 @@ int main(int argc, char *argv[]) std::string test; + disk_backend *temp_d = nullptr; + int opt = -1; while((opt = getopt(argc, argv, "hm:T:r:R:p:ndtL:b:l:s:Q:")) != -1) { @@ -134,11 +136,17 @@ int main(int argc, char *argv[]) break; case 'R': - rk05_files.push_back(new disk_backend_file(optarg)); + temp_d = new disk_backend_file(optarg); + if (!temp_d->begin()) + error_exit(false, "Cannot use file \"%s\" for RK05", optarg); + rk05_files.push_back(temp_d); break; case 'r': - rl02_files.push_back(new disk_backend_file(optarg)); + temp_d = new disk_backend_file(optarg); + if (!temp_d->begin()) + error_exit(false, "Cannot use file \"%s\" for RL02", optarg); + rl02_files.push_back(temp_d); break; case 'p': From 06d4373fc7626686f354453014d0a46ccb8ce9a4 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Tue, 21 Mar 2023 22:38:28 +0100 Subject: [PATCH 13/19] resolve hostname --- disk_backend_nbd.cpp | 33 ++++++++++++++++++++++++--------- disk_backend_nbd.h | 13 ++++++++++--- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/disk_backend_nbd.cpp b/disk_backend_nbd.cpp index 3d5d3e9..2ad6e30 100644 --- a/disk_backend_nbd.cpp +++ b/disk_backend_nbd.cpp @@ -12,16 +12,9 @@ disk_backend_nbd::disk_backend_nbd(const std::string & host, const int port) : - fd(socket(AF_INET, SOCK_STREAM, 0)) + host(host), + port(port) { - struct addrinfo hints, *res; - int status; - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; - char *host = "esp-942daf.local"; - char *port = "5556"; - status = getaddrinfo(host, port, &hints, &res) } disk_backend_nbd::~disk_backend_nbd() @@ -29,6 +22,28 @@ disk_backend_nbd::~disk_backend_nbd() close(fd); } +bool disk_backend_nbd::begin() +{ + addrinfo *res = nullptr; + + addrinfo hints { 0 }; + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + + char port_str[8] { 0 }; + snprintf(port_str, sizeof port_str, "%d", port); + + int rc = getaddrinfo(host.c_str(), port_str, &hints, &res); + + if (rc != 0) { + DOLOG(ll_error, true, "disk_backend_nbd: cannot resolve \"%s\":%s: %s", host.c_str(), port_str, gai_strerror(rc)); + + return false; + } + + return true; +} + bool disk_backend_nbd::read(const off_t offset, const size_t n, uint8_t *const target) { DOLOG(debug, false, "disk_backend_nbd::read: read %zu bytes from offset %zu", n, offset); diff --git a/disk_backend_nbd.h b/disk_backend_nbd.h index 0fe8678..a86b89f 100644 --- a/disk_backend_nbd.h +++ b/disk_backend_nbd.h @@ -1,4 +1,7 @@ +#include #include +#include +#include #include "disk_backend.h" @@ -6,13 +9,17 @@ class disk_backend_nbd : public disk_backend { private: - const int fd { -1 }; + const std::string host; + const int port; + int fd { -1 }; public: disk_backend_nbd(const std::string & host, const int port); virtual ~disk_backend_nbd(); - bool read(const off_t offset, const size_t n, uint8_t *const target); + bool begin() override; - bool write(const off_t offset, const size_t n, const uint8_t *const from); + bool read(const off_t offset, const size_t n, uint8_t *const target) override; + + bool write(const off_t offset, const size_t n, const uint8_t *const from) override; }; From 68a7c8376e9e97e96568124df39450dbe79a7a3d Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Tue, 21 Mar 2023 22:39:19 +0100 Subject: [PATCH 14/19] override --- ESP32/disk_backend_esp32.h | 6 +++--- disk_backend_file.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ESP32/disk_backend_esp32.h b/ESP32/disk_backend_esp32.h index 383eccf..1021497 100644 --- a/ESP32/disk_backend_esp32.h +++ b/ESP32/disk_backend_esp32.h @@ -14,9 +14,9 @@ public: disk_backend_esp32(const std::string & filename); virtual ~disk_backend_esp32(); - bool begin(); + bool begin() override; - bool read(const off_t offset, const size_t n, uint8_t *const target); + bool read(const off_t offset, const size_t n, uint8_t *const target) override; - bool write(const off_t offset, const size_t n, const uint8_t *const from); + bool write(const off_t offset, const size_t n, const uint8_t *const from) override; }; diff --git a/disk_backend_file.h b/disk_backend_file.h index bf1bd6d..b239e1c 100644 --- a/disk_backend_file.h +++ b/disk_backend_file.h @@ -14,9 +14,9 @@ public: disk_backend_file(const std::string & filename); virtual ~disk_backend_file(); - bool begin(); + bool begin() override; - bool read(const off_t offset, const size_t n, uint8_t *const target); + bool read(const off_t offset, const size_t n, uint8_t *const target) override; - bool write(const off_t offset, const size_t n, const uint8_t *const from); + bool write(const off_t offset, const size_t n, const uint8_t *const from) override; }; From f61d49c98fcc4574b01dca3bca45a3a6372545b9 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Wed, 22 Mar 2023 07:33:08 +0100 Subject: [PATCH 15/19] connect --- ESP32/disk_backend_nbd.cpp | 1 + ESP32/disk_backend_nbd.h | 1 + disk_backend_nbd.cpp | 79 +++++++++++++++++++++++++++++++------- disk_backend_nbd.h | 6 +-- 4 files changed, 70 insertions(+), 17 deletions(-) create mode 120000 ESP32/disk_backend_nbd.cpp create mode 120000 ESP32/disk_backend_nbd.h diff --git a/ESP32/disk_backend_nbd.cpp b/ESP32/disk_backend_nbd.cpp new file mode 120000 index 0000000..2a6ef58 --- /dev/null +++ b/ESP32/disk_backend_nbd.cpp @@ -0,0 +1 @@ +../disk_backend_nbd.cpp \ No newline at end of file diff --git a/ESP32/disk_backend_nbd.h b/ESP32/disk_backend_nbd.h new file mode 120000 index 0000000..722191b --- /dev/null +++ b/ESP32/disk_backend_nbd.h @@ -0,0 +1 @@ +../disk_backend_nbd.h \ No newline at end of file diff --git a/disk_backend_nbd.cpp b/disk_backend_nbd.cpp index 2ad6e30..0210ca8 100644 --- a/disk_backend_nbd.cpp +++ b/disk_backend_nbd.cpp @@ -1,12 +1,15 @@ #include #include +#include #include "disk_backend_nbd.h" #include "log.h" #ifdef ESP32 +#include #include #else +#include #include #endif @@ -24,30 +27,73 @@ disk_backend_nbd::~disk_backend_nbd() bool disk_backend_nbd::begin() { - addrinfo *res = nullptr; - - addrinfo hints { 0 }; - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; - - char port_str[8] { 0 }; - snprintf(port_str, sizeof port_str, "%d", port); - - int rc = getaddrinfo(host.c_str(), port_str, &hints, &res); - - if (rc != 0) { - DOLOG(ll_error, true, "disk_backend_nbd: cannot resolve \"%s\":%s: %s", host.c_str(), port_str, gai_strerror(rc)); - + if (!connect(false)) { + DOLOG(ll_error, true, "disk_backend_nbd: cannot connect to NBD server"); return false; } + DOLOG(info, true, "disk_backend_nbd: connected to NBD server"); + return true; } +bool disk_backend_nbd::connect(const bool retry) +{ + do { + // LOOP until connected, logging message, exponential backoff? + addrinfo *res = nullptr; + + addrinfo hints { 0 }; + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + + char port_str[8] { 0 }; + snprintf(port_str, sizeof port_str, "%d", port); + + int rc = getaddrinfo(host.c_str(), port_str, &hints, &res); + + if (rc != 0) { +#ifdef ESP32 + DOLOG(ll_error, true, "disk_backend_nbd: cannot resolve \"%s\":%s", host.c_str(), port_str); +#else + DOLOG(ll_error, true, "disk_backend_nbd: cannot resolve \"%s\":%s: %s", host.c_str(), port_str, gai_strerror(rc)); +#endif + + sleep(1); + + continue; + } + + for(addrinfo *p = res; p != NULL; p = p->ai_next) { + if ((fd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) { + continue; + } + + if (::connect(fd, p->ai_addr, p->ai_addrlen) == -1) { + close(fd); + fd = -1; + DOLOG(ll_error, true, "disk_backend_nbd: cannot connect"); + continue; + } + + break; + } + + freeaddrinfo(res); + } + while(fd == -1 && retry); + + return fd != -1; +} + bool disk_backend_nbd::read(const off_t offset, const size_t n, uint8_t *const target) { DOLOG(debug, false, "disk_backend_nbd::read: read %zu bytes from offset %zu", n, offset); + connect(true); + + // TODO: loop dat als read() aangeeft dat de peer weg is, dat er dan gereconnect wordt + // anders return false return pread(fd, target, n, offset) == ssize_t(n); } @@ -55,5 +101,10 @@ bool disk_backend_nbd::write(const off_t offset, const size_t n, const uint8_t * { DOLOG(debug, false, "disk_backend_nbd::write: write %zu bytes to offset %zu", n, offset); + connect(true); + + // TODO: loop dat als write() aangeeft dat de peer weg is, dat er dan gereconnect wordt + // anders return false + return pwrite(fd, from, n, offset) == ssize_t(n); } diff --git a/disk_backend_nbd.h b/disk_backend_nbd.h index a86b89f..b5d4129 100644 --- a/disk_backend_nbd.h +++ b/disk_backend_nbd.h @@ -1,6 +1,4 @@ -#include #include -#include #include #include "disk_backend.h" @@ -10,9 +8,11 @@ class disk_backend_nbd : public disk_backend { private: const std::string host; - const int port; + const int port { 0 }; int fd { -1 }; + bool connect(const bool retry); + public: disk_backend_nbd(const std::string & host, const int port); virtual ~disk_backend_nbd(); From 89a9fbead0d4242ca4e761d2525524396c2c7ff3 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Wed, 22 Mar 2023 10:24:23 +0100 Subject: [PATCH 16/19] NBD: implemented read/write --- disk_backend_nbd.cpp | 175 +++++++++++++++++++++++++++++++++++++++++-- main.cpp | 20 ++++- utils.cpp | 47 ++++++++++++ utils.h | 3 + 4 files changed, 236 insertions(+), 9 deletions(-) diff --git a/disk_backend_nbd.cpp b/disk_backend_nbd.cpp index 0210ca8..eba79d7 100644 --- a/disk_backend_nbd.cpp +++ b/disk_backend_nbd.cpp @@ -1,9 +1,12 @@ #include +#include #include +#include #include #include "disk_backend_nbd.h" #include "log.h" +#include "utils.h" #ifdef ESP32 #include @@ -13,6 +16,9 @@ #include #endif +#define HTONLL(x) ((1==htonl(1)) ? (x) : (((uint64_t)htonl((x) & 0xFFFFFFFFUL)) << 32) | htonl((uint32_t)((x) >> 32))) +#define NTOHLL(x) ((1==ntohl(1)) ? (x) : (((uint64_t)ntohl((x) & 0xFFFFFFFFUL)) << 32) | ntohl((uint32_t)((x) >> 32))) + disk_backend_nbd::disk_backend_nbd(const std::string & host, const int port) : host(host), @@ -80,6 +86,30 @@ bool disk_backend_nbd::connect(const bool retry) } freeaddrinfo(res); + + struct __attribute__ ((packed)) { + uint8_t magic1[8]; + uint8_t magic2[8]; + uint64_t size; + uint32_t flags; + uint8_t padding[124]; + } nbd_hello; + + if (fd != -1) { + if (READ(fd, reinterpret_cast(&nbd_hello), sizeof nbd_hello) != sizeof nbd_hello) { + close(fd); + fd = -1; + DOLOG(debug, false, "disk_backend_nbd::connect: connect short read"); + } + } + + if (memcmp(nbd_hello.magic1, "NBDMAGIC", 8) != 0) { + close(fd); + fd = -1; + DOLOG(debug, false, "disk_backend_nbd::connect: magic invalid"); + } + + DOLOG(info, false, "NBD size: %u", NTOHLL(nbd_hello.size)); } while(fd == -1 && retry); @@ -90,21 +120,150 @@ bool disk_backend_nbd::read(const off_t offset, const size_t n, uint8_t *const t { DOLOG(debug, false, "disk_backend_nbd::read: read %zu bytes from offset %zu", n, offset); - connect(true); + if (n == 0) + return true; - // TODO: loop dat als read() aangeeft dat de peer weg is, dat er dan gereconnect wordt - // anders return false - return pread(fd, target, n, offset) == ssize_t(n); + do { + if (fd == -1 && !connect(true)) { + DOLOG(debug, false, "disk_backend_nbd::read: (re-)connect"); + sleep(1); + continue; + } + + struct __attribute__ ((packed)) { + uint32_t magic; + uint32_t type; + uint64_t handle; + uint64_t offset; + uint32_t length; + } nbd_request { 0 }; + + nbd_request.magic = ntohl(0x25609513); + nbd_request.type = 0; // READ + nbd_request.offset = HTONLL(uint64_t(offset)); + nbd_request.length = htonl(n); + + if (WRITE(fd, reinterpret_cast(&nbd_request), sizeof nbd_request) != sizeof nbd_request) { + DOLOG(debug, false, "disk_backend_nbd::read: problem sending request"); + close(fd); + fd = -1; + sleep(1); + continue; + } + + struct __attribute__ ((packed)) { + uint32_t magic; + uint32_t error; + uint64_t handle; + } nbd_reply; + + if (READ(fd, reinterpret_cast(&nbd_reply), sizeof nbd_reply) != sizeof nbd_reply) { + DOLOG(debug, false, "disk_backend_nbd::read: problem receiving reply header"); + close(fd); + fd = -1; + sleep(1); + continue; + } + + if (ntohl(nbd_reply.magic) != 0x67446698) { + DOLOG(debug, false, "disk_backend_nbd::read: bad reply header %08x", nbd_reply.magic); + close(fd); + fd = -1; + sleep(1); + continue; + } + + int error = ntohl(nbd_reply.error); + if (error) { + DOLOG(debug, false, "disk_backend_nbd::read: NBD server indicated error: %d", error); + return false; + } + + if (READ(fd, reinterpret_cast(target), n) != ssize_t(n)) { + DOLOG(debug, false, "disk_backend_nbd::read: problem receiving payload"); + close(fd); + fd = -1; + sleep(1); + continue; + } + } + while(fd == -1); + + return true; } bool disk_backend_nbd::write(const off_t offset, const size_t n, const uint8_t *const from) { DOLOG(debug, false, "disk_backend_nbd::write: write %zu bytes to offset %zu", n, offset); - connect(true); + if (n == 0) + return true; - // TODO: loop dat als write() aangeeft dat de peer weg is, dat er dan gereconnect wordt - // anders return false + do { + if (!connect(true)) { + DOLOG(debug, false, "disk_backend_nbd::write: (re-)connect"); + sleep(1); + continue; + } - return pwrite(fd, from, n, offset) == ssize_t(n); + struct __attribute__ ((packed)) { + uint32_t magic; + uint32_t type; + uint64_t handle; + uint64_t offset; + uint32_t length; + } nbd_request { 0 }; + + nbd_request.magic = ntohl(0x25609513); + nbd_request.type = 1; // WRITE + nbd_request.offset = HTONLL(uint64_t(offset)); + nbd_request.length = htonl(n); + + if (WRITE(fd, reinterpret_cast(&nbd_request), sizeof nbd_request) != sizeof nbd_request) { + DOLOG(debug, false, "disk_backend_nbd::write: problem sending request"); + close(fd); + fd = -1; + sleep(1); + continue; + } + + if (WRITE(fd, reinterpret_cast(from), n) != ssize_t(n)) { + DOLOG(debug, false, "disk_backend_nbd::write: problem sending payload"); + close(fd); + fd = -1; + sleep(1); + continue; + } + + struct __attribute__ ((packed)) { + uint32_t magic; + uint32_t error; + uint64_t handle; + } nbd_reply; + + if (READ(fd, reinterpret_cast(&nbd_reply), sizeof nbd_reply) != sizeof nbd_reply) { + DOLOG(debug, false, "disk_backend_nbd::write: problem receiving reply header"); + close(fd); + fd = -1; + sleep(1); + continue; + } + + if (ntohl(nbd_reply.magic) != 0x67446698) { + DOLOG(debug, false, "disk_backend_nbd::write: bad reply header %08x", nbd_reply.magic); + close(fd); + fd = -1; + sleep(1); + continue; + } + + int error = ntohl(nbd_reply.error); + if (error) { + DOLOG(debug, false, "disk_backend_nbd::write: NBD server indicated error: %d", error); + return false; + } + } + while(fd == -1); + + return true; } diff --git a/main.cpp b/main.cpp index 8746e82..c2fef1b 100644 --- a/main.cpp +++ b/main.cpp @@ -14,6 +14,7 @@ #include "debugger.h" #include "disk_backend.h" #include "disk_backend_file.h" +#include "disk_backend_nbd.h" #include "gen.h" #include "kw11-l.h" #include "loaders.h" @@ -47,6 +48,7 @@ void help() printf("-T t.bin load file as a binary tape file (like simh \"load\" command)\n"); printf("-R d.rk load file as a RK05 disk device\n"); printf("-r d.rl load file as a RL02 disk device\n"); + printf("-N host:port:type use NBD-server as disk device, type being either \"rk05\" or \"rl02\"\n"); printf("-p 123 set CPU start pointer to decimal(!) value\n"); printf("-b x enable bootloader (build-in), parameter must be \"rk05\" or \"rl02\"\n"); printf("-n ncurses UI\n"); @@ -85,7 +87,7 @@ int main(int argc, char *argv[]) disk_backend *temp_d = nullptr; int opt = -1; - while((opt = getopt(argc, argv, "hm:T:r:R:p:ndtL:b:l:s:Q:")) != -1) + while((opt = getopt(argc, argv, "hm:T:r:R:p:ndtL:b:l:s:Q:N:")) != -1) { switch(opt) { case 'h': @@ -149,6 +151,22 @@ int main(int argc, char *argv[]) rl02_files.push_back(temp_d); break; + case 'N': { + auto parts = split(optarg, ":"); + if (parts.size() != 3) + error_exit(false, "-N: parameter missing"); + + temp_d = new disk_backend_nbd(parts.at(0), atoi(parts.at(1).c_str())); + + if (parts.at(2) == "rk05") + rk05_files.push_back(temp_d); + else if (parts.at(2) == "rl02") + rl02_files.push_back(temp_d); + else + error_exit(false, "\"%s\" is not recognized as a disk type", parts.at(2).c_str()); + } + break; + case 'p': start_addr = atoi(optarg); sa_set = true; diff --git a/utils.cpp b/utils.cpp index c026511..f744e3f 100644 --- a/utils.cpp +++ b/utils.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -144,3 +145,49 @@ void set_thread_name(std::string name) pthread_setname_np(pthread_self(), name.c_str()); #endif } + +ssize_t WRITE(int fd, const char *whereto, size_t len) +{ + ssize_t cnt=0; + + while(len > 0) + { + ssize_t rc = write(fd, whereto, len); + + if (rc == -1) + return -1; + else if (rc == 0) + return -1; + else + { + whereto += rc; + len -= rc; + cnt += rc; + } + } + + return cnt; +} + +ssize_t READ(int fd, char *whereto, size_t len) +{ + ssize_t cnt=0; + + while(len > 0) + { + ssize_t rc = read(fd, whereto, len); + + if (rc == -1) + return -1; + else if (rc == 0) + break; + else + { + whereto += rc; + len -= rc; + cnt += rc; + } + } + + return cnt; +} diff --git a/utils.h b/utils.h index 15eee2b..25c6bd3 100644 --- a/utils.h +++ b/utils.h @@ -18,3 +18,6 @@ uint64_t get_us(); void myusleep(uint64_t us); void set_thread_name(std::string name); + +ssize_t WRITE(int fd, const char *whereto, size_t len); +ssize_t READ(int fd, char *whereto, size_t len); From 9040a2b075dd033178d7a3f238e709485e03b9ea Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Wed, 22 Mar 2023 11:26:13 +0100 Subject: [PATCH 17/19] ESP32: configure network & NBD disk backend --- ESP32/main.ino | 242 +++++++++++++++++++++++++++++++++++-------------- debugger.cpp | 27 ++++++ 2 files changed, 202 insertions(+), 67 deletions(-) diff --git a/ESP32/main.ino b/ESP32/main.ino index 985ac0e..275b70d 100644 --- a/ESP32/main.ino +++ b/ESP32/main.ino @@ -1,4 +1,4 @@ -// (C) 2018-2022 by Folkert van Heusden +// (C) 2018-2023 by Folkert van Heusden // Released under Apache License v2.0 #include #include @@ -14,6 +14,7 @@ #include "debugger.h" #include "disk_backend.h" #include "disk_backend_esp32.h" +#include "disk_backend_nbd.h" #include "error.h" #include "esp32.h" #include "gen.h" @@ -55,58 +56,87 @@ void console_thread_wrapper_io(void *const c) cnsl->operator()(); } -void setup_wifi_stations() +typedef enum { BE_NETWORK, BE_SD } disk_backend_t; +std::optional select_disk_backend(console *const c) { -#if 0 - WiFi.mode(WIFI_STA); + c->put_string("1. network (NBD), 2. local SD card, 9. abort"); - WiFi.softAP("PDP-11 KEK", nullptr, 5, 0, 4); + int ch = -1; + while(ch == -1 && ch != '1' && ch != '2' && ch != '9') + ch = c->wait_char(500); -#if 0 - Serial.println(F("Scanning for WiFi access points...")); + c->put_string_lf(format("%c", ch)); - int n = WiFi.scanNetworks(); + if (ch == '9') + return { }; - Serial.println(F("scan done")); + if (ch == '1') + return BE_NETWORK; - if (n == 0) - Serial.println(F("no networks found")); - else { - for (int i = 0; i < n; ++i) { - // Print SSID and RSSI for each network found - Serial.print(i + 1); - Serial.print(F(": ")); - Serial.print(WiFi.SSID(i)); - Serial.print(F(" (")); - Serial.print(WiFi.RSSI(i)); - Serial.print(F(")")); - Serial.println(WiFi.encryptionType(i) == WIFI_AUTH_OPEN ? " " : "*"); - delay(10); - } +// if (ch == '2') + return BE_SD; +} + +typedef enum { DT_RK05, DT_RL02 } disk_type_t; + +std::optional select_disk_type(console *const c) +{ + c->put_string("1. RK05, 2. RL02, 9. abort"); + + int ch = -1; + while(ch == -1 && ch != '1' && ch != '2' && ch != '9') + ch = c->wait_char(500); + + c->put_string_lf(format("%c", ch)); + + if (ch == '9') + return { }; + + if (ch == '1') + return DT_RK05; + +// if (ch == '2') + return DT_RL02; +} + +std::optional, std::vector > > select_nbd_server(console *const c) +{ + c->flush_input(); + + std::string hostname = c->read_line("Enter hostname (or empty to abort): "); + + if (hostname.empty()) + return { }; + + std::string port_str = c->read_line("Enter port number (or empty to abort): "); + + if (port_str.empty()) + return { }; + + auto disk_type = select_disk_type(c); + + if (disk_type.has_value() == false) + return { }; + + disk_backend *d = new disk_backend_nbd(hostname, atoi(port_str.c_str())); + + if (d->begin() == false) { + c->put_string_lf("Cannot initialize NBD client"); + delete d; + return { }; } - std::string ssid = read_terminal_line("SSID: "); - std::string password = read_terminal_line("password: "); - WiFi.begin(ssid.c_str(), password.c_str()); -#else - WiFi.begin("www.vanheusden.com", "Ditiseentest31415926"); - //WiFi.begin("NURDspace-guest", "harkharkhark"); -#endif + if (disk_type.value() == DT_RK05) + return { { { d }, { } } }; - while (WiFi.status() != WL_CONNECTED) { - Serial.print('.'); + if (disk_type.value() == DT_RL02) + return { { { }, { d } } }; - delay(250); - } - - on_wifi = true; - - Serial.println(WiFi.localIP()); -#endif + return { }; } // RK05, RL02 files -std::pair, std::vector > select_disk_files(console *const c) +std::optional, std::vector > > select_disk_files(console *const c) { c->debug("MISO: %d", int(MISO)); c->debug("MOSI: %d", int(MOSI)); @@ -128,16 +158,10 @@ std::pair, std::vector > select_disk if (selected_file.empty()) continue; - c->put_string("1. RK05, 2. RL02, 3. re-select file"); + auto disk_type = select_disk_type(c); - int ch = -1; - while(ch == -1 && ch != '1' && ch != '2' && ch != '3') - ch = c->wait_char(500); - - c->put_string_lf(format("%c", ch)); - - if (ch == '3') - continue; + if (disk_type.has_value() == false) + return { }; c->put_string("Opening file: "); c->put_string_lf(selected_file.c_str()); @@ -158,17 +182,115 @@ std::pair, std::vector > select_disk continue; } - if (ch == '1') - return { { temp }, { } }; + if (disk_type.value() == DT_RK05) + return { { { temp }, { } } }; - if (ch == '2') - return { { }, { temp } }; + if (disk_type.value() == DT_RL02) + return { { { }, { temp } } }; } c->put_string_lf("open failed"); } } +void configure_disk(console *const c) +{ + for(;;) { + Serial.println(F("Load disk")); + + auto backend = select_disk_backend(cnsl); + + if (backend.has_value() == false) + break; + + std::optional, std::vector > > files; + + if (backend == BE_NETWORK) + files = select_nbd_server(cnsl); + else // if (backend == BE_SD) + files = select_disk_files(cnsl); + + if (files.has_value() == false) + break; + + if (files.value().first.empty() == false) + b->add_rk05(new rk05(files.value().first, b, cnsl->get_disk_read_activity_flag(), cnsl->get_disk_write_activity_flag())); + + if (files.value().second.empty() == false) + b->add_rl02(new rl02(files.value().second, b, cnsl->get_disk_read_activity_flag(), cnsl->get_disk_write_activity_flag())); + + // TODO: allow bootloader to be selected + if (files.value().first.empty() == false) + setBootLoader(b, BL_RK05); + else + setBootLoader(b, BL_RL02); + + break; + } +} + +void set_hostname() +{ + WiFi.setHostname("PDP-11"); +} + +void configure_network(console *const c) +{ + WiFi.persistent(true); + + WiFi.setAutoReconnect(true); + + WiFi.mode(WIFI_STA); + + c->put_string_lf("Scanning for wireless networks..."); + + int n_ssids = WiFi.scanNetworks(); + + c->put_string_lf("Wireless networks:"); + + for(int i=0; iput_string_lf(format("\t%s", WiFi.SSID(i).c_str())); + + c->flush_input(); + + std::string wifi_ap = c->read_line("Enter SSID[|PSK]: "); + + auto parts = split(wifi_ap, "|"); + + if (parts.size() > 2) { + c->put_string_lf("Invalid SSID/PSK: should not contain '|'"); + return; + } + + set_hostname(); + + if (parts.size() == 1) + WiFi.begin(parts.at(0).c_str()); + else + WiFi.begin(parts.at(0).c_str(), parts.at(1).c_str()); +} + +void start_network(console *const c) +{ + WiFi.mode(WIFI_STA); + + set_hostname(); + + WiFi.begin(); + + int i = 0; + while (WiFi.waitForConnectResult() != WL_CONNECTED && i < 10 * 3) { + c->put_string("."); + + delay(1000 / 3); + + i++; + } + + c->put_string_lf(""); + c->put_string_lf(format("Local IP address: %s", WiFi.localIP().toString().c_str())); +} + void setup() { Serial.begin(115200); @@ -216,20 +338,6 @@ void setup() { // setup_wifi_stations(); - Serial.println(F("Load RK05")); - auto disk_files = select_disk_files(cnsl); - - if (disk_files.first.empty() == false) - b->add_rk05(new rk05(disk_files.first, b, cnsl->get_disk_read_activity_flag(), cnsl->get_disk_write_activity_flag())); - - if (disk_files.second.empty() == false) - b->add_rl02(new rl02(disk_files.second, b, cnsl->get_disk_read_activity_flag(), cnsl->get_disk_write_activity_flag())); - - if (disk_files.first.empty() == false) - setBootLoader(b, BL_RK05); - else - setBootLoader(b, BL_RL02); - Serial.print(F("Free RAM after init: ")); Serial.println(ESP.getFreeHeap()); diff --git a/debugger.cpp b/debugger.cpp index 743e292..9b02f40 100644 --- a/debugger.cpp +++ b/debugger.cpp @@ -10,6 +10,11 @@ #include "esp32.h" void setBootLoader(bus *const b); + +void configure_disk(console *const c); + +void configure_network(console *const c); +void start_network(console *const c); #endif // returns size of instruction (in bytes) @@ -343,6 +348,23 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto #endif continue; } +#if defined(ESP32) + else if (cmd == "cfgdisk") { + configure_disk(cnsl); + + continue; + } + else if (cmd == "cfgnet") { + configure_network(cnsl); + + continue; + } + else if (cmd == "startnet") { + start_network(cnsl); + + continue; + } +#endif else if (cmd == "quit" || cmd == "q") { #if defined(ESP32) ESP.restart(); @@ -365,6 +387,11 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto cnsl->put_string_lf("setpc - set PC to value"); cnsl->put_string_lf("setmem - set memory (a=) to value (v=), both in octal, one byte"); cnsl->put_string_lf("toggle - set switch (s=, 0...15 (decimal)) of the front panel to state (t=, 0 or 1)"); +#if defined(ESP32) + cnsl->put_string_lf("cfgnet - configure network (e.g. WiFi)"); + cnsl->put_string_lf("startnet - start network"); + cnsl->put_string_lf("cfgdisk - configure disk"); +#endif continue; } From 4799cba2de626ff63668a1de87ec4657554f6f1d Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Wed, 22 Mar 2023 13:06:33 +0100 Subject: [PATCH 18/19] Revert "d/i index 0 for i is more logical? because it is default mode." This reverts commit cf420ca726efed6f19d1eae937a2676d269a67cf. => breaks at least the unix v6 bootloader --- bus.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bus.h b/bus.h index 3aa583e..f60921d 100644 --- a/bus.h +++ b/bus.h @@ -56,7 +56,7 @@ class cpu; class memory; class tty; -typedef enum { i_space, d_space } d_i_space_t; +typedef enum { d_space, i_space } d_i_space_t; typedef struct { uint16_t virtual_address; From cfc819630ea3b54c4c2ecb78fd7f32628577fe46 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Wed, 22 Mar 2023 13:08:23 +0100 Subject: [PATCH 19/19] Revert "MMR2 tracking" This reverts commit 2afa705209dfa012fed5f1b66a787bcb9bcd6be2. => breaks EKBA (from XXDP) --- cpu.cpp | 26 ++++++++++++++++---------- cpu.h | 2 +- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/cpu.cpp b/cpu.cpp index eaa9c23..a73cda0 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -1301,7 +1301,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) psw &= 0xff00; // only alter lower 8 bits psw |= getGAM(dst_mode, dst_reg, word_mode, false).value.value() & 0xef; // can't change bit 4 #else - schedule_trap(010); + trap(010); #endif } else { @@ -1332,7 +1332,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) setPSW_n(extend_b7); } #else - schedule_trap(010); + trap(010); #endif } else { // SXT @@ -1446,7 +1446,7 @@ bool cpu::condition_code_operations(const uint16_t instr) setPSW_spl(level); // // trap via vector 010 only(?) on an 11/60 and not(?) on an 11/70 -// schedule_trap(010); +// trap(010); return true; } @@ -1474,7 +1474,7 @@ void cpu::pushStack(const uint16_t v) if (getRegister(6) == stackLimitRegister) { DOLOG(debug, true, "stackLimitRegister reached %06o while pushing %06o", stackLimitRegister, v); - schedule_trap(123); + trap(123, 7); // TODO } else { uint16_t a = addRegister(6, false, -2); @@ -1509,11 +1509,11 @@ bool cpu::misc_operations(const uint16_t instr) return true; case 0b0000000000000011: // BPT - schedule_trap(014); + trap(014); return true; case 0b0000000000000100: // IOT - schedule_trap(020); + trap(020); return true; case 0b0000000000000110: // RTT @@ -1523,7 +1523,7 @@ bool cpu::misc_operations(const uint16_t instr) case 0b0000000000000111: // MFPT //setRegister(0, 0); - schedule_trap(010); // does not exist on PDP-11/70 + trap(010); // does not exist on PDP-11/70 return true; case 0b0000000000000101: // RESET @@ -1533,12 +1533,12 @@ bool cpu::misc_operations(const uint16_t instr) } if ((instr >> 8) == 0b10001000) { // EMT - schedule_trap(030); + trap(030); return true; } if ((instr >> 8) == 0b10001001) { // TRAP - schedule_trap(034); + trap(034); return true; } @@ -2177,9 +2177,15 @@ void cpu::step_b() uint16_t temp_pc = getPC(); + if ((b->getMMR0() & 0160000) == 0) + b->setMMR2(temp_pc); + try { uint16_t instr = b->readWord(temp_pc); + if (temp_pc == 025250) + DOLOG(debug, true, "GREP %06o %06o", temp_pc, instr); + addRegister(7, false, 2); if (double_operand_instructions(instr)) @@ -2196,7 +2202,7 @@ void cpu::step_b() DOLOG(warning, true, "UNHANDLED instruction %06o @ %06o", instr, temp_pc); - schedule_trap(010); + trap(010); } catch(const int exception) { DOLOG(debug, true, "bus-trap during execution of command (%d)", exception); diff --git a/cpu.h b/cpu.h index 40db82c..d7395ee 100644 --- a/cpu.h +++ b/cpu.h @@ -132,7 +132,7 @@ public: void setStackLimitRegister(const uint16_t v) { stackLimitRegister = v; } uint16_t getStackPointer(const int which) const { assert(which >= 0 && which < 4); return sp[which]; } - uint16_t getPC() const { b->setMMR2(pc); return pc; } + uint16_t getPC() const { return pc; } void setRegister(const int nr, const bool reg_set, const bool prev_mode, const uint16_t value); void setRegister(const int nr, const bool prev_mode, const uint16_t v) { setRegister(nr, (getPSW() >> 11) & 1, prev_mode, v); }