diff --git a/include/kernel/handles.hpp b/include/kernel/handles.hpp index b038049f..e3ccf165 100644 --- a/include/kernel/handles.hpp +++ b/include/kernel/handles.hpp @@ -43,6 +43,7 @@ namespace KernelHandles { PTM_U, // PTM service (Used for accessing various console info, such as battery, shell and pedometer state) PTM_SYSM, // PTM system service PTM_PLAY, // PTM Play service, used for retrieving play history + PTM_GETS, // PTM RTC service (GetSystemTime) SOC, // Socket service SSL, // SSL service (Totally didn't expect that) Y2R, // Also does camera stuff diff --git a/include/services/ptm.hpp b/include/services/ptm.hpp index ae845725..7b2d48f2 100644 --- a/include/services/ptm.hpp +++ b/include/services/ptm.hpp @@ -13,16 +13,20 @@ class PTMService { const EmulatorConfig& config; // Service commands + void clearSoftwareClosedFlag(u32 messagePointer); void configureNew3DSCPU(u32 messagePointer); void getAdapterState(u32 messagePointer); void getBatteryChargeState(u32 messagePointer); void getBatteryLevel(u32 messagePointer); + void getSoftwareClosedFlag(u32 messagePointer); void getStepHistory(u32 messagePointer); void getStepHistoryAll(u32 messagePointer); + void getSystemTime(u32 messagePointer); void getTotalStepCount(u32 messagePointer); public: enum class Type { + GETS, // ptm:gets U, // ptm:u SYSM, // ptm:sysm PLAY, // ptm:play diff --git a/src/core/services/ptm.cpp b/src/core/services/ptm.cpp index 071fa012..46d1ffeb 100644 --- a/src/core/services/ptm.cpp +++ b/src/core/services/ptm.cpp @@ -11,11 +11,16 @@ namespace PTMCommands { GetStepHistoryAll = 0x000F0084, ConfigureNew3DSCPU = 0x08180040, + // ptm:gets functions + GetSystemTime = 0x04010000, + // ptm:play functions GetPlayHistory = 0x08070082, GetPlayHistoryStart = 0x08080000, GetPlayHistoryLength = 0x08090000, CalcPlayHistoryStart = 0x080B0080, + GetSoftwareClosedFlag = 0x080F0000, + ClearSoftwareClosedFlag = 0x08100000, }; } @@ -48,6 +53,19 @@ void PTMService::handleSyncRequest(u32 messagePointer, PTMService::Type type) { default: Helpers::panic("PTM PLAY service requested. Command: %08X\n", command); break; } + } else if (type == Type::GETS) { + switch (command) { + case PTMCommands::GetSystemTime: getSystemTime(messagePointer); break; + + default: Helpers::panic("PTM GETS service requested. Command: %08X\n", command); break; + } + } else if (type == Type::SYSM) { + switch (command) { + case PTMCommands::GetSoftwareClosedFlag: getSoftwareClosedFlag(messagePointer); break; + case PTMCommands::ClearSoftwareClosedFlag: clearSoftwareClosedFlag(messagePointer); break; + + default: Helpers::panic("PTM SYSM service requested. Command: %08X\n", command); break; + } } else { Helpers::panic("PTM service requested. Command: %08X\n", command); } @@ -103,4 +121,24 @@ void PTMService::configureNew3DSCPU(u32 messagePointer) { log("PTM::ConfigureNew3DSCPU [stubbed]\n"); mem.write32(messagePointer, IPC::responseHeader(0x818, 1, 0)); mem.write32(messagePointer + 4, Result::Success); +} + +void PTMService::getSystemTime(u32 messagePointer) { + log("PTM::GetSystemTime [stubbed]\n"); + mem.write32(messagePointer, IPC::responseHeader(0x401, 3, 0)); + mem.write32(messagePointer + 4, Result::Success); + mem.write64(messagePointer + 8, 0); // Milliseconds since 2000? +} + +void PTMService::getSoftwareClosedFlag(u32 messagePointer) { + log("PTM::GetSoftwareClosedFlag\n"); + mem.write32(messagePointer, IPC::responseHeader(0x80F, 2, 0)); + mem.write32(messagePointer + 4, Result::Success); + mem.write8(messagePointer + 8, 0); // Show software closed dialog +} + +void PTMService::clearSoftwareClosedFlag(u32 messagePointer) { + log("PTM::ClearSoftwareClosedFlag\n"); + mem.write32(messagePointer, IPC::responseHeader(0x810, 1, 0)); + mem.write32(messagePointer + 4, Result::Success); } \ No newline at end of file diff --git a/src/core/services/service_manager.cpp b/src/core/services/service_manager.cpp index 2a95b5c9..c3315b9e 100644 --- a/src/core/services/service_manager.cpp +++ b/src/core/services/service_manager.cpp @@ -130,6 +130,7 @@ static std::map serviceMap = { { "ptm:u", KernelHandles::PTM_U }, // TODO: ptm:u and ptm:sysm have very different command sets { "ptm:sysm", KernelHandles::PTM_SYSM }, { "ptm:play", KernelHandles::PTM_PLAY }, + { "ptm:gets", KernelHandles::PTM_GETS }, { "soc:U", KernelHandles::SOC }, { "ssl:C", KernelHandles::SSL }, { "y2r:u", KernelHandles::Y2R }, @@ -229,6 +230,7 @@ void ServiceManager::sendCommandToService(u32 messagePointer, Handle handle) { case KernelHandles::NEWS_U: news_u.handleSyncRequest(messagePointer); break; case KernelHandles::NS_S: Helpers::panic("Unimplemented SendSyncRequest to ns:s"); break; case KernelHandles::NWM_UDS: nwm_uds.handleSyncRequest(messagePointer); break; + case KernelHandles::PTM_GETS: ptm.handleSyncRequest(messagePointer, PTMService::Type::GETS); break; case KernelHandles::PTM_PLAY: ptm.handleSyncRequest(messagePointer, PTMService::Type::PLAY); break; case KernelHandles::PTM_SYSM: ptm.handleSyncRequest(messagePointer, PTMService::Type::SYSM); break; case KernelHandles::PTM_U: ptm.handleSyncRequest(messagePointer, PTMService::Type::U); break;