Made _CYCLE an Enum
This commit is contained in:
parent
c6dcec323c
commit
d0b0c2f25a
1 changed files with 17 additions and 13 deletions
30
mmu.py
30
mmu.py
|
@ -24,13 +24,20 @@ from functools import partial
|
||||||
from pdptraps import PDPTraps
|
from pdptraps import PDPTraps
|
||||||
from types import SimpleNamespace
|
from types import SimpleNamespace
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
|
||||||
|
# used internally to represent reads vs writes
|
||||||
|
class _CYCLE(Enum):
|
||||||
|
READ = 'r'
|
||||||
|
WRITE = 'w'
|
||||||
|
|
||||||
|
|
||||||
class MemoryMgmt:
|
class MemoryMgmt:
|
||||||
ISPACE = 0
|
ISPACE = 0
|
||||||
DSPACE = 1
|
DSPACE = 1
|
||||||
|
|
||||||
# I/O addreses for various registers relative to I/O page base
|
# I/O addresses for various registers relative to I/O page base
|
||||||
# From the pdp11/70 (and others) 1981 processor handbook, Appendix A
|
# From the pdp11/70 (and others) 1981 processor handbook, Appendix A
|
||||||
#
|
#
|
||||||
# Each block is:
|
# Each block is:
|
||||||
|
@ -61,9 +68,6 @@ class MemoryMgmt:
|
||||||
# memory control (parity, etc) is not implemented but needs to respond
|
# memory control (parity, etc) is not implemented but needs to respond
|
||||||
MCR_OFFS = 0o17746
|
MCR_OFFS = 0o17746
|
||||||
|
|
||||||
# encodes read vs write cycles
|
|
||||||
CYCLE = SimpleNamespace(READ='r', WRITE='w')
|
|
||||||
|
|
||||||
TransKey = namedtuple('TransKey', ('segno', 'mode', 'space', 'cycle'))
|
TransKey = namedtuple('TransKey', ('segno', 'mode', 'space', 'cycle'))
|
||||||
|
|
||||||
def __init__(self, cpu, /, *, nocache=False):
|
def __init__(self, cpu, /, *, nocache=False):
|
||||||
|
@ -146,9 +150,9 @@ class MemoryMgmt:
|
||||||
return aprfile[aprnum][parpdr]
|
return aprfile[aprnum][parpdr]
|
||||||
else:
|
else:
|
||||||
# dump any matching cache entries in both reading/writing form.
|
# dump any matching cache entries in both reading/writing form.
|
||||||
for w in (self.CYCLE.READ, self.CYCLE.WRITE):
|
for rw in (_CYCLE.READ, _CYCLE.WRITE):
|
||||||
if (aprnum, mode, space, w) in self.segcache:
|
if (aprnum, mode, space, rw) in self.segcache:
|
||||||
del self.segcache[(aprnum, mode, space, w)]
|
del self.segcache[(aprnum, mode, space, rw)]
|
||||||
|
|
||||||
aprfile[aprnum][parpdr] = value
|
aprfile[aprnum][parpdr] = value
|
||||||
|
|
||||||
|
@ -330,7 +334,7 @@ class MemoryMgmt:
|
||||||
# already happened (here). So the "found it in cache" logic up top
|
# already happened (here). So the "found it in cache" logic up top
|
||||||
# of this function needn't worry about AW bit updates.
|
# of this function needn't worry about AW bit updates.
|
||||||
|
|
||||||
AW_update = 0o300 if cycle == self.CYCLE.WRITE else 0o200
|
AW_update = 0o300 if cycle == _CYCLE.WRITE else 0o200
|
||||||
# XXX ^^^^^ not sure if a write should be 0o300 or naked 0o100
|
# XXX ^^^^^ not sure if a write should be 0o300 or naked 0o100
|
||||||
|
|
||||||
if (pdr & AW_update) != AW_update:
|
if (pdr & AW_update) != AW_update:
|
||||||
|
@ -417,10 +421,10 @@ class MemoryMgmt:
|
||||||
self._raisetrap(self.MMR0_BITS.ABORT_NR, vaddr, xkey)
|
self._raisetrap(self.MMR0_BITS.ABORT_NR, vaddr, xkey)
|
||||||
|
|
||||||
# control mode 1 is an abort if writing, mgmt trap if read
|
# control mode 1 is an abort if writing, mgmt trap if read
|
||||||
case 1 if cycle == self.CYCLE.READ:
|
case 1 if cycle == _CYCLE.READ:
|
||||||
straps = self.cpu.STRAPBITS.MEMMGT
|
straps = self.cpu.STRAPBITS.MEMMGT
|
||||||
|
|
||||||
case 1 | 2 if cycle == self.CYCLE.WRITE:
|
case 1 | 2 if cycle == _CYCLE.WRITE:
|
||||||
self._raisetrap(self.MMR0_BITS.ABORT_RDONLY, vaddr, xkey)
|
self._raisetrap(self.MMR0_BITS.ABORT_RDONLY, vaddr, xkey)
|
||||||
|
|
||||||
# control mode 4 is mgmt trap on any access (read or write)
|
# control mode 4 is mgmt trap on any access (read or write)
|
||||||
|
@ -428,7 +432,7 @@ class MemoryMgmt:
|
||||||
straps = self.cpu.STRAPBITS.MEMMGT
|
straps = self.cpu.STRAPBITS.MEMMGT
|
||||||
|
|
||||||
# control mode 5 is mgmt trap if WRITING
|
# control mode 5 is mgmt trap if WRITING
|
||||||
case 5 if cycle == self.CYCLE.WRITE:
|
case 5 if cycle == _CYCLE.WRITE:
|
||||||
straps = self.cpu.STRAPBITS.MEMMGT
|
straps = self.cpu.STRAPBITS.MEMMGT
|
||||||
|
|
||||||
return straps
|
return straps
|
||||||
|
@ -440,7 +444,7 @@ class MemoryMgmt:
|
||||||
If value is not None, perform a write; return None.
|
If value is not None, perform a write; return None.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
cycle = self.CYCLE.READ if value is None else self.CYCLE.WRITE
|
cycle = _CYCLE.READ if value is None else _CYCLE.WRITE
|
||||||
pa = self.v2p(vaddr, mode, space, cycle)
|
pa = self.v2p(vaddr, mode, space, cycle)
|
||||||
if pa >= self.iopage_base:
|
if pa >= self.iopage_base:
|
||||||
return self.ub.mmio.wordRW(pa & self.cpu.IOPAGE_MASK, value)
|
return self.ub.mmio.wordRW(pa & self.cpu.IOPAGE_MASK, value)
|
||||||
|
@ -454,7 +458,7 @@ class MemoryMgmt:
|
||||||
If value is not None, perform a write; return None.
|
If value is not None, perform a write; return None.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
cycle = self.CYCLE.READ if value is None else self.CYCLE.WRITE
|
cycle = _CYCLE.READ if value is None else _CYCLE.WRITE
|
||||||
pa = self.v2p(vaddr, mode, space, cycle)
|
pa = self.v2p(vaddr, mode, space, cycle)
|
||||||
|
|
||||||
# Physical memory is represented as an array of 16-bit word
|
# Physical memory is represented as an array of 16-bit word
|
||||||
|
|
Loading…
Add table
Reference in a new issue