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) while(!Serial)
delay(100); 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.print(F("GIT hash: "));
Serial.println(version_str); Serial.println(version_str);
Serial.println(F("Build on: " __DATE__ " " __TIME__)); Serial.println(F("Build on: " __DATE__ " " __TIME__));

2
bus.h
View file

@ -123,6 +123,8 @@ public:
kw11_l *getKW11_L() { return kw11_l_; } kw11_l *getKW11_L() { return kw11_l_; }
tty *getTty() { return tty_; } tty *getTty() { return tty_; }
mmu *getMMU() { return mmu_; } 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 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); } uint16_t readByte(const uint16_t a) { return read(a, wm_byte, rm_cur); }

View file

@ -38,7 +38,7 @@
#include "rp2040.h" #include "rp2040.h"
#endif #endif
void setBootLoader(bus *const b); void set_boot_loader(bus *const b);
void configure_disk(console *const c); 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 #endif
std::optional<disk_backend_t> select_disk_backend(console *const c) #if 0
{
#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 !defined(BUILD_FOR_RP2040) #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) 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 { }; return { };
} }
#endif #endif
#endif
// RK05, RL02 files // disk image files
std::optional<std::tuple<std::vector<disk_backend *>, std::vector<disk_backend *>, std::string> > select_disk_files(console *const c) std::optional<disk_backend *> select_disk_file(console *const c)
{ {
#if IS_POSIX #if IS_POSIX
c->put_string_lf("Files in current directory: "); 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()) if (selected_file.empty())
return { }; return { };
auto disk_type = select_disk_type(c);
if (disk_type.has_value() == false)
return { };
c->put_string("Opening file: "); c->put_string("Opening file: ");
c->put_string_lf(selected_file.c_str()); 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 #endif
if (can_open_file) { if (can_open_file) {
if (disk_type.value() == DT_TAPE)
return { { { }, { }, selected_file } };
#if IS_POSIX #if IS_POSIX
disk_backend *temp = new disk_backend_file(selected_file); disk_backend *temp = new disk_backend_file(selected_file);
#else #else
@ -406,63 +345,117 @@ std::optional<std::tuple<std::vector<disk_backend *>, std::vector<disk_backend *
continue; continue;
} }
if (disk_type.value() == DT_RK05) return { temp };
return { { { temp }, { }, "" } };
if (disk_type.value() == DT_RL02)
return { { { }, { temp }, "" } };
} }
c->put_string_lf("open failed"); 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) cnsl->put_string_lf(title);
b->add_rk05(new rk05(std::get<0>(disk_files), b, cnsl->get_disk_read_activity_flag(), cnsl->get_disk_write_activity_flag()));
if (std::get<1>(disk_files).empty() == false) cnsl->put_string("> ");
b->add_rl02(new rl02(std::get<1>(disk_files), b, cnsl->get_disk_read_activity_flag(), cnsl->get_disk_write_activity_flag()));
if (std::get<2>(disk_files).empty() == false) { int ch = -1;
auto addr = loadTape(b, std::get<2>(disk_files)); while(ch == -1) {
auto temp = cnsl->wait_char(500);
if (addr.has_value()) if (temp.has_value()) {
b->getCpu()->setPC(addr.value()); for(auto & a: allowed) {
if (a == temp.value()) {
ch = temp.value();
break;
}
}
}
} }
if (std::get<0>(disk_files).empty() == false) cnsl->put_string_lf(format("%c", ch));
setBootLoader(b, BL_RK05);
else if (std::get<1>(disk_files).empty() == false) return ch;
setBootLoader(b, BL_RL02);
} }
void configure_disk(bus *const b, console *const cnsl) 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(;;) { 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; 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 (image_file.has_value()) {
if (backend == BE_NETWORK) cartridge_slots->push_back(image_file.value());
files = select_nbd_server(cnsl);
else // if (backend == BE_SD)
#endif
files = select_disk_files(cnsl);
if (files.has_value() == false) cnsl->put_string_lf("Cartridge loaded");
break; }
}
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; continue;
} }
else if (parts[0] == "bl" && parts.size() == 2) { 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"); cnsl->put_string_lf("Bootloader set");
continue; 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); 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(); cpu *const c = b -> getCpu();

View file

@ -11,6 +11,6 @@
typedef enum { BL_NONE, BL_RK05, BL_RL02 } bootloader_t; typedef enum { BL_NONE, BL_RK05, BL_RL02 } bootloader_t;
void loadbin(bus *const b, uint16_t base, const char *const file); 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); std::optional<uint16_t> loadTape(bus *const b, const std::string & file);
void load_p11_x11(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) if (validate_json.empty() == false)
return run_cpu_validation(validate_json); 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__); DOLOG(info, true, "Built on: " __DATE__ " " __TIME__);
@ -525,26 +525,18 @@ int main(int argc, char *argv[])
cpu *c = new cpu(b, &event); cpu *c = new cpu(b, &event);
b->add_cpu(c); b->add_cpu(c);
if (rk05_files.empty() == false) { if (rk05_files.empty() == false)
if (enable_bootloader == false) bootloader = BL_RK05;
DOLOG(warning, true, "Note: loading RK05 with no (RK05-) bootloader selected");
else
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)
} bootloader = BL_RL02;
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 (enable_bootloader) 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 { else {
FILE *fh = fopen(deserialize.c_str(), "r"); FILE *fh = fopen(deserialize.c_str(), "r");

5
rk05.h
View file

@ -9,7 +9,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "device.h" #include "disk_device.h"
#include "disk_backend.h" #include "disk_backend.h"
@ -25,12 +25,11 @@
class bus; class bus;
class rk05 : public device class rk05: public disk_device
{ {
private: private:
bus *const b { nullptr }; bus *const b { nullptr };
uint16_t registers [7] { 0 }; uint16_t registers [7] { 0 };
std::vector<disk_backend *> fhs;
uint8_t xfer_buffer[512] { 0 }; uint8_t xfer_buffer[512] { 0 };
std::atomic_bool *const disk_read_acitivity { nullptr }; 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]++; 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); 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; break;
} }
@ -325,7 +325,7 @@ void rl02::writeWord(const uint16_t addr, uint16_t v)
while(count > 0) { while(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 (!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); 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; break;
} }

9
rl02.h
View file

@ -9,7 +9,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "device.h" #include "disk_device.h"
#include "disk_backend.h" #include "disk_backend.h"
#include "gen.h" #include "gen.h"
@ -27,7 +27,7 @@ constexpr const int rl02_bytes_per_sector = 256;
class bus; class bus;
class rl02 : public device class rl02: public disk_device
{ {
private: private:
bus *const b; bus *const b;
@ -37,10 +37,9 @@ private:
uint8_t head { 0 }; uint8_t head { 0 };
uint8_t sector { 0 }; uint8_t sector { 0 };
uint16_t mpr[3]; uint16_t mpr[3];
std::vector<disk_backend *> fhs;
std::atomic_bool *const disk_read_activity { nullptr }; std::atomic_bool *const disk_read_activity { nullptr };
std::atomic_bool *const disk_write_activity { nullptr }; std::atomic_bool *const disk_write_activity { nullptr };
uint32_t get_bus_address() const; uint32_t get_bus_address() const;
void update_bus_address(const uint32_t a); void update_bus_address(const uint32_t a);