convert RTC to OOP

This commit is contained in:
Arisotura 2023-11-03 21:20:09 +01:00
parent 440b356674
commit e4f4e94694
6 changed files with 138 additions and 109 deletions

View File

@ -179,6 +179,7 @@ u16 KeyCnt[2];
u16 RCnt; u16 RCnt;
SPIHost* SPI; SPIHost* SPI;
class RTC* RTC;
bool Running; bool Running;
@ -218,12 +219,12 @@ bool Init()
DMAs[7] = new DMA(1, 3); DMAs[7] = new DMA(1, 3);
SPI = new SPIHost(); SPI = new SPIHost();
RTC = new class RTC();
if (!NDSCart::Init()) return false; if (!NDSCart::Init()) return false;
if (!GBACart::Init()) return false; if (!GBACart::Init()) return false;
if (!GPU::Init()) return false; if (!GPU::Init()) return false;
if (!SPU::Init()) return false; if (!SPU::Init()) return false;
if (!RTC::Init()) return false;
if (!Wifi::Init()) return false; if (!Wifi::Init()) return false;
if (!DSi::Init()) return false; if (!DSi::Init()) return false;
@ -254,11 +255,13 @@ void DeInit()
delete SPI; delete SPI;
SPI = nullptr; SPI = nullptr;
delete RTC;
RTC = nullptr;
NDSCart::DeInit(); NDSCart::DeInit();
GBACart::DeInit(); GBACart::DeInit();
GPU::DeInit(); GPU::DeInit();
SPU::DeInit(); SPU::DeInit();
RTC::DeInit();
Wifi::DeInit(); Wifi::DeInit();
DSi::DeInit(); DSi::DeInit();
@ -647,7 +650,7 @@ void Reset()
GPU::Reset(); GPU::Reset();
SPU::Reset(); SPU::Reset();
SPI->Reset(); SPI->Reset();
RTC::Reset(); RTC->Reset();
Wifi::Reset(); Wifi::Reset();
// TODO: move the SOUNDBIAS/degrade logic to SPU? // TODO: move the SOUNDBIAS/degrade logic to SPU?
@ -849,7 +852,7 @@ bool DoSavestate(Savestate* file)
GPU::DoSavestate(file); GPU::DoSavestate(file);
SPU::DoSavestate(file); SPU::DoSavestate(file);
SPI->DoSavestate(file); SPI->DoSavestate(file);
RTC::DoSavestate(file); RTC->DoSavestate(file);
Wifi::DoSavestate(file); Wifi::DoSavestate(file);
if (ConsoleType == 1) if (ConsoleType == 1)
@ -3866,7 +3869,7 @@ u8 ARM7IORead8(u32 addr)
case 0x04000136: return (KeyInput >> 16) & 0xFF; case 0x04000136: return (KeyInput >> 16) & 0xFF;
case 0x04000137: return KeyInput >> 24; case 0x04000137: return KeyInput >> 24;
case 0x04000138: return RTC::Read() & 0xFF; case 0x04000138: return RTC->Read() & 0xFF;
case 0x040001A2: case 0x040001A2:
if (ExMemCnt[0] & (1<<11)) if (ExMemCnt[0] & (1<<11))
@ -3957,7 +3960,7 @@ u16 ARM7IORead16(u32 addr)
case 0x04000134: return RCnt; case 0x04000134: return RCnt;
case 0x04000136: return KeyInput >> 16; case 0x04000136: return KeyInput >> 16;
case 0x04000138: return RTC::Read(); case 0x04000138: return RTC->Read();
case 0x04000180: return IPCSync7; case 0x04000180: return IPCSync7;
case 0x04000184: case 0x04000184:
@ -4047,7 +4050,7 @@ u32 ARM7IORead32(u32 addr)
case 0x04000130: return (KeyInput & 0xFFFF) | (KeyCnt[1] << 16); case 0x04000130: return (KeyInput & 0xFFFF) | (KeyCnt[1] << 16);
case 0x04000134: return RCnt | (KeyInput & 0xFFFF0000); case 0x04000134: return RCnt | (KeyInput & 0xFFFF0000);
case 0x04000138: return RTC::Read(); case 0x04000138: return RTC->Read();
case 0x04000180: return IPCSync7; case 0x04000180: return IPCSync7;
case 0x04000184: return ARM7IORead16(addr); case 0x04000184: return ARM7IORead16(addr);
@ -4139,7 +4142,7 @@ void ARM7IOWrite8(u32 addr, u8 val)
RCnt = (RCnt & 0x00FF) | (val << 8); RCnt = (RCnt & 0x00FF) | (val << 8);
return; return;
case 0x04000138: RTC::Write(val, true); return; case 0x04000138: RTC->Write(val, true); return;
case 0x04000188: case 0x04000188:
ARM7IOWrite32(addr, val | (val << 8) | (val << 16) | (val << 24)); 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 0x04000132: KeyCnt[1] = val; return;
case 0x04000134: RCnt = val; return; case 0x04000134: RCnt = val; return;
case 0x04000138: RTC::Write(val, false); return; case 0x04000138: RTC->Write(val, false); return;
case 0x04000180: case 0x04000180:
IPCSync9 &= 0xFFF0; IPCSync9 &= 0xFFF0;
@ -4395,7 +4398,7 @@ void ARM7IOWrite32(u32 addr, u32 val)
case 0x04000130: KeyCnt[1] = val >> 16; return; case 0x04000130: KeyCnt[1] = val >> 16; return;
case 0x04000134: RCnt = val & 0xFFFF; 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 0x04000180:
case 0x04000184: case 0x04000184:

