all repos — mgba @ 1a2831200c5e28c408c75bbbd4c14a28801c8216

mGBA Game Boy Advance Emulator

GBA Hardware: Fix RTC
Vicki Pfau vi@endrift.com
Sat, 08 Aug 2020 21:28:55 -0700
commit

1a2831200c5e28c408c75bbbd4c14a28801c8216

parent

49f573662b29cdebb6964a3de6ae0038fc2ffa75

3 files changed, 23 insertions(+), 17 deletions(-)

jump to
M CHANGESCHANGES

@@ -12,6 +12,7 @@ - DS Video: Fix affine parameter advancing (fixes mgba.io/i/802)

- 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
M include/mgba/internal/gba/hardware.hinclude/mgba/internal/gba/hardware.h

@@ -53,12 +53,6 @@ GPIO_WRITE_ONLY = 0,

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 @@ RTC_TIME = 6,

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 @@ int32_t bits;

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]; };
M src/gba/hardware.csrc/gba/hardware.c

@@ -131,7 +131,7 @@ hw->rtc.commandActive = 0;

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 @@ break;

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 @@ mLOG(GBA_HW, WARN, "Invalid RTC command byte: %02X", rtc->bits);

} } 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 @@ return 0;

} 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 @@ rtc->time[0] = _rtcBCD(date.tm_year - 100);

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);