mirror of https://github.com/mgba-emu/mgba.git
Python: Add GB SIO
This commit is contained in:
parent
efd8c4b466
commit
362c572009
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue