Python: Add memory access

This commit is contained in:
Jeffrey Pfau 2016-10-27 18:39:52 -07:00
parent 572eb40d42
commit e2bcd2e05a
3 changed files with 96 additions and 0 deletions

View File

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

View File

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

View File

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