From a460aa9d82a3a2d2a7a5bdb6e8157f5f17426954 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sun, 12 Jun 2022 22:34:09 +0200 Subject: [PATCH 1/4] PSW handling fixes --- bus.cpp | 4 +++- cpu.cpp | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/bus.cpp b/bus.cpp index 315c070..7a65cb1 100644 --- a/bus.cpp +++ b/bus.cpp @@ -407,6 +407,8 @@ uint16_t bus::write(const uint16_t a, const bool word_mode, uint16_t value, cons DOLOG(debug, true, "writeb PSW %s", a & 1 ? "MSB" : "LSB"); uint16_t vtemp = c -> getPSW(); + value &= ~16; // cannot set T bit via this + if (a & 1) vtemp = (vtemp & 0x00ff) | (value << 8); else @@ -433,7 +435,7 @@ uint16_t bus::write(const uint16_t a, const bool word_mode, uint16_t value, cons else { if (a == 0177776) { // PSW DOLOG(debug, true, "write PSW %o", value); - c -> setPSW(value, false); + c -> setPSW(value & ~16, false); return value; } diff --git a/cpu.cpp b/cpu.cpp index 9680a5b..e596d41 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -1366,9 +1366,9 @@ bool cpu::single_operand_instructions(const uint16_t instr) case 0b000110111: // MFPS (get PSW to something) / SXT if (word_mode) { // MFPS uint16_t temp = psw & 0xff; - bool extend_b7 = temp & 128; + bool extend_b7 = psw & 128; - if (extend_b7) + if (extend_b7 && dst_mode == 0) temp |= 0xff00; set_flags = putGAM(dst_mode, dst_reg, word_mode, temp, false); @@ -1376,7 +1376,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) if (set_flags) { setPSW_z(temp == 0); setPSW_v(false); - setPSW_n(!extend_b7); + setPSW_n(extend_b7); } } else { // SXT From 6eeb65eeb3d82e6471b274d98feee499463f96ee Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Mon, 13 Jun 2022 15:19:10 +0200 Subject: [PATCH 2/4] PAR/PDR fixes (FKTH??) --- bus.cpp | 24 ++++++++++++++++++++++++ cpu.h | 4 ++++ main.cpp | 18 +++++++++++++++++- 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/bus.cpp b/bus.cpp index 7a65cb1..61c9432 100644 --- a/bus.cpp +++ b/bus.cpp @@ -550,6 +550,11 @@ uint16_t bus::write(const uint16_t a, const bool word_mode, uint16_t value, cons pages[001][is_d][page].pdr = value; } + if (c->get_34()) // 11/34 has no cache bit + pages[001][is_d][page].pdr &= 32767; + + pages[001][is_d][page].pdr &= ~(128 + 64 + 32 + 16); // set bit 4 & 5 to 0 as they are unused and A/W are set to 0 by writes + DOLOG(debug, true, "write supervisor %c PDR for %d: %o [%d]", is_d ? 'D' : 'I', page, value, word_mode); return value; @@ -566,6 +571,9 @@ uint16_t bus::write(const uint16_t a, const bool word_mode, uint16_t value, cons pages[001][is_d][page].par = value; } + if (c->get_34()) // 11/34 has 12 bit PARs + pages[001][is_d][page].par &= 4095; + DOLOG(debug, true, "write supervisor %c PAR for %d: %o (%07o)", is_d ? 'D' : 'I', page, word_mode ? value & 0xff : value, pages[001][is_d][page].par * 64); return value; @@ -584,6 +592,11 @@ uint16_t bus::write(const uint16_t a, const bool word_mode, uint16_t value, cons pages[000][is_d][page].pdr = value; } + if (c->get_34()) // 11/34 has no cache bit + pages[000][is_d][page].pdr &= 32767; + + pages[000][is_d][page].pdr &= ~(128 + 64 + 32 + 16); // set bit 4 & 5 to 0 as they are unused and A/W are set to 0 by writes + DOLOG(debug, true, "write kernel %c PDR for %d: %o [%d]", is_d ? 'D' : 'I', page, value, word_mode); return value; @@ -600,6 +613,9 @@ uint16_t bus::write(const uint16_t a, const bool word_mode, uint16_t value, cons pages[000][is_d][page].par = value; } + if (c->get_34()) // 11/34 has 12 bit PARs + pages[000][is_d][page].par &= 4095; + DOLOG(debug, true, "write kernel %c PAR for %d: %o (%07o)", is_d ? 'D' : 'I', page, word_mode ? value & 0xff : value, pages[000][is_d][page].par * 64); return value; @@ -618,6 +634,11 @@ uint16_t bus::write(const uint16_t a, const bool word_mode, uint16_t value, cons pages[003][is_d][page].pdr = value; } + if (c->get_34()) // 11/34 has no cache bit + pages[003][is_d][page].pdr &= 32767; + + pages[003][is_d][page].pdr &= ~(128 + 64 + 32 + 16); // set bit 4 & 5 to 0 as they are unused and A/W are set to 0 by writes + DOLOG(debug, true, "write user %c PDR for %d: %o [%d]", is_d ? 'D' : 'I', page, value, word_mode); return value; @@ -634,6 +655,9 @@ uint16_t bus::write(const uint16_t a, const bool word_mode, uint16_t value, cons pages[003][is_d][page].par = value; } + if (c->get_34()) // 11/34 has 12 bit PARs + pages[003][is_d][page].par &= 4095; + DOLOG(debug, true, "write user %c PAR for %d: %o (%07o)", is_d ? 'D' : 'I', page, word_mode ? value & 0xff : value, pages[003][is_d][page].par * 64); return value; diff --git a/cpu.h b/cpu.h index cbd06cc..c32a4b8 100644 --- a/cpu.h +++ b/cpu.h @@ -25,6 +25,7 @@ private: bool emulateMFPT { false }; uint64_t instruction_count { 0 }; uint64_t running_since { 0 }; + bool mode11_70 { true }; // level, vector std::map > queued_interrupts; @@ -66,6 +67,9 @@ public: explicit cpu(bus *const b, std::atomic_uint32_t *const event); ~cpu(); + void set_34(const bool v) { mode11_70 = !v; } + bool get_34() { return !mode11_70; } + bool check_breakpoint(); void set_breakpoint(const uint16_t addr); void remove_breakpoint(const uint16_t addr); diff --git a/main.cpp b/main.cpp index 61c2f88..5b5d048 100644 --- a/main.cpp +++ b/main.cpp @@ -80,13 +80,17 @@ int main(int argc, char *argv[]) log_level_t ll_file = none; int opt = -1; - while((opt = getopt(argc, argv, "hm:T:r:R:p:ndtL:b:l:")) != -1) + while((opt = getopt(argc, argv, "hm:T:r:R:p:ndtL:b:l:3")) != -1) { switch(opt) { case 'h': help(); return 1; + case '3': + c->set_34(true); // switch from 11/70 to 11/34 + break; + case 'b': if (strcasecmp(optarg, "rk05") == 0) bootloader = BL_RK05; @@ -190,11 +194,23 @@ int main(int argc, char *argv[]) sigaction(SIGTERM, &sa, nullptr); sigaction(SIGINT , &sa, nullptr); +#if 0 // loadbin(b, 0, "test.dat"); // c->setRegister(7, 0); //load_p11_x11(b, "/home/folkert/Projects/PDP-11/work/p11-2.10i/Tests/mtpi.x11"); + + b->write(0172340, true, 0x34, false); + b->write(0172341, true, 0x12, false); + printf("%04x\n", b->read(0172340, false, false, true)); + printf("%04x\n", b->read(0172340, true, false, true)); + printf("%04x\n", b->read(0172341, true, false, true)); + b->write(0172341, true, 0x88, false); + printf("%04x\n", b->read(0172340, false, false, true)); + return 0; +#endif + cnsl->start_thread(); if (run_debugger) From 1dfb1ab32530ce5e90d9b44db33bb3fd43340dee Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Mon, 13 Jun 2022 19:26:40 +0200 Subject: [PATCH 3/4] 11/34 needs special masking of bits in pdr --- bus.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bus.cpp b/bus.cpp index 61c9432..1ae9b07 100644 --- a/bus.cpp +++ b/bus.cpp @@ -551,7 +551,7 @@ uint16_t bus::write(const uint16_t a, const bool word_mode, uint16_t value, cons } if (c->get_34()) // 11/34 has no cache bit - pages[001][is_d][page].pdr &= 32767; + pages[001][is_d][page].pdr &= 077516; pages[001][is_d][page].pdr &= ~(128 + 64 + 32 + 16); // set bit 4 & 5 to 0 as they are unused and A/W are set to 0 by writes @@ -593,7 +593,7 @@ uint16_t bus::write(const uint16_t a, const bool word_mode, uint16_t value, cons } if (c->get_34()) // 11/34 has no cache bit - pages[000][is_d][page].pdr &= 32767; + pages[000][is_d][page].pdr &= 077516; pages[000][is_d][page].pdr &= ~(128 + 64 + 32 + 16); // set bit 4 & 5 to 0 as they are unused and A/W are set to 0 by writes @@ -635,7 +635,7 @@ uint16_t bus::write(const uint16_t a, const bool word_mode, uint16_t value, cons } if (c->get_34()) // 11/34 has no cache bit - pages[003][is_d][page].pdr &= 32767; + pages[003][is_d][page].pdr &= 077516; pages[003][is_d][page].pdr &= ~(128 + 64 + 32 + 16); // set bit 4 & 5 to 0 as they are unused and A/W are set to 0 by writes From a000df36b85f66b4a28250df4008f0e01d303a0e Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Mon, 13 Jun 2022 19:26:54 +0200 Subject: [PATCH 4/4] fix for crash due to logging changes --- loaders.cpp | 6 +++--- loaders.h | 2 +- main.cpp | 40 ++++++++++++++++++++++++++++------------ 3 files changed, 32 insertions(+), 16 deletions(-) diff --git a/loaders.cpp b/loaders.cpp index 6513e2a..0088f42 100644 --- a/loaders.cpp +++ b/loaders.cpp @@ -104,11 +104,11 @@ void setBootLoader(bus *const b, const bootloader_t which) c -> setRegister(7, offset); } -uint16_t loadTape(bus *const b, const char *const file) +uint16_t loadTape(bus *const b, const std::string & file) { - FILE *fh = fopen(file, "rb"); + FILE *fh = fopen(file.c_str(), "rb"); if (!fh) { - DOLOG(ll_error, true, "Cannot open %s", file); + DOLOG(ll_error, true, "Cannot open %s", file.c_str()); return -1; } diff --git a/loaders.h b/loaders.h index 5825f0c..89241ad 100644 --- a/loaders.h +++ b/loaders.h @@ -8,5 +8,5 @@ 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); -uint16_t loadTape(bus *const b, const char *const file); +uint16_t 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 5b5d048..e487ac0 100644 --- a/main.cpp +++ b/main.cpp @@ -57,15 +57,6 @@ int main(int argc, char *argv[]) { //setlocale(LC_ALL, ""); - bus *b = new bus(); - - cpu *c = new cpu(b, &event); - b->add_cpu(c); - - kw11_l *lf = new kw11_l(b); - - c -> setEmulateMFPT(true); - std::vector rk05_files; std::vector rl02_files; @@ -79,6 +70,13 @@ int main(int argc, char *argv[]) log_level_t ll_screen = none; log_level_t ll_file = none; + bool mode_34 = false; + + uint16_t start_addr= 01000; + bool sa_set = false; + + std::string tape; + int opt = -1; while((opt = getopt(argc, argv, "hm:T:r:R:p:ndtL:b:l:3")) != -1) { @@ -88,7 +86,7 @@ int main(int argc, char *argv[]) return 1; case '3': - c->set_34(true); // switch from 11/70 to 11/34 + mode_34 = true; // switch from 11/70 to 11/34 break; case 'b': @@ -114,7 +112,7 @@ int main(int argc, char *argv[]) break; case 'T': - c->setRegister(7, loadTape(b, optarg)); + tape = optarg; break; case 'R': @@ -126,7 +124,8 @@ int main(int argc, char *argv[]) break; case 'p': - c->setRegister(7, atoi(optarg)); + start_addr = atoi(optarg); + sa_set = true; break; case 'L': { @@ -154,8 +153,25 @@ int main(int argc, char *argv[]) setlog(logfile, ll_file, ll_screen); + bus *b = new bus(); + + cpu *c = new cpu(b, &event); + b->add_cpu(c); + + c->set_34(mode_34); + + kw11_l *lf = new kw11_l(b); + + c->setEmulateMFPT(true); + std::atomic_bool interrupt_emulation { false }; + if (tape.empty() == false) + c->setRegister(7, loadTape(b, tape)); + + if (sa_set) + c->setRegister(7, start_addr); + if (withUI) cnsl = new console_ncurses(&event, b); else {