From 1da19f0241e6c099469ed88e8b7525b2ba902fe4 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Thu, 25 Apr 2024 23:59:21 +0200 Subject: [PATCH 01/19] mixed commit: disk overlay for snapshots/state-dumps, compile fixes for ESP32 --- ESP32/console_esp32.cpp | 6 +-- ESP32/console_esp32.h | 4 +- ESP32/console_shabadge.cpp | 4 +- ESP32/console_shabadge.h | 2 +- ESP32/disk_backend_esp32.cpp | 6 +-- ESP32/disk_backend_esp32.h | 8 ++-- ESP32/main.ino | 9 ++-- ESP32/mmu.cpp | 1 + ESP32/mmu.h | 1 + debugger.cpp | 6 +-- disk_backend.cpp | 81 +++++++++++++++++++++++++++++++++++- disk_backend.h | 26 ++++++++++-- disk_backend_file.cpp | 48 +++++++++++++++------ disk_backend_file.h | 8 ++-- disk_backend_nbd.cpp | 45 ++++++++++++++++---- disk_backend_nbd.h | 11 +++-- gen.h | 7 +++- main.cpp | 52 ++++++++++------------- mmu.h | 2 + rk05.cpp | 4 +- rl02.cpp | 4 +- 21 files changed, 244 insertions(+), 91 deletions(-) create mode 120000 ESP32/mmu.cpp create mode 120000 ESP32/mmu.h diff --git a/ESP32/console_esp32.cpp b/ESP32/console_esp32.cpp index 690a1b6..d4efeb0 100644 --- a/ESP32/console_esp32.cpp +++ b/ESP32/console_esp32.cpp @@ -1,4 +1,4 @@ -// (C) 2018-2023 by Folkert van Heusden +// (C) 2018-2024 by Folkert van Heusden // Released under MIT license #include @@ -13,8 +13,8 @@ #define NEOPIXELS_PIN 25 -console_esp32::console_esp32(std::atomic_uint32_t *const stop_event, bus *const b, std::vector & io_ports, const int t_width, const int t_height) : - console(stop_event, b, t_width, t_height), +console_esp32::console_esp32(std::atomic_uint32_t *const stop_event, std::vector & io_ports, const int t_width, const int t_height) : + console(stop_event, t_width, t_height), io_ports(io_ports) { } diff --git a/ESP32/console_esp32.h b/ESP32/console_esp32.h index fd3aa30..b83aded 100644 --- a/ESP32/console_esp32.h +++ b/ESP32/console_esp32.h @@ -1,4 +1,4 @@ -// (C) 2018-2023 by Folkert van Heusden +// (C) 2018-2024 by Folkert van Heusden // Released under MIT license #include @@ -18,7 +18,7 @@ protected: void put_char_ll(const char c) override; public: - console_esp32(std::atomic_uint32_t *const stop_event, bus *const b, std::vector & io_ports, const int t_width, const int t_height); + console_esp32(std::atomic_uint32_t *const stop_event, std::vector & io_ports, const int t_width, const int t_height); virtual ~console_esp32(); void put_string_lf(const std::string & what) override; diff --git a/ESP32/console_shabadge.cpp b/ESP32/console_shabadge.cpp index 8720724..b8cdf77 100644 --- a/ESP32/console_shabadge.cpp +++ b/ESP32/console_shabadge.cpp @@ -15,8 +15,8 @@ #define COLORED 0 #define UNCOLORED 1 -console_shabadge::console_shabadge(std::atomic_uint32_t *const stop_event, bus *const b, std::vector & io_ports) : - console_esp32(stop_event, b, io_ports, 296 / 8, 128 / 8) +console_shabadge::console_shabadge(std::atomic_uint32_t *const stop_event, std::vector & io_ports) : + console_esp32(stop_event, io_ports, 296 / 8, 128 / 8) { if (epd.Init() != 0) Serial.println("Init of DEPG0290B01 failed"); diff --git a/ESP32/console_shabadge.h b/ESP32/console_shabadge.h index 8a77cb2..bf09419 100644 --- a/ESP32/console_shabadge.h +++ b/ESP32/console_shabadge.h @@ -22,7 +22,7 @@ private: void put_char_ll(const char c) override; public: - console_shabadge(std::atomic_uint32_t *const stop_event, bus *const b, std::vector & io_ports); + console_shabadge(std::atomic_uint32_t *const stop_event, std::vector & io_ports); virtual ~console_shabadge(); void panel_update_thread() override; diff --git a/ESP32/disk_backend_esp32.cpp b/ESP32/disk_backend_esp32.cpp index fdc33c5..9f42509 100644 --- a/ESP32/disk_backend_esp32.cpp +++ b/ESP32/disk_backend_esp32.cpp @@ -29,7 +29,7 @@ void disk_backend_esp32::emit_error() DOLOG(ll_error, true, "SdFat error: %d/%d", sd.sdErrorCode(), sd.sdErrorData()); } -bool disk_backend_esp32::begin() +bool disk_backend_esp32::begin(const bool dummy) { if (!fh->open(filename.c_str(), O_RDWR)) { DOLOG(ll_error, true, "rk05: cannot open \"%s\"", filename.c_str()); @@ -41,7 +41,7 @@ bool disk_backend_esp32::begin() return true; } -bool disk_backend_esp32::read(const off_t offset, const size_t n, uint8_t *const target) +bool disk_backend_esp32::read(const off_t offset, const size_t n, uint8_t *const target, const size_t sector_size) { DOLOG(debug, false, "disk_backend_esp32::read: read %zu bytes from offset %zu", n, offset); @@ -77,7 +77,7 @@ bool disk_backend_esp32::read(const off_t offset, const size_t n, uint8_t *const return true; } -bool disk_backend_esp32::write(const off_t offset, const size_t n, const uint8_t *const from) +bool disk_backend_esp32::write(const off_t offset, const size_t n, const uint8_t *const from, const size_t sector_size) { DOLOG(debug, false, "disk_backend_esp32::write: write %zu bytes to offset %zu", n, offset); diff --git a/ESP32/disk_backend_esp32.h b/ESP32/disk_backend_esp32.h index c24ae51..b0f048a 100644 --- a/ESP32/disk_backend_esp32.h +++ b/ESP32/disk_backend_esp32.h @@ -23,9 +23,11 @@ public: disk_backend_esp32(const std::string & filename); virtual ~disk_backend_esp32(); - bool begin() override; + std::string get_identifier() const { return filename; } - bool read(const off_t offset, const size_t n, uint8_t *const target) override; + bool begin(const bool dummy) override; - bool write(const off_t offset, const size_t n, const uint8_t *const from) override; + bool read(const off_t offset, const size_t n, uint8_t *const target, const size_t sector_size) override; + + bool write(const off_t offset, const size_t n, const uint8_t *const from, const size_t sector_size) override; }; diff --git a/ESP32/main.ino b/ESP32/main.ino index 3407eef..c5fe75c 100644 --- a/ESP32/main.ino +++ b/ESP32/main.ino @@ -38,7 +38,6 @@ #include "esp32.h" #endif #include "gen.h" -#include "kw11-l.h" #include "loaders.h" #include "memory.h" #include "tty.h" @@ -286,13 +285,11 @@ void setup() { std::vector serial_ports { &Serial_RS232, &Serial }; #if defined(SHA2017) - cnsl = new console_shabadge(&stop_event, b, serial_ports); + cnsl = new console_shabadge(&stop_event, serial_ports); #elif defined(ESP32) || defined(BUILD_FOR_RP2040) - cnsl = new console_esp32(&stop_event, b, serial_ports, 80, 25); + cnsl = new console_esp32(&stop_event, serial_ports, 80, 25); #endif - - Serial.println(F("Start line-frequency interrupt")); - kw11_l *lf = new kw11_l(b, cnsl); + cnsl->set_bus(b); running = cnsl->get_running_flag(); diff --git a/ESP32/mmu.cpp b/ESP32/mmu.cpp new file mode 120000 index 0000000..b83d63b --- /dev/null +++ b/ESP32/mmu.cpp @@ -0,0 +1 @@ +../mmu.cpp \ No newline at end of file diff --git a/ESP32/mmu.h b/ESP32/mmu.h new file mode 120000 index 0000000..cc56dfb --- /dev/null +++ b/ESP32/mmu.h @@ -0,0 +1 @@ +../mmu.h \ No newline at end of file diff --git a/debugger.cpp b/debugger.cpp index 30da333..29de1b7 100644 --- a/debugger.cpp +++ b/debugger.cpp @@ -125,7 +125,7 @@ std::optional, std::vectorbegin() == false) { + if (d->begin(false) == false) { c->put_string_lf("Cannot initialize NBD client from configuration file"); delete d; return { }; @@ -273,7 +273,7 @@ std::optional, std::vectorbegin() == false) { + if (d->begin(false) == false) { c->put_string_lf("Cannot initialize NBD client"); delete d; return { }; @@ -397,7 +397,7 @@ std::optional, std::vectorbegin()) { + if (!temp->begin(false)) { c->put_string("Cannot use: "); c->put_string_lf(selected_file.c_str()); diff --git a/disk_backend.cpp b/disk_backend.cpp index 971be4a..488ee94 100644 --- a/disk_backend.cpp +++ b/disk_backend.cpp @@ -4,8 +4,10 @@ #include #include "disk_backend.h" +#if IS_POSIX #include "disk_backend_file.h" #include "disk_backend_nbd.h" +#endif disk_backend::disk_backend() @@ -17,6 +19,80 @@ disk_backend::~disk_backend() } #if IS_POSIX +void disk_backend::store_object_in_overlay(const off_t id, const std::vector & data) +{ + overlay.insert_or_assign(id, data); +} + +std::optional > disk_backend::get_object_from_overlay(const off_t id) +{ + auto it = overlay.find(id); + if (it != overlay.end()) + return it->second; + + return { }; +} + +std::optional > disk_backend::get_from_overlay(const off_t offset, const size_t sector_size) +{ + assert((offset % sector_size) == 0); + + if (use_overlay) + return get_object_from_overlay(offset / sector_size); + + return { }; +} + +bool disk_backend::store_mem_range_in_overlay(const off_t offset, const size_t n, const uint8_t *const from, const size_t sector_size) +{ + assert((offset % sector_size) == 0); + assert((n % sector_size) == 0); + + if (use_overlay) { + for(size_t o=0; o(from + o, from + o + sector_size)); + + return true; + } + + return false; +} + +json_t *disk_backend::serialize_overlay() const +{ + json_t *out = json_object(); + + for(auto & id: overlay) { + json_t *j_data = json_array(); + + for(size_t i=0; i data; + for(size_t i=0; ibegin(); + d->deserialize_overlay(j); + + // assume we want snapshots (again?) + d->begin(true); return d; } diff --git a/disk_backend.h b/disk_backend.h index 141c2d8..48fbb20 100644 --- a/disk_backend.h +++ b/disk_backend.h @@ -3,7 +3,11 @@ #pragma once +#include +#include #include +#include +#include #include #include "gen.h" @@ -11,6 +15,20 @@ class disk_backend { +protected: +#if IS_POSIX + bool use_overlay { false }; + std::map > overlay; + + void store_object_in_overlay(const off_t id, const std::vector & data); + bool store_mem_range_in_overlay(const off_t offset, const size_t n, const uint8_t *const from, const size_t sector_size); + std::optional > get_object_from_overlay(const off_t id); + std::optional > get_from_overlay(const off_t offset, const size_t sector_size); + + json_t *serialize_overlay() const; + void deserialize_overlay(const json_t *const j); +#endif + public: disk_backend(); virtual ~disk_backend(); @@ -20,9 +38,11 @@ public: static disk_backend *deserialize(const json_t *const j); #endif - virtual bool begin() = 0; + virtual std::string get_identifier() const = 0; - virtual bool read(const off_t offset, const size_t n, uint8_t *const target) = 0; + virtual bool begin(const bool disk_snapshots) = 0; - virtual bool write(const off_t offset, const size_t n, const uint8_t *const from) = 0; + virtual bool read(const off_t offset, const size_t n, uint8_t *const target, const size_t sector_size) = 0; + + virtual bool write(const off_t offset, const size_t n, const uint8_t *const from, const size_t sector_size) = 0; }; diff --git a/disk_backend_file.cpp b/disk_backend_file.cpp index 127faa3..19ee4d2 100644 --- a/disk_backend_file.cpp +++ b/disk_backend_file.cpp @@ -1,11 +1,13 @@ // (C) 2018-2024 by Folkert van Heusden // Released under MIT license +#include #include #include #include #include "disk_backend_file.h" +#include "gen.h" #include "log.h" @@ -26,6 +28,8 @@ json_t *disk_backend_file::serialize() const json_object_set(j, "disk-backend-type", json_string("file")); + json_object_set(j, "overlay", serialize_overlay()); + // TODO store checksum of backend json_object_set(j, "filename", json_string(filename.c_str())); @@ -39,8 +43,10 @@ disk_backend_file *disk_backend_file::deserialize(const json_t *const j) } #endif -bool disk_backend_file::begin() +bool disk_backend_file::begin(const bool snapshots) { + use_overlay = snapshots; + fd = open(filename.c_str(), O_RDWR); if (fd == -1) { @@ -52,30 +58,48 @@ bool disk_backend_file::begin() return true; } -bool disk_backend_file::read(const off_t offset, const size_t n, uint8_t *const target) +bool disk_backend_file::read(const off_t offset_in, const size_t n, uint8_t *const target, const size_t sector_size) { - DOLOG(debug, false, "disk_backend_file::read: read %zu bytes from offset %zu", n, offset); + DOLOG(debug, false, "disk_backend_file::read: read %zu bytes from offset %zu", n, offset_in); + + assert((offset % sector_size) == 0); + assert((n % sector_size) == 0); + + for(off_t o=0; o #include #include #include @@ -54,6 +55,8 @@ json_t *disk_backend_nbd::serialize() const json_object_set(j, "disk-backend-type", json_string("nbd")); + json_object_set(j, "overlay", serialize_overlay()); + // TODO store checksum of backend json_object_set(j, "host", json_string(host.c_str())); json_object_set(j, "port", json_integer(port)); @@ -68,8 +71,12 @@ disk_backend_nbd *disk_backend_nbd::deserialize(const json_t *const j) } #endif -bool disk_backend_nbd::begin() +bool disk_backend_nbd::begin(const bool snapshots) { +#if IS_POSIX + use_overlay = snapshots; +#endif + if (!connect(false)) { DOLOG(ll_error, true, "disk_backend_nbd: cannot connect to NBD server"); return false; @@ -154,14 +161,27 @@ bool disk_backend_nbd::connect(const bool retry) return fd != -1; } -bool disk_backend_nbd::read(const off_t offset, const size_t n, uint8_t *const target) +bool disk_backend_nbd::read(const off_t offset_in, const size_t n, uint8_t *const target, const size_t sector_size) { - DOLOG(debug, false, "disk_backend_nbd::read: read %zu bytes from offset %zu", n, offset); + DOLOG(debug, false, "disk_backend_nbd::read: read %zu bytes from offset %zu", n, offset_in); if (n == 0) return true; - do { + size_t o = 0; + off_t offset = offset_in; + + while(offset < offset_in + off_t(n)) { +#if IS_POSIX + auto o_rc = get_from_overlay(offset, sector_size); + if (o_rc.has_value()) { + memcpy(&target[o], o_rc.value().data(), sector_size); + offset += sector_size; + o += sector_size; + continue; + } +#endif + if (fd == -1 && !connect(true)) { DOLOG(warning, true, "disk_backend_nbd::read: (re-)connect"); sleep(1); @@ -179,7 +199,7 @@ bool disk_backend_nbd::read(const off_t offset, const size_t n, uint8_t *const t nbd_request.magic = ntohl(0x25609513); nbd_request.type = 0; // READ nbd_request.offset = HTONLL(uint64_t(offset)); - nbd_request.length = htonl(n); + nbd_request.length = htonl(sector_size); if (WRITE(fd, reinterpret_cast(&nbd_request), sizeof nbd_request) != sizeof nbd_request) { DOLOG(warning, true, "disk_backend_nbd::read: problem sending request"); @@ -217,26 +237,33 @@ bool disk_backend_nbd::read(const off_t offset, const size_t n, uint8_t *const t return false; } - if (READ(fd, reinterpret_cast(target), n) != ssize_t(n)) { + if (READ(fd, reinterpret_cast(target), sector_size) != ssize_t(sector_size)) { DOLOG(warning, true, "disk_backend_nbd::read: problem receiving payload"); close(fd); fd = -1; sleep(1); continue; } + + offset += sector_size; + o += sector_size; } - while(fd == -1); return true; } -bool disk_backend_nbd::write(const off_t offset, const size_t n, const uint8_t *const from) +bool disk_backend_nbd::write(const off_t offset, const size_t n, const uint8_t *const from, const size_t sector_size) { DOLOG(debug, false, "disk_backend_nbd::write: write %zu bytes to offset %zu", n, offset); if (n == 0) return true; +#if IS_POSIX + if (store_mem_range_in_overlay(offset, n, from, sector_size)) + return true; +#endif + do { if (!connect(true)) { DOLOG(warning, true, "disk_backend_nbd::write: (re-)connect"); @@ -250,7 +277,7 @@ bool disk_backend_nbd::write(const off_t offset, const size_t n, const uint8_t * uint64_t handle; uint64_t offset; uint32_t length; - } nbd_request { 0 }; + } nbd_request { }; nbd_request.magic = ntohl(0x25609513); nbd_request.type = 1; // WRITE diff --git a/disk_backend_nbd.h b/disk_backend_nbd.h index b6679a8..fb369b9 100644 --- a/disk_backend_nbd.h +++ b/disk_backend_nbd.h @@ -1,4 +1,4 @@ -// (C) 2018-2023 by Folkert van Heusden +// (C) 2018-2024 by Folkert van Heusden // Released under MIT license #include @@ -6,6 +6,7 @@ #include "disk_backend.h" #include "gen.h" +#include "utils.h" class disk_backend_nbd : public disk_backend @@ -26,9 +27,11 @@ public: static disk_backend_nbd *deserialize(const json_t *const j); #endif - bool begin() override; + std::string get_identifier() const override { return format("%s:%d", host.c_str(), port); } - bool read(const off_t offset, const size_t n, uint8_t *const target) override; + bool begin(const bool snapshots) override; - bool write(const off_t offset, const size_t n, const uint8_t *const from) override; + bool read(const off_t offset, const size_t n, uint8_t *const target, const size_t sector_size) override; + + bool write(const off_t offset, const size_t n, const uint8_t *const from, const size_t sector_size) override; }; diff --git a/gen.h b/gen.h index 46c1f04..8629ac9 100644 --- a/gen.h +++ b/gen.h @@ -13,8 +13,11 @@ typedef enum { wm_word = 0, wm_byte = 1 } word_mode_t; typedef enum { rm_prev, rm_cur } rm_selection_t; -#define IS_POSIX (defined(linux) || defined (__unix__) || (defined (__APPLE__) && defined (__MACH__))) -#define IS_UP (!(IS_POSIX)) /* is microprocessor */ +#if (defined(linux) || defined (__unix__) || (defined (__APPLE__) && defined (__MACH__))) +#define IS_POSIX 1 +#else +#define IS_POSIX 0 +#endif #if IS_POSIX #include diff --git a/main.cpp b/main.cpp index d25804c..24de903 100644 --- a/main.cpp +++ b/main.cpp @@ -295,10 +295,19 @@ void get_metrics(cpu *const c) } } +void start_disk_devices(const std::vector & backends, const bool enable_snapshots) +{ + for(auto & backend: backends) { + if (backend->begin(enable_snapshots) == false) + error_exit(false, "Failed to initialize disk backend \"%s\"", backend->get_identifier().c_str()); + } +} + void help() { printf("-h this help\n"); printf("-D x deserialize state from file\n"); + printf("-P when serializing state to file (in the debugger), include an overlay: changes to disk-files are then non-persistent, they only exist in the state-dump\n"); printf("-T t.bin load file as a binary tape file (like simh \"load\" command), also for .BIC files\n"); printf("-B run tape file as a unit test (for .BIC files)\n"); printf("-R d.rk load file as a RK05 disk device\n"); @@ -318,27 +327,8 @@ void help() printf("-M log metrics\n"); } -#include "breakpoint_parser.h" int main(int argc, char *argv[]) { -#if 0 - { - bus *b = new bus(); - cpu *c = new cpu(b, &event); - b->add_cpu(c); - - std::pair > rc = parse_breakpoint(b, "(pc=0123 and (r0=01456 or r2=1) and memWV[0444]=0222)"); - printf("%p\n", rc.first); - - if (rc.second.has_value()) - printf("%s\n", rc.second.value().c_str()); - delete rc.first; - delete b; - } - - return 0; -#endif - //setlocale(LC_ALL, ""); std::vector rk05_files; @@ -365,7 +355,7 @@ int main(int argc, char *argv[]) std::string test; - disk_backend *temp_d = nullptr; + bool disk_snapshots = false; std::optional set_ram_size; @@ -376,7 +366,7 @@ int main(int argc, char *argv[]) std::string deserialize; int opt = -1; - while((opt = getopt(argc, argv, "hD:MT:Br:R:p:ndtL:bl:s:Q:N:J:XS:")) != -1) + while((opt = getopt(argc, argv, "hD:MT:Br:R:p:ndtL:bl:s:Q:N:J:XS:P")) != -1) { switch(opt) { case 'h': @@ -441,17 +431,11 @@ int main(int argc, char *argv[]) break; case 'R': - 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); + rk05_files.push_back(new disk_backend_file(optarg)); break; case 'r': - 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); + rl02_files.push_back(new disk_backend_file(optarg)); break; case 'N': { @@ -459,7 +443,7 @@ int main(int argc, char *argv[]) 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())); + disk_backend *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); @@ -494,6 +478,10 @@ int main(int argc, char *argv[]) set_ram_size = std::stoi(optarg); break; + case 'P': + disk_snapshots = true; + break; + default: fprintf(stderr, "-%c is not understood\n", opt); return 1; @@ -511,6 +499,10 @@ int main(int argc, char *argv[]) DOLOG(info, true, "Built on: " __DATE__ " " __TIME__); + start_disk_devices(rk05_files, disk_snapshots); + + start_disk_devices(rl02_files, disk_snapshots); + #if !defined(_WIN32) if (withUI) cnsl = new console_ncurses(&event); diff --git a/mmu.h b/mmu.h index e78a5da..4b2b4ad 100644 --- a/mmu.h +++ b/mmu.h @@ -41,8 +41,10 @@ private: uint16_t PIR { 0 }; uint16_t CSR { 0 }; +#if IS_POSIX void add_par_pdr(json_t *const target, const int run_mode, const bool is_d, const std::string & name) const; void set_par_pdr(const json_t *const j_in, const int run_mode, const bool is_d, const std::string & name); +#endif public: mmu(); diff --git a/rk05.cpp b/rk05.cpp index 8b1aaf8..34d0c37 100644 --- a/rk05.cpp +++ b/rk05.cpp @@ -156,7 +156,7 @@ void rk05::writeWord(const uint16_t addr, const uint16_t v) for(size_t i=0; ireadUnibusByte(work_memoff++); - if (!fhs.at(device)->write(work_diskoffb, cur, xfer_buffer)) + if (!fhs.at(device)->write(work_diskoffb, cur, xfer_buffer, 512)) DOLOG(ll_error, true, "RK05(%d) write error %s to %u len %u", device, strerror(errno), work_diskoffb, cur); work_diskoffb += cur; @@ -191,7 +191,7 @@ void rk05::writeWord(const uint16_t addr, const uint16_t v) while(temp > 0) { uint32_t cur = std::min(uint32_t(sizeof xfer_buffer), temp); - if (!fhs.at(device)->read(temp_diskoffb, cur, xfer_buffer)) { + if (!fhs.at(device)->read(temp_diskoffb, cur, xfer_buffer, 512)) { DOLOG(ll_error, true, "RK05 read error %s from %u len %u", strerror(errno), temp_diskoffb, cur); break; } diff --git a/rl02.cpp b/rl02.cpp index 0256c86..339e93c 100644 --- a/rl02.cpp +++ b/rl02.cpp @@ -271,7 +271,7 @@ void rl02::writeWord(const uint16_t addr, uint16_t v) mpr[0]++; } - if (!fhs.at(device)->write(temp_disk_offset, cur, xfer_buffer)) { + if (!fhs.at(device)->write(temp_disk_offset, cur, xfer_buffer, 256)) { DOLOG(ll_error, true, "RL02: write error, device %d, disk offset %u, read size %u, cylinder %d, head %d, sector %d", device, temp_disk_offset, cur, track, head, sector); break; } @@ -325,7 +325,7 @@ void rl02::writeWord(const uint16_t addr, uint16_t v) while(count > 0) { uint32_t cur = std::min(uint32_t(sizeof xfer_buffer), count); - if (!fhs.at(device)->read(temp_disk_offset, cur, xfer_buffer)) { + if (!fhs.at(device)->read(temp_disk_offset, cur, xfer_buffer, 256)) { DOLOG(ll_error, true, "RL02: read error, device %d, disk offset %u, read size %u, cylinder %d, head %d, sector %d", device, temp_disk_offset, cur, track, head, sector); break; } From 8caad6ae37b853ef05b881cd2471b0ff886898a9 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Fri, 26 Apr 2024 15:01:27 +0200 Subject: [PATCH 02/19] disk configure menu --- ESP32/main.ino | 2 +- bus.h | 2 + debugger.cpp | 191 ++++++++++++++++++++++++------------------------- disk_device.h | 22 ++++++ loaders.cpp | 2 +- loaders.h | 2 +- main.cpp | 28 +++----- rk05.h | 5 +- rl02.cpp | 4 +- rl02.h | 9 ++- 10 files changed, 137 insertions(+), 130 deletions(-) create mode 100644 disk_device.h diff --git a/ESP32/main.ino b/ESP32/main.ino index c5fe75c..1609ba9 100644 --- a/ESP32/main.ino +++ b/ESP32/main.ino @@ -216,7 +216,7 @@ void setup() { while(!Serial) delay(100); - Serial.println(F("This PDP-11 emulator is called \"kek\" (reason for that is forgotten) and was written by Folkert van Heusden.")); + Serial.println(F("PDP11 emulator, by Folkert van Heusden")); Serial.print(F("GIT hash: ")); Serial.println(version_str); Serial.println(F("Build on: " __DATE__ " " __TIME__)); diff --git a/bus.h b/bus.h index b0ae4c8..1e8db64 100644 --- a/bus.h +++ b/bus.h @@ -123,6 +123,8 @@ public: kw11_l *getKW11_L() { return kw11_l_; } tty *getTty() { return tty_; } mmu *getMMU() { return mmu_; } + rk05 *getRK05() { return rk05_; } + rl02 *getRL02() { return rl02_; } uint16_t read (const uint16_t a, const word_mode_t word_mode, const rm_selection_t mode_selection, const bool peek_only=false, const d_i_space_t s = i_space); uint16_t readByte(const uint16_t a) { return read(a, wm_byte, rm_cur); } diff --git a/debugger.cpp b/debugger.cpp index 29de1b7..c8fb8fd 100644 --- a/debugger.cpp +++ b/debugger.cpp @@ -38,7 +38,7 @@ #include "rp2040.h" #endif -void setBootLoader(bus *const b); +void set_boot_loader(bus *const b); void configure_disk(console *const c); @@ -196,61 +196,7 @@ bool save_disk_configuration(const std::string & nbd_host, const int nbd_port, c } #endif -std::optional select_disk_backend(console *const c) -{ -#if defined(BUILD_FOR_RP2040) - return BE_SD; -#elif linux - c->put_string("1. network (NBD), 2. local filesystem, 9. abort"); -#else - c->put_string("1. network (NBD), 2. local SD card, 9. abort"); -#endif - - int ch = -1; - while(ch == -1 && ch != '1' && ch != '2' && ch != '9') { - auto temp = c->wait_char(500); - - if (temp.has_value()) - ch = temp.value(); - } - - c->put_string_lf(format("%c", ch)); - - if (ch == '1') - return BE_NETWORK; - - if (ch == '2') - return BE_SD; - - return { }; -} - -std::optional select_disk_type(console *const c) -{ - c->put_string("1. RK05, 2. RL02, 3. tape/BIC, 9. abort"); - - int ch = -1; - while(ch == -1 && ch != '1' && ch != '2' && ch != '3' && ch != '9') { - auto temp = c->wait_char(500); - - if (temp.has_value()) - ch = temp.value(); - } - - c->put_string_lf(format("%c", ch)); - - if (ch == '1') - return DT_RK05; - - if (ch == '2') - return DT_RL02; - - if (ch == '3') - return DT_TAPE; - - return { }; -} - +#if 0 #if !defined(BUILD_FOR_RP2040) std::optional, std::vector, std::string> > select_nbd_server(console *const c) { @@ -293,9 +239,10 @@ std::optional, std::vector, std::vector, std::string> > select_disk_files(console *const c) +// disk image files +std::optional select_disk_file(console *const c) { #if IS_POSIX c->put_string_lf("Files in current directory: "); @@ -367,11 +314,6 @@ std::optional, std::vectorput_string("Opening file: "); c->put_string_lf(selected_file.c_str()); @@ -388,9 +330,6 @@ std::optional, std::vector, std::vectorput_string_lf("open failed"); } + + return { }; } -void set_disk_configuration(bus *const b, console *const cnsl, std::tuple, std::vector, std::string> & disk_files) +int wait_for_key(const std::string & title, console *const cnsl, const std::vector & allowed) { - if (std::get<0>(disk_files).empty() == false) - b->add_rk05(new rk05(std::get<0>(disk_files), b, cnsl->get_disk_read_activity_flag(), cnsl->get_disk_write_activity_flag())); + cnsl->put_string_lf(title); - if (std::get<1>(disk_files).empty() == false) - b->add_rl02(new rl02(std::get<1>(disk_files), b, cnsl->get_disk_read_activity_flag(), cnsl->get_disk_write_activity_flag())); + cnsl->put_string("> "); - if (std::get<2>(disk_files).empty() == false) { - auto addr = loadTape(b, std::get<2>(disk_files)); + int ch = -1; + while(ch == -1) { + auto temp = cnsl->wait_char(500); - if (addr.has_value()) - b->getCpu()->setPC(addr.value()); + if (temp.has_value()) { + for(auto & a: allowed) { + if (a == temp.value()) { + ch = temp.value(); + break; + } + } + } } - if (std::get<0>(disk_files).empty() == false) - setBootLoader(b, BL_RK05); - else if (std::get<1>(disk_files).empty() == false) - setBootLoader(b, BL_RL02); + cnsl->put_string_lf(format("%c", ch)); + + return ch; } void configure_disk(bus *const b, console *const cnsl) { + // TODO tape + int ch = wait_for_key("1. RK05, 2. RL02, 9. abort", cnsl, { '1', '2', '3', '9' }); + + bootloader_t bl = BL_NONE; + disk_device *dd = nullptr; + + if (ch == '1') { + dd = b->getRK05(); + bl = BL_RK05; + } + else if (ch == '2') { + dd = b->getRL02(); + bl = BL_RL02; + } + else if (ch == '9') { + return; + } + for(;;) { - cnsl->put_string_lf("Load disk"); + std::vector keys_allowed { '1', '2', '9' }; - auto backend = select_disk_backend(cnsl); + auto cartridge_slots = dd->access_disk_backends(); + int slot_key = 'A'; + for(auto & slot: *cartridge_slots) { + cnsl->put_string_lf(format(" %c. %s", slot_key, slot ? slot->get_identifier().c_str() : "-")); + keys_allowed.push_back(slot_key); + slot_key++; + } - if (backend.has_value() == false) + int ch = wait_for_key("Select cartridge to setup, 1. to add a cartridge, 2. to load a bootloader or 9. to exit", cnsl, keys_allowed); + if (ch == '9') break; - std::optional, std::vector, std::string> > files; + if (ch == '1') { + auto image_file = select_disk_file(cnsl); -#if !defined(BUILD_FOR_RP2040) - if (backend == BE_NETWORK) - files = select_nbd_server(cnsl); - else // if (backend == BE_SD) -#endif - files = select_disk_files(cnsl); + if (image_file.has_value()) { + cartridge_slots->push_back(image_file.value()); - if (files.has_value() == false) - break; + cnsl->put_string_lf("Cartridge loaded"); + } + } + else if (ch == '2') { + set_boot_loader(b, bl); - set_disk_configuration(b, cnsl, files.value()); + cnsl->put_string_lf("Bootloader loaded"); + } + else { + int slot = ch - 'A'; - break; + for(;;) { + int ch = wait_for_key("Select cartridge action: 1. load, 2. unload, 9. exit", cnsl, { '1', '2', '9' }); + if (ch == '9') + break; + + if (ch == '1') { + auto image_file = select_disk_file(cnsl); + + if (image_file.has_value()) { + delete cartridge_slots->at(slot); + cartridge_slots->at(slot) = image_file.value(); + + cnsl->put_string_lf("Cartridge loaded"); + } + } + else if (ch == '2') { + if (cartridge_slots->at(slot)) { + delete cartridge_slots->at(slot); + cartridge_slots->at(slot) = nullptr; + + cnsl->put_string_lf("Cartridge unloaded"); + } + } + } + } } } @@ -1026,7 +1019,7 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto continue; } else if (parts[0] == "bl" && parts.size() == 2) { - setBootLoader(b, parts.at(1) == "rk05" ? BL_RK05 : BL_RL02); + set_boot_loader(b, parts.at(1) == "rk05" ? BL_RK05 : BL_RL02); cnsl->put_string_lf("Bootloader set"); continue; diff --git a/disk_device.h b/disk_device.h new file mode 100644 index 0000000..266fe84 --- /dev/null +++ b/disk_device.h @@ -0,0 +1,22 @@ +#pragma once + +#include + +#include "device.h" +#include "disk_backend.h" + + +class disk_device: public device +{ +protected: + std::vector fhs; + +public: + disk_device() { + } + + virtual ~disk_device() { + } + + std::vector * access_disk_backends() { return &fhs; } +}; diff --git a/loaders.cpp b/loaders.cpp index a28ac4c..8f71e3d 100644 --- a/loaders.cpp +++ b/loaders.cpp @@ -28,7 +28,7 @@ void loadbin(bus *const b, uint16_t base, const char *const file) fclose(fh); } -void setBootLoader(bus *const b, const bootloader_t which) +void set_boot_loader(bus *const b, const bootloader_t which) { cpu *const c = b -> getCpu(); diff --git a/loaders.h b/loaders.h index 35235df..704535a 100644 --- a/loaders.h +++ b/loaders.h @@ -11,6 +11,6 @@ typedef enum { BL_NONE, BL_RK05, BL_RL02 } bootloader_t; void loadbin(bus *const b, uint16_t base, const char *const file); -void setBootLoader(bus *const b, const bootloader_t which); +void set_boot_loader(bus *const b, const bootloader_t which); std::optional loadTape(bus *const b, const std::string & file); void load_p11_x11(bus *const b, const std::string & file); diff --git a/main.cpp b/main.cpp index 24de903..56f7c72 100644 --- a/main.cpp +++ b/main.cpp @@ -495,7 +495,7 @@ int main(int argc, char *argv[]) if (validate_json.empty() == false) return run_cpu_validation(validate_json); - DOLOG(info, true, "This PDP-11 emulator is called \"kek\" (reason for that is forgotten) and was written by Folkert van Heusden."); + DOLOG(info, true, "PDP11 emulator, by Folkert van Heusden"); DOLOG(info, true, "Built on: " __DATE__ " " __TIME__); @@ -525,26 +525,18 @@ int main(int argc, char *argv[]) cpu *c = new cpu(b, &event); b->add_cpu(c); - if (rk05_files.empty() == false) { - if (enable_bootloader == false) - DOLOG(warning, true, "Note: loading RK05 with no (RK05-) bootloader selected"); - else - bootloader = BL_RK05; + if (rk05_files.empty() == false) + bootloader = BL_RK05; - b->add_rk05(new rk05(rk05_files, b, cnsl->get_disk_read_activity_flag(), cnsl->get_disk_write_activity_flag())); - } - - if (rl02_files.empty() == false) { - if (enable_bootloader == false) - DOLOG(warning, true, "Note: loading RL02 with no (RL02-) bootloader selected"); - else - bootloader = BL_RL02; - - b->add_rl02(new rl02(rl02_files, b, cnsl->get_disk_read_activity_flag(), cnsl->get_disk_write_activity_flag())); - } + if (rl02_files.empty() == false) + bootloader = BL_RL02; if (enable_bootloader) - setBootLoader(b, bootloader); + set_boot_loader(b, bootloader); + + b->add_rk05(new rk05(rk05_files, b, cnsl->get_disk_read_activity_flag(), cnsl->get_disk_write_activity_flag())); + + b->add_rl02(new rl02(rl02_files, b, cnsl->get_disk_read_activity_flag(), cnsl->get_disk_write_activity_flag())); } else { FILE *fh = fopen(deserialize.c_str(), "r"); diff --git a/rk05.h b/rk05.h index 7ba4682..5189011 100644 --- a/rk05.h +++ b/rk05.h @@ -9,7 +9,7 @@ #include #include -#include "device.h" +#include "disk_device.h" #include "disk_backend.h" @@ -25,12 +25,11 @@ class bus; -class rk05 : public device +class rk05: public disk_device { private: bus *const b { nullptr }; uint16_t registers [7] { 0 }; - std::vector fhs; uint8_t xfer_buffer[512] { 0 }; std::atomic_bool *const disk_read_acitivity { nullptr }; diff --git a/rl02.cpp b/rl02.cpp index 339e93c..a62067f 100644 --- a/rl02.cpp +++ b/rl02.cpp @@ -271,7 +271,7 @@ void rl02::writeWord(const uint16_t addr, uint16_t v) mpr[0]++; } - if (!fhs.at(device)->write(temp_disk_offset, cur, xfer_buffer, 256)) { + if (fhs.at(device) == nullptr || fhs.at(device)->write(temp_disk_offset, cur, xfer_buffer, 256) == false) { DOLOG(ll_error, true, "RL02: write error, device %d, disk offset %u, read size %u, cylinder %d, head %d, sector %d", device, temp_disk_offset, cur, track, head, sector); break; } @@ -325,7 +325,7 @@ void rl02::writeWord(const uint16_t addr, uint16_t v) while(count > 0) { uint32_t cur = std::min(uint32_t(sizeof xfer_buffer), count); - if (!fhs.at(device)->read(temp_disk_offset, cur, xfer_buffer, 256)) { + if (fhs.at(device) == nullptr || fhs.at(device)->read(temp_disk_offset, cur, xfer_buffer, 256) == false) { DOLOG(ll_error, true, "RL02: read error, device %d, disk offset %u, read size %u, cylinder %d, head %d, sector %d", device, temp_disk_offset, cur, track, head, sector); break; } diff --git a/rl02.h b/rl02.h index 4a9858e..be8a96d 100644 --- a/rl02.h +++ b/rl02.h @@ -9,7 +9,7 @@ #include #include -#include "device.h" +#include "disk_device.h" #include "disk_backend.h" #include "gen.h" @@ -27,7 +27,7 @@ constexpr const int rl02_bytes_per_sector = 256; class bus; -class rl02 : public device +class rl02: public disk_device { private: bus *const b; @@ -37,10 +37,9 @@ private: uint8_t head { 0 }; uint8_t sector { 0 }; uint16_t mpr[3]; - std::vector fhs; - std::atomic_bool *const disk_read_activity { nullptr }; - std::atomic_bool *const disk_write_activity { nullptr }; + std::atomic_bool *const disk_read_activity { nullptr }; + std::atomic_bool *const disk_write_activity { nullptr }; uint32_t get_bus_address() const; void update_bus_address(const uint32_t a); From d86fd2690e9b31bd98cce54bd103ef79193a28a5 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Fri, 26 Apr 2024 15:08:39 +0200 Subject: [PATCH 03/19] select file or nbd --- debugger.cpp | 55 ++++++++++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/debugger.cpp b/debugger.cpp index c8fb8fd..4d696ec 100644 --- a/debugger.cpp +++ b/debugger.cpp @@ -196,50 +196,32 @@ bool save_disk_configuration(const std::string & nbd_host, const int nbd_port, c } #endif -#if 0 #if !defined(BUILD_FOR_RP2040) -std::optional, std::vector, std::string> > select_nbd_server(console *const c) +std::optional select_nbd_server(console *const cnsl) { - c->flush_input(); + cnsl->flush_input(); - std::string hostname = c->read_line("Enter hostname (or empty to abort): "); + std::string hostname = cnsl->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): "); + std::string port_str = cnsl->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) == false) { - c->put_string_lf("Cannot initialize NBD client"); + cnsl->put_string_lf("Cannot initialize NBD client"); delete d; return { }; } - if (save_disk_configuration(hostname, atoi(port_str.c_str()), { }, disk_type.value(), c)) - c->put_string_lf("NBD disk configuration saved"); - else - c->put_string_lf("NBD disk configuration NOT saved"); - - if (disk_type.value() == DT_RK05) - return { { { d }, { }, "" } }; - - if (disk_type.value() == DT_RL02) - return { { { }, { d }, "" } }; - - return { }; + return d; } #endif -#endif // disk image files std::optional select_disk_file(console *const c) @@ -379,6 +361,25 @@ int wait_for_key(const std::string & title, console *const cnsl, const std::vect return ch; } +std::optional select_disk_backend(console *const cnsl) +{ +#if defined(BUILD_FOR_RP2040) + return select_disk_file(cnsl); +#else + int ch = wait_for_key("1. local disk, 2. network disk (NBD), 9. abort", cnsl, { '1', '2', '9' }); + if (ch == '9') + return { }; + + if (ch == '1') + return select_disk_file(cnsl); + + if (ch == '2') + return select_nbd_server(cnsl); + + return { }; +#endif +} + void configure_disk(bus *const b, console *const cnsl) { // TODO tape @@ -415,7 +416,7 @@ void configure_disk(bus *const b, console *const cnsl) break; if (ch == '1') { - auto image_file = select_disk_file(cnsl); + auto image_file = select_disk_backend(cnsl); if (image_file.has_value()) { cartridge_slots->push_back(image_file.value()); @@ -437,7 +438,7 @@ void configure_disk(bus *const b, console *const cnsl) break; if (ch == '1') { - auto image_file = select_disk_file(cnsl); + auto image_file = select_disk_backend(cnsl); if (image_file.has_value()) { delete cartridge_slots->at(slot); @@ -1152,7 +1153,7 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto "bl - set bootload (rl02 or rk05)", #if IS_POSIX "ser - serialize state to a file", - "dser - deserialize state from a file", +// "dser - deserialize state from a file", #endif #if defined(ESP32) "cfgnet - configure network (e.g. WiFi)", From 90af933fb7b2c7ed66c5db13f89f83f86483eb71 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Fri, 26 Apr 2024 15:29:49 +0200 Subject: [PATCH 04/19] code clean-up & compile fix for ESP32 --- ESP32/disk_device.h | 1 + ESP32/main.ino | 7 +-- debugger.cpp | 150 -------------------------------------------- debugger.h | 4 -- 4 files changed, 2 insertions(+), 160 deletions(-) create mode 120000 ESP32/disk_device.h diff --git a/ESP32/disk_device.h b/ESP32/disk_device.h new file mode 120000 index 0000000..dbcee94 --- /dev/null +++ b/ESP32/disk_device.h @@ -0,0 +1 @@ +../disk_device.h \ No newline at end of file diff --git a/ESP32/main.ino b/ESP32/main.ino index 1609ba9..618845e 100644 --- a/ESP32/main.ino +++ b/ESP32/main.ino @@ -193,12 +193,7 @@ void recall_configuration(console *const cnsl) cnsl->put_string_lf("Starting network..."); start_network(cnsl); - auto disk_configuration = load_disk_configuration(cnsl); - - if (disk_configuration.has_value()) { - cnsl->put_string_lf("Starting disk..."); - set_disk_configuration(b, cnsl, disk_configuration.value()); - } + // TODO } #endif diff --git a/debugger.cpp b/debugger.cpp index 4d696ec..c48241b 100644 --- a/debugger.cpp +++ b/debugger.cpp @@ -10,7 +10,6 @@ #include #else #include -#include #include #endif @@ -47,155 +46,12 @@ void check_network(console *const c); void start_network(console *const c); void set_tty_serial_speed(console *const c, const uint32_t bps); - -void recall_configuration(console *const c); #endif -#define NET_DISK_CFG_FILE "net-disk.json" - #if !defined(BUILD_FOR_RP2040) && !defined(linux) extern SdFs SD; #endif -#ifndef linux -#define MAX_CFG_SIZE 1024 -StaticJsonDocument json_doc; -#endif - -typedef enum { BE_NETWORK, BE_SD } disk_backend_t; - -#if !defined(BUILD_FOR_RP2040) -std::optional, std::vector, std::string> > load_disk_configuration(console *const c) -{ -#if IS_POSIX - json_error_t error; - json_t *json = json_load_file("." NET_DISK_CFG_FILE, JSON_REJECT_DUPLICATES, &error); - if (!json) { - c->put_string_lf(format("Cannot load ." NET_DISK_CFG_FILE ": %s", error.text)); - - return { }; - } - - std::string nbd_host = json_string_value (json_object_get(json, "NBD-host")); - int nbd_port = json_integer_value(json_object_get(json, "NBD-port")); - - std::string disk_type_temp = json_string_value (json_object_get(json, "disk-type")); - - std::string tape_file = json_string_value (json_object_get(json, "tape-file")); - - json_decref(json); -#else - File dataFile = LittleFS.open("/" NET_DISK_CFG_FILE, "r"); - if (!dataFile) - return { }; - - size_t size = dataFile.size(); - - char buffer[MAX_CFG_SIZE]; - - if (size > sizeof buffer) { // this should not happen - dataFile.close(); - - return { }; - } - - dataFile.read(reinterpret_cast(buffer), size); - buffer[(sizeof buffer) - 1] = 0x00; - - dataFile.close(); - - auto error = deserializeJson(json_doc, buffer); - if (error) // this should not happen - return { }; - - String nbd_host = json_doc["NBD-host"]; - int nbd_port = json_doc["NBD-port"]; - - String disk_type_temp = json_doc["disk-type"]; - - String tape_file = json_doc["tape-file"]; -#endif - - disk_type_t disk_type = DT_RK05; - - if (disk_type_temp == "rl02") - disk_type = DT_RL02; - else if (disk_type_temp == "tape") - disk_type = DT_TAPE; - - disk_backend *d = new disk_backend_nbd(nbd_host.c_str(), nbd_port); - - if (d->begin(false) == false) { - c->put_string_lf("Cannot initialize NBD client from configuration file"); - delete d; - return { }; - } - - c->put_string_lf(format("Connection to NBD server at %s:%d success", nbd_host.c_str(), nbd_port)); - - if (disk_type == DT_RK05) - return { { { d }, { }, "" } }; - - if (disk_type == DT_RL02) - return { { { }, { d }, "" } }; - - if (disk_type == DT_TAPE) - return { { { }, { }, tape_file.c_str() } }; - - return { }; -} - -bool save_disk_configuration(const std::string & nbd_host, const int nbd_port, const std::optional & tape_file, const disk_type_t dt, console *const cnsl) -{ -#if IS_POSIX - json_t *json = json_object(); - - json_object_set(json, "NBD-host", json_string(nbd_host.c_str())); - json_object_set(json, "NBD-port", json_integer(nbd_port)); - - if (dt == DT_RK05) - json_object_set(json, "disk-type", json_string("rk05")); - else if (dt == DT_RL02) - json_object_set(json, "disk-type", json_string("rl02")); - else - json_object_set(json, "disk-type", json_string("tape")); - - json_object_set(json, "tape-file", json_string(tape_file.has_value() ? tape_file.value().c_str() : "")); - - bool succeeded = json_dump_file(json, "." NET_DISK_CFG_FILE, 0) == 0; - json_decref(json); - - if (succeeded == false) { - cnsl->put_string_lf(format("Cannot write ." NET_DISK_CFG_FILE)); - - return false; - } -#else - json_doc["NBD-host"] = nbd_host; - json_doc["NBD-port"] = nbd_port; - - if (dt == DT_RK05) - json_doc["disk-type"] = "rk05"; - else if (dt == DT_RL02) - json_doc["disk-type"] = "rl02"; - else - json_doc["disk-type"] = "tape"; - - json_doc["tape-file"] = tape_file.has_value() ? tape_file.value() : ""; - - File dataFile = LittleFS.open("/" NET_DISK_CFG_FILE, "w"); - if (!dataFile) - return false; - - serializeJson(json_doc, dataFile); - - dataFile.close(); -#endif - - return true; -} -#endif - #if !defined(BUILD_FOR_RP2040) std::optional select_nbd_server(console *const cnsl) { @@ -995,11 +851,6 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto cnsl->put_string_lf("serspd requires an (decimal) parameter"); } - continue; - } - else if (cmd == "init") { - recall_configuration(cnsl); - continue; } #endif @@ -1160,7 +1011,6 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto "startnet - start network", "chknet - check network status", "serspd - set serial speed in bps (8N1 are default)", - "init - reload (disk-)configuration from flash", #endif "cfgdisk - configure disk", nullptr diff --git a/debugger.h b/debugger.h index 6a39e46..083f0a1 100644 --- a/debugger.h +++ b/debugger.h @@ -6,10 +6,6 @@ #include "gen.h" -std::optional, std::vector, std::string> > load_disk_configuration(console *const c); -bool save_disk_configuration(const std::string & nbd_host, const int nbd_port, const disk_type_t dt); -void set_disk_configuration(bus *const b, console *const cnsl, std::tuple, std::vector, std::string> & disk_files); - int disassemble(cpu *const c, console *const cnsl, const uint16_t pc, const bool instruction_only); void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const stop_event, const bool tracing); From 7cc3dab687ef13cf136c48be5992f7267e36ca38 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Fri, 26 Apr 2024 16:01:31 +0200 Subject: [PATCH 05/19] casing --- loaders.cpp | 16 ++++++++-------- loaders.h | 4 ++-- main.cpp | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/loaders.cpp b/loaders.cpp index 8f71e3d..8752141 100644 --- a/loaders.cpp +++ b/loaders.cpp @@ -23,14 +23,14 @@ void loadbin(bus *const b, uint16_t base, const char *const file) FILE *fh = fopen(file, "rb"); while(!feof(fh)) - b -> writeByte(base++, fgetc(fh)); + b->writeByte(base++, fgetc(fh)); fclose(fh); } void set_boot_loader(bus *const b, const bootloader_t which) { - cpu *const c = b -> getCpu(); + cpu *const c = b->getCpu(); uint16_t offset = 0; uint16_t start = 0; @@ -139,12 +139,12 @@ void set_boot_loader(bus *const b, const bootloader_t which) } for(int i=0; i writeWord(offset + i * 2, bl[i]); + b->writeWord(offset + i * 2, bl[i]); - c -> setRegister(7, start); + c->setRegister(7, start); } -std::optional loadTape(bus *const b, const std::string & file) +std::optional load_tape(bus *const b, const std::string & file) { #if defined(ESP32) File32 fh; @@ -211,7 +211,7 @@ std::optional loadTape(bus *const b, const std::string & file) #endif csum += c; - b -> writeByte(p++, c); + b->writeByte(p++, c); } #if defined(ESP32) @@ -271,6 +271,6 @@ void load_p11_x11(bus *const b, const std::string & file) fclose(fh); - cpu *const c = b -> getCpu(); - c -> setRegister(7, 0); + cpu *const c = b->getCpu(); + c->setRegister(7, 0); } diff --git a/loaders.h b/loaders.h index 704535a..4b6846f 100644 --- a/loaders.h +++ b/loaders.h @@ -1,4 +1,4 @@ -// (C) 2018-2023 by Folkert van Heusden +// (C) 2018-2024 by Folkert van Heusden // Released under MIT license #include @@ -12,5 +12,5 @@ typedef enum { BL_NONE, BL_RK05, BL_RL02 } bootloader_t; void loadbin(bus *const b, uint16_t base, const char *const file); void set_boot_loader(bus *const b, const bootloader_t which); -std::optional loadTape(bus *const b, const std::string & file); +std::optional load_tape(bus *const b, const std::string & file); void load_p11_x11(bus *const b, const std::string & file); diff --git a/main.cpp b/main.cpp index 56f7c72..7426408 100644 --- a/main.cpp +++ b/main.cpp @@ -574,7 +574,7 @@ int main(int argc, char *argv[]) std::optional bic_start; if (tape.empty() == false) { - bic_start = loadTape(b, tape); + bic_start = load_tape(b, tape); if (bic_start.has_value() == false) return 1; // fail From 6be8f2c970ed4a12d109f1c24a9364e0cccb9318 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Fri, 26 Apr 2024 16:05:29 +0200 Subject: [PATCH 06/19] ESP32: allocate memory & init disks --- ESP32/main.ino | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/ESP32/main.ino b/ESP32/main.ino index 618845e..8748cd1 100644 --- a/ESP32/main.ino +++ b/ESP32/main.ino @@ -70,6 +70,9 @@ std::atomic_bool *running { nullptr }; bool trace_output { false }; +std::vector rk05_files; +std::vector rl02_files; + void console_thread_wrapper_panel(void *const c) { console *const cnsl = reinterpret_cast(c); @@ -258,12 +261,20 @@ void setup() { Serial.println(F("Init bus")); b = new bus(); + Serial.println(F("Allocate memory")); + b->set_memory_size(DEFAULT_N_PAGES); + Serial.println(F("Init CPU")); c = new cpu(b, &stop_event); Serial.println(F("Connect CPU to BUS")); b->add_cpu(c); + Serial.println(F("Connect RK05 and RL02 to BUS")); + b->add_rk05(new rk05(rk05_files, b, cnsl->get_disk_read_activity_flag(), cnsl->get_disk_write_activity_flag())); + + b->add_rl02(new rl02(rl02_files, b, cnsl->get_disk_read_activity_flag(), cnsl->get_disk_write_activity_flag())); + constexpr uint32_t hwSerialConfig = SERIAL_8N1; uint32_t bitrate = load_serial_speed_configuration(); From 723edfd0f975c03718605a6763600ec6086338b4 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Fri, 26 Apr 2024 16:13:38 +0200 Subject: [PATCH 07/19] instantiate rk05/rl02 after console has been setup --- ESP32/main.ino | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ESP32/main.ino b/ESP32/main.ino index 8748cd1..bb29dd8 100644 --- a/ESP32/main.ino +++ b/ESP32/main.ino @@ -270,11 +270,6 @@ void setup() { Serial.println(F("Connect CPU to BUS")); b->add_cpu(c); - Serial.println(F("Connect RK05 and RL02 to BUS")); - b->add_rk05(new rk05(rk05_files, b, cnsl->get_disk_read_activity_flag(), cnsl->get_disk_write_activity_flag())); - - b->add_rl02(new rl02(rl02_files, b, cnsl->get_disk_read_activity_flag(), cnsl->get_disk_write_activity_flag())); - constexpr uint32_t hwSerialConfig = SERIAL_8N1; uint32_t bitrate = load_serial_speed_configuration(); @@ -299,6 +294,11 @@ void setup() { running = cnsl->get_running_flag(); + Serial.println(F("Connect RK05 and RL02 to BUS")); + b->add_rk05(new rk05(rk05_files, b, cnsl->get_disk_read_activity_flag(), cnsl->get_disk_write_activity_flag())); + + b->add_rl02(new rl02(rl02_files, b, cnsl->get_disk_read_activity_flag(), cnsl->get_disk_write_activity_flag())); + Serial.println(F("Init TTY")); tty_ = new tty(cnsl, b); Serial.println(F("Connect TTY to bus")); From 4824cab4206da97b8ecf896918c4fffa0313e573 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Fri, 26 Apr 2024 21:21:27 +0200 Subject: [PATCH 08/19] comment --- gen.h | 1 + 1 file changed, 1 insertion(+) diff --git a/gen.h b/gen.h index 8629ac9..291e32b 100644 --- a/gen.h +++ b/gen.h @@ -28,5 +28,6 @@ typedef enum { rm_prev, rm_cur } rm_selection_t; // see also https://github.com/espressif/esp-idf/issues/1934 #define DEFAULT_N_PAGES 12 #else +// more requires unibusmap support #define DEFAULT_N_PAGES 31 #endif From 108de1ccba2f67af3924ff1f101f0754af0e69c2 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sat, 27 Apr 2024 08:54:54 +0200 Subject: [PATCH 09/19] overlay chatty debug removed --- rl02.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rl02.cpp b/rl02.cpp index a62067f..6974218 100644 --- a/rl02.cpp +++ b/rl02.cpp @@ -365,7 +365,7 @@ void rl02::writeWord(const uint16_t addr, uint16_t v) *disk_read_activity = false; } else { - DOLOG(warning, false, "RL02: command %d not implemented", command); + DOLOG(debug, false, "RL02: command %d not implemented", command); } if (do_int) { From 4c921738b4833b09b19e0c4a9a3a0ab5cba7e992 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sat, 27 Apr 2024 09:36:48 +0200 Subject: [PATCH 10/19] tweaks --- CMakeLists.txt | 4 ++-- ESP32/platformio.ini | 2 +- breakpoint_register.cpp | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bdb83e8..70291a2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,8 +6,8 @@ cmake_minimum_required(VERSION 3.9) add_compile_options(-Wall -pedantic -Wextra) -#add_compile_options(-fsanitize=address) -#add_link_options(-fsanitize=address) +#add_compile_options(-fsanitize=undefined) +#add_link_options(-fsanitize=undefined) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED True) diff --git a/ESP32/platformio.ini b/ESP32/platformio.ini index 948ef3a..c085fdd 100644 --- a/ESP32/platformio.ini +++ b/ESP32/platformio.ini @@ -17,7 +17,7 @@ board_build.filesystem = littlefs lib_deps = greiman/SdFat@^2.1.2 adafruit/Adafruit NeoPixel bblanchon/ArduinoJson@^6.19.4 -build_flags = -std=gnu++2a -DESP32=1 -ggdb3 -D_GLIBCXX_USE_C99 +build_flags = -std=gnu++2a -DESP32=1 -ggdb3 -D_GLIBCXX_USE_C99 -Wall build_unflags = -std=gnu++11 -std=gnu++17 extra_scripts = pre:prepare.py diff --git a/breakpoint_register.cpp b/breakpoint_register.cpp index 9a94f63..832aef0 100644 --- a/breakpoint_register.cpp +++ b/breakpoint_register.cpp @@ -101,12 +101,12 @@ std::pair > breakpoint_registe else if (key == "PC" || key == "pc") { return { new breakpoint_register(b, 7, values), { } }; } - else if (key.substr(0, 3) == "MMR" or key.substr(0, 3) == "mmr") { + else if (key.substr(0, 3) == "MMR" || key.substr(0, 3) == "mmr") { int which = key[3] - '0'; return { new breakpoint_register(b, hr_mmr0 + which, values), { } }; } - else if (key.substr(0, 3) == "PSW" or key.substr(0, 3) == "psw") { + else if (key.substr(0, 3) == "PSW" || key.substr(0, 3) == "psw") { return { new breakpoint_register(b, hr_psw, values), { } }; } From b3932c2100da5b9012b46c83bccd6b0c8a762fbd Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sat, 27 Apr 2024 12:23:30 +0200 Subject: [PATCH 11/19] init variables --- mmu.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/mmu.cpp b/mmu.cpp index 5e42949..17abfe5 100644 --- a/mmu.cpp +++ b/mmu.cpp @@ -9,6 +9,7 @@ mmu::mmu() { + reset(); } mmu::~mmu() From 19ea36c809ad921d47a114450051e3004acdd189 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sat, 27 Apr 2024 21:28:00 +0200 Subject: [PATCH 12/19] dp - stop panel --- ESP32/console_esp32.cpp | 8 ++++++-- ESP32/main.ino | 2 ++ ESP32/platformio.ini | 15 +++++++++++++++ console.h | 4 +++- console_ncurses.cpp | 2 +- debugger.cpp | 6 ++++++ 6 files changed, 33 insertions(+), 4 deletions(-) diff --git a/ESP32/console_esp32.cpp b/ESP32/console_esp32.cpp index d4efeb0..787733f 100644 --- a/ESP32/console_esp32.cpp +++ b/ESP32/console_esp32.cpp @@ -72,7 +72,6 @@ void console_esp32::panel_update_thread() pixels.begin(); pixels.clear(); - pixels.show(); constexpr uint8_t brightness = 16; @@ -103,7 +102,7 @@ void console_esp32::panel_update_thread() pixels.clear(); pixels.show(); - for(;;) { + while(!stop_panel) { vTaskDelay(20 / portTICK_PERIOD_MS); try { @@ -141,5 +140,10 @@ void console_esp32::panel_update_thread() put_string_lf("Unknown exception in panel thread"); } } + + pixels.clear(); + pixels.show(); + + Serial.println(F("panel task terminating")); #endif } diff --git a/ESP32/main.ino b/ESP32/main.ino index bb29dd8..cbe8a39 100644 --- a/ESP32/main.ino +++ b/ESP32/main.ino @@ -78,6 +78,8 @@ void console_thread_wrapper_panel(void *const c) console *const cnsl = reinterpret_cast(c); cnsl->panel_update_thread(); + + vTaskSuspend(nullptr); } uint32_t load_serial_speed_configuration() diff --git a/ESP32/platformio.ini b/ESP32/platformio.ini index 948ef3a..6fb61ee 100644 --- a/ESP32/platformio.ini +++ b/ESP32/platformio.ini @@ -35,3 +35,18 @@ lib_deps = greiman/SdFat@^2.1.2 build_flags = -std=gnu++2a -DESP32=1 -DSHA2017 -ggdb3 -D_GLIBCXX_USE_C99 -ISHAdisplay/Arduino/libraries/epd2in9-badge -ISHAdisplay/Arduino/libraries/epdpaint -ISHAdisplay/components/epaper-29-dke build_unflags = -std=gnu++11 -std=gnu++17 upload_protocol = esptool + +[env:ESP32-ttgo-t-beam] +build_src_filter = +<*> -<.git/> -<.svn/> - - - - - - - - +platform = espressif32 +board = ttgo-t-beam +framework = arduino +monitor_speed = 115200 +upload_speed = 1000000 +board_build.filesystem = littlefs +lib_deps = greiman/SdFat@^2.1.2 + adafruit/Adafruit NeoPixel + bblanchon/ArduinoJson@^6.19.4 +build_flags = -std=gnu++17 -DESP32=1 -ggdb3 -D_GLIBCXX_USE_C99 +build_unflags = -std=gnu++11 +extra_scripts = pre:prepare.py diff --git a/console.h b/console.h index 5cb932f..6101602 100644 --- a/console.h +++ b/console.h @@ -29,7 +29,8 @@ private: #endif protected: - std::atomic_uint32_t *const stop_event { nullptr }; + std::atomic_uint32_t *const stop_event { nullptr }; + std::atomic_bool stop_panel { false }; bus *b { nullptr }; #if !defined(BUILD_FOR_RP2040) @@ -88,5 +89,6 @@ public: std::atomic_bool * get_disk_read_activity_flag() { return &disk_read_activity_flag; } std::atomic_bool * get_disk_write_activity_flag() { return &disk_write_activity_flag; } + void stop_panel_thread() { stop_panel = true; } virtual void panel_update_thread() = 0; }; diff --git a/console_ncurses.cpp b/console_ncurses.cpp index df2e736..9ec7753 100644 --- a/console_ncurses.cpp +++ b/console_ncurses.cpp @@ -133,7 +133,7 @@ void console_ncurses::panel_update_thread() constexpr int refresh_rate = 50; - while(*stop_event != EVENT_TERMINATE) { + while(*stop_event != EVENT_TERMINATE && stop_panel == false) { myusleep(1000000 / refresh_rate); // note that these are approximately as there's no mutex on the emulation diff --git a/debugger.cpp b/debugger.cpp index c48241b..9d2244b 100644 --- a/debugger.cpp +++ b/debugger.cpp @@ -951,6 +951,11 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto continue; } + else if (cmd == "dp") { + cnsl->stop_panel_thread(); + + continue; + } else if (cmd == "bt") { if (c->get_debug() == false) cnsl->put_string_lf("Debug mode is disabled!"); @@ -1006,6 +1011,7 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto "ser - serialize state to a file", // "dser - deserialize state from a file", #endif + "dp - stop panel", #if defined(ESP32) "cfgnet - configure network (e.g. WiFi)", "startnet - start network", From ff1da92dc8248d67066f1abf4a5a5642291b6a9e Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sat, 27 Apr 2024 21:39:13 +0200 Subject: [PATCH 13/19] fix for syslog --- debugger.cpp | 7 +++++-- log.cpp | 9 ++++++--- log.h | 3 ++- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/debugger.cpp b/debugger.cpp index 9d2244b..9b5fcb9 100644 --- a/debugger.cpp +++ b/debugger.cpp @@ -942,7 +942,10 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto } #endif else if (parts[0] == "setsl" && parts.size() == 3) { - setloghost(parts.at(1).c_str(), parse_ll(parts[2])); + if (setloghost(parts.at(1).c_str(), parse_ll(parts[2])) == false) + cnsl->put_string_lf("Failed parsing IP address"); + else + send_syslog(info, "Hello, world!"); continue; } @@ -1011,7 +1014,7 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto "ser - serialize state to a file", // "dser - deserialize state from a file", #endif - "dp - stop panel", + "dp - disable panel", #if defined(ESP32) "cfgnet - configure network (e.g. WiFi)", "startnet - start network", diff --git a/log.cpp b/log.cpp index d250081..df44581 100644 --- a/log.cpp +++ b/log.cpp @@ -54,16 +54,19 @@ void setlogfile(const char *const lf, const log_level_t ll_file, const log_level atexit(closelog); } -void setloghost(const char *const host, const log_level_t ll) +bool setloghost(const char *const host, const log_level_t ll) { - inet_aton(host, &syslog_ip_addr.sin_addr); - syslog_ip_addr.sin_port = htons(514); + syslog_ip_addr.sin_family = AF_INET; + bool ok = inet_aton(host, &syslog_ip_addr.sin_addr) == 1; + syslog_ip_addr.sin_port = htons(514); is_file = false; log_level_file = ll; l_timestamp = false; + + return ok; } void setll(const log_level_t ll_screen, const log_level_t ll_file) diff --git a/log.h b/log.h index 50b6ce5..668cf33 100644 --- a/log.h +++ b/log.h @@ -12,9 +12,10 @@ typedef enum { ll_emerg = 0, ll_alert, ll_critical, ll_error, warning, notice, i log_level_t parse_ll(const std::string & str); void setlogfile(const char *const lf, const log_level_t ll_file, const log_level_t ll_screen, const bool l_timestamp); -void setloghost(const char *const host, const log_level_t ll); +bool setloghost(const char *const host, const log_level_t ll); void setll(const log_level_t ll_screen, const log_level_t ll_file); void setloguid(const int uid, const int gid); +void send_syslog(const int ll, const std::string & what); void closelog(); void dolog(const log_level_t ll, const char *fmt, ...); From 9e71b84b1ac0edbf39d6854c90c6a5910a5a8da4 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sat, 27 Apr 2024 21:57:09 +0200 Subject: [PATCH 14/19] static -> constexpr const --- loaders.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/loaders.cpp b/loaders.cpp index 8752141..3c89805 100644 --- a/loaders.cpp +++ b/loaders.cpp @@ -30,7 +30,7 @@ void loadbin(bus *const b, uint16_t base, const char *const file) void set_boot_loader(bus *const b, const bootloader_t which) { - cpu *const c = b->getCpu(); + cpu *const c = b->getCpu(); uint16_t offset = 0; uint16_t start = 0; @@ -40,7 +40,7 @@ void set_boot_loader(bus *const b, const bootloader_t which) if (which == BL_RK05) { start = offset = 01000; - static uint16_t rk05_code[] = { + constexpr const uint16_t rk05_code[] = { 0012700, 0177406, 0012710, @@ -92,7 +92,7 @@ void set_boot_loader(bus *const b, const bootloader_t which) start = offset = 01000; /* from https://www.pdp-11.nl/peripherals/disk/rl-info.html - static uint16_t rl02_code[] = { + constexpr const uint16_t rl02_code[] = { 0012701, 0174400, 0012761, @@ -120,7 +120,7 @@ void set_boot_loader(bus *const b, const bootloader_t which) */ // from http://gunkies.org/wiki/RL11_disk_controller - static uint16_t rl02_code[] = { + constexpr const uint16_t rl02_code[] = { 0012700, 0174400, 0012760, From c591387481f0fddff3670afc6f15caac0afcc4c6 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sat, 27 Apr 2024 22:01:13 +0200 Subject: [PATCH 15/19] old code --- debugger.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/debugger.cpp b/debugger.cpp index 9b5fcb9..c276cbe 100644 --- a/debugger.cpp +++ b/debugger.cpp @@ -37,13 +37,9 @@ #include "rp2040.h" #endif -void set_boot_loader(bus *const b); - -void configure_disk(console *const c); - -void configure_network(console *const c); -void check_network(console *const c); -void start_network(console *const c); +void configure_network(console *const cnsl); +void check_network(console *const cnsl); +void start_network(console *const cnsl); void set_tty_serial_speed(console *const c, const uint32_t bps); #endif From 473f247bccaba7aae8152602ace0b0dd72ec0eea Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sat, 27 Apr 2024 22:43:24 +0200 Subject: [PATCH 16/19] debug (ESP32) --- debugger.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/debugger.cpp b/debugger.cpp index c276cbe..12c259a 100644 --- a/debugger.cpp +++ b/debugger.cpp @@ -821,6 +821,12 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto continue; } #if defined(ESP32) + else if (cmd == "debug") { + if (heap_caps_check_integrity(MALLOC_CAP_DEFAULT, true) == false) + cnsl->put_string_lf("HEAP corruption!"); + + continue; + } else if (cmd == "cfgnet") { configure_network(cnsl); @@ -1016,6 +1022,7 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto "startnet - start network", "chknet - check network status", "serspd - set serial speed in bps (8N1 are default)", + "debug - debugging info", #endif "cfgdisk - configure disk", nullptr From f9797d5e8e2493775f5d8197afdfe439ea9680c8 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sat, 27 Apr 2024 22:43:43 +0200 Subject: [PATCH 17/19] init NBD structures --- disk_backend_nbd.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/disk_backend_nbd.cpp b/disk_backend_nbd.cpp index 310e31c..031aede 100644 --- a/disk_backend_nbd.cpp +++ b/disk_backend_nbd.cpp @@ -91,10 +91,10 @@ bool disk_backend_nbd::connect(const bool retry) { do { // LOOP until connected, logging message, exponential backoff? - addrinfo *res = nullptr; + addrinfo *res = nullptr; addrinfo hints { 0 }; - hints.ai_family = AF_INET; + hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; char port_str[8] { 0 }; @@ -137,7 +137,7 @@ bool disk_backend_nbd::connect(const bool retry) uint64_t size; uint32_t flags; uint8_t padding[124]; - } nbd_hello; + } nbd_hello { }; if (fd != -1) { if (READ(fd, reinterpret_cast(&nbd_hello), sizeof nbd_hello) != sizeof nbd_hello) { @@ -194,7 +194,7 @@ bool disk_backend_nbd::read(const off_t offset_in, const size_t n, uint8_t *cons uint64_t handle; uint64_t offset; uint32_t length; - } nbd_request { 0 }; + } nbd_request { }; nbd_request.magic = ntohl(0x25609513); nbd_request.type = 0; // READ From 3453b1d9c39f480cd202e390701baeca6696fd22 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sat, 27 Apr 2024 22:50:17 +0200 Subject: [PATCH 18/19] debugging on ESP32 --- ESP32/main.ino | 15 +++++++++++++++ debugger.cpp | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/ESP32/main.ino b/ESP32/main.ino index cbe8a39..15c3220 100644 --- a/ESP32/main.ino +++ b/ESP32/main.ino @@ -18,6 +18,9 @@ #include #include #endif +#if defined(ESP32) +#include "esp_heap_caps.h" +#endif #if defined(SHA2017) #include "console_shabadge.h" @@ -210,6 +213,14 @@ void set_tty_serial_speed(console *const c, const uint32_t bps) c->put_string_lf("Failed to store configuration file with serial settings"); } +#if defined(ESP32) +void heap_caps_alloc_failed_hook(size_t requested_size, uint32_t caps, const char *function_name) +{ + printf("%s was called but failed to allocate %d bytes with 0x%X capabilities\r\n", function_name, requested_size, caps); +} + +#endif + void setup() { Serial.begin(115200); @@ -224,6 +235,10 @@ void setup() { Serial.print(F("Size of int: ")); Serial.println(sizeof(int)); +#if defined(ESP32) + heap_caps_register_failed_alloc_callback(heap_caps_alloc_failed_hook); +#endif + #if !defined(BUILD_FOR_RP2040) Serial.print(F("CPU clock frequency (MHz): ")); Serial.println(getCpuFrequencyMhz()); diff --git a/debugger.cpp b/debugger.cpp index 12c259a..51e425b 100644 --- a/debugger.cpp +++ b/debugger.cpp @@ -822,7 +822,7 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto } #if defined(ESP32) else if (cmd == "debug") { - if (heap_caps_check_integrity(MALLOC_CAP_DEFAULT, true) == false) + if (heap_caps_check_integrity_all(true) == false) cnsl->put_string_lf("HEAP corruption!"); continue; From fef50688aaa3ea05748591e4d47c0581394b7501 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sat, 27 Apr 2024 23:18:14 +0200 Subject: [PATCH 19/19] constants removal --- bus.cpp | 16 +++++++--------- bus.h | 4 ---- debugger.cpp | 3 ++- memory.h | 2 ++ 4 files changed, 11 insertions(+), 14 deletions(-) diff --git a/bus.cpp b/bus.cpp index 5d73884..232d82d 100644 --- a/bus.cpp +++ b/bus.cpp @@ -120,8 +120,6 @@ bus *bus::deserialize(const json_t *const j, console *const cnsl, std::atomic_ui void bus::set_memory_size(const int n_pages) { - this->n_pages = n_pages; - uint32_t n_bytes = n_pages * 8192l; delete m; @@ -474,7 +472,7 @@ uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm } // LO size register field must be all 1s, so subtract 1 - uint32_t system_size = n_pages * 8192l / 64 - 1; + uint32_t system_size = m->get_memory_size() / 64 - 1; if (a == ADDR_SYSSIZE + 2) { // system size HI uint16_t temp = system_size >> 16; @@ -505,7 +503,7 @@ uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm return 0; } - if (m_offset >= uint32_t(n_pages * 8192)) { + if (m_offset >= m->get_memory_size()) { if (peek_only) { DOLOG(debug, false, "READ from %06o - out of range!", addr_in); return 0; @@ -696,8 +694,8 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c } } - if (m_offset >= n_pages * 8192l && !is_io) [[unlikely]] { - DOLOG(debug, !peek_only, "bus::calculate_physical_address %o >= %o", m_offset, n_pages * 8192l); + if (m_offset >= m->get_memory_size() && !is_io) [[unlikely]] { + DOLOG(debug, !peek_only, "bus::calculate_physical_address %o >= %o", m_offset, m->get_memory_size()); DOLOG(debug, false, "TRAP(04) (throw 6) on address %06o", a); if (mmu_->is_locked() == false) { @@ -1025,7 +1023,7 @@ write_rc_t bus::write(const uint16_t addr_in, const word_mode_t word_mode, uint1 DOLOG(debug, false, "WRITE to %06o/%07o %c %c: %06o", addr_in, m_offset, space == d_space ? 'D' : 'I', word_mode == wm_byte ? 'B' : 'W', value); - if (m_offset >= uint32_t(n_pages * 8192)) { + if (m_offset >= m->get_memory_size()) { c->trap(004); // no such RAM throw 1; } @@ -1042,7 +1040,7 @@ void bus::writePhysical(const uint32_t a, const uint16_t value) { DOLOG(debug, false, "physicalWRITE %06o to %o", value, a); - if (a >= n_pages * 8192l) { + if (a >= m->get_memory_size()) { DOLOG(debug, false, "physicalWRITE to %o: trap 004", a); c->trap(004); throw 12; @@ -1054,7 +1052,7 @@ void bus::writePhysical(const uint32_t a, const uint16_t value) uint16_t bus::readPhysical(const uint32_t a) { - if (a >= n_pages * 8192l) { + if (a >= m->get_memory_size()) { DOLOG(debug, false, "physicalREAD from %o: trap 004", a); c->trap(004); throw 13; diff --git a/bus.h b/bus.h index 1e8db64..800e926 100644 --- a/bus.h +++ b/bus.h @@ -75,10 +75,7 @@ private: rl02 *rl02_ { nullptr }; tty *tty_ { nullptr }; kw11_l *kw11_l_ { nullptr }; - mmu *mmu_ { nullptr }; - - int n_pages { DEFAULT_N_PAGES }; memory *m { nullptr }; uint16_t microprogram_break_register { 0 }; @@ -104,7 +101,6 @@ public: void set_debug_mode() { console_switches |= 128; } uint16_t get_console_leds() { return console_leds; } - int get_memory_size() const { return n_pages; } void set_memory_size(const int n_pages); void mmudebug(const uint16_t a); diff --git a/debugger.cpp b/debugger.cpp index 51e425b..ee35957 100644 --- a/debugger.cpp +++ b/debugger.cpp @@ -26,6 +26,7 @@ #include "disk_backend_nbd.h" #include "loaders.h" #include "log.h" +#include "memory.h" #include "tty.h" #include "utils.h" @@ -865,7 +866,7 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto if (parts.size() == 2) b->set_memory_size(std::stoi(parts.at(1))); else { - int n_pages = b->get_memory_size(); + int n_pages = b->getRAM()->get_memory_size(); cnsl->put_string_lf(format("Memory size: %u pages or %u kB (decimal)", n_pages, n_pages * 8192 / 1024)); } diff --git a/memory.h b/memory.h index 1a5dcbc..8ec1c14 100644 --- a/memory.h +++ b/memory.h @@ -18,6 +18,8 @@ public: memory(const uint32_t size); ~memory(); + uint32_t get_memory_size() const { return size; } + void reset(); #if IS_POSIX json_t *serialize() const;