make sure only the trap/interrupt vectors are retrieved from kernel space, not general reads
This commit is contained in:
parent
fa8d6d9f9d
commit
7ad20f2705
3 changed files with 12 additions and 9 deletions
10
bus.cpp
10
bus.cpp
|
@ -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
|
const uint8_t apf = a >> 13; // active page field
|
||||||
|
|
||||||
if (a < 01000)
|
if (use_prev)
|
||||||
run_mode = 0;
|
|
||||||
else if (use_prev)
|
|
||||||
run_mode = (c->getPSW() >> 12) & 3;
|
run_mode = (c->getPSW() >> 12) & 3;
|
||||||
|
|
||||||
uint32_t m_offset = pages[run_mode][apf].par * 64; // memory offset
|
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
|
const uint8_t apf = a >> 13; // active page field
|
||||||
|
|
||||||
if (a < 01000)
|
if (use_prev)
|
||||||
run_mode = 0;
|
|
||||||
else if (use_prev)
|
|
||||||
run_mode = (c->getPSW() >> 12) & 3;
|
run_mode = (c->getPSW() >> 12) & 3;
|
||||||
|
|
||||||
uint32_t m_offset = pages[run_mode][apf].par * 64;
|
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) {
|
else if (m_offset >= n_pages * 8192) {
|
||||||
D(fprintf(stderr, "bus::write %o >= %o\n", 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;
|
pages[run_mode][apf].pdr |= 1 << 7;
|
||||||
|
|
||||||
|
|
2
bus.h
2
bus.h
|
@ -65,6 +65,8 @@ public:
|
||||||
|
|
||||||
void writeUnibusByte(const uint16_t a, const uint8_t value);
|
void writeUnibusByte(const uint16_t a, const uint8_t value);
|
||||||
|
|
||||||
|
uint16_t getMMR0() { return MMR0; }
|
||||||
|
|
||||||
void setMMR2(const uint16_t value) { MMR2 = value; }
|
void setMMR2(const uint16_t value) { MMR2 = value; }
|
||||||
|
|
||||||
uint16_t get_switch_register() const { return switch_register; }
|
uint16_t get_switch_register() const { return switch_register; }
|
||||||
|
|
9
cpu.cpp
9
cpu.cpp
|
@ -1197,6 +1197,13 @@ void cpu::trap(const uint16_t vector, const int new_ipl)
|
||||||
uint16_t before_psw = getPSW();
|
uint16_t before_psw = getPSW();
|
||||||
uint16_t before_pc = getPC();
|
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'
|
// switch to kernel mode & update 'previous mode'
|
||||||
uint16_t new_psw = b->readWord(vector + 2) & 0147777; // mask off old 'previous mode'
|
uint16_t new_psw = b->readWord(vector + 2) & 0147777; // mask off old 'previous mode'
|
||||||
if (new_ipl != -1)
|
if (new_ipl != -1)
|
||||||
|
@ -1207,8 +1214,6 @@ void cpu::trap(const uint16_t vector, const int new_ipl)
|
||||||
pushStack(before_psw);
|
pushStack(before_psw);
|
||||||
pushStack(before_pc);
|
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);)
|
D(fprintf(stderr, "TRAP %o: PC is now %06o, PSW is now %06o\n", vector, getPC(), new_psw);)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue