RL02 serialization
This commit is contained in:
parent
859577479f
commit
4eb557cbc5
9 changed files with 165 additions and 15 deletions
13
bus.cpp
13
bus.cpp
|
@ -62,7 +62,10 @@ json_t *bus::serialize() const
|
|||
if (c)
|
||||
json_object_set(j_out, "cpu", c->serialize());
|
||||
|
||||
// TODO: rl02, rk05, tm11
|
||||
if (rl02_)
|
||||
json_object_set(j_out, "rl02", rl02_->serialize());
|
||||
|
||||
// TODO: rk05, tm11
|
||||
|
||||
return j_out;
|
||||
}
|
||||
|
@ -103,7 +106,13 @@ bus *bus::deserialize(const json_t *const j, console *const cnsl, std::atomic_ui
|
|||
b->add_cpu(cpu_);
|
||||
}
|
||||
|
||||
// TODO: rl02, rk05, tm11
|
||||
temp = json_object_get(j, "rl02");
|
||||
if (temp) {
|
||||
rl02 *rl02_ = rl02::deserialize(temp, b);
|
||||
b->add_rl02(rl02_);
|
||||
}
|
||||
|
||||
// TODO: rk05, tm11
|
||||
|
||||
return b;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
// (C) 2018-2023 by Folkert van Heusden
|
||||
// (C) 2018-2024 by Folkert van Heusden
|
||||
// Released under MIT license
|
||||
|
||||
#include "disk_backend.h"
|
||||
#include "disk_backend_file.h"
|
||||
#include "disk_backend_nbd.h"
|
||||
|
||||
|
||||
disk_backend::disk_backend()
|
||||
{
|
||||
|
@ -10,3 +13,20 @@ disk_backend::disk_backend()
|
|||
disk_backend::~disk_backend()
|
||||
{
|
||||
}
|
||||
|
||||
#if IS_POSIX
|
||||
disk_backend *disk_backend::deserialize(const json_t *const j)
|
||||
{
|
||||
std::string type = json_string_value(json_object_get(j, "disk-backend-type"));
|
||||
|
||||
if (type == "file")
|
||||
return disk_backend_file::deserialize(j);
|
||||
|
||||
if (type == "nbd")
|
||||
return disk_backend_nbd::deserialize(j);
|
||||
|
||||
// should not be reached
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// (C) 2018-2023 by Folkert van Heusden
|
||||
// (C) 2018-2024 by Folkert van Heusden
|
||||
// Released under MIT license
|
||||
|
||||
#pragma once
|
||||
|
@ -6,6 +6,8 @@
|
|||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "gen.h"
|
||||
|
||||
|
||||
class disk_backend
|
||||
{
|
||||
|
@ -13,6 +15,11 @@ public:
|
|||
disk_backend();
|
||||
virtual ~disk_backend();
|
||||
|
||||
#if IS_POSIX
|
||||
virtual json_t *serialize() const = 0;
|
||||
static disk_backend *deserialize(const json_t *const j);
|
||||
#endif
|
||||
|
||||
virtual bool begin() = 0;
|
||||
|
||||
virtual bool read(const off_t offset, const size_t n, uint8_t *const target) = 0;
|
||||
|
|
|
@ -19,6 +19,26 @@ disk_backend_file::~disk_backend_file()
|
|||
close(fd);
|
||||
}
|
||||
|
||||
#if IS_POSIX
|
||||
json_t *disk_backend_file::serialize() const
|
||||
{
|
||||
json_t *j = json_object();
|
||||
|
||||
json_object_set(j, "disk-backend-type", json_string("file"));
|
||||
|
||||
// TODO store checksum of backend
|
||||
json_object_set(j, "filename", json_string(filename.c_str()));
|
||||
|
||||
return j;
|
||||
}
|
||||
|
||||
disk_backend_file *disk_backend_file::deserialize(const json_t *const j)
|
||||
{
|
||||
// TODO verify checksum of backend
|
||||
return new disk_backend_file(json_string_value(json_object_get(j, "filename")));
|
||||
}
|
||||
#endif
|
||||
|
||||
bool disk_backend_file::begin()
|
||||
{
|
||||
fd = open(filename.c_str(), O_RDWR);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// (C) 2018-2023 by Folkert van Heusden
|
||||
// (C) 2018-2024 by Folkert van Heusden
|
||||
// Released under MIT license
|
||||
|
||||
#include <string>
|
||||
|
@ -17,6 +17,11 @@ public:
|
|||
disk_backend_file(const std::string & filename);
|
||||
virtual ~disk_backend_file();
|
||||
|
||||
#if IS_POSIX
|
||||
json_t *serialize() const override;
|
||||
static disk_backend_file *deserialize(const json_t *const j);
|
||||
#endif
|
||||
|
||||
bool begin() override;
|
||||
|
||||
bool read(const off_t offset, const size_t n, uint8_t *const target) override;
|
||||
|
|
|
@ -47,6 +47,27 @@ disk_backend_nbd::~disk_backend_nbd()
|
|||
close(fd);
|
||||
}
|
||||
|
||||
#if IS_POSIX
|
||||
json_t *disk_backend_nbd::serialize() const
|
||||
{
|
||||
json_t *j = json_object();
|
||||
|
||||
json_object_set(j, "disk-backend-type", json_string("nbd"));
|
||||
|
||||
// TODO store checksum of backend
|
||||
json_object_set(j, "host", json_string(host.c_str()));
|
||||
json_object_set(j, "port", json_integer(port));
|
||||
|
||||
return j;
|
||||
}
|
||||
|
||||
disk_backend_nbd *disk_backend_nbd::deserialize(const json_t *const j)
|
||||
{
|
||||
// TODO verify checksum of backend
|
||||
return new disk_backend_nbd(json_string_value(json_object_get(j, "host")), json_integer_value(json_object_get(j, "port")));
|
||||
}
|
||||
#endif
|
||||
|
||||
bool disk_backend_nbd::begin()
|
||||
{
|
||||
if (!connect(false)) {
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <sys/types.h>
|
||||
|
||||
#include "disk_backend.h"
|
||||
#include "gen.h"
|
||||
|
||||
|
||||
class disk_backend_nbd : public disk_backend
|
||||
|
@ -20,6 +21,11 @@ public:
|
|||
disk_backend_nbd(const std::string & host, const unsigned port);
|
||||
virtual ~disk_backend_nbd();
|
||||
|
||||
#if IS_POSIX
|
||||
json_t *serialize() const override;
|
||||
static disk_backend_nbd *deserialize(const json_t *const j);
|
||||
#endif
|
||||
|
||||
bool begin() override;
|
||||
|
||||
bool read(const off_t offset, const size_t n, uint8_t *const target) override;
|
||||
|
|
70
rl02.cpp
70
rl02.cpp
|
@ -31,10 +31,10 @@ static const char * const commands[] = {
|
|||
"read data w/o header check"
|
||||
};
|
||||
|
||||
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) :
|
||||
rl02::rl02(const std::vector<disk_backend *> & files, bus *const b, std::atomic_bool *const disk_read_activity, std::atomic_bool *const disk_write_activity) :
|
||||
b(b),
|
||||
disk_read_acitivity(disk_read_acitivity),
|
||||
disk_write_acitivity(disk_write_acitivity)
|
||||
disk_read_activity (disk_read_activity),
|
||||
disk_write_activity(disk_write_activity)
|
||||
{
|
||||
fhs = files;
|
||||
|
||||
|
@ -58,6 +58,54 @@ void rl02::reset()
|
|||
sector = 0;
|
||||
}
|
||||
|
||||
#if IS_POSIX
|
||||
json_t *rl02::serialize() const
|
||||
{
|
||||
json_t *j = json_object();
|
||||
|
||||
json_t *j_backends = json_array();
|
||||
for(auto & dbe: fhs)
|
||||
json_array_append(j_backends, dbe->serialize());
|
||||
|
||||
json_object_set(j, "backends", j_backends);
|
||||
|
||||
for(int regnr=0; regnr<4; regnr++)
|
||||
json_object_set(j, format("register-%d", regnr).c_str(), json_integer(registers[regnr]));
|
||||
|
||||
for(int mprnr=0; mprnr<3; mprnr++)
|
||||
json_object_set(j, format("mpr-%d", mprnr).c_str(), json_integer(mpr[mprnr]));
|
||||
|
||||
json_object_set(j, "track", json_integer(track));
|
||||
json_object_set(j, "head", json_integer(head));
|
||||
json_object_set(j, "sector", json_integer(sector));
|
||||
|
||||
return j;
|
||||
}
|
||||
|
||||
rl02 *rl02::deserialize(const json_t *const j, bus *const b)
|
||||
{
|
||||
std::vector<disk_backend *> backends;
|
||||
|
||||
json_t *j_backends = json_object_get(j, "backends");
|
||||
for(size_t i=0; i<json_array_size(j_backends); i++)
|
||||
backends.push_back(disk_backend::deserialize(json_array_get(j_backends, i)));
|
||||
|
||||
rl02 *r = new rl02(backends, b, nullptr, nullptr);
|
||||
|
||||
for(int regnr=0; regnr<4; regnr++)
|
||||
r->registers[regnr] = json_integer_value(json_object_get(j, format("register-%d", regnr).c_str()));
|
||||
|
||||
for(int mprnr=0; mprnr<3; mprnr++)
|
||||
r->mpr[mprnr] = json_integer_value(json_object_get(j, format("mpr-%d", mprnr).c_str()));
|
||||
|
||||
r->track = json_integer_value(json_object_get(j, "track" ));
|
||||
r->head = json_integer_value(json_object_get(j, "head" ));
|
||||
r->sector = json_integer_value(json_object_get(j, "sector"));
|
||||
|
||||
return r;
|
||||
}
|
||||
#endif
|
||||
|
||||
uint8_t rl02::readByte(const uint16_t addr)
|
||||
{
|
||||
uint16_t v = readWord(addr & ~1);
|
||||
|
@ -152,8 +200,6 @@ void rl02::writeWord(const uint16_t addr, uint16_t v)
|
|||
|
||||
bool do_int = false;
|
||||
|
||||
*disk_read_acitivity = true;
|
||||
|
||||
if (size_t(device) >= fhs.size()) {
|
||||
DOLOG(info, false, "RL02: PDP11/70 is accessing a not-attached virtual disk %d", device);
|
||||
|
||||
|
@ -194,6 +240,9 @@ void rl02::writeWord(const uint16_t addr, uint16_t v)
|
|||
do_int = true;
|
||||
}
|
||||
else if (command == 5) { // write data
|
||||
if (disk_write_activity)
|
||||
*disk_write_activity = true;
|
||||
|
||||
uint32_t memory_address = get_bus_address();
|
||||
|
||||
uint32_t count = (65536l - registers[(RL02_MPR - RL02_BASE) / 2]) * 2;
|
||||
|
@ -247,8 +296,14 @@ void rl02::writeWord(const uint16_t addr, uint16_t v)
|
|||
}
|
||||
|
||||
do_int = true;
|
||||
|
||||
if (disk_write_activity)
|
||||
*disk_write_activity = false;
|
||||
}
|
||||
else if (command == 6 || command == 7) { // read data / read data without header check
|
||||
if (disk_read_activity)
|
||||
*disk_read_activity = true;
|
||||
|
||||
uint32_t memory_address = get_bus_address();
|
||||
|
||||
uint32_t count = (65536l - registers[(RL02_MPR - RL02_BASE) / 2]) * 2;
|
||||
|
@ -305,6 +360,9 @@ void rl02::writeWord(const uint16_t addr, uint16_t v)
|
|||
}
|
||||
|
||||
do_int = true;
|
||||
|
||||
if (disk_read_activity)
|
||||
*disk_read_activity = false;
|
||||
}
|
||||
else {
|
||||
DOLOG(warning, false, "RL02: command %d not implemented", command);
|
||||
|
@ -317,7 +375,5 @@ void rl02::writeWord(const uint16_t addr, uint16_t v)
|
|||
b->getCpu()->queue_interrupt(5, 0160);
|
||||
}
|
||||
}
|
||||
|
||||
*disk_read_acitivity = false;
|
||||
}
|
||||
}
|
||||
|
|
12
rl02.h
12
rl02.h
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include "device.h"
|
||||
#include "disk_backend.h"
|
||||
#include "gen.h"
|
||||
|
||||
|
||||
#define RL02_CSR 0174400 // control status register
|
||||
|
@ -38,8 +39,8 @@ private:
|
|||
uint16_t mpr[3];
|
||||
std::vector<disk_backend *> fhs;
|
||||
|
||||
std::atomic_bool *const disk_read_acitivity { nullptr };
|
||||
std::atomic_bool *const disk_write_acitivity { 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);
|
||||
|
@ -47,11 +48,16 @@ private:
|
|||
uint32_t calc_offset() const;
|
||||
|
||||
public:
|
||||
rl02(const std::vector<disk_backend *> & 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_activity, std::atomic_bool *const disk_write_activity);
|
||||
virtual ~rl02();
|
||||
|
||||
void reset() override;
|
||||
|
||||
#if IS_POSIX
|
||||
json_t *serialize() const;
|
||||
static rl02 *deserialize(const json_t *const j, bus *const b);
|
||||
#endif
|
||||
|
||||
uint8_t readByte(const uint16_t addr) override;
|
||||
uint16_t readWord(const uint16_t addr) override;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue