implement DSi RTC commands

This commit is contained in:
Arisotura 2023-10-25 20:29:13 +02:00
parent 162ae37882
commit 0e56590af0
1 changed files with 225 additions and 95 deletions

View File

@ -21,6 +21,7 @@
#include <string.h>
#include <time.h>
#include "NDS.h"
#include "RTC.h"
#include "Platform.h"
@ -52,6 +53,13 @@ u8 Alarm2[3];
u8 ClockAdjust;
u8 FreeReg;
// DSi registers
u32 MinuteCount;
u8 FOUT1;
u8 FOUT2;
u8 AlarmDate1[3];
u8 AlarmDate2[3];
bool Init()
{
@ -79,6 +87,12 @@ void Reset()
memset(Alarm2, 0, sizeof(Alarm2));
ClockAdjust = 0;
FreeReg = 0;
MinuteCount = 0;
FOUT1 = 0;
FOUT2 = 0;
memset(AlarmDate1, 0, sizeof(AlarmDate1));
memset(AlarmDate2, 0, sizeof(AlarmDate2));
}
void DoSavestate(Savestate* file)
@ -103,6 +117,12 @@ void DoSavestate(Savestate* file)
file->VarArray(Alarm2, sizeof(Alarm2));
file->Var8(&ClockAdjust);
file->Var8(&FreeReg);
file->Var32(&MinuteCount);
file->Var8(&FOUT1);
file->Var8(&FOUT2);
file->VarArray(AlarmDate1, sizeof(AlarmDate1));
file->VarArray(AlarmDate2, sizeof(AlarmDate2));
}
@ -112,19 +132,9 @@ u8 BCD(u8 val)
}
void ByteIn(u8 val)
void CmdRead()
{
if (InputPos == 0)
{
if ((val & 0xF0) == 0x60)
{
u8 rev[16] = {0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6};
CurCmd = rev[val & 0xF];
}
else
CurCmd = val;
if (CurCmd & 0x80)
if ((CurCmd & 0x0F) == 0x06)
{
switch (CurCmd & 0x70)
{
@ -179,10 +189,55 @@ void ByteIn(u8 val)
case 0x30: Output[0] = ClockAdjust; break;
case 0x70: Output[0] = FreeReg; break;
}
return;
}
else if ((CurCmd & 0x0F) == 0x0E)
{
if (NDS::ConsoleType != 1)
{
Log(LogLevel::Debug, "RTC: unknown read command %02X\n", CurCmd);
return;
}
switch (CurCmd & 0x70)
{
case 0x00:
Output[0] = (MinuteCount >> 16) & 0xFF;
Output[1] = (MinuteCount >> 8) & 0xFF;
Output[2] = MinuteCount & 0xFF;
break;
case 0x40: Output[0] = FOUT1; break;
case 0x20: Output[0] = FOUT2; break;
case 0x10:
Output[0] = AlarmDate1[0];
Output[1] = AlarmDate1[1];
Output[2] = AlarmDate1[2];
break;
case 0x50:
Output[0] = AlarmDate2[0];
Output[1] = AlarmDate2[1];
Output[2] = AlarmDate2[2];
break;
default:
Log(LogLevel::Debug, "RTC: unknown read command %02X\n", CurCmd);
break;
}
return;
}
Log(LogLevel::Debug, "RTC: unknown read command %02X\n", CurCmd);
}
void CmdWrite(u8 val)
{
if ((CurCmd & 0x0F) == 0x06)
{
switch (CurCmd & 0x70)
{
case 0x00:
@ -225,6 +280,81 @@ void ByteIn(u8 val)
if (InputPos == 1) FreeReg = val;
break;
}
return;
}
else if ((CurCmd & 0x0F) == 0x0E)
{
if (NDS::ConsoleType != 1)
{
Log(LogLevel::Debug, "RTC: unknown write command %02X\n", CurCmd);
return;
}
switch (CurCmd & 0x70)
{
case 0x00:
Log(LogLevel::Debug, "RTC: trying to write read-only minute counter\n");
break;
case 0x40:
if (InputPos == 1) FOUT1 = val;
break;
case 0x20:
if (InputPos == 1) FOUT2 = val;
break;
case 0x10:
if (InputPos <= 3) AlarmDate1[InputPos-1] = val;
break;
case 0x50:
if (InputPos <= 3) AlarmDate2[InputPos-1] = val;
break;
default:
Log(LogLevel::Debug, "RTC: unknown write command %02X\n", CurCmd);
break;
}
return;
}
Log(LogLevel::Debug, "RTC: unknown write command %02X\n", CurCmd);
}
void ByteIn(u8 val)
{
if (InputPos == 0)
{
if ((val & 0xF0) == 0x60)
{
u8 rev[16] = {0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6};
CurCmd = rev[val & 0xF];
}
else
CurCmd = val;
if (NDS::ConsoleType == 1)
{
// for DSi: handle extra commands
if (((CurCmd & 0xF0) == 0x70) && ((CurCmd & 0xFE) != 0x76))
{
u8 rev[16] = {0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE};
CurCmd = rev[CurCmd & 0xF];
}
}
if (CurCmd & 0x80)
{
CmdRead();
}
return;
}
CmdWrite(val);
}