Fixes #23 RTT/RTI too trusting
This commit is contained in:
parent
b7da554118
commit
bbaf5e8bc6
2 changed files with 43 additions and 23 deletions
50
machine.py
50
machine.py
|
@ -956,29 +956,13 @@ class PDP1170(PDP11):
|
||||||
# could test if necessary but it's just easier to do this every time
|
# could test if necessary but it's just easier to do this every time
|
||||||
self._syncregs() # in case any mode/regset changes
|
self._syncregs() # in case any mode/regset changes
|
||||||
|
|
||||||
# prevent UNDEFINED_MODE from entering the PSW (current mode)
|
d = self._psw2dict(value)
|
||||||
m = (value >> 14) & 3
|
|
||||||
if m == self.UNDEFINED_MODE:
|
if self.UNDEFINED_MODE in (d['curmode'], d['prevmode']):
|
||||||
raise PDPTraps.ReservedInstruction
|
raise PDPTraps.ReservedInstruction
|
||||||
self.psw_curmode = m
|
|
||||||
|
|
||||||
# prevent UNDEFINED_MODE from entering the PSW (previous mode)
|
for attr, val in d.items():
|
||||||
m = (value >> 12) & 3
|
setattr(self, 'psw_' + attr, val)
|
||||||
if m == self.UNDEFINED_MODE:
|
|
||||||
raise PDPTraps.ReservedInstruction
|
|
||||||
self.psw_prevmode = m
|
|
||||||
|
|
||||||
prevregset = self.psw_regset
|
|
||||||
self.psw_regset = (value >> 11) & 1
|
|
||||||
|
|
||||||
newpri = (value >> 5) & 7
|
|
||||||
self.psw_pri = newpri
|
|
||||||
|
|
||||||
self.psw_trap = (value >> 4) & 1
|
|
||||||
self.psw_n = (value >> 3) & 1
|
|
||||||
self.psw_z = (value >> 2) & 1
|
|
||||||
self.psw_v = (value >> 1) & 1
|
|
||||||
self.psw_c = value & 1
|
|
||||||
|
|
||||||
# set up the correct register file and install correct SP
|
# set up the correct register file and install correct SP
|
||||||
self.r = self.registerfiles[self.psw_regset]
|
self.r = self.registerfiles[self.psw_regset]
|
||||||
|
@ -986,6 +970,30 @@ class PDP1170(PDP11):
|
||||||
|
|
||||||
# the PC was already sync'd in syncregs()
|
# the PC was already sync'd in syncregs()
|
||||||
|
|
||||||
|
_pswfields = {
|
||||||
|
'curmode': (14, 3), # bits 14:15
|
||||||
|
'prevmode': (12, 3), # bits 12:13
|
||||||
|
'regset': (11, 1), # bit 11
|
||||||
|
# 8 9 10 unused
|
||||||
|
'pri': (5, 7), # bits: 5:7
|
||||||
|
'trap': (4, 1),
|
||||||
|
'n': (3, 1),
|
||||||
|
'z': (2, 1),
|
||||||
|
'v': (1, 1),
|
||||||
|
'c': (0, 1),
|
||||||
|
}
|
||||||
|
|
||||||
|
def _psw2dict(self, pswval):
|
||||||
|
return {attr: (pswval >> bi[0]) & bi[1]
|
||||||
|
for attr, bi in self._pswfields.items()}
|
||||||
|
|
||||||
|
def _dict2psw(self, d):
|
||||||
|
psw = 0
|
||||||
|
for attr, val in d.items():
|
||||||
|
shf, mask = self._pswfields[attr]
|
||||||
|
psw |= (val & mask) << shf
|
||||||
|
return psw
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def logging_hack(self):
|
def logging_hack(self):
|
||||||
return self.logger.level
|
return self.logger.level
|
||||||
|
|
16
op000.py
16
op000.py
|
@ -48,7 +48,19 @@ def op_wait(cpu, inst):
|
||||||
|
|
||||||
def op_rtt(cpu, inst):
|
def op_rtt(cpu, inst):
|
||||||
cpu.r[cpu.PC] = cpu.stackpop()
|
cpu.r[cpu.PC] = cpu.stackpop()
|
||||||
cpu.psw = cpu.stackpop()
|
newpsw_d = cpu._psw2dict(cpu.stackpop())
|
||||||
|
|
||||||
|
# this knows KERNEL < SUPERVISOR < USER
|
||||||
|
newpsw_d['curmode'] = max(cpu.psw_curmode, newpsw_d['curmode'])
|
||||||
|
newpsw_d['prevmode'] = max(cpu.psw_prevmode, newpsw_d['prevmode'])
|
||||||
|
|
||||||
|
# if not in kernel mode, cannot change pri
|
||||||
|
if cpu.psw_curmode != cpu.KERNEL:
|
||||||
|
newpsw_d['pri'] = cpu.psw_pri
|
||||||
|
|
||||||
|
# Regset cannot be changed to zero if it is currently 1
|
||||||
|
newpsw_d['pri'] |= (cpu.psw_regset | newpsw_d['pri'])
|
||||||
|
cpu.psw = cpu._dict2psw(newpsw_d)
|
||||||
|
|
||||||
|
|
||||||
def op_02xx(cpu, inst):
|
def op_02xx(cpu, inst):
|
||||||
|
@ -115,7 +127,7 @@ def op000_dispatcher(cpu, inst):
|
||||||
if inst == 0:
|
if inst == 0:
|
||||||
op_halt(cpu, inst)
|
op_halt(cpu, inst)
|
||||||
elif inst == 6 or inst == 2: # RTI and RTT are identical!!
|
elif inst == 6 or inst == 2: # RTI and RTT are identical!!
|
||||||
op_rtt(cpu, inst)
|
op_rtt(cpu, inst) # (because trace not implemented)
|
||||||
elif inst == 1:
|
elif inst == 1:
|
||||||
op_wait(cpu, inst)
|
op_wait(cpu, inst)
|
||||||
elif inst == 3:
|
elif inst == 3:
|
||||||
|
|
Loading…
Add table
Reference in a new issue