Merge branch 'master' into d_i

This commit is contained in:
folkert van heusden 2022-06-13 20:59:07 +02:00
commit 37654c61a6
6 changed files with 82 additions and 20 deletions

28
bus.cpp
View file

@ -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"); DOLOG(debug, true, "writeb PSW %s", a & 1 ? "MSB" : "LSB");
uint16_t vtemp = c -> getPSW(); uint16_t vtemp = c -> getPSW();
value &= ~16; // cannot set T bit via this
if (a & 1) if (a & 1)
vtemp = (vtemp & 0x00ff) | (value << 8); vtemp = (vtemp & 0x00ff) | (value << 8);
else else
@ -435,7 +437,7 @@ uint16_t bus::write(const uint16_t a, const bool word_mode, uint16_t value, cons
else { else {
if (a == 0177776) { // PSW if (a == 0177776) { // PSW
DOLOG(debug, true, "write PSW %o", value); DOLOG(debug, true, "write PSW %o", value);
c -> setPSW(value, false); c -> setPSW(value & ~16, false);
return value; 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; 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); DOLOG(debug, true, "write supervisor %c PDR for %d: %o [%d]", is_d ? 'D' : 'I', page, value, word_mode);
return value; 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; 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); 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; 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; 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); DOLOG(debug, true, "write kernel %c PDR for %d: %o [%d]", is_d ? 'D' : 'I', page, value, word_mode);
return value; 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; 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); 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; 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; 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); DOLOG(debug, true, "write user %c PDR for %d: %o [%d]", is_d ? 'D' : 'I', page, value, word_mode);
return value; 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; 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); 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; return value;

View file

@ -1366,9 +1366,9 @@ bool cpu::single_operand_instructions(const uint16_t instr)
case 0b000110111: // MFPS (get PSW to something) / SXT case 0b000110111: // MFPS (get PSW to something) / SXT
if (word_mode) { // MFPS if (word_mode) { // MFPS
uint16_t temp = psw & 0xff; 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; temp |= 0xff00;
set_flags = putGAM(dst_mode, dst_reg, word_mode, temp, false); 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) { if (set_flags) {
setPSW_z(temp == 0); setPSW_z(temp == 0);
setPSW_v(false); setPSW_v(false);
setPSW_n(!extend_b7); setPSW_n(extend_b7);
} }
} }
else { // SXT else { // SXT

4
cpu.h
View file

@ -25,6 +25,7 @@ private:
bool emulateMFPT { false }; bool emulateMFPT { false };
uint64_t instruction_count { 0 }; uint64_t instruction_count { 0 };
uint64_t running_since { 0 }; uint64_t running_since { 0 };
bool mode11_70 { true };
// level, vector // level, vector
std::map<uint8_t, std::set<uint8_t> > queued_interrupts; std::map<uint8_t, std::set<uint8_t> > queued_interrupts;
@ -66,6 +67,9 @@ public:
explicit cpu(bus *const b, std::atomic_uint32_t *const event); explicit cpu(bus *const b, std::atomic_uint32_t *const event);
~cpu(); ~cpu();
void set_34(const bool v) { mode11_70 = !v; }
bool get_34() { return !mode11_70; }
bool check_breakpoint(); bool check_breakpoint();
void set_breakpoint(const uint16_t addr); void set_breakpoint(const uint16_t addr);
void remove_breakpoint(const uint16_t addr); void remove_breakpoint(const uint16_t addr);

View file

@ -104,11 +104,11 @@ void setBootLoader(bus *const b, const bootloader_t which)
c -> setRegister(7, offset); 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) { if (!fh) {
DOLOG(ll_error, true, "Cannot open %s", file); DOLOG(ll_error, true, "Cannot open %s", file.c_str());
return -1; return -1;
} }

View file

@ -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 loadbin(bus *const b, uint16_t base, const char *const file);
void setBootLoader(bus *const b, const bootloader_t which); 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); void load_p11_x11(bus *const b, const std::string & file);

View file

@ -57,15 +57,6 @@ int main(int argc, char *argv[])
{ {
//setlocale(LC_ALL, ""); //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<std::string> rk05_files; std::vector<std::string> rk05_files;
std::vector<std::string> rl02_files; std::vector<std::string> rl02_files;
@ -79,14 +70,25 @@ int main(int argc, char *argv[])
log_level_t ll_screen = none; log_level_t ll_screen = none;
log_level_t ll_file = 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; 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) { switch(opt) {
case 'h': case 'h':
help(); help();
return 1; return 1;
case '3':
mode_34 = true; // switch from 11/70 to 11/34
break;
case 'b': case 'b':
if (strcasecmp(optarg, "rk05") == 0) if (strcasecmp(optarg, "rk05") == 0)
bootloader = BL_RK05; bootloader = BL_RK05;
@ -110,7 +112,7 @@ int main(int argc, char *argv[])
break; break;
case 'T': case 'T':
c->setRegister(7, loadTape(b, optarg)); tape = optarg;
break; break;
case 'R': case 'R':
@ -122,7 +124,8 @@ int main(int argc, char *argv[])
break; break;
case 'p': case 'p':
c->setRegister(7, atoi(optarg)); start_addr = atoi(optarg);
sa_set = true;
break; break;
case 'L': { case 'L': {
@ -150,8 +153,25 @@ int main(int argc, char *argv[])
setlog(logfile, ll_file, ll_screen); 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 }; 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) if (withUI)
cnsl = new console_ncurses(&event, b); cnsl = new console_ncurses(&event, b);
else { else {
@ -190,11 +210,23 @@ int main(int argc, char *argv[])
sigaction(SIGTERM, &sa, nullptr); sigaction(SIGTERM, &sa, nullptr);
sigaction(SIGINT , &sa, nullptr); sigaction(SIGINT , &sa, nullptr);
#if 0
// loadbin(b, 0, "test.dat"); // loadbin(b, 0, "test.dat");
// c->setRegister(7, 0); // c->setRegister(7, 0);
//load_p11_x11(b, "/home/folkert/Projects/PDP-11/work/p11-2.10i/Tests/mtpi.x11"); //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(); cnsl->start_thread();
if (run_debugger) if (run_debugger)