disk backend

This commit is contained in:
folkert van heusden 2023-03-21 21:45:25 +01:00
parent a672841865
commit 6236d96b83
Signed by untrusted user who does not match committer: folkert
GPG key ID: 6B6455EDFEED3BD1
10 changed files with 117 additions and 162 deletions

View file

@ -14,6 +14,8 @@ add_executable(
console_posix.cpp console_posix.cpp
cpu.cpp cpu.cpp
debugger.cpp debugger.cpp
disk_backend.cpp
disk_backend_file.cpp
error.cpp error.cpp
kw11-l.cpp kw11-l.cpp
loaders.cpp loaders.cpp

9
disk_backend.cpp Normal file
View file

@ -0,0 +1,9 @@
#include "disk_backend.h"
disk_backend::disk_backend()
{
}
disk_backend::~disk_backend()
{
}

16
disk_backend.h Normal file
View file

@ -0,0 +1,16 @@
#pragma once
#include <stdint.h>
#include <sys/types.h>
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;
};

30
disk_backend_file.cpp Normal file
View file

@ -0,0 +1,30 @@
#include <fcntl.h>
#include <unistd.h>
#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);
}

18
disk_backend_file.h Normal file
View file

@ -0,0 +1,18 @@
#include <string>
#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);
};

View file

