Merge branch 'master' into d_i
This commit is contained in:
commit
37654c61a6
6 changed files with 82 additions and 20 deletions
28
bus.cpp
28
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");
|
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;
|
||||||
|
|
6
cpu.cpp
6
cpu.cpp
|
@ -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
4
cpu.h
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
56
main.cpp
56
main.cpp
|
@ -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)
|
||||||
|
|
Loading…
Add table
Reference in a new issue