From 6236d96b8328b9923fe8661f5d1190a5725de243 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Tue, 21 Mar 2023 21:45:25 +0100 Subject: [PATCH] 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);