add test for (user mode) PC wrap-around
This commit is contained in:
parent
4651d137f7
commit
379aeca487
1 changed files with 98 additions and 1 deletions
99
pdptests.py
99
pdptests.py
|
@ -40,7 +40,7 @@ from pdpasmhelper import InstructionBlock
|
|||
|
||||
class TestMethods(unittest.TestCase):
|
||||
|
||||
PDPLOGLEVEL = 'WARNING'
|
||||
PDPLOGLEVEL = 'DEBUG'
|
||||
|
||||
# used to create various instances, collects all the options
|
||||
# detail into this one place... mostly this is about loglevel
|
||||
|
@ -200,6 +200,59 @@ class TestMethods(unittest.TestCase):
|
|||
self.loadphysmem(p, a, instloc)
|
||||
return p, instloc
|
||||
|
||||
def u64mapped_pdp(self, p=None, /):
|
||||
# Make a PDP11 with:
|
||||
# * kernel space mapped to first 56K of memory (straight through)
|
||||
# * top of kernel space mapped to I/O page
|
||||
# * 64KB of user space mapped to phys 64K-128K
|
||||
#
|
||||
# No I/D separation.
|
||||
#
|
||||
if p is None:
|
||||
p = self.make_pdp()
|
||||
|
||||
cn = self.usefulconstants()
|
||||
|
||||
a = InstructionBlock()
|
||||
a.mov(0o160000, 'sp') # start system stack at top of K mem
|
||||
|
||||
# kernel segs 0 .. 6 to physical zero .. 56K
|
||||
a.mov(cn.KISA0, 'r4')
|
||||
for i in range(7):
|
||||
a.mov((i * 8192) >> 6, '(r4)+')
|
||||
|
||||
# kernel seg 7 to I/O page
|
||||
a.mov(0o776000 >> 6, '(r4)')
|
||||
|
||||
# user segs 0 .. 7 to physical 64K .. 128K
|
||||
a.mov(cn.UISA0, 'r4')
|
||||
for i in range(8):
|
||||
a.mov((65536 + (i * 8192)) >> 6, '(r4)+')
|
||||
|
||||
# set K and U PDRs
|
||||
# 77406 = PDR<2:0> = ACF = 0o110 = read/write
|
||||
# PLF<14:8> =0o0774 = full length (128*64 bytes = 8K)
|
||||
|
||||
a.mov(0o77406, 'r0')
|
||||
|
||||
a.mov(cn.KISD0, 'r4')
|
||||
for i in range(8):
|
||||
a.mov('r0', '(r4)+')
|
||||
|
||||
a.mov(cn.UISD0, 'r4')
|
||||
for i in range(8):
|
||||
a.mov('r0', '(r4)+')
|
||||
|
||||
# turn on relocation mode ...
|
||||
a.inc(a.ptr(cn.MMR0))
|
||||
|
||||
# and halt
|
||||
a.literal(0)
|
||||
|
||||
instloc = 0o4000 # 2K
|
||||
self.loadphysmem(p, a, instloc)
|
||||
return p, instloc
|
||||
|
||||
# test a typical sequence to set up a stack
|
||||
# This is really a test of label support in pdpasmhelper
|
||||
def test_fwdlabrel(self):
|
||||
|
@ -1118,6 +1171,50 @@ class TestMethods(unittest.TestCase):
|
|||
|
||||
self.assertEqual(good, h.hexdigest())
|
||||
|
||||
def test_pcwrap(self):
|
||||
# tests that the PC correctly wraps 0177776 --> 0
|
||||
p, a = self.u64mapped_pdp()
|
||||
p.run(pc=a)
|
||||
|
||||
# put machine into USER mode, clear all registers (on principle)
|
||||
# NOTE: DO NOT BASH p.psw_curmode directly, that bypasses all
|
||||
# the KSP vs USP magic
|
||||
p.psw = (p.USER << 14)
|
||||
|
||||
for i in range(8):
|
||||
p.r[i] = 0
|
||||
|
||||
# jam a MOV R2,R3 instruction at the end of user space
|
||||
# and a MOV R3,R4 instruction at location 0
|
||||
# The test verifies these correctly wrapped around
|
||||
p.mmu.wordRW(0o177776, 0o010203)
|
||||
p.mmu.wordRW(0, 0o010304)
|
||||
|
||||
# NOTE ... when PC reaches location 2, it executes a HALT (0).
|
||||
# This causes a ReservedInstruction trap in user mode. Since
|
||||
# none of the vectors have been filled in, control will transfer
|
||||
# (in KERNEL mode, because PSW in vector is zero) to location 0,
|
||||
# where it will find another HALT instruction (i.e., 0) and stop.
|
||||
# So all this works without making more scaffolding for that...
|
||||
|
||||
# this magic number MUST be negative because the N bit is
|
||||
# also checked in the saved PSW check below.
|
||||
magic = 0o123321
|
||||
p.r[2] = magic
|
||||
p.run(pc=0o177776)
|
||||
|
||||
# both MOV instructions should have executed
|
||||
self.assertEqual(p.r[2], magic)
|
||||
self.assertEqual(p.r[3], magic)
|
||||
self.assertEqual(p.r[4], magic)
|
||||
|
||||
# the ReservedInstruction trap should have put the (user) PC
|
||||
# value which is 2 past the halt instruction (i.e., 4) on stack
|
||||
self.assertEqual(p.mmu.wordRW(0o160000 - 4), 4)
|
||||
|
||||
# and the saved PSW which should be plain user mode, N-bit
|
||||
self.assertEqual(p.mmu.wordRW(0o160000 - 2), (p.USER << 14) | 0o10)
|
||||
|
||||
def test_trap(self):
|
||||
# test some traps
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue