GBA Hardware: Backport generic RTC source into core
Jeffrey Pfau jeffrey@endrift.com
Mon, 29 Jun 2015 21:09:36 -0700
5 files changed,
46 insertions(+),
31 deletions(-)
M
CHANGES
→
CHANGES
@@ -90,6 +90,7 @@ - ARM7: Reduce the size of the Thumb instruction table
- GBA: Don't include GBACLIDebugger struct unless needed - SDL: Clean up GL context - GBA Audio: Implement audio reset for channels A/B + - GBA Hardware: Backport generic RTC source into core 0.2.1: (2015-05-13) Bugfixes:
M
src/gba/hardware.c
→
src/gba/hardware.c
@@ -17,6 +17,8 @@ static void _rtcProcessByte(struct GBACartridgeHardware* hw);
static void _rtcUpdateClock(struct GBACartridgeHardware* hw); static unsigned _rtcBCD(unsigned value); +static time_t _rtcGenericCallback(struct GBARTCSource* source); + static void _gyroReadPins(struct GBACartridgeHardware* hw); static void _rumbleReadPins(struct GBACartridgeHardware* hw);@@ -246,7 +248,9 @@ void _rtcUpdateClock(struct GBACartridgeHardware* hw) {
time_t t; struct GBARTCSource* rtc = hw->p->rtcSource; if (rtc) { - rtc->sample(rtc); + if (rtc->sample) { + rtc->sample(rtc); + } t = rtc->unixTime(rtc); } else { t = time(0);@@ -277,6 +281,27 @@ counter += (value % 10) << 4;
return counter; } +time_t _rtcGenericCallback(struct GBARTCSource* source) { + struct GBARTCGenericSource* rtc = (struct GBARTCGenericSource*) source; + switch (rtc->override) { + case RTC_NO_OVERRIDE: + default: + return time(0); + case RTC_FIXED: + return rtc->value; + case RTC_FAKE_EPOCH: + return rtc->value + rtc->p->video.frameCounter * (int64_t) VIDEO_TOTAL_LENGTH / GBA_ARM7TDMI_FREQUENCY; + } +} + +void GBARTCGenericSourceInit(struct GBARTCGenericSource* rtc, struct GBA* gba) { + rtc->p = gba; + rtc->override = RTC_NO_OVERRIDE; + rtc->value = 0; + rtc->d.sample = 0; + rtc->d.unixTime = _rtcGenericCallback; +} + // == Gyro void GBAHardwareInitGyro(struct GBACartridgeHardware* hw) {@@ -466,7 +491,6 @@ void GBAHardwareDeserialize(struct GBACartridgeHardware* hw, const struct GBASerializedState* state) {
hw->readWrite = state->hw.readWrite; hw->pinState = state->hw.pinState; hw->direction = state->hw.pinDirection; - // TODO: Deterministic RTC hw->rtc = state->hw.rtc; hw->gyroSample = state->hw.gyroSample; hw->gyroEdge = state->hw.gyroEdge;
M
src/gba/hardware.h
→
src/gba/hardware.h
@@ -35,6 +35,17 @@
time_t (*unixTime)(struct GBARTCSource*); }; +struct GBARTCGenericSource { + struct GBARTCSource d; + struct GBA* p; + enum { + RTC_NO_OVERRIDE, + RTC_FIXED, + RTC_FAKE_EPOCH + } override; + int64_t value; +}; + enum GBAHardwareDevice { HW_NO_OVERRIDE = 0x8000, HW_NONE = 0,@@ -131,6 +142,8 @@ uint8_t GBAHardwareTiltRead(struct GBACartridgeHardware* gpio, uint32_t address);
struct GBAVideo; bool GBAHardwarePlayerCheckScreen(const struct GBAVideo* video); + +void GBARTCGenericSourceInit(struct GBARTCGenericSource* rtc, struct GBA* gba); struct GBASerializedState; void GBAHardwareSerialize(const struct GBACartridgeHardware* gpio, struct GBASerializedState* state);
M
src/platform/qt/GameController.cpp
→
src/platform/qt/GameController.cpp
@@ -81,27 +81,12 @@ return lux->value;
}; setLuminanceLevel(0); - m_rtc.p = this; - m_rtc.override = GameControllerRTC::NO_OVERRIDE; - m_rtc.sample = [](GBARTCSource* context) {}; - m_rtc.unixTime = [](GBARTCSource* context) -> time_t { - GameControllerRTC* rtc = static_cast<GameControllerRTC*>(context); - switch (rtc->override) { - case GameControllerRTC::NO_OVERRIDE: - default: - return time(nullptr); - case GameControllerRTC::FIXED: - return rtc->value; - case GameControllerRTC::FAKE_EPOCH: - return rtc->value + rtc->p->m_threadContext.gba->video.frameCounter * (int64_t) VIDEO_TOTAL_LENGTH / GBA_ARM7TDMI_FREQUENCY; - } - }; - m_threadContext.startCallback = [](GBAThread* context) { GameController* controller = static_cast<GameController*>(context->userData); controller->m_audioProcessor->setInput(context); context->gba->luminanceSource = &controller->m_lux; - context->gba->rtcSource = &controller->m_rtc; + GBARTCGenericSourceInit(&controller->m_rtc, context->gba); + context->gba->rtcSource = &controller->m_rtc.d; context->gba->rumble = controller->m_inputController->rumble(); context->gba->rotationSource = controller->m_inputController->rotationSource(); controller->m_fpsTarget = context->fpsTarget;@@ -730,16 +715,16 @@ setLuminanceValue(value);
} void GameController::setRealTime() { - m_rtc.override = GameControllerRTC::NO_OVERRIDE; + m_rtc.override = GBARTCGenericSource::RTC_NO_OVERRIDE; } void GameController::setFixedTime(const QDateTime& time) { - m_rtc.override = GameControllerRTC::FIXED; + m_rtc.override = GBARTCGenericSource::RTC_FIXED; m_rtc.value = time.toMSecsSinceEpoch() / 1000; } void GameController::setFakeEpoch(const QDateTime& time) { - m_rtc.override = GameControllerRTC::FAKE_EPOCH; + m_rtc.override = GBARTCGenericSource::RTC_FAKE_EPOCH; m_rtc.value = time.toMSecsSinceEpoch() / 1000; }
M
src/platform/qt/GameController.h
→
src/platform/qt/GameController.h
@@ -205,15 +205,7 @@ int m_luxLevel;
static const int LUX_LEVELS[10]; - struct GameControllerRTC : GBARTCSource { - GameController* p; - enum { - NO_OVERRIDE, - FIXED, - FAKE_EPOCH - } override; - int64_t value; - } m_rtc; + GBARTCGenericSource m_rtc; }; }