src/platform/python/mgba/memory.py (view raw)
1# Copyright (c) 2013-2016 Jeffrey Pfau
2#
3# This Source Code Form is subject to the terms of the Mozilla Public
4# License, v. 2.0. If a copy of the MPL was not distributed with this
5# file, You can obtain one at http://mozilla.org/MPL/2.0/.
6from ._pylib import ffi, lib
7
8class MemoryView(object):
9 def __init__(self, core, width, size, base=0, sign="u"):
10 self._core = core
11 self._width = width
12 self._size = size
13 self._base = base
14 self._busRead = getattr(self._core, "busRead" + str(width * 8))
15 self._busWrite = getattr(self._core, "busWrite" + str(width * 8))
16 self._rawRead = getattr(self._core, "rawRead" + str(width * 8))
17 self._rawWrite = getattr(self._core, "rawWrite" + str(width * 8))
18 self._mask = (1 << (width * 8)) - 1 # Used to force values to fit within range so that negative values work
19 if sign == "u" or sign == "unsigned":
20 self._type = "uint{}_t".format(width * 8)
21 elif sign == "i" or sign == "s" or sign == "signed":
22 self._type = "int{}_t".format(width * 8)
23 else:
24 raise ValueError("Invalid sign type: '{}'".format(sign))
25
26 def _addrCheck(self, address):
27 if address >= self._size or address + self._width > self._size:
28 raise IndexError()
29 if address < 0:
30 raise IndexError()
31
32 def __len__(self):
33 return self._size
34
35 def __getitem__(self, address):
36 self._addrCheck(address)
37 return int(ffi.cast(self._type, self._busRead(self._core, self._base + address)))
38
39 def __setitem__(self, address, value):
40 self._addrCheck(address)
41 self._busWrite(self._core, self._base + address, value & self._mask)
42
43 def rawRead(self, address, segment=-1):
44 self._addrCheck(address)
45 return int(ffi.cast(self._type, self._rawRead(self._core, self._base + address, segment)))
46
47 def rawWrite(self, address, value, segment=-1):
48 self._addrCheck(address)
49 self._rawWrite(self._core, self._base + address, segment, value & self._mask)
50
51class Memory(object):
52 def __init__(self, core, size, base=0):
53 self.size = size
54 self.base = base
55
56 self.u8 = MemoryView(core, 1, size, base, "u")
57 self.u16 = MemoryView(core, 2, size, base, "u")
58 self.u32 = MemoryView(core, 4, size, base, "u")
59 self.s8 = MemoryView(core, 1, size, base, "s")
60 self.s16 = MemoryView(core, 2, size, base, "s")
61 self.s32 = MemoryView(core, 4, size, base, "s")
62
63 def __len__(self):
64 return self._size