From 1a2831200c5e28c408c75bbbd4c14a28801c8216 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 8 Aug 2020 21:28:55 -0700 Subject: [PATCH] GBA Hardware: Fix RTC --- CHANGES | 1 + include/mgba/internal/gba/hardware.h | 21 +++++++++++++-------- src/gba/hardware.c | 18 +++++++++--------- 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/CHANGES b/CHANGES index 6c503a44f..d12ece948 100644 --- a/CHANGES +++ b/CHANGES @@ -12,6 +12,7 @@ Bugfixes: - DS Video: Fix 2D/3D blending alpha values - DS I/O: Enable POWCNT1 bit 1 at boot (fixes mgba.io/i/616) - DS Slot-1: Reply to IR 0x08 command properly (fixes mgba.io/i/666) + - GBA Hardware: Fix RTC - GBA Video: Fix mode 2 out-of-bounds VRAM crash - GBA Video: Fix regression adjusting brightness of backdrop - DS GX: Properly reject invalid commands diff --git a/include/mgba/internal/gba/hardware.h b/include/mgba/internal/gba/hardware.h index a06da3a80..498334356 100644 --- a/include/mgba/internal/gba/hardware.h +++ b/include/mgba/internal/gba/hardware.h @@ -53,12 +53,6 @@ enum GPIODirection { GPIO_READ_WRITE = 1 }; -DECL_BITFIELD(RTCControl, uint8_t); -DECL_BIT(RTCControl, Reset, 0); -DECL_BIT(RTCControl, Hour24, 1); -DECL_BIT(RTCControl, IRQ1, 4); -DECL_BIT(RTCControl, IRQ2, 5); - enum RTCCommand { RTC_STATUS1 = 0, RTC_ALARM1 = 1, @@ -70,6 +64,17 @@ enum RTCCommand { RTC_FREE_REG = 7 }; +DECL_BITFIELD(RTCStatus1, uint8_t); +DECL_BIT(RTCStatus1, Reset, 0); +DECL_BIT(RTCStatus1, Hour24, 1); +DECL_BIT(RTCStatus1, IRQ1, 4); +DECL_BIT(RTCStatus1, IRQ2, 5); + +DECL_BITFIELD(RTCControl, uint8_t); +DECL_BIT(RTCControl, MinIRQ, 3); +DECL_BIT(RTCControl, Hour24, 6); +DECL_BIT(RTCControl, Poweroff, 7); + DECL_BITFIELD(RTCCommandData, uint8_t); DECL_BITS(RTCCommandData, Magic, 0, 4); DECL_BITS(RTCCommandData, Command, 4, 3); @@ -89,9 +94,9 @@ struct GBARTC { uint8_t commandActive; uint8_t alarm1[3]; RTCCommandData command; - RTCStatus2 status2; + uint8_t status1; uint8_t freeReg; - RTCControl control; + uint8_t control; // Used for status2 on DS uint8_t alarm2[3]; uint8_t time[7]; }; diff --git a/src/gba/hardware.c b/src/gba/hardware.c index 54a7d565f..374132f6c 100644 --- a/src/gba/hardware.c +++ b/src/gba/hardware.c @@ -131,7 +131,7 @@ void GBAHardwareInitRTC(struct GBACartridgeHardware* hw) { hw->rtc.command = 0; hw->rtc.control = 0x40; hw->rtc.freeReg = 0; - hw->rtc.status2 = 0; + hw->rtc.status1 = 0; memset(hw->rtc.time, 0, sizeof(hw->rtc.time)); } @@ -245,7 +245,7 @@ void GBARTCProcessByte(struct GBARTC* rtc, struct mRTCSource* source) { case RTC_FORCE_IRQ: break; case RTC_ALARM1: - if (RTCStatus2GetINT1(rtc->status2) == 4) { + if (RTCStatus2GetINT1(rtc->control) == 4) { rtc->bytesRemaining = 3; } } @@ -254,14 +254,14 @@ void GBARTCProcessByte(struct GBARTC* rtc, struct mRTCSource* source) { } } else { switch (RTCCommandDataGetCommand(rtc->command)) { - case RTC_STATUS1: - rtc->control = rtc->bits & 0xFE; + case RTC_STATUS2: + rtc->control = rtc->bits; break; case RTC_FORCE_IRQ: mLOG(GBA_HW, STUB, "Unimplemented RTC command %u", RTCCommandDataGetCommand(rtc->command)); break; - case RTC_STATUS2: - rtc->status2 = rtc->bits; + case RTC_STATUS1: + rtc->status1 = rtc->bits & 0xFE; break; case RTC_FREE_REG: rtc->freeReg = rtc->bits; @@ -292,10 +292,10 @@ unsigned GBARTCOutput(struct GBARTC* rtc) { } switch (RTCCommandDataGetCommand(rtc->command)) { case RTC_STATUS1: - outputByte = rtc->control; + outputByte = rtc->status1; break; case RTC_STATUS2: - outputByte = rtc->status2; + outputByte = rtc->control; break; case RTC_DATETIME: case RTC_TIME: @@ -332,7 +332,7 @@ void _rtcUpdateClock(struct GBARTC* rtc, struct mRTCSource* source) { rtc->time[1] = _rtcBCD(date.tm_mon + 1); rtc->time[2] = _rtcBCD(date.tm_mday); rtc->time[3] = _rtcBCD(date.tm_wday); - if (RTCControlIsHour24(rtc->control)) { + if (RTCControlIsHour24(rtc->control) || RTCStatus1IsHour24(rtc->status1)) { rtc->time[4] = _rtcBCD(date.tm_hour); } else { rtc->time[4] = _rtcBCD(date.tm_hour % 12);