GBA Hardware: Fix RTC

This commit is contained in:
Vicki Pfau 2020-08-08 21:28:55 -07:00
parent 49f573662b
commit 1a2831200c
3 changed files with 23 additions and 17 deletions

View File

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

View File

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

View File

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