@ -12,6 +12,8 @@
#include "console_posix.h" #include "console_posix.h"
#include "cpu.h" #include "cpu.h"
#include "debugger.h" #include "debugger.h"
#include "disk_backend.h"
#include "disk_backend_file.h"
#include "gen.h" #include "gen.h"
#include "kw11-l.h" #include "kw11-l.h"
#include "loaders.h" #include "loaders.h"
@ -59,8 +61,8 @@ int main(int argc, char *argv[])
{ {
//setlocale(LC_ALL, ""); //setlocale(LC_ALL, "");
std::vector<std::string> rk05_files; std::vector<disk_backend *> rk05_files;
std::vector<std::string> rl02_files; std::vector<disk_backend *> rl02_files;
bool run_debugger = false; bool run_debugger = false;
bool tracing = false; bool tracing = false;
@ -132,11 +134,11 @@ int main(int argc, char *argv[])
break; break;
case 'R': case 'R':
rk05_files.push_back(optarg); rk05_files.push_back(new disk_backend_file(optarg));
break; break;
case 'r': case 'r':
rl02_files.push_back(optarg); rl02_files.push_back(new disk_backend_file(optarg));
break; break;
case 'p': case 'p':

View file

@ -22,42 +22,21 @@ static const char * const regnames[] = {
"RK05_DATABUF " "RK05_DATABUF "
}; };
rk05::rk05(const std::vector<std::string> & files, bus *const b, std::atomic_bool *const disk_read_acitivity, std::atomic_bool *const disk_write_acitivity) : rk05::rk05(const std::vector<disk_backend *> & files, bus *const b, std::atomic_bool *const disk_read_acitivity, std::atomic_bool *const disk_write_acitivity) :
b(b), b(b),
disk_read_acitivity(disk_read_acitivity), disk_read_acitivity(disk_read_acitivity),
disk_write_acitivity(disk_write_acitivity) disk_write_acitivity(disk_write_acitivity)
{ {
memset(registers, 0x00, sizeof registers); memset(registers, 0x00, sizeof registers );
memset(xfer_buffer, 0x00, sizeof xfer_buffer); memset(xfer_buffer, 0x00, sizeof xfer_buffer);
for(auto file : files) { fhs = 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);
}
} }
rk05::~rk05() rk05::~rk05()
{ {
for(auto fh : fhs) { for(auto fh : fhs)
#if defined(ESP32)
fh->close();
delete fh; delete fh;
#else
fclose(fh);
#endif
}
} }
uint8_t rk05::readByte(const uint16_t addr) 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; i<reclen; i++) for(size_t i=0; i<reclen; i++)
xfer_buffer[i] = b->readUnibusByte(memoff + i); xfer_buffer[i] = b->readUnibusByte(memoff + i);
#if defined(ESP32) if (!fhs.at(device)->write(diskoffb, reclen, xfer_buffer))
File32 *fh = fhs.at(device); DOLOG(ll_error, true, "RK05 pwrite error %s", strerror(errno));
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 (v & 2048) if (v & 2048)
DOLOG(debug, true, "RK05 inhibit BA increase"); 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); 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; int temp_diskoffb = diskoffb;
#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
uint32_t temp = reclen; uint32_t temp = reclen;
uint32_t p = memoff; uint32_t p = memoff;
while(proceed && temp > 0) { while(temp > 0) {
uint32_t cur = std::min(uint32_t(sizeof xfer_buffer), temp); uint32_t cur = std::min(uint32_t(sizeof xfer_buffer), temp);
#if defined(ESP32) if (!fhs.at(device)->read(temp_diskoffb, cur, xfer_buffer)) {
yield(); DOLOG(ll_error, true, "RK05 read error %s", strerror(errno));
break;
}
if (fh->read(xfer_buffer, cur) != size_t(cur)) temp_diskoffb += 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
for(uint32_t i=0; i<cur; i++) { for(uint32_t i=0; i<cur; i++) {
if (p < 0160000) if (p < 0160000)

21
rk05.h
View file

@ -1,4 +1,4 @@
// (C) 2018-2022 by Folkert van Heusden // (C) 2018-2023 by Folkert van Heusden
// Released under Apache License v2.0 // Released under Apache License v2.0
#pragma once #pragma once
@ -8,9 +8,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#if defined(ESP32) #include "disk_backend.h"
#include "esp32.h"
#endif
#define RK05_DS 0177400 // drive status #define RK05_DS 0177400 // drive status
@ -28,19 +26,16 @@ class bus;
class rk05 class rk05
{ {
private: private:
bus *const b; bus *const b { nullptr };
uint16_t registers[7]; uint16_t registers [ 7];
uint8_t xfer_buffer[512]; uint8_t xfer_buffer[512];
#if defined(ESP32) std::vector<disk_backend *> fhs;
std::vector<File32 *> fhs;
#else
std::vector<FILE *> fhs;
#endif
std::atomic_bool *const disk_read_acitivity { nullptr }; std::atomic_bool *const disk_read_acitivity { nullptr };
std::atomic_bool *const disk_write_acitivity { nullptr }; std::atomic_bool *const disk_write_acitivity { nullptr };
public: public:
rk05(const std::vector<std::string> & files, bus *const b, std::atomic_bool *const disk_read_acitivity, std::atomic_bool *const disk_write_acitivity); rk05(const std::vector<disk_backend *> & files, bus *const b, std::atomic_bool *const disk_read_acitivity, std::atomic_bool *const disk_write_acitivity);
virtual ~rk05(); virtual ~rk05();
uint8_t readByte(const uint16_t addr); uint8_t readByte(const uint16_t addr);

View file

@ -22,7 +22,7 @@ static const char * const regnames[] = {
"multipurpose " "multipurpose "
}; };
rl02::rl02(const std::vector<std::string> & files, bus *const b, std::atomic_bool *const disk_read_acitivity, std::atomic_bool *const disk_write_acitivity) : rl02::rl02(const std::vector<disk_backend *> & files, bus *const b, std::atomic_bool *const disk_read_acitivity, std::atomic_bool *const disk_write_acitivity) :
b(b), b(b),
disk_read_acitivity(disk_read_acitivity), disk_read_acitivity(disk_read_acitivity),
disk_write_acitivity(disk_write_acitivity) disk_write_acitivity(disk_write_acitivity)
@ -30,34 +30,13 @@ rl02::rl02(const std::vector<std::string> & files, bus *const b, std::atomic_boo
memset(registers, 0x00, sizeof registers); memset(registers, 0x00, sizeof registers);
memset(xfer_buffer, 0x00, sizeof xfer_buffer); memset(xfer_buffer, 0x00, sizeof xfer_buffer);
for(auto file : files) { fhs = 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);
}
} }
rl02::~rl02() rl02::~rl02()
{ {
for(auto fh : fhs) { for(auto fh : fhs)
#if defined(ESP32)
fh->close();
delete fh; delete fh;
#else
fclose(fh);
#endif
}
} }
uint8_t rl02::readByte(const uint16_t addr) 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 if (command == 2) { // get status
registers[(RL02_MPR - RL02_BASE) / 2] = 0; 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 else if (command == 6 || command == 7) { // read data / read data without header check
*disk_read_acitivity = true; *disk_read_acitivity = true;
bool proceed = true; bool proceed = true;
#if defined(ESP32) uint32_t temp_disk_offset = disk_offset;
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 memory_address = registers[(RL02_BAR - RL02_BASE) / 2]; 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) { while(proceed && count > 0) {
uint32_t cur = std::min(uint32_t(sizeof xfer_buffer), count); uint32_t cur = std::min(uint32_t(sizeof xfer_buffer), count);
#if defined(ESP32) if (!fhs.at(device)->read(temp_disk_offset, cur, xfer_buffer)) {
yield(); DOLOG(ll_error, true, "RL02 read error %s", strerror(errno));
break;
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
for(uint32_t i=0; i<cur; i++, p++) for(uint32_t i=0; i<cur; i++, p++)
b->writeByte(p, xfer_buffer[i]); b->writeByte(p, xfer_buffer[i]);
temp_disk_offset += cur;
count -= cur; count -= cur;
} }

16
rl02.h
View file

@ -1,4 +1,4 @@
// (C) 2022 by Folkert van Heusden // (C) 2023 by Folkert van Heusden
// Released under Apache License v2.0 // Released under Apache License v2.0
#pragma once #pragma once
@ -8,9 +8,8 @@
#include <string> #include <string>
#include <vector> #include <vector>
#if defined(ESP32) #include "disk_backend.h"
#include "esp32.h"
#endif
#define RL02_CSR 0174400 // control status register #define RL02_CSR 0174400 // control status register
#define RL02_BAR 0174402 // bus address register #define RL02_BAR 0174402 // bus address register
@ -27,12 +26,7 @@ private:
bus *const b; bus *const b;
uint16_t registers[4]; uint16_t registers[4];
uint8_t xfer_buffer[512]; uint8_t xfer_buffer[512];
std::vector<disk_backend *> fhs;
#if defined(ESP32)
std::vector<File32 *> fhs;
#else
std::vector<FILE *> fhs;
#endif
std::atomic_bool *const disk_read_acitivity { nullptr }; std::atomic_bool *const disk_read_acitivity { nullptr };
std::atomic_bool *const disk_write_acitivity { nullptr }; std::atomic_bool *const disk_write_acitivity { nullptr };
@ -40,7 +34,7 @@ private:
uint32_t calcOffset(uint16_t); uint32_t calcOffset(uint16_t);
public: public:
rl02(const std::vector<std::string> & files, bus *const b, std::atomic_bool *const disk_read_acitivity, std::atomic_bool *const disk_write_acitivity); rl02(const std::vector<disk_backend *> & files, bus *const b, std::atomic_bool *const disk_read_acitivity, std::atomic_bool *const disk_write_acitivity);
virtual ~rl02(); virtual ~rl02();
uint8_t readByte(const uint16_t addr); uint8_t readByte(const uint16_t addr);