Repository navigation
Expand file tree
/
Copy pathbus.py
More file actions
88 lines (69 loc) · 2.91 KB
/
Copy pathbus.py
File metadata and controls
88 lines (69 loc) · 2.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
from typing import List, Tuple
import device
import memory
import rom
class Bus:
class CacheEntry:
def __init__(self):
self._start_addr: int = 0
self._end_addr: int = 0
self._wait_states: int = 0
self._device: device.Device = None
def __init__(self, size: int, devices: List[device], roms: List[rom.Rom]):
self._size = size
self._m = memory.Memory(size)
self._devices = devices
self._roms = roms
self._cache: List[Bus.CacheEntry] = None
self.RecreateCache()
def GetState(self) -> List[str]:
out = []
for entry in self._cache:
out.append(f'{entry.device.GetName()}, start address: {entry.start_addr:06x}, end address: {entry.end_addr:06x}, wait states: {entry.wait_states}')
return out
def _AddEntries(self, devices: List[device]):
for device in devices:
segments = device.GetAddressList()
for segment in segments:
entry = Bus.CacheEntry()
entry.start_addr = segment[0]
entry.end_addr = entry.start_addr + segment[1]
entry.wait_states = device.GetWaitStateCycles() # different per segment?
entry.device = device
self._cache.append(entry)
def RecreateCache(self):
self._cache = []
self._AddEntries(self._devices)
for rom in self._roms:
self._AddEntries((rom,))
# last! because it is a full 1 MB
self._AddEntries((self._m,))
# The normal PC memory map has RAM below the first mapped device. Keep
# that boundary so the hot CPU memory path can avoid scanning the
# device cache for ordinary RAM accesses.
self._direct_ram_end = self._size
for entry in self._cache:
if entry.device is not self._m:
self._direct_ram_end = min(self._direct_ram_end, entry.start_addr)
def ClearMemory(self):
self._m = memory.Memory(self._size)
self.RecreateCache()
def ReadByte(self, address: int) -> Tuple[int, int]:
if address < self._direct_ram_end:
return (self._m._m[address], 0)
for entry in self._cache:
if address >= entry.start_addr and address < entry.end_addr:
return (entry.device.ReadByte(address), entry.wait_states)
print(f'ReadByte from {address:06x} UNHANDLED')
return (0xff, 1) # TODO
def WriteByte(self, address: int, v: int) -> int:
assert v >= 0 and v <= 255
if address < self._direct_ram_end:
self._m._m[address] = v
return 0
for entry in self._cache:
if address >= entry.start_addr and address < entry.end_addr:
entry.device.WriteByte(address, v)
return entry.wait_states
print(f'WriteByte to {address:06x} ({v:02x}) UNHANDLED')
return 1 # TODO