View File

@ -31,6 +31,7 @@
//#define DEBUG_CHECK_DESYNC //#define DEBUG_CHECK_DESYNC
class SPIHost; class SPIHost;
class RTC;
namespace NDS namespace NDS
{ {
@ -249,6 +250,7 @@ extern u32 KeyInput;
extern u16 RCnt; extern u16 RCnt;
extern SPIHost* SPI; extern SPIHost* SPI;
extern class RTC* RTC;
const u32 ARM7WRAMSize = 0x10000; const u32 ARM7WRAMSize = 0x10000;
extern u8* ARM7WRAM; extern u8* ARM7WRAM;

View File

@ -24,52 +24,29 @@
using Platform::Log; using Platform::Log;
using Platform::LogLevel; 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); 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(); ResetState();
// indicate the power was off // indicate the power was off
// this will be changed if a previously saved RTC state is loaded // this will be changed if a previously saved RTC state is loaded
State.StatusReg1 = 0x80; State.StatusReg1 = 0x80;
return true;
} }
void DeInit() RTC::~RTC()
{ {
NDS::UnregisterEventFunc(NDS::Event_RTC, 0); NDS::UnregisterEventFunc(NDS::Event_RTC, 0);
} }
void Reset() void RTC::Reset()
{ {
Input = 0; Input = 0;
InputBit = 0; InputBit = 0;
@ -84,7 +61,7 @@ void Reset()
ScheduleTimer(true); ScheduleTimer(true);
} }
void DoSavestate(Savestate* file) void RTC::DoSavestate(Savestate* file)
{ {
file->Section("RTC."); 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); return (val % 10) | ((val / 10) << 4);
} }
u8 FromBCD(u8 val) u8 RTC::FromBCD(u8 val)
{ {
return (val & 0xF) + ((val >> 4) * 10); return (val & 0xF) + ((val >> 4) * 10);
} }
u8 BCDIncrement(u8 val) u8 RTC::BCDIncrement(u8 val)
{ {
val++; val++;
if ((val & 0x0F) >= 0x0A) if ((val & 0x0F) >= 0x0A)
@ -127,7 +104,7 @@ u8 BCDIncrement(u8 val)
return 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) if (val < vmin || val > vmax)
val = vmin; 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)); memcpy(&state, &State, sizeof(State));
} }
void SetState(StateData& state) void RTC::SetState(StateData& state)
{ {
memcpy(&State, &state, sizeof(State)); memcpy(&State, &state, sizeof(State));
@ -155,7 +132,7 @@ void SetState(StateData& state)
WriteDateTime(i+1, State.DateTime[i]); 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 = FromBCD(State.DateTime[0]);
year += 2000; 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); 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}; 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; State.StatusReg1 &= ~0x80;
} }
void ResetState() void RTC::ResetState()
{ {
memset(&State, 0, sizeof(State)); memset(&State, 0, sizeof(State));
State.DateTime[1] = 1; State.DateTime[1] = 1;
@ -234,7 +211,7 @@ void ResetState()
} }
void SetIRQ(u8 irq) void RTC::SetIRQ(u8 irq)
{ {
u8 oldstat = State.IRQFlag; u8 oldstat = State.IRQFlag;
State.IRQFlag |= irq; State.IRQFlag |= irq;
@ -250,12 +227,12 @@ void SetIRQ(u8 irq)
} }
} }
void ClearIRQ(u8 irq) void RTC::ClearIRQ(u8 irq)
{ {
State.IRQFlag &= ~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 // 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; u8 numdays;
@ -438,12 +415,12 @@ u8 DaysInMonth()
return numdays; return numdays;
} }
void CountYear() void RTC::CountYear()
{ {
State.DateTime[0] = BCDIncrement(State.DateTime[0]); State.DateTime[0] = BCDIncrement(State.DateTime[0]);
} }
void CountMonth() void RTC::CountMonth()
{ {
State.DateTime[1] = BCDIncrement(State.DateTime[1]); State.DateTime[1] = BCDIncrement(State.DateTime[1]);
if (State.DateTime[1] > 0x12) if (State.DateTime[1] > 0x12)
@ -453,7 +430,7 @@ void CountMonth()
} }
} }
void CheckEndOfMonth() void RTC::CheckEndOfMonth()
{ {
if (State.DateTime[2] > DaysInMonth()) if (State.DateTime[2] > DaysInMonth())
{ {
@ -462,7 +439,7 @@ void CheckEndOfMonth()
} }
} }
void CountDay() void RTC::CountDay()
{ {
// day-of-week counter // day-of-week counter
State.DateTime[3]++; State.DateTime[3]++;
@ -474,7 +451,7 @@ void CountDay()
CheckEndOfMonth(); CheckEndOfMonth();
} }
void CountHour() void RTC::CountHour()
{ {
u8 hour = BCDIncrement(State.DateTime[4] & 0x3F); u8 hour = BCDIncrement(State.DateTime[4] & 0x3F);
u8 pm = State.DateTime[4] & 0x40; u8 pm = State.DateTime[4] & 0x40;
@ -506,7 +483,7 @@ void CountHour()
State.DateTime[4] = hour | pm; State.DateTime[4] = hour | pm;
} }
void CountMinute() void RTC::CountMinute()
{ {
State.MinuteCount++; State.MinuteCount++;
State.DateTime[5] = BCDIncrement(State.DateTime[5]); State.DateTime[5] = BCDIncrement(State.DateTime[5]);
@ -520,7 +497,7 @@ void CountMinute()
ProcessIRQ(0); ProcessIRQ(0);
} }
void CountSecond() void RTC::CountSecond()
{ {
State.DateTime[6] = BCDIncrement(State.DateTime[6]); State.DateTime[6] = BCDIncrement(State.DateTime[6]);
if (State.DateTime[6] >= 0x60) if (State.DateTime[6] >= 0x60)
@ -531,7 +508,7 @@ void CountSecond()
} }
void ScheduleTimer(bool first) void RTC::ScheduleTimer(bool first)
{ {
if (first) TimerError = 0; if (first) TimerError = 0;
@ -544,7 +521,7 @@ void ScheduleTimer(bool first)
NDS::ScheduleEvent(NDS::Event_RTC, !first, delay, 0, 0); NDS::ScheduleEvent(NDS::Event_RTC, !first, delay, 0, 0);
} }
void ClockTimer(u32 param) void RTC::ClockTimer(u32 param)
{ {
ClockCount++; ClockCount++;
@ -565,7 +542,7 @@ void ClockTimer(u32 param)
} }
void WriteDateTime(int num, u8 val) void RTC::WriteDateTime(int num, u8 val)
{ {
switch (num) switch (num)
{ {
@ -619,14 +596,14 @@ void WriteDateTime(int num, u8 val)
} }
} }
void SaveDateTime() void RTC::SaveDateTime()
{ {
int y, m, d, h, i, s; int y, m, d, h, i, s;
GetDateTime(y, m, d, h, i, s); GetDateTime(y, m, d, h, i, s);
Platform::WriteDateTime(y, m, d, h, i, s); Platform::WriteDateTime(y, m, d, h, i, s);
} }
void CmdRead() void RTC::CmdRead()
{ {
if ((CurCmd & 0x0F) == 0x06) if ((CurCmd & 0x0F) == 0x06)
{ {
@ -704,7 +681,7 @@ void CmdRead()
Log(LogLevel::Debug, "RTC: unknown read command %02X\n", CurCmd); Log(LogLevel::Debug, "RTC: unknown read command %02X\n", CurCmd);
} }
void CmdWrite(u8 val) void RTC::CmdWrite(u8 val)
{ {
if ((CurCmd & 0x0F) == 0x06) if ((CurCmd & 0x0F) == 0x06)
{ {
@ -861,7 +838,7 @@ void CmdWrite(u8 val)
Log(LogLevel::Debug, "RTC: unknown write command %02X\n", CurCmd); Log(LogLevel::Debug, "RTC: unknown write command %02X\n", CurCmd);
} }
void ByteIn(u8 val) void RTC::ByteIn(u8 val)
{ {
if (InputPos == 0) if (InputPos == 0)
{ {
@ -895,13 +872,13 @@ void ByteIn(u8 val)
} }
u16 Read() u16 RTC::Read()
{ {
//printf("RTC READ %04X\n", IO); //printf("RTC READ %04X\n", IO);
return IO; return IO;
} }
void Write(u16 val, bool byte) void RTC::Write(u16 val, bool byte)
{ {
if (byte) val |= (IO & 0xFF00); if (byte) val |= (IO & 0xFF00);
@ -963,5 +940,3 @@ void Write(u16 val, bool byte)
else else
IO = (IO & 0x0001) | (val & 0xFFFE); IO = (IO & 0x0001) | (val & 0xFFFE);
} }
}

121
src/RTC.h
View File

@ -22,46 +22,95 @@
#include "types.h" #include "types.h"
#include "Savestate.h" #include "Savestate.h"
namespace RTC class RTC
{ {
public:
struct StateData struct StateData
{ {
u8 StatusReg1; u8 StatusReg1;
u8 StatusReg2; u8 StatusReg2;
u8 DateTime[7]; u8 DateTime[7];
u8 Alarm1[3]; u8 Alarm1[3];
u8 Alarm2[3]; u8 Alarm2[3];
u8 ClockAdjust; u8 ClockAdjust;
u8 FreeReg; u8 FreeReg;
u8 IRQFlag; u8 IRQFlag;
// DSi registers // DSi registers
u32 MinuteCount; u32 MinuteCount;
u8 FOUT1; u8 FOUT1;
u8 FOUT2; u8 FOUT2;
u8 AlarmDate1[3]; u8 AlarmDate1[3];
u8 AlarmDate2[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 #endif

View File

@ -597,8 +597,8 @@ void SetDateTime()
QDateTime hosttime = QDateTime::currentDateTime(); QDateTime hosttime = QDateTime::currentDateTime();
QDateTime time = hosttime.addSecs(Config::RTCOffset); QDateTime time = hosttime.addSecs(Config::RTCOffset);
RTC::SetDateTime(time.date().year(), time.date().month(), time.date().day(), NDS::RTC->SetDateTime(time.date().year(), time.date().month(), time.date().day(),
time.time().hour(), time.time().minute(), time.time().second()); time.time().hour(), time.time().minute(), time.time().second());
} }
void Reset() void Reset()

View File

@ -361,7 +361,7 @@ void EmuThread::run()
RTC::StateData state; RTC::StateData state;
Platform::FileRead(&state, sizeof(state), 1, file); Platform::FileRead(&state, sizeof(state), 1, file);
Platform::CloseFile(file); Platform::CloseFile(file);
RTC::SetState(state); NDS::RTC->SetState(state);
} }
char melontitle[100]; char melontitle[100];
@ -666,7 +666,7 @@ void EmuThread::run()
if (file) if (file)
{ {
RTC::StateData state; RTC::StateData state;
RTC::GetState(state); NDS::RTC->GetState(state);
Platform::FileWrite(&state, sizeof(state), 1, file); Platform::FileWrite(&state, sizeof(state), 1, file);
Platform::CloseFile(file); Platform::CloseFile(file);
} }