diff --git a/BIC/EKBAD0.BIC b/BIC/EKBAD0.BIC new file mode 100644 index 0000000..a0c1f47 Binary files /dev/null and b/BIC/EKBAD0.BIC differ diff --git a/debugger.cpp b/debugger.cpp index f164453..d9b996e 100644 --- a/debugger.cpp +++ b/debugger.cpp @@ -3,6 +3,7 @@ #include "cpu.h" #include "gen.h" #include "log.h" +#include "tty.h" #include "utils.h" @@ -497,3 +498,21 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto } } } + +void run_bic(console *const cnsl, bus *const b, std::atomic_uint32_t *const stop_event, const bool tracing, const uint16_t start_addr) +{ + cpu *const c = b->getCpu(); + + c->setRegister(7, start_addr); + + tty *const t = b->getTty(); + + while(*stop_event == EVENT_NONE && t->get_reset_0x0a() == false) { + c->step_a(); + + if (tracing) + disassemble(c, cnsl, c->getPC(), false); + + c->step_b(); + } +} diff --git a/debugger.h b/debugger.h index 2fe3b8b..79bd067 100644 --- a/debugger.h +++ b/debugger.h @@ -2,3 +2,4 @@ #include "console.h" void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const stop_event, const bool tracing); +void run_bic(console *const cnsl, bus *const b, std::atomic_uint32_t *const stop_event, const bool tracing, const uint16_t bic_start); diff --git a/loaders.cpp b/loaders.cpp index 9f618b3..c600d18 100644 --- a/loaders.cpp +++ b/loaders.cpp @@ -145,7 +145,7 @@ std::optional loadTape(bus *const b, const std::string & file) return { }; } - uint16_t start = 0, end = 0; + std::optional start; for(;!feof(fh);) { uint8_t buffer[6]; @@ -181,9 +181,6 @@ std::optional loadTape(bus *const b, const std::string & file) csum += c; b -> writeByte(p++, c); - - if (p > end) - end = p; } int fcs = fgetc(fh); @@ -195,6 +192,9 @@ std::optional loadTape(bus *const b, const std::string & file) fclose(fh); + if (start.has_value() == false) + start = 0200; // assume BIC file + return start; } diff --git a/main.cpp b/main.cpp index a93c8dc..8ca0573 100644 --- a/main.cpp +++ b/main.cpp @@ -45,7 +45,8 @@ void sw_handler(int s) void help() { printf("-h this help\n"); - printf("-T t.bin load file as a binary tape file (like simh \"load\" command)\n"); + printf("-T t.bin load file as a binary tape file (like simh \"load\" command), also for .BIC files\n"); + printf("-B run tape file as a unit test (for .BIC files)\n"); printf("-R d.rk load file as a RK05 disk device\n"); printf("-r d.rl load file as a RL02 disk device\n"); printf("-N host:port:type use NBD-server as disk device, type being either \"rk05\" or \"rl02\"\n"); @@ -79,6 +80,7 @@ int main(int argc, char *argv[]) bool sa_set = false; std::string tape; + bool is_bic = false; uint16_t console_switches = 0; @@ -87,7 +89,7 @@ int main(int argc, char *argv[]) disk_backend *temp_d = nullptr; int opt = -1; - while((opt = getopt(argc, argv, "hm:T:r:R:p:ndtL:b:l:s:Q:N:")) != -1) + while((opt = getopt(argc, argv, "hm:T:Br:R:p:ndtL:b:l:s:Q:N:")) != -1) { switch(opt) { case 'h': @@ -137,6 +139,10 @@ int main(int argc, char *argv[]) tape = optarg; break; + case 'B': + is_bic = true; + break; + case 'R': temp_d = new disk_backend_file(optarg); if (!temp_d->begin()) @@ -206,13 +212,15 @@ int main(int argc, char *argv[]) std::atomic_bool interrupt_emulation { false }; - if (tape.empty() == false) { - auto addr = loadTape(b, tape); + std::optional bic_start; - if (addr.has_value() == false) + if (tape.empty() == false) { + bic_start = loadTape(b, tape); + + if (bic_start.has_value() == false) return 1; // fail - c->setRegister(7, addr.value()); + c->setRegister(7, bic_start.value()); } if (sa_set) @@ -271,7 +279,9 @@ int main(int argc, char *argv[]) cnsl->start_thread(); - if (run_debugger || (bootloader == BL_NONE && test.empty())) + if (is_bic) + run_bic(cnsl, b, &event, tracing, bic_start.value()); + else if (run_debugger || (bootloader == BL_NONE && test.empty())) debugger(cnsl, b, &event, tracing); else { c->emulation_start(); // for statistics diff --git a/tty.cpp b/tty.cpp index 688f16b..9672987 100644 --- a/tty.cpp +++ b/tty.cpp @@ -26,6 +26,15 @@ tty::~tty() { } +bool tty::get_reset_0x0a() +{ + bool temp = had_0x0a; + + had_0x0a = false; + + return temp; +} + uint8_t tty::readByte(const uint16_t addr) { uint16_t v = readWord(addr & ~1); @@ -103,6 +112,8 @@ void tty::writeWord(const uint16_t addr, uint16_t v) DOLOG(debug, true, "PDP11TTY print '%c'", ch); c->put_char(ch); + + had_0x0a |= ch == 0x0a; // for diagnostics } DOLOG(debug, true, "set register %o to %o", addr, v); diff --git a/tty.h b/tty.h index abe6090..53542d2 100644 --- a/tty.h +++ b/tty.h @@ -25,11 +25,14 @@ private: bool have_char_1 { false }; // RCVR BUSY bit high (11) bool have_char_2 { false }; // RCVR DONE bit high (7) uint16_t registers[4] { 0 }; + bool had_0x0a { false }; // used for diagnostics public: tty(console *const c); virtual ~tty(); + bool get_reset_0x0a(); + uint8_t readByte(const uint16_t addr); uint16_t readWord(const uint16_t addr);