mirror of https://github.com/mgba-emu/mgba.git
GBA SIO: Move cycle estimation values into core
This commit is contained in:
parent
cd4132fba3
commit
1b0b540de6
|
@ -16,8 +16,6 @@ CXX_GUARD_START
|
||||||
|
|
||||||
#define MAX_GBAS 4
|
#define MAX_GBAS 4
|
||||||
|
|
||||||
extern const int GBASIOCyclesPerTransfer[4][MAX_GBAS];
|
|
||||||
|
|
||||||
mLOG_DECLARE_CATEGORY(GBA_SIO);
|
mLOG_DECLARE_CATEGORY(GBA_SIO);
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -85,6 +83,8 @@ void GBASIOWriteRCNT(struct GBASIO* sio, uint16_t value);
|
||||||
void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value);
|
void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value);
|
||||||
uint16_t GBASIOWriteRegister(struct GBASIO* sio, uint32_t address, uint16_t value);
|
uint16_t GBASIOWriteRegister(struct GBASIO* sio, uint32_t address, uint16_t value);
|
||||||
|
|
||||||
|
int32_t GBASIOTransferCycles(struct GBASIO* sio);
|
||||||
|
|
||||||
void GBASIOMultiplayerFinishTransfer(struct GBASIO* sio, uint16_t data[4], uint32_t cyclesLate);
|
void GBASIOMultiplayerFinishTransfer(struct GBASIO* sio, uint16_t data[4], uint32_t cyclesLate);
|
||||||
|
|
||||||
int GBASIOJOYSendCommand(struct GBASIODriver* sio, enum GBASIOJOYCommand command, uint8_t* data);
|
int GBASIOJOYSendCommand(struct GBASIODriver* sio, enum GBASIOJOYCommand command, uint8_t* data);
|
||||||
|
|
|
@ -105,12 +105,7 @@ static int GBASIOBattlechipGateConnectedDevices(struct GBASIODriver* driver) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void _battlechipTransfer(struct GBASIOBattlechipGate* gate) {
|
void _battlechipTransfer(struct GBASIOBattlechipGate* gate) {
|
||||||
int32_t cycles;
|
int32_t cycles = GBASIOTransferCycles(gate->d.p);
|
||||||
if (gate->d.p->mode == GBA_SIO_NORMAL_32) {
|
|
||||||
cycles = GBA_ARM7TDMI_FREQUENCY / 0x40000;
|
|
||||||
} else {
|
|
||||||
cycles = GBASIOCyclesPerTransfer[GBASIOMultiplayerGetBaud(gate->d.p->siocnt)][1];
|
|
||||||
}
|
|
||||||
mTimingDeschedule(&gate->d.p->p->timing, &gate->event);
|
mTimingDeschedule(&gate->d.p->p->timing, &gate->event);
|
||||||
mTimingSchedule(&gate->d.p->p->timing, &gate->event, cycles);
|
mTimingSchedule(&gate->d.p->p->timing, &gate->event, cycles);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
mLOG_DEFINE_CATEGORY(GBA_SIO, "GBA Serial I/O", "gba.sio");
|
mLOG_DEFINE_CATEGORY(GBA_SIO, "GBA Serial I/O", "gba.sio");
|
||||||
|
|
||||||
const int GBASIOCyclesPerTransfer[4][MAX_GBAS] = {
|
static const int GBASIOCyclesPerTransfer[4][MAX_GBAS] = {
|
||||||
{ 31976, 63427, 94884, 125829 },
|
{ 31976, 63427, 94884, 125829 },
|
||||||
{ 8378, 16241, 24104, 31457 },
|
{ 8378, 16241, 24104, 31457 },
|
||||||
{ 5750, 10998, 16241, 20972 },
|
{ 5750, 10998, 16241, 20972 },
|
||||||
|
@ -318,6 +318,31 @@ uint16_t GBASIOWriteRegister(struct GBASIO* sio, uint32_t address, uint16_t valu
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t GBASIOTransferCycles(struct GBASIO* sio) {
|
||||||
|
int connected = 0;
|
||||||
|
if (sio->activeDriver) {
|
||||||
|
connected = sio->activeDriver->connectedDevices(sio->activeDriver);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (connected < 0 || connected >= MAX_GBAS) {
|
||||||
|
mLOG(GBA_SIO, ERROR, "SIO driver returned invalid device count %i", connected);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (sio->mode) {
|
||||||
|
case GBA_SIO_MULTI:
|
||||||
|
return GBASIOCyclesPerTransfer[GBASIOMultiplayerGetBaud(sio->siocnt)][connected];
|
||||||
|
case GBA_SIO_NORMAL_8:
|
||||||
|
return 8 * GBA_ARM7TDMI_FREQUENCY / ((GBASIONormalIsInternalSc(sio->siocnt) ? 2048 : 256) * 1024);
|
||||||
|
case GBA_SIO_NORMAL_32:
|
||||||
|
return 32 * GBA_ARM7TDMI_FREQUENCY / ((GBASIONormalIsInternalSc(sio->siocnt) ? 2048 : 256) * 1024);
|
||||||
|
default:
|
||||||
|
mLOG(GBA_SIO, STUB, "No cycle count implemented for mode %s", _modeName(sio->mode));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void GBASIOMultiplayerFinishTransfer(struct GBASIO* sio, uint16_t data[4], uint32_t cyclesLate) {
|
void GBASIOMultiplayerFinishTransfer(struct GBASIO* sio, uint16_t data[4], uint32_t cyclesLate) {
|
||||||
int id = 0;
|
int id = 0;
|
||||||
if (sio->activeDriver && sio->activeDriver->deviceId) {
|
if (sio->activeDriver && sio->activeDriver->deviceId) {
|
||||||
|
|
|
@ -250,7 +250,7 @@ static uint16_t GBASIOLockstepNodeMultiWriteRegister(struct GBASIODriver* driver
|
||||||
if (!node->id && attached > 1 && GBASIOMultiplayerIsReady(node->d.p->siocnt)) {
|
if (!node->id && attached > 1 && GBASIOMultiplayerIsReady(node->d.p->siocnt)) {
|
||||||
mLOG(GBA_SIO, DEBUG, "Lockstep %i: Transfer initiated", node->id);
|
mLOG(GBA_SIO, DEBUG, "Lockstep %i: Transfer initiated", node->id);
|
||||||
ATOMIC_STORE(node->p->d.transferActive, TRANSFER_STARTING);
|
ATOMIC_STORE(node->p->d.transferActive, TRANSFER_STARTING);
|
||||||
ATOMIC_STORE(node->p->d.transferCycles, GBASIOCyclesPerTransfer[GBASIOMultiplayerGetBaud(node->d.p->siocnt)][node->p->d.attached - 1]);
|
ATOMIC_STORE(node->p->d.transferCycles, GBASIOTransferCycles(node->d.p));
|
||||||
|
|
||||||
if (mTimingIsScheduled(&driver->p->p->timing, &node->event)) {
|
if (mTimingIsScheduled(&driver->p->p->timing, &node->event)) {
|
||||||
node->eventDiff -= node->event.when - mTimingCurrentTime(&driver->p->p->timing);
|
node->eventDiff -= node->event.when - mTimingCurrentTime(&driver->p->p->timing);
|
||||||
|
@ -502,7 +502,7 @@ static void _GBASIOLockstepNodeProcessEvents(struct mTiming* timing, void* user,
|
||||||
if (node->p->d.attached < 2) {
|
if (node->p->d.attached < 2) {
|
||||||
switch (node->mode) {
|
switch (node->mode) {
|
||||||
case GBA_SIO_MULTI:
|
case GBA_SIO_MULTI:
|
||||||
cycles = GBASIOCyclesPerTransfer[GBASIOMultiplayerGetBaud(node->d.p->siocnt)][0];
|
cycles = GBASIOTransferCycles(node->d.p);
|
||||||
break;
|
break;
|
||||||
case GBA_SIO_NORMAL_8:
|
case GBA_SIO_NORMAL_8:
|
||||||
case GBA_SIO_NORMAL_32:
|
case GBA_SIO_NORMAL_32:
|
||||||
|
@ -568,15 +568,7 @@ static uint16_t GBASIOLockstepNodeNormalWriteRegister(struct GBASIODriver* drive
|
||||||
if ((value & 0x0081) == 0x0081) {
|
if ((value & 0x0081) == 0x0081) {
|
||||||
if (!node->id) {
|
if (!node->id) {
|
||||||
// Frequency
|
// Frequency
|
||||||
int32_t cycles;
|
int32_t cycles = GBASIOTransferCycles(node->d.p);
|
||||||
if (value & 2) {
|
|
||||||
cycles = 8 * 8;
|
|
||||||
} else {
|
|
||||||
cycles = 64 * 8;
|
|
||||||
}
|
|
||||||
if (value & 0x1000) {
|
|
||||||
cycles *= 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (transferActive == TRANSFER_IDLE) {
|
if (transferActive == TRANSFER_IDLE) {
|
||||||
mLOG(GBA_SIO, DEBUG, "Lockstep %i: Transfer initiated", node->id);
|
mLOG(GBA_SIO, DEBUG, "Lockstep %i: Transfer initiated", node->id);
|
||||||
|
|
Loading…
Reference in New Issue