diff --git a/src/NDS.cpp b/src/NDS.cpp index 9b9e1e71..2e71c274 100644 --- a/src/NDS.cpp +++ b/src/NDS.cpp @@ -179,6 +179,7 @@ u16 KeyCnt[2]; u16 RCnt; SPIHost* SPI; +class RTC* RTC; bool Running; @@ -218,12 +219,12 @@ bool Init() DMAs[7] = new DMA(1, 3); SPI = new SPIHost(); + RTC = new class RTC(); if (!NDSCart::Init()) return false; if (!GBACart::Init()) return false; if (!GPU::Init()) return false; if (!SPU::Init()) return false; - if (!RTC::Init()) return false; if (!Wifi::Init()) return false; if (!DSi::Init()) return false; @@ -254,11 +255,13 @@ void DeInit() delete SPI; SPI = nullptr; + delete RTC; + RTC = nullptr; + NDSCart::DeInit(); GBACart::DeInit(); GPU::DeInit(); SPU::DeInit(); - RTC::DeInit(); Wifi::DeInit(); DSi::DeInit(); @@ -647,7 +650,7 @@ void Reset() GPU::Reset(); SPU::Reset(); SPI->Reset(); - RTC::Reset(); + RTC->Reset(); Wifi::Reset(); // TODO: move the SOUNDBIAS/degrade logic to SPU? @@ -849,7 +852,7 @@ bool DoSavestate(Savestate* file) GPU::DoSavestate(file); SPU::DoSavestate(file); SPI->DoSavestate(file); - RTC::DoSavestate(file); + RTC->DoSavestate(file); Wifi::DoSavestate(file); if (ConsoleType == 1) @@ -3866,7 +3869,7 @@ u8 ARM7IORead8(u32 addr) case 0x04000136: return (KeyInput >> 16) & 0xFF; case 0x04000137: return KeyInput >> 24; - case 0x04000138: return RTC::Read() & 0xFF; + case 0x04000138: return RTC->Read() & 0xFF; case 0x040001A2: if (ExMemCnt[0] & (1<<11)) @@ -3957,7 +3960,7 @@ u16 ARM7IORead16(u32 addr) case 0x04000134: return RCnt; case 0x04000136: return KeyInput >> 16; - case 0x04000138: return RTC::Read(); + case 0x04000138: return RTC->Read(); case 0x04000180: return IPCSync7; case 0x04000184: @@ -4047,7 +4050,7 @@ u32 ARM7IORead32(u32 addr) case 0x04000130: return (KeyInput & 0xFFFF) | (KeyCnt[1] << 16); case 0x04000134: return RCnt | (KeyInput & 0xFFFF0000); - case 0x04000138: return RTC::Read(); + case 0x04000138: return RTC->Read(); case 0x04000180: return IPCSync7; case 0x04000184: return ARM7IORead16(addr); @@ -4139,7 +4142,7 @@ void ARM7IOWrite8(u32 addr, u8 val) RCnt = (RCnt & 0x00FF) | (val << 8); return; - case 0x04000138: RTC::Write(val, true); return; + case 0x04000138: RTC->Write(val, true); return; case 0x04000188: ARM7IOWrite32(addr, val | (val << 8) | (val << 16) | (val << 24)); @@ -4227,7 +4230,7 @@ void ARM7IOWrite16(u32 addr, u16 val) case 0x04000132: KeyCnt[1] = val; return; case 0x04000134: RCnt = val; return; - case 0x04000138: RTC::Write(val, false); return; + case 0x04000138: RTC->Write(val, false); return; case 0x04000180: IPCSync9 &= 0xFFF0; @@ -4395,7 +4398,7 @@ void ARM7IOWrite32(u32 addr, u32 val) case 0x04000130: KeyCnt[1] = val >> 16; return; case 0x04000134: RCnt = val & 0xFFFF; return; - case 0x04000138: RTC::Write(val & 0xFFFF, false); return; + case 0x04000138: RTC->Write(val & 0xFFFF, false); return; case 0x04000180: case 0x04000184: diff --git a/src/NDS.h b/src/NDS.h index b0126ed3..a3e74b66 100644 --- a/src/NDS.h +++ b/src/NDS.h @@ -31,6 +31,7 @@ //#define DEBUG_CHECK_DESYNC class SPIHost; +class RTC; namespace NDS { @@ -249,6 +250,7 @@ extern u32 KeyInput; extern u16 RCnt; extern SPIHost* SPI; +extern class RTC* RTC; const u32 ARM7WRAMSize = 0x10000; extern u8* ARM7WRAM; diff --git a/src/RTC.cpp b/src/RTC.cpp index 527b7f47..30eab006 100644 --- a/src/RTC.cpp +++ b/src/RTC.cpp @@ -24,52 +24,29 @@ using Platform::Log; using Platform::LogLevel; -namespace RTC -{ -/// This value represents the Nintendo DS IO register, -/// \em not the value of the system's clock. -/// The actual system time is taken directly from the host. -u16 IO; - -u8 Input; -u32 InputBit; -u32 InputPos; - -u8 Output[8]; -u32 OutputBit; -u32 OutputPos; - -u8 CurCmd; - -StateData State; - -s32 TimerError; -u32 ClockCount; void WriteDateTime(int num, u8 val); -bool Init() +RTC::RTC() { - NDS::RegisterEventFunc(NDS::Event_RTC, 0, ClockTimer); + NDS::RegisterEventFunc(NDS::Event_RTC, 0, MemberEventFunc(RTC, ClockTimer)); ResetState(); // indicate the power was off // this will be changed if a previously saved RTC state is loaded State.StatusReg1 = 0x80; - - return true; } -void DeInit() +RTC::~RTC() { NDS::UnregisterEventFunc(NDS::Event_RTC, 0); } -void Reset() +void RTC::Reset() { Input = 0; InputBit = 0; @@ -84,7 +61,7 @@ void Reset() ScheduleTimer(true); } -void DoSavestate(Savestate* file) +void RTC::DoSavestate(Savestate* file) { file->Section("RTC."); @@ -107,17 +84,17 @@ void DoSavestate(Savestate* file) } -u8 BCD(u8 val) +u8 RTC::BCD(u8 val) { return (val % 10) | ((val / 10) << 4); } -u8 FromBCD(u8 val) +u8 RTC::FromBCD(u8 val) { return (val & 0xF) + ((val >> 4) * 10); } -u8 BCDIncrement(u8 val) +u8 RTC::BCDIncrement(u8 val) { val++; if ((val & 0x0F) >= 0x0A) @@ -127,7 +104,7 @@ u8 BCDIncrement(u8 val) return val; } -u8 BCDSanitize(u8 val, u8 vmin, u8 vmax) +u8 RTC::BCDSanitize(u8 val, u8 vmin, u8 vmax) { if (val < vmin || val > vmax) val = vmin; @@ -140,12 +117,12 @@ u8 BCDSanitize(u8 val, u8 vmin, u8 vmax) } -void GetState(StateData& state) +void RTC::GetState(StateData& state) { memcpy(&state, &State, sizeof(State)); } -void SetState(StateData& state) +void RTC::SetState(StateData& state) { memcpy(&State, &state, sizeof(State)); @@ -155,7 +132,7 @@ void SetState(StateData& state) WriteDateTime(i+1, State.DateTime[i]); } -void GetDateTime(int& year, int& month, int& day, int& hour, int& minute, int& second) +void RTC::GetDateTime(int& year, int& month, int& day, int& hour, int& minute, int& second) { year = FromBCD(State.DateTime[0]); year += 2000; @@ -176,7 +153,7 @@ void GetDateTime(int& year, int& month, int& day, int& hour, int& minute, int& s second = FromBCD(State.DateTime[6] & 0x7F); } -void SetDateTime(int year, int month, int day, int hour, int minute, int second) +void RTC::SetDateTime(int year, int month, int day, int hour, int minute, int second) { int monthdays[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; @@ -226,7 +203,7 @@ void SetDateTime(int year, int month, int day, int hour, int minute, int second) State.StatusReg1 &= ~0x80; } -void ResetState() +void RTC::ResetState() { memset(&State, 0, sizeof(State)); State.DateTime[1] = 1; @@ -234,7 +211,7 @@ void ResetState() } -void SetIRQ(u8 irq) +void RTC::SetIRQ(u8 irq) { u8 oldstat = State.IRQFlag; State.IRQFlag |= irq; @@ -250,12 +227,12 @@ void SetIRQ(u8 irq) } } -void ClearIRQ(u8 irq) +void RTC::ClearIRQ(u8 irq) { State.IRQFlag &= ~irq; } -void ProcessIRQ(int type) // 0=minute carry 1=periodic 2=status reg write +void RTC::ProcessIRQ(int type) // 0=minute carry 1=periodic 2=status reg write { // INT1 @@ -395,7 +372,7 @@ void ProcessIRQ(int type) // 0=minute carry 1=periodic 2=status reg write } -u8 DaysInMonth() +u8 RTC::DaysInMonth() { u8 numdays; @@ -438,12 +415,12 @@ u8 DaysInMonth() return numdays; } -void CountYear() +void RTC::CountYear() { State.DateTime[0] = BCDIncrement(State.DateTime[0]); } -void CountMonth() +void RTC::CountMonth() { State.DateTime[1] = BCDIncrement(State.DateTime[1]); if (State.DateTime[1] > 0x12) @@ -453,7 +430,7 @@ void CountMonth() } } -void CheckEndOfMonth() +void RTC::CheckEndOfMonth() { if (State.DateTime[2] > DaysInMonth()) { @@ -462,7 +439,7 @@ void CheckEndOfMonth() } } -void CountDay() +void RTC::CountDay() { // day-of-week counter State.DateTime[3]++; @@ -474,7 +451,7 @@ void CountDay() CheckEndOfMonth(); } -void CountHour() +void RTC::CountHour() { u8 hour = BCDIncrement(State.DateTime[4] & 0x3F); u8 pm = State.DateTime[4] & 0x40; @@ -506,7 +483,7 @@ void CountHour() State.DateTime[4] = hour | pm; } -void CountMinute() +void RTC::CountMinute() { State.MinuteCount++; State.DateTime[5] = BCDIncrement(State.DateTime[5]); @@ -520,7 +497,7 @@ void CountMinute() ProcessIRQ(0); } -void CountSecond() +void RTC::CountSecond() { State.DateTime[6] = BCDIncrement(State.DateTime[6]); if (State.DateTime[6] >= 0x60) @@ -531,7 +508,7 @@ void CountSecond() } -void ScheduleTimer(bool first) +void RTC::ScheduleTimer(bool first) { if (first) TimerError = 0; @@ -544,7 +521,7 @@ void ScheduleTimer(bool first) NDS::ScheduleEvent(NDS::Event_RTC, !first, delay, 0, 0); } -void ClockTimer(u32 param) +void RTC::ClockTimer(u32 param) { ClockCount++; @@ -565,7 +542,7 @@ void ClockTimer(u32 param) } -void WriteDateTime(int num, u8 val) +void RTC::WriteDateTime(int num, u8 val) { switch (num) { @@ -619,14 +596,14 @@ void WriteDateTime(int num, u8 val) } } -void SaveDateTime() +void RTC::SaveDateTime() { int y, m, d, h, i, s; GetDateTime(y, m, d, h, i, s); Platform::WriteDateTime(y, m, d, h, i, s); } -void CmdRead() +void RTC::CmdRead() { if ((CurCmd & 0x0F) == 0x06) { @@ -704,7 +681,7 @@ void CmdRead() Log(LogLevel::Debug, "RTC: unknown read command %02X\n", CurCmd); } -void CmdWrite(u8 val) +void RTC::CmdWrite(u8 val) { if ((CurCmd & 0x0F) == 0x06) { @@ -861,7 +838,7 @@ void CmdWrite(u8 val) Log(LogLevel::Debug, "RTC: unknown write command %02X\n", CurCmd); } -void ByteIn(u8 val) +void RTC::ByteIn(u8 val) { if (InputPos == 0) { @@ -895,13 +872,13 @@ void ByteIn(u8 val) } -u16 Read() +u16 RTC::Read() { //printf("RTC READ %04X\n", IO); return IO; } -void Write(u16 val, bool byte) +void RTC::Write(u16 val, bool byte) { if (byte) val |= (IO & 0xFF00); @@ -963,5 +940,3 @@ void Write(u16 val, bool byte) else IO = (IO & 0x0001) | (val & 0xFFFE); } - -} diff --git a/src/RTC.h b/src/RTC.h index ff842711..db78f676 100644 --- a/src/RTC.h +++ b/src/RTC.h @@ -22,46 +22,95 @@ #include "types.h" #include "Savestate.h" -namespace RTC +class RTC { +public: -struct StateData -{ - u8 StatusReg1; - u8 StatusReg2; - u8 DateTime[7]; - u8 Alarm1[3]; - u8 Alarm2[3]; - u8 ClockAdjust; - u8 FreeReg; + struct StateData + { + u8 StatusReg1; + u8 StatusReg2; + u8 DateTime[7]; + u8 Alarm1[3]; + u8 Alarm2[3]; + u8 ClockAdjust; + u8 FreeReg; - u8 IRQFlag; + u8 IRQFlag; - // DSi registers - u32 MinuteCount; - u8 FOUT1; - u8 FOUT2; - u8 AlarmDate1[3]; - u8 AlarmDate2[3]; + // DSi registers + u32 MinuteCount; + u8 FOUT1; + u8 FOUT2; + u8 AlarmDate1[3]; + u8 AlarmDate2[3]; + }; + + RTC(); + ~RTC(); + + void Reset(); + + void DoSavestate(Savestate* file); + + void GetState(StateData& state); + void SetState(StateData& state); + void GetDateTime(int& year, int& month, int& day, int& hour, int& minute, int& second); + void SetDateTime(int year, int month, int day, int hour, int minute, int second); + + void ClockTimer(u32 param); + + u16 Read(); + void Write(u16 val, bool byte); + +private: + /// This value represents the Nintendo DS IO register, + /// \em not the value of the system's clock. + /// The actual system time is taken directly from the host. + u16 IO; + + u8 Input; + u32 InputBit; + u32 InputPos; + + u8 Output[8]; + u32 OutputBit; + u32 OutputPos; + + u8 CurCmd; + + StateData State; + + s32 TimerError; + u32 ClockCount; + + void ResetState(); + void ScheduleTimer(bool first); + + u8 BCD(u8 val); + u8 FromBCD(u8 val); + u8 BCDIncrement(u8 val); + u8 BCDSanitize(u8 val, u8 vmin, u8 vmax); + + void SetIRQ(u8 irq); + void ClearIRQ(u8 irq); + void ProcessIRQ(int type); + + u8 DaysInMonth(); + void CountYear(); + void CountMonth(); + void CheckEndOfMonth(); + void CountDay(); + void CountHour(); + void CountMinute(); + void CountSecond(); + + void WriteDateTime(int num, u8 val); + void SaveDateTime(); + + void CmdRead(); + void CmdWrite(u8 val); + void ByteIn(u8 val); }; -bool Init(); -void DeInit(); -void Reset(); -void DoSavestate(Savestate* file); - -void GetState(StateData& state); -void SetState(StateData& state); -void GetDateTime(int& year, int& month, int& day, int& hour, int& minute, int& second); -void SetDateTime(int year, int month, int day, int hour, int minute, int second); -void ResetState(); - -void ScheduleTimer(bool first); -void ClockTimer(u32 param); - -u16 Read(); -void Write(u16 val, bool byte); - -} - #endif diff --git a/src/frontend/qt_sdl/ROMManager.cpp b/src/frontend/qt_sdl/ROMManager.cpp index 9b4b49c0..19ae9543 100644 --- a/src/frontend/qt_sdl/ROMManager.cpp +++ b/src/frontend/qt_sdl/ROMManager.cpp @@ -597,8 +597,8 @@ void SetDateTime() QDateTime hosttime = QDateTime::currentDateTime(); QDateTime time = hosttime.addSecs(Config::RTCOffset); - RTC::SetDateTime(time.date().year(), time.date().month(), time.date().day(), - time.time().hour(), time.time().minute(), time.time().second()); + NDS::RTC->SetDateTime(time.date().year(), time.date().month(), time.date().day(), + time.time().hour(), time.time().minute(), time.time().second()); } void Reset() diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index f6704779..0945de2a 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -361,7 +361,7 @@ void EmuThread::run() RTC::StateData state; Platform::FileRead(&state, sizeof(state), 1, file); Platform::CloseFile(file); - RTC::SetState(state); + NDS::RTC->SetState(state); } char melontitle[100]; @@ -666,7 +666,7 @@ void EmuThread::run() if (file) { RTC::StateData state; - RTC::GetState(state); + NDS::RTC->GetState(state); Platform::FileWrite(&state, sizeof(state), 1, file); Platform::CloseFile(file); }