all repos — mgba @ e2bcd2e05ad4d8fa879a5b32f56c91e1f5e4c964

mGBA Game Boy Advance Emulator

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