GBA Hardware: Begin fixing RTC implementation
Vicki Pfau vi@endrift.com
Sun, 19 Mar 2017 09:23:54 -0700
2 files changed,
40 insertions(+),
21 deletions(-)
M
include/mgba/internal/gba/hardware.h
→
include/mgba/internal/gba/hardware.h
@@ -48,24 +48,30 @@ GPIO_WRITE_ONLY = 0,
GPIO_READ_WRITE = 1 }; -DECL_BITFIELD(RTCControl, uint32_t); -DECL_BIT(RTCControl, MinIRQ, 3); -DECL_BIT(RTCControl, Hour24, 6); -DECL_BIT(RTCControl, Poweroff, 7); +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_RESET = 0, + RTC_STATUS1 = 0, + RTC_ALARM1 = 1, RTC_DATETIME = 2, RTC_FORCE_IRQ = 3, - RTC_CONTROL = 4, - RTC_TIME = 6 + RTC_STATUS2 = 4, + RTC_ALARM2 = 5, + RTC_TIME = 6, + RTC_FREE_REG = 7 }; -DECL_BITFIELD(RTCCommandData, uint32_t); +DECL_BITFIELD(RTCCommandData, uint8_t); DECL_BITS(RTCCommandData, Magic, 0, 4); DECL_BITS(RTCCommandData, Command, 4, 3); DECL_BIT(RTCCommandData, Reading, 7); +DECL_BITFIELD(RTCStatus2, uint8_t); + #pragma pack(push, 1) struct GBARTC { int32_t bytesRemaining;@@ -74,7 +80,12 @@ int32_t bitsRead;
int32_t bits; int32_t commandActive; RTCCommandData command; + RTCStatus2 status2; + uint8_t freeReg; RTCControl control; + uint8_t reserved1; + uint8_t reserved2; + uint8_t reserved3; uint8_t time[7]; }; #pragma pack(pop)
M
src/gba/hardware.c
→
src/gba/hardware.c
@@ -110,6 +110,8 @@ hw->rtc.bits = 0;
hw->rtc.commandActive = 0; hw->rtc.command = 0; hw->rtc.control = 0x40; + hw->rtc.freeReg = 0; + hw->rtc.status2 = 0; memset(hw->rtc.time, 0, sizeof(hw->rtc.time)); }@@ -216,15 +218,11 @@
rtc->bytesRemaining = RTC_BYTES[RTCCommandDataGetCommand(command)]; rtc->commandActive = rtc->bytesRemaining > 0; switch (RTCCommandDataGetCommand(command)) { - case RTC_RESET: - rtc->control = 0; - break; case RTC_DATETIME: case RTC_TIME: _rtcUpdateClock(rtc, source); break; case RTC_FORCE_IRQ: - case RTC_CONTROL: break; } } else {@@ -232,13 +230,18 @@ mLOG(GBA_HW, WARN, "Invalid RTC command byte: %02X", rtc->bits);
} } else { switch (RTCCommandDataGetCommand(rtc->command)) { - case RTC_CONTROL: - rtc->control = rtc->bits; + case RTC_STATUS1: + rtc->control = rtc->bits & 0xFE; break; case RTC_FORCE_IRQ: mLOG(GBA_HW, STUB, "Unimplemented RTC command %u", RTCCommandDataGetCommand(rtc->command)); break; - case RTC_RESET: + case RTC_STATUS2: + rtc->status2 = rtc->bits; + break; + case RTC_FREE_REG: + rtc->freeReg = rtc->bits; + break; case RTC_DATETIME: case RTC_TIME: break;@@ -256,15 +259,19 @@
unsigned GBARTCOutput(struct GBARTC* rtc) { uint8_t outputByte = 0; switch (RTCCommandDataGetCommand(rtc->command)) { - case RTC_CONTROL: + case RTC_STATUS1: outputByte = rtc->control; break; + case RTC_STATUS2: + outputByte = rtc->status2; + break; case RTC_DATETIME: case RTC_TIME: outputByte = rtc->time[7 - rtc->bytesRemaining]; break; + case RTC_FREE_REG: + outputByte = rtc->freeReg; case RTC_FORCE_IRQ: - case RTC_RESET: break; } unsigned output = (outputByte >> rtc->bitsRead) & 1;@@ -291,6 +298,7 @@ if (RTCControlIsHour24(rtc->control)) {
rtc->time[4] = _rtcBCD(date.tm_hour); } else { rtc->time[4] = _rtcBCD(date.tm_hour % 12); + rtc->time[4] |= (date.tm_hour >= 12) ? 0xC0 : 0; } rtc->time[5] = _rtcBCD(date.tm_min); rtc->time[6] = _rtcBCD(date.tm_sec);@@ -574,8 +582,8 @@ STORE_32(hw->rtc.transferStep, 0, &state->hw.rtc.transferStep);
STORE_32(hw->rtc.bitsRead, 0, &state->hw.rtc.bitsRead); STORE_32(hw->rtc.bits, 0, &state->hw.rtc.bits); STORE_32(hw->rtc.commandActive, 0, &state->hw.rtc.commandActive); - STORE_32(hw->rtc.command, 0, &state->hw.rtc.command); - STORE_32(hw->rtc.control, 0, &state->hw.rtc.control); + state->hw.rtc.command = hw->rtc.command; + state->hw.rtc.control = hw->rtc.control; memcpy(state->hw.rtc.time, hw->rtc.time, sizeof(state->hw.rtc.time)); STORE_16(hw->gyroSample, 0, &state->hw.gyroSample);@@ -606,8 +614,8 @@ LOAD_32(hw->rtc.transferStep, 0, &state->hw.rtc.transferStep);
LOAD_32(hw->rtc.bitsRead, 0, &state->hw.rtc.bitsRead); LOAD_32(hw->rtc.bits, 0, &state->hw.rtc.bits); LOAD_32(hw->rtc.commandActive, 0, &state->hw.rtc.commandActive); - LOAD_32(hw->rtc.command, 0, &state->hw.rtc.command); - LOAD_32(hw->rtc.control, 0, &state->hw.rtc.control); + hw->rtc.command = state->hw.rtc.command; + hw->rtc.control = state->hw.rtc.control; memcpy(hw->rtc.time, state->hw.rtc.time, sizeof(hw->rtc.time)); LOAD_16(hw->gyroSample, 0, &state->hw.gyroSample);