diff --git a/bus.cpp b/bus.cpp index ec55798..2f0a61a 100644 --- a/bus.cpp +++ b/bus.cpp @@ -409,6 +409,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 @@ -435,7 +437,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; } @@ -550,6 +552,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 &= 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 + DOLOG(debug, true, "write supervisor %c PDR for %d: %o [%d]", is_d ? 'D' : 'I', page, value, word_mode); return value; @@ -566,6 +573,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 +594,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 &= 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 + DOLOG(debug, true, "write kernel %c PDR for %d: %o [%d]", is_d ? 'D' : 'I', page, value, word_mode); return value; @@ -600,6 +615,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 +636,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 &= 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 + DOLOG(debug, true, "write user %c PDR for %d: %o [%d]", is_d ? 'D' : 'I', page, value, word_mode); return value; @@ -634,6 +657,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.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 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/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 61c2f88..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,14 +70,25 @@ 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:")) != -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': + mode_34 = true; // switch from 11/70 to 11/34 + break; + case 'b': if (strcasecmp(optarg, "rk05") == 0) bootloader = BL_RK05; @@ -110,7 +112,7 @@ int main(int argc, char *argv[]) break; case 'T': - c->setRegister(7, loadTape(b, optarg)); + tape = optarg; break; case 'R': @@ -122,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': { @@ -150,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 { @@ -190,11 +210,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)