all repos — mgba @ 4ac4733cfd4c4524c6a56d0406ba138d173fad61

mGBA Game Boy Advance Emulator

GBA SIO: Convert GBP to mTiming
Jeffrey Pfau jeffrey@endrift.com
Sun, 25 Dec 2016 15:22:22 -0800
commit

4ac4733cfd4c4524c6a56d0406ba138d173fad61

parent

49c8ad1b0232d6f23171065e15052e46506d97c5

3 files changed, 35 insertions(+), 31 deletions(-)

jump to
M src/gba/hardware.csrc/gba/hardware.c

@@ -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 @@ hw->gbpDriver.d.deinit = 0;

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 @@ }

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 @@ if (gbp->p->p->rumble) {

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; + } + 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); } - return gbp->p->gbpNextEvent; + gbp->d.p->normalControl.start = 0; + gbp->p->p->memory.io[REG_SIOCNT >> 1] = gbp->d.p->siocnt & ~0x0080; } // == Serialization

@@ -613,7 +612,7 @@ state->hw.lightSample = hw->lightSample;

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 @@ hw->lightSample = state->hw.lightSample;

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); + } } }
M src/gba/hardware.hsrc/gba/hardware.h

@@ -10,6 +10,7 @@ #include "util/common.h"

#include "arm/macros.h" #include "core/log.h" +#include "core/timing.h" #include "gba/interface.h" #include <time.h>

@@ -115,7 +116,7 @@ int tiltState;

unsigned gbpInputsPosted; int gbpTxPosition; - int32_t gbpNextEvent; + struct mTimingEvent gbpNextEvent; struct GBAGBPKeyCallback gbpCallback; struct GBAGBPSIODriver gbpDriver; };
M src/gba/interface.hsrc/gba/interface.h

@@ -40,7 +40,6 @@ void (*deinit)(struct GBASIODriver* driver);

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