mirror of https://github.com/mgba-emu/mgba.git
Python: Add memory access
This commit is contained in:
parent
572eb40d42
commit
e2bcd2e05a
|
@ -6,6 +6,7 @@
|
|||
from ._pylib import ffi, lib
|
||||
from .lr35902 import LR35902Core
|
||||
from .core import Core
|
||||
from .memory import Memory
|
||||
from .tile import Sprite
|
||||
|
||||
class GB(Core):
|
||||
|
@ -32,6 +33,18 @@ class GB(Core):
|
|||
self._native.video.renderer.cache = ffi.NULL
|
||||
lib.mTileCacheDeinit(cache)
|
||||
|
||||
class GBMemory(Memory):
|
||||
def __init__(self, core):
|
||||
super(GBMemory, self).__init__(core, 0x10000)
|
||||
|
||||
self.cart = Memory(core, lib.GB_SIZE_CART_BANK0 * 2, lib.GB_BASE_CART_BANK0)
|
||||
self.vram = Memory(core, lib.GB_SIZE_VRAM, lib.GB_BASE_VRAM)
|
||||
self.sram = Memory(core, lib.GB_SIZE_EXTERNAL_RAM, lib.GB_REGION_EXTERNAL_RAM)
|
||||
self.iwram = Memory(core, lib.GB_SIZE_WORKING_RAM_BANK0, lib.GB_BASE_WORKING_RAM_BANK0)
|
||||
self.oam = Memory(core, lib.GB_SIZE_OAM, lib.GB_BASE_OAM)
|
||||
self.io = Memory(core, lib.GB_SIZE_IO, lib.GB_BASE_IO)
|
||||
self.hram = Memory(core, lib.GB_SIZE_HRAM, lib.GB_BASE_HRAM)
|
||||
|
||||
class GBSprite(Sprite):
|
||||
PALETTE_BASE = 8,
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ from ._pylib import ffi, lib
|
|||
from .arm import ARMCore
|
||||
from .core import Core
|
||||
from .tile import Sprite
|
||||
from .memory import Memory
|
||||
|
||||
class GBA(Core):
|
||||
KEY_A = lib.GBA_KEY_A
|
||||
|
@ -25,6 +26,7 @@ class GBA(Core):
|
|||
self._native = ffi.cast("struct GBA*", native.board)
|
||||
self.sprites = GBAObjs(self)
|
||||
self.cpu = ARMCore(self._core.cpu)
|
||||
self.memory = GBAMemory(self._core)
|
||||
|
||||
def _initTileCache(self, cache):
|
||||
lib.GBAVideoTileCacheInit(cache)
|
||||
|
@ -34,6 +36,23 @@ class GBA(Core):
|
|||
self._native.video.renderer.cache = ffi.NULL
|
||||
lib.mTileCacheDeinit(cache)
|
||||
|
||||
class GBAMemory(Memory):
|
||||
def __init__(self, core):
|
||||
super(GBAMemory, self).__init__(core, 0x100000000)
|
||||
|
||||
self.bios = Memory(core, lib.SIZE_BIOS, lib.BASE_BIOS)
|
||||
self.wram = Memory(core, lib.SIZE_WORKING_RAM, lib.BASE_WORKING_RAM)
|
||||
self.iwram = Memory(core, lib.SIZE_WORKING_IRAM, lib.BASE_WORKING_IRAM)
|
||||
self.io = Memory(core, lib.SIZE_IO, lib.BASE_IO)
|
||||
self.palette = Memory(core, lib.SIZE_PALETTE_RAM, lib.BASE_PALETTE_RAM)
|
||||
self.vram = Memory(core, lib.SIZE_VRAM, lib.BASE_VRAM)
|
||||
self.oam = Memory(core, lib.SIZE_OAM, lib.BASE_OAM)
|
||||
self.cart0 = Memory(core, lib.SIZE_CART0, lib.BASE_CART0)
|
||||
self.cart1 = Memory(core, lib.SIZE_CART1, lib.BASE_CART1)
|
||||
self.cart2 = Memory(core, lib.SIZE_CART2, lib.BASE_CART2)
|
||||
self.cart = self.cart0
|
||||
self.sram = Memory(core, lib.SIZE_CART_SRAM, lib.BASE_CART_SRAM)
|
||||
|
||||
class GBASprite(Sprite):
|
||||
TILE_BASE = 0x800, 0x400
|
||||
PALETTE_BASE = 0x10, 1
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
# Copyright (c) 2013-2016 Jeffrey Pfau
|
||||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
from ._pylib import ffi, lib
|
||||
|
||||
class MemoryView(object):
|
||||
def __init__(self, core, width, size, base=0, sign="u"):
|
||||
self._core = core
|
||||
self._width = width
|
||||
self._size = size
|
||||
self._base = base
|
||||
self._busRead = getattr(self._core, "busRead" + str(width * 8))
|
||||
self._busWrite = getattr(self._core, "busWrite" + str(width * 8))
|
||||
self._rawRead = getattr(self._core, "rawRead" + str(width * 8))
|
||||
self._rawWrite = getattr(self._core, "rawWrite" + str(width * 8))
|
||||
self._mask = (1 << (width * 8)) - 1 # Used to force values to fit within range so that negative values work
|
||||
if sign == "u" or sign == "unsigned":
|
||||
self._type = "uint{}_t".format(width * 8)
|
||||
elif sign == "i" or sign == "s" or sign == "signed":
|
||||
self._type = "int{}_t".format(width * 8)
|
||||
else:
|
||||
raise ValueError("Invalid sign type: '{}'".format(sign))
|
||||
|
||||
def _addrCheck(self, address):
|
||||
if address >= self._size or address + self._width > self._size:
|
||||
raise IndexError()
|
||||
if address < 0:
|
||||
raise IndexError()
|
||||
|
||||
def __len__(self):
|
||||
return self._size
|
||||
|
||||
def __getitem__(self, address):
|
||||
self._addrCheck(address)
|
||||
return int(ffi.cast(self._type, self._busRead(self._core, self._base + address)))
|
||||
|
||||
def __setitem__(self, address, value):
|
||||
self._addrCheck(address)
|
||||
self._busWrite(self._core, self._base + address, value & self._mask)
|
||||
|
||||
def rawRead(self, address, segment=-1):
|
||||
self._addrCheck(address)
|
||||
return int(ffi.cast(self._type, self._rawRead(self._core, self._base + address, segment)))
|
||||
|
||||
def rawWrite(self, address, value, segment=-1):
|
||||
self._addrCheck(address)
|
||||
self._rawWrite(self._core, self._base + address, segment, value & self._mask)
|
||||
|
||||
class Memory(object):
|
||||
def __init__(self, core, size, base=0):
|
||||
self.size = size
|
||||
self.base = base
|
||||
|
||||
self.u8 = MemoryView(core, 1, size, base, "u")
|
||||
self.u16 = MemoryView(core, 2, size, base, "u")
|
||||
self.u32 = MemoryView(core, 4, size, base, "u")
|
||||
self.s8 = MemoryView(core, 1, size, base, "s")
|
||||
self.s16 = MemoryView(core, 2, size, base, "s")
|
||||
self.s32 = MemoryView(core, 4, size, base, "s")
|
||||
|
||||
def __len__(self):
|
||||
return self._size
|
Loading…
Reference in New Issue