mirror of https://github.com/mgba-emu/mgba.git
GBA SIO: Remove driver sets and driver load/unload concepts
This commit is contained in:
parent
f2bbf8e66c
commit
0823797671
|
@ -111,8 +111,6 @@ struct GBASIODriver {
|
|||
bool (*init)(struct GBASIODriver* driver);
|
||||
void (*deinit)(struct GBASIODriver* driver);
|
||||
void (*reset)(struct GBASIODriver* driver);
|
||||
bool (*load)(struct GBASIODriver* driver);
|
||||
bool (*unload)(struct GBASIODriver* driver);
|
||||
uint32_t (*driverId)(const struct GBASIODriver* renderer);
|
||||
bool (*loadState)(struct GBASIODriver* renderer, const void* state, size_t size);
|
||||
void (*saveState)(struct GBASIODriver* renderer, void** state, size_t* size);
|
||||
|
|
|
@ -62,18 +62,11 @@ DECL_BIT(GBASIORegisterRCNT, SdDirection, 5);
|
|||
DECL_BIT(GBASIORegisterRCNT, SiDirection, 6);
|
||||
DECL_BIT(GBASIORegisterRCNT, SoDirection, 7);
|
||||
|
||||
struct GBASIODriverSet {
|
||||
struct GBASIODriver* normal;
|
||||
struct GBASIODriver* multiplayer;
|
||||
struct GBASIODriver* joybus;
|
||||
};
|
||||
|
||||
struct GBASIO {
|
||||
struct GBA* p;
|
||||
|
||||
enum GBASIOMode mode;
|
||||
struct GBASIODriverSet drivers;
|
||||
struct GBASIODriver* activeDriver;
|
||||
struct GBASIODriver* driver;
|
||||
|
||||
uint16_t rcnt;
|
||||
uint16_t siocnt;
|
||||
|
@ -86,8 +79,7 @@ void GBASIOInit(struct GBASIO* sio);
|
|||
void GBASIODeinit(struct GBASIO* sio);
|
||||
void GBASIOReset(struct GBASIO* sio);
|
||||
|
||||
void GBASIOSetDriverSet(struct GBASIO* sio, struct GBASIODriverSet* drivers);
|
||||
void GBASIOSetDriver(struct GBASIO* sio, struct GBASIODriver* driver, enum GBASIOMode mode);
|
||||
void GBASIOSetDriver(struct GBASIO* sio, struct GBASIODriver* driver);
|
||||
|
||||
void GBASIOWriteRCNT(struct GBASIO* sio, uint16_t value);
|
||||
void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value);
|
||||
|
|
|
@ -527,7 +527,7 @@ void GBAHardwareDeserialize(struct GBACartridgeHardware* hw, const struct GBASer
|
|||
uint32_t when;
|
||||
LOAD_32(when, 0, &state->hw.sioNextEvent);
|
||||
if (hw->devices & HW_GB_PLAYER) {
|
||||
GBASIOSetDriver(&hw->p->sio, &hw->p->sio.gbp.d, GBA_SIO_NORMAL_32);
|
||||
GBASIOSetDriver(&hw->p->sio, &hw->p->sio.gbp.d);
|
||||
}
|
||||
if ((hw->p->memory.io[GBA_REG(SIOCNT)] & 0x0080) && when < 0x20000) {
|
||||
mTimingSchedule(&hw->p->timing, &hw->p->sio.completeEvent, when);
|
||||
|
|
|
@ -848,15 +848,15 @@ static bool _GBACoreLoadExtraState(struct mCore* core, const struct mStateExtdat
|
|||
ok = false;
|
||||
}
|
||||
}
|
||||
if (gba->sio.activeDriver && gba->sio.activeDriver->driverId && gba->sio.activeDriver->loadState &&
|
||||
if (gba->sio.driver && gba->sio.driver->driverId && gba->sio.driver->loadState &&
|
||||
mStateExtdataGet(extdata, EXTDATA_SUBSYSTEM_START + GBA_SUBSYSTEM_SIO_DRIVER, &item)) {
|
||||
if ((uint32_t) item.size > sizeof(uint32_t)) {
|
||||
uint32_t type;
|
||||
LOAD_32(type, 0, item.data);
|
||||
if (type == gba->sio.activeDriver->driverId(gba->sio.activeDriver)) {
|
||||
ok = gba->sio.activeDriver->loadState(gba->sio.activeDriver,
|
||||
(void*) ((uintptr_t) item.data + sizeof(uint32_t)),
|
||||
item.size - sizeof(type)) && ok;
|
||||
if (type == gba->sio.driver->driverId(gba->sio.driver)) {
|
||||
ok = gba->sio.driver->loadState(gba->sio.driver,
|
||||
(void*) ((uintptr_t) item.data + sizeof(uint32_t)),
|
||||
item.size - sizeof(type)) && ok;
|
||||
}
|
||||
} else if (item.data) {
|
||||
ok = false;
|
||||
|
@ -886,14 +886,14 @@ static bool _GBACoreSaveExtraState(struct mCore* core, struct mStateExtdata* ext
|
|||
}
|
||||
size = 0;
|
||||
|
||||
if (gba->sio.activeDriver && gba->sio.activeDriver->driverId && gba->sio.activeDriver->saveState) {
|
||||
gba->sio.activeDriver->saveState(gba->sio.activeDriver, &buffer, &size);
|
||||
if (gba->sio.driver && gba->sio.driver->driverId && gba->sio.driver->saveState) {
|
||||
gba->sio.driver->saveState(gba->sio.driver, &buffer, &size);
|
||||
if (size > 0 && buffer) {
|
||||
struct mStateExtdataItem item;
|
||||
item.size = size + sizeof(uint32_t);
|
||||
item.data = malloc(item.size);
|
||||
item.clean = free;
|
||||
uint32_t type = gba->sio.activeDriver->driverId(gba->sio.activeDriver);
|
||||
uint32_t type = gba->sio.driver->driverId(gba->sio.driver);
|
||||
STORE_32(type, 0, item.data);
|
||||
memcpy((void*) ((uintptr_t) item.data + sizeof(uint32_t)), buffer, size);
|
||||
mStateExtdataPut(extdata, EXTDATA_SUBSYSTEM_START + GBA_SUBSYSTEM_SIO_DRIVER, &item);
|
||||
|
@ -963,8 +963,7 @@ static void _GBACoreSetPeripheral(struct mCore* core, int type, void* periph) {
|
|||
gba->luminanceSource = periph;
|
||||
break;
|
||||
case mPERIPH_GBA_BATTLECHIP_GATE:
|
||||
GBASIOSetDriver(&gba->sio, periph, GBA_SIO_MULTI);
|
||||
GBASIOSetDriver(&gba->sio, periph, GBA_SIO_NORMAL_32);
|
||||
GBASIOSetDriver(&gba->sio, periph);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
|
|
|
@ -33,7 +33,7 @@ enum {
|
|||
BATTLECHIP_CONTINUE = 0xFFFF,
|
||||
};
|
||||
|
||||
static bool GBASIOBattlechipGateLoad(struct GBASIODriver* driver);
|
||||
static bool GBASIOBattlechipGateInit(struct GBASIODriver* driver);
|
||||
static uint16_t GBASIOBattlechipGateWriteSIOCNT(struct GBASIODriver* driver, uint16_t value);
|
||||
static bool GBASIOBattlechipGateHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode);
|
||||
static int GBASIOBattlechipGateConnectedDevices(struct GBASIODriver* driver);
|
||||
|
@ -41,7 +41,7 @@ static void GBASIOBattlechipGateFinishMultiplayer(struct GBASIODriver* driver, u
|
|||
|
||||
void GBASIOBattlechipGateCreate(struct GBASIOBattlechipGate* gate) {
|
||||
memset(&gate->d, 0, sizeof(gate->d));
|
||||
gate->d.load = GBASIOBattlechipGateLoad;
|
||||
gate->d.init = GBASIOBattlechipGateInit;
|
||||
gate->d.writeSIOCNT = GBASIOBattlechipGateWriteSIOCNT;
|
||||
gate->d.handlesMode = GBASIOBattlechipGateHandlesMode;
|
||||
gate->d.connectedDevices = GBASIOBattlechipGateConnectedDevices;
|
||||
|
@ -51,7 +51,7 @@ void GBASIOBattlechipGateCreate(struct GBASIOBattlechipGate* gate) {
|
|||
gate->flavor = GBA_FLAVOR_BATTLECHIP_GATE;
|
||||
}
|
||||
|
||||
bool GBASIOBattlechipGateLoad(struct GBASIODriver* driver) {
|
||||
bool GBASIOBattlechipGateInit(struct GBASIODriver* driver) {
|
||||
struct GBASIOBattlechipGate* gate = (struct GBASIOBattlechipGate*) driver;
|
||||
gate->state = BATTLECHIP_STATE_SYNC;
|
||||
gate->data[0] = 0x00FE;
|
||||
|
|
|
@ -263,8 +263,8 @@ void GBAReset(struct ARMCore* cpu) {
|
|||
|
||||
// GB Player SIO control should not be engaged before detection, even if we already know it's GBP
|
||||
gba->memory.hw.devices &= ~HW_GB_PLAYER;
|
||||
if (gba->sio.drivers.normal == &gba->sio.gbp.d) {
|
||||
GBASIOSetDriver(&gba->sio, NULL, GBA_SIO_NORMAL_32);
|
||||
if (gba->sio.driver == &gba->sio.gbp.d) {
|
||||
GBASIOSetDriver(&gba->sio, NULL);
|
||||
}
|
||||
|
||||
bool isELF = false;
|
||||
|
|
157
src/gba/sio.c
157
src/gba/sio.c
|
@ -20,20 +20,6 @@ static const int GBASIOCyclesPerTransfer[4][MAX_GBAS] = {
|
|||
|
||||
static void _sioFinish(struct mTiming* timing, void* user, uint32_t cyclesLate);
|
||||
|
||||
static struct GBASIODriver* _lookupDriver(struct GBASIO* sio, enum GBASIOMode mode) {
|
||||
switch (mode) {
|
||||
case GBA_SIO_NORMAL_8:
|
||||
case GBA_SIO_NORMAL_32:
|
||||
return sio->drivers.normal;
|
||||
case GBA_SIO_MULTI:
|
||||
return sio->drivers.multiplayer;
|
||||
case GBA_SIO_JOYBUS:
|
||||
return sio->drivers.joybus;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* _modeName(enum GBASIOMode mode) {
|
||||
switch (mode) {
|
||||
case GBA_SIO_NORMAL_8:
|
||||
|
@ -60,31 +46,19 @@ static void _switchMode(struct GBASIO* sio) {
|
|||
newMode = (enum GBASIOMode) (mode & 0xC);
|
||||
}
|
||||
if (newMode != sio->mode) {
|
||||
struct GBASIODriver* driver = _lookupDriver(sio, newMode);
|
||||
if (sio->mode != (enum GBASIOMode) -1) {
|
||||
mLOG(GBA_SIO, DEBUG, "Switching mode from %s to %s", _modeName(sio->mode), _modeName(newMode));
|
||||
}
|
||||
if (driver != sio->activeDriver || (driver && !driver->setMode)) {
|
||||
if (sio->activeDriver && sio->activeDriver->unload) {
|
||||
sio->activeDriver->unload(sio->activeDriver);
|
||||
}
|
||||
sio->mode = newMode;
|
||||
sio->activeDriver = driver;
|
||||
if (sio->activeDriver && sio->activeDriver->load) {
|
||||
sio->activeDriver->load(sio->activeDriver);
|
||||
}
|
||||
} else {
|
||||
sio->mode = newMode;
|
||||
if (sio->activeDriver && sio->activeDriver->setMode) {
|
||||
sio->activeDriver->setMode(sio->activeDriver, newMode);
|
||||
}
|
||||
sio->mode = newMode;
|
||||
if (sio->driver && sio->driver->setMode) {
|
||||
sio->driver->setMode(sio->driver, newMode);
|
||||
}
|
||||
|
||||
int id = 0;
|
||||
switch (newMode) {
|
||||
case GBA_SIO_MULTI:
|
||||
if (sio->activeDriver && sio->activeDriver->deviceId) {
|
||||
id = sio->activeDriver->deviceId(sio->activeDriver);
|
||||
if (sio->driver && sio->driver->deviceId) {
|
||||
id = sio->driver->deviceId(sio->driver);
|
||||
}
|
||||
sio->rcnt = GBASIORegisterRCNTSetSi(sio->rcnt, !!id);
|
||||
break;
|
||||
|
@ -96,10 +70,7 @@ static void _switchMode(struct GBASIO* sio) {
|
|||
}
|
||||
|
||||
void GBASIOInit(struct GBASIO* sio) {
|
||||
sio->drivers.normal = NULL;
|
||||
sio->drivers.multiplayer = NULL;
|
||||
sio->drivers.joybus = NULL;
|
||||
sio->activeDriver = NULL;
|
||||
sio->driver = NULL;
|
||||
|
||||
sio->completeEvent.context = sio;
|
||||
sio->completeEvent.name = "GBA SIO Complete";
|
||||
|
@ -113,73 +84,28 @@ void GBASIOInit(struct GBASIO* sio) {
|
|||
}
|
||||
|
||||
void GBASIODeinit(struct GBASIO* sio) {
|
||||
if (sio->activeDriver && sio->activeDriver->unload) {
|
||||
sio->activeDriver->unload(sio->activeDriver);
|
||||
}
|
||||
if (sio->drivers.multiplayer && sio->drivers.multiplayer->deinit) {
|
||||
sio->drivers.multiplayer->deinit(sio->drivers.multiplayer);
|
||||
}
|
||||
if (sio->drivers.joybus && sio->drivers.joybus->deinit) {
|
||||
sio->drivers.joybus->deinit(sio->drivers.joybus);
|
||||
}
|
||||
if (sio->drivers.normal && sio->drivers.normal->deinit) {
|
||||
sio->drivers.normal->deinit(sio->drivers.normal);
|
||||
if (sio->driver && sio->driver->deinit) {
|
||||
sio->driver->deinit(sio->driver);
|
||||
}
|
||||
}
|
||||
|
||||
void GBASIOReset(struct GBASIO* sio) {
|
||||
if (sio->activeDriver && sio->activeDriver->unload) {
|
||||
sio->activeDriver->unload(sio->activeDriver);
|
||||
}
|
||||
if (sio->drivers.multiplayer && sio->drivers.multiplayer->reset) {
|
||||
sio->drivers.multiplayer->reset(sio->drivers.multiplayer);
|
||||
}
|
||||
if (sio->drivers.joybus && sio->drivers.joybus->reset) {
|
||||
sio->drivers.joybus->reset(sio->drivers.joybus);
|
||||
}
|
||||
if (sio->drivers.normal && sio->drivers.normal->reset) {
|
||||
sio->drivers.normal->reset(sio->drivers.normal);
|
||||
if (sio->driver && sio->driver->reset) {
|
||||
sio->driver->reset(sio->driver);
|
||||
}
|
||||
sio->rcnt = RCNT_INITIAL;
|
||||
sio->siocnt = 0;
|
||||
sio->mode = -1;
|
||||
sio->activeDriver = NULL;
|
||||
_switchMode(sio);
|
||||
|
||||
GBASIOPlayerReset(&sio->gbp);
|
||||
}
|
||||
|
||||
void GBASIOSetDriverSet(struct GBASIO* sio, struct GBASIODriverSet* drivers) {
|
||||
GBASIOSetDriver(sio, drivers->normal, GBA_SIO_NORMAL_8);
|
||||
GBASIOSetDriver(sio, drivers->multiplayer, GBA_SIO_MULTI);
|
||||
GBASIOSetDriver(sio, drivers->joybus, GBA_SIO_JOYBUS);
|
||||
}
|
||||
|
||||
void GBASIOSetDriver(struct GBASIO* sio, struct GBASIODriver* driver, enum GBASIOMode mode) {
|
||||
struct GBASIODriver** driverLoc;
|
||||
switch (mode) {
|
||||
case GBA_SIO_NORMAL_8:
|
||||
case GBA_SIO_NORMAL_32:
|
||||
driverLoc = &sio->drivers.normal;
|
||||
break;
|
||||
case GBA_SIO_MULTI:
|
||||
driverLoc = &sio->drivers.multiplayer;
|
||||
break;
|
||||
case GBA_SIO_JOYBUS:
|
||||
driverLoc = &sio->drivers.joybus;
|
||||
break;
|
||||
default:
|
||||
mLOG(GBA_SIO, ERROR, "Setting an unsupported SIO driver: %x", mode);
|
||||
return;
|
||||
}
|
||||
if (*driverLoc) {
|
||||
if ((*driverLoc)->unload) {
|
||||
(*driverLoc)->unload(*driverLoc);
|
||||
}
|
||||
if ((*driverLoc)->deinit) {
|
||||
(*driverLoc)->deinit(*driverLoc);
|
||||
}
|
||||
void GBASIOSetDriver(struct GBASIO* sio, struct GBASIODriver* driver) {
|
||||
if (sio->driver && sio->driver->deinit) {
|
||||
sio->driver->deinit(sio->driver);
|
||||
}
|
||||
sio->driver = driver;
|
||||
if (driver) {
|
||||
driver->p = sio;
|
||||
|
||||
|
@ -191,26 +117,19 @@ void GBASIOSetDriver(struct GBASIO* sio, struct GBASIODriver* driver, enum GBASI
|
|||
}
|
||||
}
|
||||
}
|
||||
if (sio->activeDriver == *driverLoc) {
|
||||
sio->activeDriver = driver;
|
||||
if (driver && driver->load) {
|
||||
driver->load(driver);
|
||||
}
|
||||
}
|
||||
*driverLoc = driver;
|
||||
}
|
||||
|
||||
void GBASIOWriteRCNT(struct GBASIO* sio, uint16_t value) {
|
||||
sio->rcnt &= 0x1FF;
|
||||
sio->rcnt |= value & 0xC000;
|
||||
_switchMode(sio);
|
||||
if (sio->activeDriver && sio->activeDriver->writeRCNT) {
|
||||
if (sio->driver && sio->driver->writeRCNT) {
|
||||
switch (sio->mode) {
|
||||
case GBA_SIO_GPIO:
|
||||
sio->rcnt = (sio->activeDriver->writeRCNT(sio->activeDriver, value) & 0x01FF) | (sio->rcnt & 0xC000);
|
||||
sio->rcnt = (sio->driver->writeRCNT(sio->driver, value) & 0x01FF) | (sio->rcnt & 0xC000);
|
||||
break;
|
||||
default:
|
||||
sio->rcnt = (sio->activeDriver->writeRCNT(sio->activeDriver, value) & 0x01F0) | (sio->rcnt & 0xC00F);
|
||||
sio->rcnt = (sio->driver->writeRCNT(sio->driver, value) & 0x01F0) | (sio->rcnt & 0xC00F);
|
||||
}
|
||||
} else if (sio->mode == GBA_SIO_GPIO) {
|
||||
sio->rcnt &= 0xC000;
|
||||
|
@ -222,15 +141,15 @@ void GBASIOWriteRCNT(struct GBASIO* sio, uint16_t value) {
|
|||
}
|
||||
|
||||
static void _startTransfer(struct GBASIO* sio) {
|
||||
if (sio->activeDriver && sio->activeDriver->start) {
|
||||
if (!sio->activeDriver->start(sio->activeDriver)) {
|
||||
if (sio->driver && sio->driver->start) {
|
||||
if (!sio->driver->start(sio->driver)) {
|
||||
// Transfer completion is handled internally to the driver
|
||||
return;
|
||||
}
|
||||
}
|
||||
int connected = 0;
|
||||
if (sio->activeDriver && sio->activeDriver->connectedDevices) {
|
||||
connected = sio->activeDriver->connectedDevices(sio->activeDriver);
|
||||
if (sio->driver && sio->driver->connectedDevices) {
|
||||
connected = sio->driver->connectedDevices(sio->driver);
|
||||
}
|
||||
mTimingDeschedule(&sio->p->timing, &sio->completeEvent);
|
||||
mTimingSchedule(&sio->p->timing, &sio->completeEvent, GBASIOTransferCycles(sio->mode, sio->siocnt, connected));
|
||||
|
@ -244,14 +163,14 @@ void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value) {
|
|||
int id = 0;
|
||||
int connected = 0;
|
||||
bool handled = false;
|
||||
if (sio->activeDriver) {
|
||||
handled = sio->activeDriver->handlesMode(sio->activeDriver, sio->mode);
|
||||
if (sio->driver) {
|
||||
handled = sio->driver->handlesMode(sio->driver, sio->mode);
|
||||
if (handled) {
|
||||
if (sio->activeDriver->deviceId) {
|
||||
id = sio->activeDriver->deviceId(sio->activeDriver);
|
||||
if (sio->driver->deviceId) {
|
||||
id = sio->driver->deviceId(sio->driver);
|
||||
}
|
||||
connected = sio->activeDriver->connectedDevices(sio->activeDriver);
|
||||
handled = !!sio->activeDriver->writeSIOCNT;
|
||||
connected = sio->driver->connectedDevices(sio->driver);
|
||||
handled = !!sio->driver->writeSIOCNT;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -304,7 +223,7 @@ void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value) {
|
|||
break;
|
||||
}
|
||||
if (handled) {
|
||||
value = sio->activeDriver->writeSIOCNT(sio->activeDriver, value);
|
||||
value = sio->driver->writeSIOCNT(sio->driver, value);
|
||||
} else {
|
||||
// Dummy drivers
|
||||
switch (sio->mode) {
|
||||
|
@ -325,8 +244,8 @@ void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value) {
|
|||
|
||||
uint16_t GBASIOWriteRegister(struct GBASIO* sio, uint32_t address, uint16_t value) {
|
||||
int id = 0;
|
||||
if (sio->activeDriver && sio->activeDriver->deviceId) {
|
||||
id = sio->activeDriver->deviceId(sio->activeDriver);
|
||||
if (sio->driver && sio->driver->deviceId) {
|
||||
id = sio->driver->deviceId(sio->driver);
|
||||
}
|
||||
|
||||
bool handled = true;
|
||||
|
@ -455,8 +374,8 @@ int32_t GBASIOTransferCycles(enum GBASIOMode mode, uint16_t siocnt, int connecte
|
|||
|
||||
void GBASIOMultiplayerFinishTransfer(struct GBASIO* sio, uint16_t data[4], uint32_t cyclesLate) {
|
||||
int id = 0;
|
||||
if (sio->activeDriver && sio->activeDriver->deviceId) {
|
||||
id = sio->activeDriver->deviceId(sio->activeDriver);
|
||||
if (sio->driver && sio->driver->deviceId) {
|
||||
id = sio->driver->deviceId(sio->driver);
|
||||
}
|
||||
sio->p->memory.io[GBA_REG(SIOMULTI0)] = data[0];
|
||||
sio->p->memory.io[GBA_REG(SIOMULTI1)] = data[1];
|
||||
|
@ -500,20 +419,20 @@ static void _sioFinish(struct mTiming* timing, void* user, uint32_t cyclesLate)
|
|||
} data = {0};
|
||||
switch (sio->mode) {
|
||||
case GBA_SIO_MULTI:
|
||||
if (sio->activeDriver && sio->activeDriver->finishMultiplayer) {
|
||||
sio->activeDriver->finishMultiplayer(sio->activeDriver, data.multi);
|
||||
if (sio->driver && sio->driver->finishMultiplayer) {
|
||||
sio->driver->finishMultiplayer(sio->driver, data.multi);
|
||||
}
|
||||
GBASIOMultiplayerFinishTransfer(sio, data.multi, cyclesLate);
|
||||
break;
|
||||
case GBA_SIO_NORMAL_8:
|
||||
if (sio->activeDriver && sio->activeDriver->finishNormal8) {
|
||||
data.normal8 = sio->activeDriver->finishNormal8(sio->activeDriver);
|
||||
if (sio->driver && sio->driver->finishNormal8) {
|
||||
data.normal8 = sio->driver->finishNormal8(sio->driver);
|
||||
}
|
||||
GBASIONormal8FinishTransfer(sio, data.normal8, cyclesLate);
|
||||
break;
|
||||
case GBA_SIO_NORMAL_32:
|
||||
if (sio->activeDriver && sio->activeDriver->finishNormal32) {
|
||||
data.normal32 = sio->activeDriver->finishNormal32(sio->activeDriver);
|
||||
if (sio->driver && sio->driver->finishNormal32) {
|
||||
data.normal32 = sio->driver->finishNormal32(sio->driver);
|
||||
}
|
||||
GBASIONormal32FinishTransfer(sio, data.normal32, cyclesLate);
|
||||
break;
|
||||
|
|
|
@ -23,8 +23,8 @@ enum {
|
|||
};
|
||||
|
||||
static bool GBASIODolphinInit(struct GBASIODriver* driver);
|
||||
static bool GBASIODolphinLoad(struct GBASIODriver* driver);
|
||||
static bool GBASIODolphinUnload(struct GBASIODriver* driver);
|
||||
static void GBASIODolphinReset(struct GBASIODriver* driver);
|
||||
static void GBASIODolphinSetMode(struct GBASIODriver* driver, enum GBASIOMode mode);
|
||||
static bool GBASIODolphinHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode);
|
||||
static int GBASIODolphinConnectedDevices(struct GBASIODriver* driver);
|
||||
static void GBASIODolphinProcessEvents(struct mTiming* timing, void* context, uint32_t cyclesLate);
|
||||
|
@ -35,8 +35,8 @@ static void _flush(struct GBASIODolphin* dol);
|
|||
void GBASIODolphinCreate(struct GBASIODolphin* dol) {
|
||||
memset(&dol->d, 0, sizeof(dol->d));
|
||||
dol->d.init = GBASIODolphinInit;
|
||||
dol->d.load = GBASIODolphinLoad;
|
||||
dol->d.unload = GBASIODolphinUnload;
|
||||
dol->d.reset = GBASIODolphinReset;
|
||||
dol->d.setMode = GBASIODolphinSetMode;
|
||||
dol->d.handlesMode = GBASIODolphinHandlesMode;
|
||||
dol->d.connectedDevices = GBASIODolphinConnectedDevices;
|
||||
dol->event.context = dol;
|
||||
|
@ -98,26 +98,23 @@ bool GBASIODolphinConnect(struct GBASIODolphin* dol, const struct Address* addre
|
|||
|
||||
static bool GBASIODolphinInit(struct GBASIODriver* driver) {
|
||||
struct GBASIODolphin* dol = (struct GBASIODolphin*) driver;
|
||||
dol->active = false;
|
||||
dol->clockSlice = 0;
|
||||
dol->state = WAIT_FOR_FIRST_CLOCK;
|
||||
_flush(dol);
|
||||
GBASIODolphinReset(driver);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool GBASIODolphinLoad(struct GBASIODriver* driver) {
|
||||
static void GBASIODolphinReset(struct GBASIODriver* driver) {
|
||||
struct GBASIODolphin* dol = (struct GBASIODolphin*) driver;
|
||||
dol->active = true;
|
||||
dol->active = false;
|
||||
_flush(dol);
|
||||
mTimingDeschedule(&dol->d.p->p->timing, &dol->event);
|
||||
mTimingSchedule(&dol->d.p->p->timing, &dol->event, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool GBASIODolphinUnload(struct GBASIODriver* driver) {
|
||||
static void GBASIODolphinSetMode(struct GBASIODriver* driver, enum GBASIOMode mode) {
|
||||
struct GBASIODolphin* dol = (struct GBASIODolphin*) driver;
|
||||
dol->active = false;
|
||||
return true;
|
||||
dol->active = mode == GBA_SIO_JOYBUS;
|
||||
}
|
||||
|
||||
static bool GBASIODolphinHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode) {
|
||||
|
|
|
@ -55,8 +55,8 @@ void GBASIOPlayerInit(struct GBASIOPlayer* gbp) {
|
|||
}
|
||||
|
||||
void GBASIOPlayerReset(struct GBASIOPlayer* gbp) {
|
||||
if (gbp->p->sio.drivers.normal == &gbp->d) {
|
||||
GBASIOSetDriver(&gbp->p->sio, NULL, GBA_SIO_NORMAL_32);
|
||||
if (gbp->p->sio.driver == &gbp->d) {
|
||||
GBASIOSetDriver(&gbp->p->sio, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,7 +88,7 @@ void GBASIOPlayerUpdate(struct GBA* gba) {
|
|||
gba->sio.gbp.oldCallback = gba->keyCallback;
|
||||
gba->keyCallback = &gba->sio.gbp.callback.d;
|
||||
// TODO: Check if the SIO driver is actually used first
|
||||
GBASIOSetDriver(&gba->sio, &gba->sio.gbp.d, GBA_SIO_NORMAL_32);
|
||||
GBASIOSetDriver(&gba->sio, &gba->sio.gbp.d);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -79,8 +79,6 @@ static_assert(sizeof(struct GBASIOLockstepSerializedState) == 0x1F0, "GBA lockst
|
|||
static bool GBASIOLockstepDriverInit(struct GBASIODriver* driver);
|
||||
static void GBASIOLockstepDriverDeinit(struct GBASIODriver* driver);
|
||||
static void GBASIOLockstepDriverReset(struct GBASIODriver* driver);
|
||||
static bool GBASIOLockstepDriverLoad(struct GBASIODriver* driver);
|
||||
static bool GBASIOLockstepDriverUnload(struct GBASIODriver* driver);
|
||||
static uint32_t GBASIOLockstepDriverId(const struct GBASIODriver* driver);
|
||||
static bool GBASIOLockstepDriverLoadState(struct GBASIODriver* driver, const void* state, size_t size);
|
||||
static void GBASIOLockstepDriverSaveState(struct GBASIODriver* driver, void** state, size_t* size);
|
||||
|
@ -119,8 +117,6 @@ void GBASIOLockstepDriverCreate(struct GBASIOLockstepDriver* driver, struct mLoc
|
|||
driver->d.init = GBASIOLockstepDriverInit;
|
||||
driver->d.deinit = GBASIOLockstepDriverDeinit;
|
||||
driver->d.reset = GBASIOLockstepDriverReset;
|
||||
driver->d.load = GBASIOLockstepDriverLoad;
|
||||
driver->d.unload = GBASIOLockstepDriverUnload;
|
||||
driver->d.driverId = GBASIOLockstepDriverId;
|
||||
driver->d.loadState = GBASIOLockstepDriverLoadState;
|
||||
driver->d.saveState = GBASIOLockstepDriverSaveState;
|
||||
|
@ -220,27 +216,6 @@ static void GBASIOLockstepDriverReset(struct GBASIODriver* driver) {
|
|||
mTimingSchedule(&lockstep->d.p->p->timing, &lockstep->event, nextEvent);
|
||||
}
|
||||
|
||||
static bool GBASIOLockstepDriverLoad(struct GBASIODriver* driver) {
|
||||
struct GBASIOLockstepDriver* lockstep = (struct GBASIOLockstepDriver*) driver;
|
||||
if (lockstep->lockstepId) {
|
||||
struct GBASIOLockstepCoordinator* coordinator = lockstep->coordinator;
|
||||
MutexLock(&coordinator->mutex);
|
||||
struct GBASIOLockstepPlayer* player = TableLookup(&coordinator->players, lockstep->lockstepId);
|
||||
_setReady(coordinator, player, 0, coordinator->transferMode);
|
||||
MutexUnlock(&coordinator->mutex);
|
||||
GBASIOLockstepDriverSetMode(driver, driver->p->mode);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool GBASIOLockstepDriverUnload(struct GBASIODriver* driver) {
|
||||
struct GBASIOLockstepDriver* lockstep = (struct GBASIOLockstepDriver*) driver;
|
||||
if (lockstep->lockstepId) {
|
||||
GBASIOLockstepDriverSetMode(driver, -1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint32_t GBASIOLockstepDriverId(const struct GBASIODriver* driver) {
|
||||
UNUSED(driver);
|
||||
return DRIVER_ID;
|
||||
|
|
|
@ -424,7 +424,7 @@ bool CoreController::attachDolphin(const Address& address) {
|
|||
}
|
||||
if (GBASIODolphinConnect(&m_dolphin, &address, 0, 0)) {
|
||||
GBA* gba = static_cast<GBA*>(m_threadContext.core->board);
|
||||
GBASIOSetDriver(&gba->sio, &m_dolphin.d, GBA_SIO_JOYBUS);
|
||||
GBASIOSetDriver(&gba->sio, &m_dolphin.d);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -433,7 +433,8 @@ bool CoreController::attachDolphin(const Address& address) {
|
|||
void CoreController::detachDolphin() {
|
||||
if (platform() == mPLATFORM_GBA) {
|
||||
GBA* gba = static_cast<GBA*>(m_threadContext.core->board);
|
||||
GBASIOSetDriver(&gba->sio, nullptr, GBA_SIO_JOYBUS);
|
||||
// TODO: Reattach to multiplayer controller
|
||||
GBASIOSetDriver(&gba->sio, nullptr);
|
||||
}
|
||||
GBASIODolphinDestroy(&m_dolphin);
|
||||
}
|
||||
|
|
|
@ -265,9 +265,7 @@ bool MultiplayerController::attachGame(CoreController* controller) {
|
|||
GBASIOLockstepCoordinatorAttach(&m_gbaCoordinator, node);
|
||||
player.node.gba = node;
|
||||
|
||||
GBASIOSetDriver(&gba->sio, &node->d, GBA_SIO_MULTI);
|
||||
GBASIOSetDriver(&gba->sio, &node->d, GBA_SIO_NORMAL_8);
|
||||
GBASIOSetDriver(&gba->sio, &node->d, GBA_SIO_NORMAL_32);
|
||||
GBASIOSetDriver(&gba->sio, &node->d);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
@ -356,10 +354,8 @@ void MultiplayerController::detachGame(CoreController* controller) {
|
|||
#ifdef M_CORE_GBA
|
||||
case mPLATFORM_GBA: {
|
||||
GBA* gba = static_cast<GBA*>(thread->core->board);
|
||||
GBASIOLockstepDriver* node = reinterpret_cast<GBASIOLockstepDriver*>(gba->sio.drivers.multiplayer);
|
||||
GBASIOSetDriver(&gba->sio, nullptr, GBA_SIO_MULTI);
|
||||
GBASIOSetDriver(&gba->sio, nullptr, GBA_SIO_NORMAL_8);
|
||||
GBASIOSetDriver(&gba->sio, nullptr, GBA_SIO_NORMAL_32);
|
||||
GBASIOLockstepDriver* node = reinterpret_cast<GBASIOLockstepDriver*>(gba->sio.driver);
|
||||
GBASIOSetDriver(&gba->sio, nullptr);
|
||||
if (node) {
|
||||
GBASIOLockstepCoordinatorDetach(&m_gbaCoordinator, node);
|
||||
delete node->user;
|
||||
|
@ -485,12 +481,13 @@ void MultiplayerController::fixOrder() {
|
|||
switch (m_platform) {
|
||||
#ifdef M_CORE_GBA
|
||||
case mPLATFORM_GBA:
|
||||
for (int pid : m_pids.keys()) {
|
||||
// TODO: fix
|
||||
/*for (int pid : m_pids.keys()) {
|
||||
Player& p = m_pids.find(pid).value();
|
||||
GBA* gba = static_cast<GBA*>(p.controller->thread()->core->board);
|
||||
GBASIOLockstepDriver* node = reinterpret_cast<GBASIOLockstepDriver*>(gba->sio.drivers.multiplayer);
|
||||
GBASIOLockstepDriver* node = reinterpret_cast<GBASIOLockstepDriver*>(gba->sio.driver);
|
||||
m_players[node->d.deviceId(&node->d)] = pid;
|
||||
}
|
||||
}*/
|
||||
break;
|
||||
#endif
|
||||
#ifdef M_CORE_GB
|
||||
|
|
Loading…
Reference in New Issue