make sure only the trap/interrupt vectors are retrieved from kernel space, not general reads

This commit is contained in:
folkert van heusden 2022-03-27 04:29:36 +02:00
parent fa8d6d9f9d
commit 7ad20f2705
3 changed files with 12 additions and 9 deletions

10
bus.cpp
View file

@ -304,9 +304,7 @@ uint16_t bus::read(const uint16_t a, const bool word_mode, const bool use_prev)
const uint8_t apf = a >> 13; // active page field
if (a < 01000)
run_mode = 0;
else if (use_prev)
if (use_prev)
run_mode = (c->getPSW() >> 12) & 3;
uint32_t m_offset = pages[run_mode][apf].par * 64; // memory offset
@ -596,9 +594,7 @@ uint16_t bus::write(const uint16_t a, const bool word_mode, uint16_t value, cons
const uint8_t apf = a >> 13; // active page field
if (a < 01000)
run_mode = 0;
else if (use_prev)
if (use_prev)
run_mode = (c->getPSW() >> 12) & 3;
uint32_t m_offset = pages[run_mode][apf].par * 64;
@ -623,7 +619,7 @@ uint16_t bus::write(const uint16_t a, const bool word_mode, uint16_t value, cons
}
else if (m_offset >= n_pages * 8192) {
D(fprintf(stderr, "bus::write %o >= %o\n", m_offset, n_pages * 8192);)
c->schedule_trap(04); // invalid address
c->schedule_trap(04); // invalid address FIXME stop execution of that instruction: throw an exception caught in step()?
pages[run_mode][apf].pdr |= 1 << 7;

2
bus.h
View file

@ -65,6 +65,8 @@ public:
void writeUnibusByte(const uint16_t a, const uint8_t value);
uint16_t getMMR0() { return MMR0; }
void setMMR2(const uint16_t value) { MMR2 = value; }
uint16_t get_switch_register() const { return switch_register; }

View file

@ -1197,6 +1197,13 @@ void cpu::trap(const uint16_t vector, const int new_ipl)
uint16_t before_psw = getPSW();
uint16_t before_pc = getPC();
if (b->getMMR0() & 1) {
// make sure the trap vector is retrieved from kernel space
psw &= 037777; // mask off 14/15
}
setPC(b->readWord(vector + 0));
// switch to kernel mode & update 'previous mode'
uint16_t new_psw = b->readWord(vector + 2) & 0147777; // mask off old 'previous mode'
if (new_ipl != -1)
@ -1207,8 +1214,6 @@ void cpu::trap(const uint16_t vector, const int new_ipl)
pushStack(before_psw);
pushStack(before_pc);
setPC(b->readWord(vector + 0));
D(fprintf(stderr, "TRAP %o: PC is now %06o, PSW is now %06o\n", vector, getPC(), new_psw);)
}