Python: Add GB SIO

This commit is contained in:
Vicki Pfau 2017-05-31 22:40:03 -07:00
parent efd8c4b466
commit 362c572009
5 changed files with 119 additions and 30 deletions

View File

@ -34,6 +34,15 @@ enum GBMemoryBankControllerType {
GB_MBC5_RUMBLE = 0x105 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 CXX_GUARD_END
#endif #endif

View File

@ -12,6 +12,7 @@ CXX_GUARD_START
#include <mgba/core/log.h> #include <mgba/core/log.h>
#include <mgba/core/timing.h> #include <mgba/core/timing.h>
#include <mgba/gb/interface.h>
#define MAX_GBS 2 #define MAX_GBS 2
@ -34,15 +35,6 @@ struct GBSIO {
uint8_t pendingSB; 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); DECL_BITFIELD(GBRegisterSC, uint8_t);
DECL_BIT(GBRegisterSC, ShiftClock, 0); DECL_BIT(GBRegisterSC, ShiftClock, 0);
DECL_BIT(GBRegisterSC, ClockSpeed, 1); DECL_BIT(GBRegisterSC, ClockSpeed, 1);

View File

@ -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 # 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 # 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 .core import Core, needsReset
from .memory import Memory from .memory import Memory
from .tile import Sprite from .tile import Sprite
from . import createCallback
class GB(Core): class GB(Core):
KEY_A = lib.GBA_KEY_A KEY_A = lib.GBA_KEY_A
@ -34,6 +35,48 @@ class GB(Core):
self._native.video.renderer.cache = ffi.NULL self._native.video.renderer.cache = ffi.NULL
lib.mTileCacheDeinit(cache) 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): class GBMemory(Memory):
def __init__(self, core): def __init__(self, core):
super(GBMemory, self).__init__(core, 0x10000) super(GBMemory, self).__init__(core, 0x10000)

View File

@ -3,36 +3,36 @@
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <mgba/gba/interface.h>
#include "flags.h" #include "flags.h"
#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_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__); \
}
#ifdef M_CORE_GBA #ifdef M_CORE_GBA
#define CREATE_SHIM(NAME, RETURN) \ #include <mgba/gba/interface.h>
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(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__); \
}
struct GBASIOPythonDriver { struct GBASIOPythonDriver {
struct GBASIODriver d; struct GBASIODriver d;
void* pyobj; void* pyobj;
}; };
CREATE_SHIM(Init, bool); CREATE_SHIM(GBA, Init, bool);
CREATE_SHIM(Deinit, void); CREATE_SHIM(GBA, Deinit, void);
CREATE_SHIM(Load, bool); CREATE_SHIM(GBA, Load, bool);
CREATE_SHIM(Unload, bool); CREATE_SHIM(GBA, Unload, bool);
CREATE_SHIM_ARGS(WriteRegister, uint16_t, (struct GBASIODriver* driver, uint32_t address, uint16_t value), address, value); CREATE_SHIM_ARGS(GBA, WriteRegister, uint16_t, (struct GBASIODriver* driver, uint32_t address, uint16_t value), address, value);
struct GBASIODriver* GBASIOPythonDriverCreate(void* pyobj) { struct GBASIODriver* GBASIOPythonDriverCreate(void* pyobj) {
struct GBASIOPythonDriver* driver = malloc(sizeof(*driver)); struct GBASIOPythonDriver* driver = malloc(sizeof(*driver));
@ -47,3 +47,30 @@ struct GBASIODriver* GBASIOPythonDriverCreate(void* pyobj) {
} }
#endif #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

View File

@ -21,3 +21,21 @@ PYEXPORT bool _pyGBASIOPythonDriverUnload(void* driver);
PYEXPORT uint16_t _pyGBASIOPythonDriverWriteRegister(void* driver, uint32_t address, uint16_t value); PYEXPORT uint16_t _pyGBASIOPythonDriverWriteRegister(void* driver, uint32_t address, uint16_t value);
#endif #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