diff --git a/ESP32/main.ino b/ESP32/main.ino index c5fe75c..1609ba9 100644 --- a/ESP32/main.ino +++ b/ESP32/main.ino @@ -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__)); diff --git a/bus.h b/bus.h index b0ae4c8..1e8db64 100644 --- a/bus.h +++ b/bus.h @@ -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); } diff --git a/debugger.cpp b/debugger.cpp index 29de1b7..c8fb8fd 100644 --- a/debugger.cpp +++ b/debugger.cpp @@ -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 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 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::vector, std::string> > select_nbd_server(console *const c) { @@ -293,9 +239,10 @@ std::optional, std::vector, std::vector, std::string> > select_disk_files(console *const c) +// disk image files +std::optional select_disk_file(console *const c) { #if IS_POSIX c->put_string_lf("Files in current directory: "); @@ -367,11 +314,6 @@ std::optional, std::vectorput_string("Opening file: "); c->put_string_lf(selected_file.c_str()); @@ -388,9 +330,6 @@ std::optional, std::vector, std::vectorput_string_lf("open failed"); } + + return { }; } -void set_disk_configuration(bus *const b, console *const cnsl, std::tuple, std::vector, std::string> & disk_files) +int wait_for_key(const std::string & title, console *const cnsl, const std::vector & 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 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::vector, 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; diff --git a/disk_device.h b/disk_device.h new file mode 100644 index 0000000..266fe84 --- /dev/null +++ b/disk_device.h @@ -0,0 +1,22 @@ +#pragma once + +#include + +#include "device.h" +#include "disk_backend.h" + + +class disk_device: public device +{ +protected: + std::vector fhs; + +public: + disk_device() { + } + + virtual ~disk_device() { + } + + std::vector * access_disk_backends() { return &fhs; } +}; diff --git a/loaders.cpp b/loaders.cpp index a28ac4c..8f71e3d 100644 --- a/loaders.cpp +++ b/loaders.cpp @@ -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(); diff --git a/loaders.h b/loaders.h index 35235df..704535a 100644 --- a/loaders.h +++ b/loaders.h @@ -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 loadTape(bus *const b, const std::string & file); void load_p11_x11(bus *const b, const std::string & file); diff --git a/main.cpp b/main.cpp index 24de903..56f7c72 100644 --- a/main.cpp +++ b/main.cpp @@ -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"); diff --git a/rk05.h b/rk05.h index 7ba4682..5189011 100644 --- a/rk05.h +++ b/rk05.h @@ -9,7 +9,7 @@ #include #include -#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 fhs; uint8_t xfer_buffer[512] { 0 }; std::atomic_bool *const disk_read_acitivity { nullptr }; diff --git a/rl02.cpp b/rl02.cpp index 339e93c..a62067f 100644 --- a/rl02.cpp +++ b/rl02.cpp @@ -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; } diff --git a/rl02.h b/rl02.h index 4a9858e..be8a96d 100644 --- a/rl02.h +++ b/rl02.h @@ -9,7 +9,7 @@ #include #include -#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 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);