disk backend
This commit is contained in:
parent
a672841865
commit
6236d96b83
10 changed files with 117 additions and 162 deletions
|
@ -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
|
||||
|
|
9
disk_backend.cpp
Normal file
9
disk_backend.cpp
Normal file
|
@ -0,0 +1,9 @@
|
|||
#include "disk_backend.h"
|
||||
|
||||
disk_backend::disk_backend()
|
||||
{
|
||||
}
|
||||
|
||||
disk_backend::~disk_backend()
|
||||
{
|
||||
}
|
16
disk_backend.h
Normal file
16
disk_backend.h
Normal 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
30
disk_backend_file.cpp
Normal 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
18
disk_backend_file.h
Normal 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);
|
||||
};
|
10
main.cpp
10
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<std::string> rk05_files;
|
||||
std::vector<std::string> rl02_files;
|
||||
std::vector<disk_backend *> rk05_files;
|
||||
std::vector<disk_backend *> 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':
|
||||
|
|
82
rk05.cpp
82
rk05.cpp
|
@ -22,42 +22,21 @@ static const char * const regnames[] = {
|
|||
"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),
|
||||
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; i<reclen; i++)
|
||||
xfer_buffer[i] = b->readUnibusByte(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<cur; i++) {
|
||||
if (p < 0160000)
|
||||
|
|
21
rk05.h
21
rk05.h
|
@ -1,4 +1,4 @@
|
|||
// (C) 2018-2022 by Folkert van Heusden
|
||||
// (C) 2018-2023 by Folkert van Heusden
|
||||
// Released under Apache License v2.0
|
||||
#pragma once
|
||||
|
||||
|
@ -8,9 +8,7 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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<File32 *> fhs;
|
||||
#else
|
||||
std::vector<FILE *> fhs;
|
||||
#endif
|
||||
bus *const b { nullptr };
|
||||
uint16_t registers [ 7];
|
||||
uint8_t xfer_buffer[512];
|
||||
std::vector<disk_backend *> fhs;
|
||||
|
||||
std::atomic_bool *const disk_read_acitivity { nullptr };
|
||||
std::atomic_bool *const disk_write_acitivity { nullptr };
|
||||
|
||||
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();
|
||||
|
||||
uint8_t readByte(const uint16_t addr);
|
||||
|
|
75
rl02.cpp
75
rl02.cpp
|
@ -22,7 +22,7 @@ static const char * const regnames[] = {
|
|||
"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),
|
||||
disk_read_acitivity(disk_read_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(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; i<cur; i++, p++)
|
||||
b->writeByte(p, xfer_buffer[i]);
|
||||
|
||||
temp_disk_offset += cur;
|
||||
|
||||
count -= cur;
|
||||
}
|
||||
|
||||
|
|
16
rl02.h
16
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 <string>
|
||||
#include <vector>
|
||||
|
||||
#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<File32 *> fhs;
|
||||
#else
|
||||
std::vector<FILE *> fhs;
|
||||
#endif
|
||||
std::vector<disk_backend *> 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<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();
|
||||
|
||||
uint8_t readByte(const uint16_t addr);
|
||||
|
|
Loading…
Add table
Reference in a new issue