mirror of https://github.com/mgba-emu/mgba.git
GBA SIO: Convert GBP to mTiming
This commit is contained in:
parent
49c8ad1b02
commit
4ac4733cfd
|
@ -33,7 +33,7 @@ static void _lightReadPins(struct GBACartridgeHardware* hw);
|
|||
|
||||
static uint16_t _gbpRead(struct mKeyCallback*);
|
||||
static uint16_t _gbpSioWriteRegister(struct GBASIODriver* driver, uint32_t address, uint16_t value);
|
||||
static int32_t _gbpSioProcessEvents(struct GBASIODriver* driver, int32_t cycles);
|
||||
static void _gbpSioProcessEvents(struct mTiming* timing, void* user, uint32_t cyclesLate);
|
||||
|
||||
static const int RTC_BYTES[8] = {
|
||||
0, // Force reset
|
||||
|
@ -57,8 +57,11 @@ void GBAHardwareInit(struct GBACartridgeHardware* hw, uint16_t* base) {
|
|||
hw->gbpDriver.d.load = 0;
|
||||
hw->gbpDriver.d.unload = 0;
|
||||
hw->gbpDriver.d.writeRegister = _gbpSioWriteRegister;
|
||||
hw->gbpDriver.d.processEvents = _gbpSioProcessEvents;
|
||||
hw->gbpDriver.p = hw;
|
||||
hw->gbpNextEvent.context = &hw->gbpDriver;
|
||||
hw->gbpNextEvent.name = "GBA SIO Game Boy Player";
|
||||
hw->gbpNextEvent.callback = _gbpSioProcessEvents;
|
||||
hw->gbpNextEvent.priority = 0x80;
|
||||
}
|
||||
|
||||
void GBAHardwareClear(struct GBACartridgeHardware* hw) {
|
||||
|
@ -521,7 +524,6 @@ void GBAHardwarePlayerUpdate(struct GBA* gba) {
|
|||
if (GBAHardwarePlayerCheckScreen(&gba->video)) {
|
||||
gba->memory.hw.devices |= HW_GB_PLAYER;
|
||||
gba->memory.hw.gbpInputsPosted = 0;
|
||||
gba->memory.hw.gbpNextEvent = INT_MAX;
|
||||
gba->keyCallback = &gba->memory.hw.gbpCallback.d;
|
||||
GBASIOSetDriver(&gba->sio, &gba->memory.hw.gbpDriver.d, SIO_NORMAL_32);
|
||||
}
|
||||
|
@ -551,37 +553,34 @@ uint16_t _gbpSioWriteRegister(struct GBASIODriver* driver, uint32_t address, uin
|
|||
gbp->p->p->rumble->setRumble(gbp->p->p->rumble, (rx & mask) == 0x22);
|
||||
}
|
||||
}
|
||||
gbp->p->gbpNextEvent = 2048;
|
||||
mTimingSchedule(&gbp->p->p->timing, &gbp->p->gbpNextEvent, 2048);
|
||||
}
|
||||
value &= 0x78FB;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
int32_t _gbpSioProcessEvents(struct GBASIODriver* driver, int32_t cycles) {
|
||||
struct GBAGBPSIODriver* gbp = (struct GBAGBPSIODriver*) driver;
|
||||
gbp->p->gbpNextEvent -= cycles;
|
||||
if (gbp->p->gbpNextEvent <= 0) {
|
||||
uint32_t tx = 0;
|
||||
int txPosition = gbp->p->gbpTxPosition;
|
||||
if (txPosition > 16) {
|
||||
gbp->p->gbpTxPosition = 0;
|
||||
txPosition = 0;
|
||||
} else if (txPosition > 12) {
|
||||
txPosition = 12;
|
||||
}
|
||||
tx = _gbpTxData[txPosition];
|
||||
++gbp->p->gbpTxPosition;
|
||||
gbp->p->p->memory.io[REG_SIODATA32_LO >> 1] = tx;
|
||||
gbp->p->p->memory.io[REG_SIODATA32_HI >> 1] = tx >> 16;
|
||||
if (gbp->d.p->normalControl.irq) {
|
||||
GBARaiseIRQ(gbp->p->p, IRQ_SIO);
|
||||
}
|
||||
gbp->d.p->normalControl.start = 0;
|
||||
gbp->p->p->memory.io[REG_SIOCNT >> 1] = gbp->d.p->siocnt;
|
||||
gbp->p->gbpNextEvent = INT_MAX;
|
||||
void _gbpSioProcessEvents(struct mTiming* timing, void* user, uint32_t cyclesLate) {
|
||||
UNUSED(timing);
|
||||
UNUSED(cyclesLate);
|
||||
struct GBAGBPSIODriver* gbp = user;
|
||||
uint32_t tx = 0;
|
||||
int txPosition = gbp->p->gbpTxPosition;
|
||||
if (txPosition > 16) {
|
||||
gbp->p->gbpTxPosition = 0;
|
||||
txPosition = 0;
|
||||
} else if (txPosition > 12) {
|
||||
txPosition = 12;
|
||||
}
|
||||
return gbp->p->gbpNextEvent;
|
||||
tx = _gbpTxData[txPosition];
|
||||
++gbp->p->gbpTxPosition;
|
||||
gbp->p->p->memory.io[REG_SIODATA32_LO >> 1] = tx;
|
||||
gbp->p->p->memory.io[REG_SIODATA32_HI >> 1] = tx >> 16;
|
||||
if (gbp->d.p->normalControl.irq) {
|
||||
GBARaiseIRQ(gbp->p->p, IRQ_SIO);
|
||||
}
|
||||
gbp->d.p->normalControl.start = 0;
|
||||
gbp->p->p->memory.io[REG_SIOCNT >> 1] = gbp->d.p->siocnt & ~0x0080;
|
||||
}
|
||||
|
||||
// == Serialization
|
||||
|
@ -613,7 +612,7 @@ void GBAHardwareSerialize(const struct GBACartridgeHardware* hw, struct GBASeria
|
|||
flags1 = GBASerializedHWFlags1SetLightEdge(flags1, hw->lightEdge);
|
||||
flags2 = GBASerializedHWFlags2SetGbpInputsPosted(flags2, hw->gbpInputsPosted);
|
||||
flags2 = GBASerializedHWFlags2SetGbpTxPosition(flags2, hw->gbpTxPosition);
|
||||
STORE_32(hw->gbpNextEvent, 0, &state->hw.gbpNextEvent);
|
||||
STORE_32(hw->gbpNextEvent.when - mTimingCurrentTime(&hw->p->timing), 0, &state->hw.gbpNextEvent);
|
||||
STORE_16(flags1, 0, &state->hw.flags1);
|
||||
state->hw.flags2 = flags2;
|
||||
}
|
||||
|
@ -645,8 +644,13 @@ void GBAHardwareDeserialize(struct GBACartridgeHardware* hw, const struct GBASer
|
|||
hw->lightEdge = GBASerializedHWFlags1GetLightEdge(flags1);
|
||||
hw->gbpInputsPosted = GBASerializedHWFlags2GetGbpInputsPosted(state->hw.flags2);
|
||||
hw->gbpTxPosition = GBASerializedHWFlags2GetGbpTxPosition(state->hw.flags2);
|
||||
LOAD_32(hw->gbpNextEvent, 0, &state->hw.gbpNextEvent);
|
||||
|
||||
uint32_t when;
|
||||
LOAD_32(when, 0, &state->hw.gbpNextEvent);
|
||||
if (hw->devices & HW_GB_PLAYER) {
|
||||
GBASIOSetDriver(&hw->p->sio, &hw->gbpDriver.d, SIO_NORMAL_32);
|
||||
if (hw->p->memory.io[REG_SIOCNT >> 1] & 0x0080) {
|
||||
mTimingSchedule(&hw->p->timing, &hw->gbpNextEvent, when);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include "arm/macros.h"
|
||||
#include "core/log.h"
|
||||
#include "core/timing.h"
|
||||
#include "gba/interface.h"
|
||||
|
||||
#include <time.h>
|
||||
|
@ -115,7 +116,7 @@ struct GBACartridgeHardware {
|
|||
|
||||
unsigned gbpInputsPosted;
|
||||
int gbpTxPosition;
|
||||
int32_t gbpNextEvent;
|
||||
struct mTimingEvent gbpNextEvent;
|
||||
struct GBAGBPKeyCallback gbpCallback;
|
||||
struct GBAGBPSIODriver gbpDriver;
|
||||
};
|
||||
|
|
|
@ -40,7 +40,6 @@ struct GBASIODriver {
|
|||
bool (*load)(struct GBASIODriver* driver);
|
||||
bool (*unload)(struct GBASIODriver* driver);
|
||||
uint16_t (*writeRegister)(struct GBASIODriver* driver, uint32_t address, uint16_t value);
|
||||
int32_t (*processEvents)(struct GBASIODriver* driver, int32_t cycles);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue