disk configure menu

This commit is contained in:
folkert van heusden 2024-04-26 15:01:27 +02:00
parent 1da19f0241
commit 8caad6ae37
Signed by untrusted user who does not match committer: folkert
GPG key ID: 6B6455EDFEED3BD1
10 changed files with 137 additions and 130 deletions

View file

@ -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__));

2
bus.h
View file

@ -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); }

View file

@ -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<disk_backend_t> 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<disk_type_t> 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::tuple<std::vector<disk_backend *>, std::vector<disk_backend *>, std::string> > select_nbd_server(console *const c)
{
@ -293,9 +239,10 @@ std::optional<std::tuple<std::vector<disk_backend *>, std::vector<disk_backend *
return { };
}
#endif
#endif
// RK05, RL02 files
std::optional<std::tuple<std::vector<disk_backend *>, std::vector<disk_backend *>, std::string> > select_disk_files(console *const c)
// disk image files
std::optional<disk_backend *> select_disk_file(console *const c)
{
#if IS_POSIX
c->put_string_lf("Files in current directory: ");
@ -367,11 +314,6 @@ std::optional<std::tuple<std::vector<disk_backend *>, std::vector<disk_backend *
if (selected_file.empty())
return { };
auto disk_type = select_disk_type(c);
if (disk_type.has_value() == false)
return { };
c->put_string("Opening file: ");
c->put_string_lf(selected_file.c_str());
@ -388,9 +330,6 @@ std::optional<std::tuple<std::vector<disk_backend *>, std::vector<disk_backend *
#endif
if (can_open_file) {
if (disk_type.value() == DT_TAPE)
return { { { }, { }, selected_file } };
#if IS_POSIX
disk_backend *temp = new disk_backend_file(selected_file);
#else
@ -406,63 +345,117 @@ std::optional<std::tuple<std::vector<disk_backend *>, std::vector<disk_backend *
continue;
}
if (disk_type.value() == DT_RK05)
return { { { temp }, { }, "" } };
if (disk_type.value() == DT_RL02)
return { { { }, { temp }, "" } };
return { temp };
}
c->put_string_lf("open failed");
}
return { };
}
void set_disk_configuration(bus *const b, console *const cnsl, std::tuple<std::vector<disk_backend *>, std::vector<disk_backend *>, std::string> & disk_files)
int wait_for_key(const std::string & title, console *const cnsl, const std::vector<char> & 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<char> 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::tuple<std::vector<disk_backend *>, std::vector<disk_backend *>, 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;

22
disk_device.h Normal file
View file

@ -0,0 +1,22 @@
#pragma once
#include <vector>
#include "device.h"
#include "disk_backend.h"
class disk_device: public device
{
protected:
std::vector<disk_backend *> fhs;
public:
disk_device() {
}
virtual ~disk_device() {
}
std::vector<disk_backend *> * access_disk_backends() { return &fhs; }
};

View file

@ -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();

View file

@ -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<uint16_t> loadTape(bus *const b, const std::string & file);
void load_p11_x11(bus *const b, const std::string & file);

View file

@ -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");

5
rk05.h
View file

@ -9,7 +9,7 @@
#include <string>
#include <vector>
#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<disk_backend *> fhs;
uint8_t xfer_buffer[512] { 0 };
std::atomic_bool *const disk_read_acitivity { nullptr };

View file

@ -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;
}

9
rl02.h
View file

@ -9,7 +9,7 @@
#include <string>
#include <vector>
#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<disk_backend *> 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);