Made _CYCLE an Enum

This commit is contained in:
Neil Webber 2023-09-15 06:15:10 -04:00
parent c6dcec323c
commit d0b0c2f25a

30
mmu.py
View file

@ -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