Python: Add GB SIO
Vicki Pfau vi@endrift.com
Wed, 31 May 2017 22:40:03 -0700
5 files changed,
118 insertions(+),
29 deletions(-)
M
include/mgba/gb/interface.h
→
include/mgba/gb/interface.h
@@ -34,6 +34,15 @@ GB_MBC3_RTC = 0x103,
GB_MBC5_RUMBLE = 0x105 }; +struct GBSIODriver { + struct GBSIO* p; + + bool (*init)(struct GBSIODriver* driver); + void (*deinit)(struct GBSIODriver* driver); + void (*writeSB)(struct GBSIODriver* driver, uint8_t value); + uint8_t (*writeSC)(struct GBSIODriver* driver, uint8_t value); +}; + CXX_GUARD_END #endif
M
include/mgba/internal/gb/sio.h
→
include/mgba/internal/gb/sio.h
@@ -12,6 +12,7 @@ CXX_GUARD_START
#include <mgba/core/log.h> #include <mgba/core/timing.h> +#include <mgba/gb/interface.h> #define MAX_GBS 2@@ -32,15 +33,6 @@ int32_t period;
int remainingBits; uint8_t pendingSB; -}; - -struct GBSIODriver { - struct GBSIO* p; - - bool (*init)(struct GBSIODriver* driver); - void (*deinit)(struct GBSIODriver* driver); - void (*writeSB)(struct GBSIODriver* driver, uint8_t value); - uint8_t (*writeSC)(struct GBSIODriver* driver, uint8_t value); }; DECL_BITFIELD(GBRegisterSC, uint8_t);
M
src/platform/python/mgba/gb.py
→
src/platform/python/mgba/gb.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2013-2016 Jeffrey Pfau +# Copyright (c) 2013-2017 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@@ -8,6 +8,7 @@ from .lr35902 import LR35902Core
from .core import Core, needsReset from .memory import Memory from .tile import Sprite +from . import createCallback class GB(Core): KEY_A = lib.GBA_KEY_A@@ -33,6 +34,48 @@
def _deinitTileCache(self, cache): self._native.video.renderer.cache = ffi.NULL lib.mTileCacheDeinit(cache) + + def attachSIO(self, link): + lib.GBSIOSetDriver(ffi.addressof(self._native.sio), link._native) + +createCallback("GBSIOPythonDriver", "init") +createCallback("GBSIOPythonDriver", "deinit") +createCallback("GBSIOPythonDriver", "writeSB") +createCallback("GBSIOPythonDriver", "writeSC") + +class GBSIODriver(object): + def __init__(self): + self._handle = ffi.new_handle(self) + self._native = ffi.gc(lib.GBSIOPythonDriverCreate(self._handle), lib.free) + + def init(self): + return True + + def deinit(self): + pass + + def writeSB(self, value): + pass + + def writeSC(self, value): + return value + +class GBSIOSimpleDriver(GBSIODriver): + def __init__(self): + super(GBSIOSimpleDriver, self).__init__() + self.tx = 0xFF + self.rx = 0xFF + + def writeSB(self, value): + self.rx = value + + def schedule(self, period=0x100, when=0): + self._native.p.remainingBits = 8 + self._native.p.period = period + self._native.p.pendingSB = self.tx + self.tx = 0xFF + lib.mTimingDeschedule(ffi.addressof(self._native.p.p.timing), ffi.addressof(self._native.p.event)) + lib.mTimingSchedule(ffi.addressof(self._native.p.p.timing), ffi.addressof(self._native.p.event), when) class GBMemory(Memory): def __init__(self, core):
M
src/platform/python/sio.c
→
src/platform/python/sio.c
@@ -3,36 +3,36 @@ *
* 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/. */ -#include <mgba/gba/interface.h> - #include "flags.h" -#ifdef M_CORE_GBA +#define CREATE_SHIM(PLAT, NAME, RETURN) \ + RETURN _py ## PLAT ## SIOPythonDriver ## NAME (void* driver); \ + static RETURN _py ## PLAT ## SIOPythonDriver ## NAME ## Shim(struct PLAT ## SIODriver* driver) { \ + struct PLAT ## SIODriver* py = (struct PLAT ## SIODriver*) driver; \ + return _py ## PLAT ## SIOPythonDriver ## NAME(py); \ + } -#define CREATE_SHIM(NAME, RETURN) \ - RETURN _pyGBASIOPythonDriver ## NAME (void* driver); \ - static RETURN _pyGBASIOPythonDriver ## NAME ## Shim(struct GBASIODriver* driver) { \ - struct GBASIODriver* py = (struct GBASIODriver*) driver; \ - return _pyGBASIOPythonDriver ## NAME(py); \ +#define CREATE_SHIM_ARGS(PLAT, NAME, RETURN, TYPES, ...) \ + RETURN _py ## PLAT ## SIOPythonDriver ## NAME TYPES; \ + static RETURN _py ## PLAT ## SIOPythonDriver ## NAME ## Shim TYPES { \ + struct PLAT ## SIODriver* py = (struct PLAT ## SIODriver*) driver; \ + return _py ## PLAT ## SIOPythonDriver ## NAME(py, __VA_ARGS__); \ } -#define CREATE_SHIM_ARGS(NAME, RETURN, TYPES, ...) \ - RETURN _pyGBASIOPythonDriver ## NAME TYPES; \ - static RETURN _pyGBASIOPythonDriver ## NAME ## Shim TYPES { \ - struct GBASIODriver* py = (struct GBASIODriver*) driver; \ - return _pyGBASIOPythonDriver ## NAME(py, __VA_ARGS__); \ - } +#ifdef M_CORE_GBA + +#include <mgba/gba/interface.h> struct GBASIOPythonDriver { struct GBASIODriver d; void* pyobj; }; -CREATE_SHIM(Init, bool); -CREATE_SHIM(Deinit, void); -CREATE_SHIM(Load, bool); -CREATE_SHIM(Unload, bool); -CREATE_SHIM_ARGS(WriteRegister, uint16_t, (struct GBASIODriver* driver, uint32_t address, uint16_t value), address, value); +CREATE_SHIM(GBA, Init, bool); +CREATE_SHIM(GBA, Deinit, void); +CREATE_SHIM(GBA, Load, bool); +CREATE_SHIM(GBA, Unload, bool); +CREATE_SHIM_ARGS(GBA, WriteRegister, uint16_t, (struct GBASIODriver* driver, uint32_t address, uint16_t value), address, value); struct GBASIODriver* GBASIOPythonDriverCreate(void* pyobj) { struct GBASIOPythonDriver* driver = malloc(sizeof(*driver));@@ -47,3 +47,30 @@ return &driver->d;
} #endif + +#ifdef M_CORE_GB + +#include <mgba/gb/interface.h> + +struct GBSIOPythonDriver { + struct GBSIODriver d; + void* pyobj; +}; + +CREATE_SHIM(GB, Init, bool); +CREATE_SHIM(GB, Deinit, void); +CREATE_SHIM_ARGS(GB, WriteSB, void, (struct GBSIODriver* driver, uint8_t value), value); +CREATE_SHIM_ARGS(GB, WriteSC, uint8_t, (struct GBSIODriver* driver, uint8_t value), value); + +struct GBSIODriver* GBSIOPythonDriverCreate(void* pyobj) { + struct GBSIOPythonDriver* driver = malloc(sizeof(*driver)); + driver->d.init = _pyGBSIOPythonDriverInitShim; + driver->d.deinit = _pyGBSIOPythonDriverDeinitShim; + driver->d.writeSB = _pyGBSIOPythonDriverWriteSBShim; + driver->d.writeSC = _pyGBSIOPythonDriverWriteSCShim; + + driver->pyobj = pyobj; + return &driver->d; +} + +#endif
M
src/platform/python/sio.h
→
src/platform/python/sio.h
@@ -21,3 +21,21 @@ PYEXPORT bool _pyGBASIOPythonDriverUnload(void* driver);
PYEXPORT uint16_t _pyGBASIOPythonDriverWriteRegister(void* driver, uint32_t address, uint16_t value); #endif + +#ifdef M_CORE_GB + +#include <mgba/gb/interface.h> + +struct GBSIOPythonDriver { + struct GBSIODriver d; + void* pyobj; +}; + +struct GBSIODriver* GBSIOPythonDriverCreate(void* pyobj); + +PYEXPORT bool _pyGBSIOPythonDriverInit(void* driver); +PYEXPORT void _pyGBSIOPythonDriverDeinit(void* driver); +PYEXPORT void _pyGBSIOPythonDriverWriteSB(void* driver, uint8_t value); +PYEXPORT uint8_t _pyGBSIOPythonDriverWriteSC(void* driver, uint8_t value); + +#endif