load/unload tape

This commit is contained in:
folkert van heusden 2024-05-01 22:25:22 +02:00
parent 95db008a68
commit e643b2a0bb
Signed by untrusted user who does not match committer: folkert
GPG key ID: 6B6455EDFEED3BD1
5 changed files with 112 additions and 53 deletions

2
bus.h
View file

@ -49,6 +49,7 @@ class console;
class cpu;
class kw11_l;
class memory;
class tm_11;
class tty;
typedef enum { T_PROCEED, T_ABORT_4, T_TRAP_250 } trap_action_t;
@ -121,6 +122,7 @@ public:
mmu *getMMU() { return mmu_; }
rk05 *getRK05() { return rk05_; }
rl02 *getRL02() { return rl02_; }
tm_11 *getTM11() { return tm11; }
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_byte(const uint16_t a) { return read(a, wm_byte, rm_cur); }

View file

@ -76,35 +76,8 @@ std::optional<disk_backend *> select_nbd_server(console *const cnsl)
}
#endif
// disk image files
std::optional<disk_backend *> select_disk_file(console *const c)
std::optional<std::string> select_host_file(console *const c)
{
#if IS_POSIX
c->put_string_lf("Files in current directory: ");
#else
c->put_string_lf(format("MISO: %d", int(MISO)));
c->put_string_lf(format("MOSI: %d", int(MOSI)));
c->put_string_lf(format("SCK : %d", int(SCK )));
c->put_string_lf(format("SS : %d", int(SS )));
c->put_string_lf("Files on SD-card:");
#if defined(SHA2017)
if (!SD.begin(21, SD_SCK_MHZ(10)))
SD.initErrorHalt();
#elif !defined(BUILD_FOR_RP2040)
if (!SD.begin(SS, SD_SCK_MHZ(15))) {
auto err = SD.sdErrorCode();
if (err)
c->put_string_lf(format("SDerror: 0x%x, data: 0x%x", err, SD.sdErrorData()));
else
c->put_string_lf("Failed to initialize SD card");
return { };
}
#endif
#endif
for(;;) {
#if defined(linux)
DIR *dir = opendir(".");
@ -164,27 +137,65 @@ std::optional<disk_backend *> select_disk_file(console *const c)
fh.close();
#endif
if (can_open_file) {
#if IS_POSIX
disk_backend *temp = new disk_backend_file(selected_file);
#else
disk_backend *temp = new disk_backend_esp32(selected_file);
#endif
if (!temp->begin(false)) {
c->put_string("Cannot use: ");
c->put_string_lf(selected_file.c_str());
delete temp;
continue;
}
return { temp };
}
if (can_open_file)
return selected_file;
c->put_string_lf("open failed");
}
}
// disk image files
std::optional<disk_backend *> select_disk_file(console *const c)
{
#if IS_POSIX
c->put_string_lf("Files in current directory: ");
#else
c->put_string_lf(format("MISO: %d", int(MISO)));
c->put_string_lf(format("MOSI: %d", int(MOSI)));
c->put_string_lf(format("SCK : %d", int(SCK )));
c->put_string_lf(format("SS : %d", int(SS )));
c->put_string_lf("Files on SD-card:");
#if defined(SHA2017)
if (!SD.begin(21, SD_SCK_MHZ(10)))
SD.initErrorHalt();
#elif !defined(BUILD_FOR_RP2040)
if (!SD.begin(SS, SD_SCK_MHZ(15))) {
auto err = SD.sdErrorCode();
if (err)
c->put_string_lf(format("SDerror: 0x%x, data: 0x%x", err, SD.sdErrorData()));
else
c->put_string_lf("Failed to initialize SD card");
return { };
}
#endif
#endif
for(;;) {
auto selected_file = select_host_file(c);
if (selected_file.has_value() == false)
break;
#if IS_POSIX
disk_backend *temp = new disk_backend_file(selected_file.value());
#else
disk_backend *temp = new disk_backend_esp32(selected_file.value());
#endif
if (!temp->begin(false)) {
c->put_string("Cannot use: ");
c->put_string_lf(selected_file.value().c_str());
delete temp;
continue;
}
return { temp };
}
return { };
}
@ -235,7 +246,6 @@ std::optional<disk_backend *> select_disk_backend(console *const cnsl)
void configure_disk(bus *const b, console *const cnsl)
{
// TODO tape
int type_ch = wait_for_key("1. RK05, 2. RL02, 9. abort", cnsl, { '1', '2', '3', '9' });
bootloader_t bl = BL_NONE;
@ -590,6 +600,19 @@ void serialize_state(console *const cnsl, const bus *const b, const std::string
}
#endif
void tm11_load_tape(console *const cnsl, bus *const b)
{
auto file = select_host_file(cnsl);
if (file.has_value())
b->getTM11()->load(file.value());
}
void tm11_unload_tape(bus *const b)
{
b->getTM11()->unload();
}
void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const stop_event, const bool tracing_in)
{
int32_t trace_start_addr = -1;
@ -959,6 +982,16 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
continue;
}
else if (cmd == "lt") {
tm11_load_tape(cnsl, b);
continue;
}
else if (cmd == "ult") {
tm11_unload_tape(b);
continue;
}
else if (cmd == "dp") {
cnsl->stop_panel_thread();
@ -1012,6 +1045,8 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
"setmem - set memory (a=) to value (v=), both in octal, one byte",
"toggle - set switch (s=, 0...15 (decimal)) of the front panel to state (t=, 0 or 1)",
"cls - clear screen",
"lt - load tape (parameter is filename)",
"ult - unload tape",
"stats - show run statistics",
"ramsize - set ram size (page count (8 kB))",
"bl - set bootload (rl02 or rk05)",

View file

@ -580,6 +580,9 @@ int main(int argc, char *argv[])
cnsl->set_bus(b);
cnsl->begin();
tm_11 *tm_11_ = new tm_11(b);
b->add_tm11(tm_11_);
running = cnsl->get_running_flag();
std::atomic_bool interrupt_emulation { false };

View file

@ -10,18 +10,35 @@
#include "memory.h"
#include "utils.h"
tm_11::tm_11(const std::string & file, memory *const m): file(file), m(m)
tm_11::tm_11(bus *const b): m(b->getRAM())
{
}
tm_11::~tm_11()
{
fclose(fh);
if (fh)
fclose(fh);
}
void tm_11::begin()
void tm_11::unload()
{
if (fh) {
fclose(fh);
fh = nullptr;
}
tape_file.clear();
reset();
}
void tm_11::load(const std::string & file)
{
if (fh)
fclose(fh);
fh = fopen(file.c_str(), "rb");
tape_file = file;
reset();
}

View file

@ -7,6 +7,7 @@
#include <stdio.h>
#include <string>
#include "bus.h"
#include "device.h"
#define TM_11_MTS 0172520 // status register
@ -24,18 +25,19 @@ class memory;
class tm_11 : public device
{
private:
std::string file;
memory *const m { nullptr };
uint16_t registers[6] { 0 };
uint8_t xfer_buffer[65536];
int offset { 0 };
FILE *fh { nullptr };
std::string tape_file;
public:
tm_11(const std::string & file, memory *const m);
tm_11(bus *const b);
virtual ~tm_11();
void begin();
void load(const std::string & file);
void unload();
void reset() override;