mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-07-14 11:17:08 +12:00
Long overdue clang-format pass on most of the project (#773)
Some checks are pending
Android Build / x64 (release) (push) Waiting to run
Android Build / arm64 (release) (push) Waiting to run
HTTP Server Build / build (push) Waiting to run
Hydra Core Build / Windows (push) Waiting to run
Hydra Core Build / MacOS (push) Waiting to run
Hydra Core Build / Linux (push) Waiting to run
Hydra Core Build / Android-x64 (push) Waiting to run
Hydra Core Build / ARM-Libretro (push) Waiting to run
Linux AppImage Build / build (push) Waiting to run
Linux Build / build (push) Waiting to run
MacOS Build / MacOS-arm64 (push) Waiting to run
MacOS Build / MacOS-x86_64 (push) Waiting to run
MacOS Build / MacOS-Universal (push) Blocked by required conditions
Qt Build / Windows (push) Waiting to run
Qt Build / MacOS-arm64 (push) Waiting to run
Qt Build / MacOS-x86_64 (push) Waiting to run
Qt Build / MacOS-Universal (push) Blocked by required conditions
Qt Build / Linux (push) Waiting to run
Windows Build / build (push) Waiting to run
iOS Simulator Build / build (push) Waiting to run
Some checks are pending
Android Build / x64 (release) (push) Waiting to run
Android Build / arm64 (release) (push) Waiting to run
HTTP Server Build / build (push) Waiting to run
Hydra Core Build / Windows (push) Waiting to run
Hydra Core Build / MacOS (push) Waiting to run
Hydra Core Build / Linux (push) Waiting to run
Hydra Core Build / Android-x64 (push) Waiting to run
Hydra Core Build / ARM-Libretro (push) Waiting to run
Linux AppImage Build / build (push) Waiting to run
Linux Build / build (push) Waiting to run
MacOS Build / MacOS-arm64 (push) Waiting to run
MacOS Build / MacOS-x86_64 (push) Waiting to run
MacOS Build / MacOS-Universal (push) Blocked by required conditions
Qt Build / Windows (push) Waiting to run
Qt Build / MacOS-arm64 (push) Waiting to run
Qt Build / MacOS-x86_64 (push) Waiting to run
Qt Build / MacOS-Universal (push) Blocked by required conditions
Qt Build / Linux (push) Waiting to run
Windows Build / build (push) Waiting to run
iOS Simulator Build / build (push) Waiting to run
This commit is contained in:
parent
d1f4ae2911
commit
8e20bd6220
65 changed files with 13445 additions and 26224 deletions
|
@ -1,4 +1,5 @@
|
|||
#include "services/act.hpp"
|
||||
|
||||
#include "ipc.hpp"
|
||||
|
||||
namespace ACTCommands {
|
||||
|
@ -33,7 +34,7 @@ void ACTService::initialize(u32 messagePointer) {
|
|||
|
||||
void ACTService::generateUUID(u32 messagePointer) {
|
||||
log("ACT::GenerateUUID (stubbed)\n");
|
||||
|
||||
|
||||
// TODO: The header is probably wrong
|
||||
mem.write32(messagePointer, IPC::responseHeader(0xD, 1, 0));
|
||||
mem.write32(messagePointer + 4, Result::Success);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "services/am.hpp"
|
||||
|
||||
#include "ipc.hpp"
|
||||
|
||||
namespace AMCommands {
|
||||
|
@ -22,19 +23,19 @@ void AMService::handleSyncRequest(u32 messagePointer) {
|
|||
}
|
||||
|
||||
void AMService::listTitleInfo(u32 messagePointer) {
|
||||
log("AM::ListDLCOrLicenseTicketInfos\n"); // Yes this is the actual name
|
||||
log("AM::ListDLCOrLicenseTicketInfos\n"); // Yes this is the actual name
|
||||
u32 ticketCount = mem.read32(messagePointer + 4);
|
||||
u64 titleID = mem.read64(messagePointer + 8);
|
||||
u32 pointer = mem.read32(messagePointer + 24);
|
||||
|
||||
for (u32 i = 0; i < ticketCount; i++) {
|
||||
mem.write64(pointer, titleID); // Title ID
|
||||
mem.write64(pointer + 8, 0); // Ticket ID
|
||||
mem.write16(pointer + 16, 0); // Version
|
||||
mem.write16(pointer + 18, 0); // Padding
|
||||
mem.write32(pointer + 20, 0); // Size
|
||||
mem.write64(pointer, titleID); // Title ID
|
||||
mem.write64(pointer + 8, 0); // Ticket ID
|
||||
mem.write16(pointer + 16, 0); // Version
|
||||
mem.write16(pointer + 18, 0); // Padding
|
||||
mem.write32(pointer + 20, 0); // Size
|
||||
|
||||
pointer += 24; // = sizeof(TicketInfo)
|
||||
pointer += 24; // = sizeof(TicketInfo)
|
||||
}
|
||||
|
||||
mem.write32(messagePointer, IPC::responseHeader(0x1007, 2, 2));
|
||||
|
|
|
@ -6,6 +6,4 @@ void AmiiboDevice::reset() {
|
|||
}
|
||||
|
||||
// Load amiibo information from our raw 540 byte array
|
||||
void AmiiboDevice::loadFromRaw() {
|
||||
|
||||
}
|
||||
void AmiiboDevice::loadFromRaw() {}
|
|
@ -1,10 +1,11 @@
|
|||
#include "services/apt.hpp"
|
||||
#include "ipc.hpp"
|
||||
#include "kernel.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
#include "ipc.hpp"
|
||||
#include "kernel.hpp"
|
||||
|
||||
namespace APTCommands {
|
||||
enum : u32 {
|
||||
GetLockHandle = 0x00010040,
|
||||
|
@ -84,8 +85,7 @@ void APTService::appletUtility(u32 messagePointer) {
|
|||
u32 outputSize = mem.read32(messagePointer + 12);
|
||||
u32 inputPointer = mem.read32(messagePointer + 20);
|
||||
|
||||
log("APT::AppletUtility(utility = %d, input size = %x, output size = %x, inputPointer = %08X)\n", utility, inputSize, outputSize,
|
||||
inputPointer);
|
||||
log("APT::AppletUtility(utility = %d, input size = %x, output size = %x, inputPointer = %08X)\n", utility, inputSize, outputSize, inputPointer);
|
||||
|
||||
std::vector<u8> out(outputSize);
|
||||
const u32 outputBuffer = mem.read32(messagePointer + 0x104);
|
||||
|
@ -111,8 +111,9 @@ void APTService::getAppletInfo(u32 messagePointer) {
|
|||
mem.write32(messagePointer, IPC::responseHeader(0x06, 7, 0));
|
||||
mem.write32(messagePointer + 4, Result::Success);
|
||||
|
||||
mem.write8(messagePointer + 20, 1); // 1 = registered
|
||||
mem.write8(messagePointer + 24, 1); // 1 = loaded
|
||||
mem.write8(messagePointer + 20, 1); // 1 = registered
|
||||
mem.write8(messagePointer + 24, 1); // 1 = loaded
|
||||
|
||||
// TODO: The rest of this
|
||||
}
|
||||
|
||||
|
@ -122,7 +123,7 @@ void APTService::isRegistered(u32 messagePointer) {
|
|||
|
||||
mem.write32(messagePointer, IPC::responseHeader(0x09, 2, 0));
|
||||
mem.write32(messagePointer + 4, Result::Success);
|
||||
mem.write8(messagePointer + 8, 1); // Return that the app is always registered. This might break with home menu?
|
||||
mem.write8(messagePointer + 8, 1); // Return that the app is always registered. This might break with home menu?
|
||||
}
|
||||
|
||||
void APTService::preloadLibraryApplet(u32 messagePointer) {
|
||||
|
@ -178,7 +179,7 @@ void APTService::checkNew3DS(u32 messagePointer) {
|
|||
log("APT::CheckNew3DS\n");
|
||||
mem.write32(messagePointer, IPC::responseHeader(0x102, 2, 0));
|
||||
mem.write32(messagePointer + 4, Result::Success);
|
||||
mem.write8(messagePointer + 8, (model == ConsoleModel::New3DS) ? 1 : 0); // u8, Status (0 = Old 3DS, 1 = New 3DS)
|
||||
mem.write8(messagePointer + 8, (model == ConsoleModel::New3DS) ? 1 : 0); // u8, Status (0 = Old 3DS, 1 = New 3DS)
|
||||
}
|
||||
|
||||
// TODO: Figure out the slight way this differs from APT::CheckNew3DS
|
||||
|
@ -186,7 +187,7 @@ void APTService::checkNew3DSApp(u32 messagePointer) {
|
|||
log("APT::CheckNew3DSApp\n");
|
||||
mem.write32(messagePointer, IPC::responseHeader(0x101, 2, 0));
|
||||
mem.write32(messagePointer + 4, Result::Success);
|
||||
mem.write8(messagePointer + 8, (model == ConsoleModel::New3DS) ? 1 : 0); // u8, Status (0 = Old 3DS, 1 = New 3DS)
|
||||
mem.write8(messagePointer + 8, (model == ConsoleModel::New3DS) ? 1 : 0); // u8, Status (0 = Old 3DS, 1 = New 3DS)
|
||||
}
|
||||
|
||||
void APTService::enable(u32 messagePointer) {
|
||||
|
@ -207,14 +208,14 @@ void APTService::initialize(u32 messagePointer) {
|
|||
notificationEvent = kernel.makeEvent(ResetType::OneShot);
|
||||
resumeEvent = kernel.makeEvent(ResetType::OneShot);
|
||||
|
||||
kernel.signalEvent(resumeEvent.value()); // Seems to be signalled on startup
|
||||
kernel.signalEvent(resumeEvent.value()); // Seems to be signalled on startup
|
||||
}
|
||||
|
||||
mem.write32(messagePointer, IPC::responseHeader(0x2, 1, 3));
|
||||
mem.write32(messagePointer + 4, Result::Success);
|
||||
mem.write32(messagePointer + 8, 0x04000000); // Translation descriptor
|
||||
mem.write32(messagePointer + 12, notificationEvent.value()); // Notification Event Handle
|
||||
mem.write32(messagePointer + 16, resumeEvent.value()); // Resume Event Handle
|
||||
mem.write32(messagePointer + 8, 0x04000000); // Translation descriptor
|
||||
mem.write32(messagePointer + 12, notificationEvent.value()); // Notification Event Handle
|
||||
mem.write32(messagePointer + 16, resumeEvent.value()); // Resume Event Handle
|
||||
}
|
||||
|
||||
void APTService::inquireNotification(u32 messagePointer) {
|
||||
|
@ -234,11 +235,11 @@ void APTService::getLockHandle(u32 messagePointer) {
|
|||
}
|
||||
|
||||
mem.write32(messagePointer, IPC::responseHeader(0x1, 3, 2));
|
||||
mem.write32(messagePointer + 4, Result::Success); // Result code
|
||||
mem.write32(messagePointer + 8, 0); // AppletAttr
|
||||
mem.write32(messagePointer + 12, 0); // APT State (bit0 = Power Button State, bit1 = Order To Close State)
|
||||
mem.write32(messagePointer + 16, 0); // Translation descriptor
|
||||
mem.write32(messagePointer + 20, lockHandle.value()); // Lock handle
|
||||
mem.write32(messagePointer + 4, Result::Success); // Result code
|
||||
mem.write32(messagePointer + 8, 0); // AppletAttr
|
||||
mem.write32(messagePointer + 12, 0); // APT State (bit0 = Power Button State, bit1 = Order To Close State)
|
||||
mem.write32(messagePointer + 16, 0); // Translation descriptor
|
||||
mem.write32(messagePointer + 20, lockHandle.value()); // Lock handle
|
||||
}
|
||||
|
||||
// This apparently does nothing on the original kernel either?
|
||||
|
@ -254,7 +255,7 @@ void APTService::sendParameter(u32 messagePointer) {
|
|||
const u32 cmd = mem.read32(messagePointer + 12);
|
||||
const u32 paramSize = mem.read32(messagePointer + 16);
|
||||
|
||||
const u32 parameterHandle = mem.read32(messagePointer + 24); // What dis?
|
||||
const u32 parameterHandle = mem.read32(messagePointer + 24); // What dis?
|
||||
const u32 parameterPointer = mem.read32(messagePointer + 32);
|
||||
log("APT::SendParameter (source app = %X, dest app = %X, cmd = %X, size = %X)", sourceAppID, destAppID, cmd, paramSize);
|
||||
|
||||
|
@ -298,7 +299,9 @@ void APTService::receiveParameter(u32 messagePointer) {
|
|||
const u32 buffer = mem.read32(messagePointer + 0x100 + 4);
|
||||
log("APT::ReceiveParameter(app ID = %X, size = %04X)\n", app, size);
|
||||
|
||||
if (size > 0x1000) Helpers::panic("APT::ReceiveParameter with size > 0x1000");
|
||||
if (size > 0x1000) {
|
||||
Helpers::panic("APT::ReceiveParameter with size > 0x1000");
|
||||
}
|
||||
auto parameter = appletManager.receiveParameter();
|
||||
|
||||
mem.write32(messagePointer, IPC::responseHeader(0xD, 4, 4));
|
||||
|
@ -326,7 +329,9 @@ void APTService::glanceParameter(u32 messagePointer) {
|
|||
const u32 buffer = mem.read32(messagePointer + 0x100 + 4);
|
||||
log("APT::GlanceParameter(app ID = %X, size = %04X)\n", app, size);
|
||||
|
||||
if (size > 0x1000) Helpers::panic("APT::GlanceParameter with size > 0x1000");
|
||||
if (size > 0x1000) {
|
||||
Helpers::panic("APT::GlanceParameter with size > 0x1000");
|
||||
}
|
||||
auto parameter = appletManager.glanceParameter();
|
||||
|
||||
// TODO: Properly implement this. We currently stub it similar
|
||||
|
@ -355,8 +360,8 @@ void APTService::replySleepQuery(u32 messagePointer) {
|
|||
}
|
||||
|
||||
void APTService::setApplicationCpuTimeLimit(u32 messagePointer) {
|
||||
u32 fixed = mem.read32(messagePointer + 4); // MUST be 1.
|
||||
u32 percentage = mem.read32(messagePointer + 8); // CPU time percentage between 5% and 89%
|
||||
u32 fixed = mem.read32(messagePointer + 4); // MUST be 1.
|
||||
u32 percentage = mem.read32(messagePointer + 8); // CPU time percentage between 5% and 89%
|
||||
log("APT::SetApplicationCpuTimeLimit (percentage = %d%%)\n", percentage);
|
||||
|
||||
mem.write32(messagePointer, IPC::responseHeader(0x4F, 1, 0));
|
||||
|
@ -409,15 +414,16 @@ void APTService::theSmashBrosFunction(u32 messagePointer) {
|
|||
}
|
||||
|
||||
void APTService::getWirelessRebootInfo(u32 messagePointer) {
|
||||
const u32 size = mem.read32(messagePointer + 4); // Size of data to read
|
||||
const u32 size = mem.read32(messagePointer + 4); // Size of data to read
|
||||
log("APT::GetWirelessRebootInfo (size = %X)\n", size);
|
||||
|
||||
if (size > 0x10)
|
||||
if (size > 0x10) {
|
||||
Helpers::panic("APT::GetWirelessInfo with size > 0x10 bytes");
|
||||
}
|
||||
|
||||
mem.write32(messagePointer, IPC::responseHeader(0x45, 1, 2));
|
||||
mem.write32(messagePointer + 4, Result::Success);
|
||||
for (u32 i = 0; i < size; i++) {
|
||||
mem.write8(messagePointer + 0x104 + i, 0); // Temporarily stub this until we add SetWirelessRebootInfo
|
||||
mem.write8(messagePointer + 0x104 + i, 0); // Temporarily stub this until we add SetWirelessRebootInfo
|
||||
}
|
||||
}
|
||||
|
|
|
@ -194,6 +194,7 @@ void BOSSService::sendProperty(u32 messagePointer) {
|
|||
mem.write32(messagePointer, IPC::responseHeader(0x14, 1, 2));
|
||||
mem.write32(messagePointer + 4, Result::Success);
|
||||
mem.write32(messagePointer + 8, 0); // Read size
|
||||
|
||||
// TODO: Should this do anything else?
|
||||
}
|
||||
|
||||
|
|
|
@ -47,5 +47,5 @@ void CECDService::openAndRead(u32 messagePointer) {
|
|||
// TODO: We should implement this properly the time comes
|
||||
mem.write32(messagePointer, IPC::responseHeader(0x12, 2, 2));
|
||||
mem.write32(messagePointer + 4, Result::Success);
|
||||
mem.write32(messagePointer + 8, 0); // Bytes read
|
||||
mem.write32(messagePointer + 8, 0); // Bytes read
|
||||
}
|
|
@ -1,13 +1,14 @@
|
|||
#include "services/cfg.hpp"
|
||||
#include "services/dsp.hpp"
|
||||
#include "system_models.hpp"
|
||||
#include "ipc.hpp"
|
||||
|
||||
#include <array>
|
||||
#include <bit>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "ipc.hpp"
|
||||
#include "services/dsp.hpp"
|
||||
#include "system_models.hpp"
|
||||
|
||||
namespace CFGCommands {
|
||||
enum : u32 {
|
||||
GetConfigInfoBlk2 = 0x00010082,
|
||||
|
@ -101,7 +102,7 @@ void CFGService::getSystemModel(u32 messagePointer) {
|
|||
|
||||
mem.write32(messagePointer, IPC::responseHeader(0x05, 2, 0));
|
||||
mem.write32(messagePointer + 4, Result::Success);
|
||||
mem.write8(messagePointer + 8, SystemModel::Nintendo3DS); // TODO: Make this adjustable via GUI
|
||||
mem.write8(messagePointer + 8, SystemModel::Nintendo3DS); // TODO: Make this adjustable via GUI
|
||||
}
|
||||
|
||||
// Write a UTF16 string to 3DS memory starting at "pointer". Appends a null terminator.
|
||||
|
@ -111,16 +112,15 @@ void CFGService::writeStringU16(u32 pointer, const std::u16string& string) {
|
|||
pointer += 2;
|
||||
}
|
||||
|
||||
mem.write16(pointer, static_cast<u16>(u'\0')); // Null terminator
|
||||
mem.write16(pointer, static_cast<u16>(u'\0')); // Null terminator
|
||||
}
|
||||
|
||||
void CFGService::getConfigInfoBlk2(u32 messagePointer) {
|
||||
u32 size = mem.read32(messagePointer + 4);
|
||||
u32 blockID = mem.read32(messagePointer + 8);
|
||||
u32 output = mem.read32(messagePointer + 16); // Pointer to write the output data to
|
||||
u32 output = mem.read32(messagePointer + 16); // Pointer to write the output data to
|
||||
log("CFG::GetConfigInfoBlk2 (size = %X, block ID = %X, output pointer = %08X\n", size, blockID, output);
|
||||
|
||||
|
||||
getConfigInfo(output, blockID, size, 0x2);
|
||||
mem.write32(messagePointer, IPC::responseHeader(0x1, 1, 2));
|
||||
mem.write32(messagePointer + 4, Result::Success);
|
||||
|
@ -254,7 +254,7 @@ void CFGService::genUniqueConsoleHash(u32 messagePointer) {
|
|||
mem.write32(messagePointer + 4, Result::Success);
|
||||
// We need to implement hash generation & the SHA-256 digest properly later on. We have cryptopp so the hashing isn't too hard to do
|
||||
// Let's stub it for now
|
||||
mem.write32(messagePointer + 8, 0x33646D6F ^ salt); // Lower word of hash
|
||||
mem.write32(messagePointer + 8, 0x33646D6F ^ salt); // Lower word of hash
|
||||
mem.write32(messagePointer + 12, 0xA3534841 ^ salt); // Upper word of hash
|
||||
}
|
||||
|
||||
|
@ -303,13 +303,13 @@ void CFGService::getCountryCodeID(u32 messagePointer) {
|
|||
log("CFG::GetCountryCodeID (code = %04X)\n", characterCode);
|
||||
|
||||
mem.write32(messagePointer, IPC::responseHeader(0x0A, 2, 0));
|
||||
|
||||
|
||||
// If the character code is valid, return its table ID and a success code
|
||||
if (auto search = countryCodeToTableIDMap.find(characterCode); search != countryCodeToTableIDMap.end()) {
|
||||
mem.write32(messagePointer + 4, Result::Success);
|
||||
mem.write16(messagePointer + 8, search->second);
|
||||
}
|
||||
|
||||
|
||||
else {
|
||||
Helpers::warn("CFG::GetCountryCodeID: Invalid country code %X", characterCode);
|
||||
mem.write32(messagePointer + 4, Result::CFG::NotFound);
|
||||
|
@ -340,7 +340,7 @@ void CFGService::secureInfoGetByte101(u32 messagePointer) {
|
|||
|
||||
mem.write32(messagePointer, IPC::responseHeader(0x407, 2, 0));
|
||||
mem.write32(messagePointer + 4, Result::Success);
|
||||
mem.write8(messagePointer + 8, 0); // Secure info byte 0x101 is usually 0 according to 3DBrew
|
||||
mem.write8(messagePointer + 8, 0); // Secure info byte 0x101 is usually 0 according to 3DBrew
|
||||
}
|
||||
|
||||
void CFGService::getLocalFriendCodeSeed(u32 messagePointer) {
|
||||
|
@ -379,7 +379,7 @@ void CFGService::translateCountryInfo(u32 messagePointer) {
|
|||
// By default the translated code is the input
|
||||
u32 result = country;
|
||||
|
||||
if (direction == 0) { // Translate from version B to version A
|
||||
if (direction == 0) { // Translate from version B to version A
|
||||
switch (country) {
|
||||
case 0x6E040000: result = 0x6E030000; break;
|
||||
case 0x6E050000: result = 0x6E040000; break;
|
||||
|
@ -388,7 +388,7 @@ void CFGService::translateCountryInfo(u32 messagePointer) {
|
|||
case 0x6E030000: result = 0x6E070000; break;
|
||||
default: break;
|
||||
}
|
||||
} else if (direction == 1) { // Translate from version A to version B
|
||||
} else if (direction == 1) { // Translate from version A to version B
|
||||
switch (country) {
|
||||
case 0x6E030000: result = 0x6E040000; break;
|
||||
case 0x6E040000: result = 0x6E050000; break;
|
||||
|
@ -423,7 +423,7 @@ void CFGService::norInitialize(u32 messagePointer) {
|
|||
void CFGService::norReadData(u32 messagePointer) {
|
||||
log("CFG::NOR::ReadData\n");
|
||||
Helpers::warn("Unimplemented CFG::NOR::ReadData");
|
||||
|
||||
|
||||
mem.write32(messagePointer, IPC::responseHeader(0x5, 1, 0));
|
||||
mem.write32(messagePointer + 4, Result::Success);
|
||||
}
|
|
@ -36,8 +36,8 @@ void CSNDService::handleSyncRequest(u32 messagePointer) {
|
|||
|
||||
void CSNDService::acquireSoundChannels(u32 messagePointer) {
|
||||
log("CSND::AcquireSoundChannels\n");
|
||||
// The CSND service talks to the DSP using the DSP FIFO to negotiate what CSND channels are allocated to the DSP, and this seems to be channels 0-7 (usually). The rest are dedicated to CSND services.
|
||||
// https://www.3dbrew.org/wiki/CSND_Services
|
||||
// The CSND service talks to the DSP using the DSP FIFO to negotiate what CSND channels are allocated to the DSP, and this seems to be channels
|
||||
// 0-7 (usually). The rest are dedicated to CSND services. https://www.3dbrew.org/wiki/CSND_Services
|
||||
constexpr u32 csndChannelMask = 0xFFFFFF00;
|
||||
|
||||
mem.write32(messagePointer, IPC::responseHeader(0x5, 2, 0));
|
||||
|
@ -52,7 +52,8 @@ void CSNDService::initialize(u32 messagePointer) {
|
|||
const u32 offset2 = mem.read32(messagePointer + 16);
|
||||
const u32 offset3 = mem.read32(messagePointer + 20);
|
||||
|
||||
log("CSND::Initialize (Block size = %08X, offset0 = %X, offset1 = %X, offset2 = %X, offset3 = %X)\n", blockSize, offset0, offset1, offset2, offset3);
|
||||
log("CSND::Initialize (Block size = %08X, offset0 = %X, offset1 = %X, offset2 = %X, offset3 = %X)\n", blockSize, offset0, offset1, offset2,
|
||||
offset3);
|
||||
|
||||
// Align block size to 4KB. CSND shared memory block is currently stubbed to be 0x3000 == 12KB, so panic if this is more than requested
|
||||
blockSize = (blockSize + 0xFFF) & ~0xFFF;
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
#include "services/dlp_srvr.hpp"
|
||||
|
||||
#include "ipc.hpp"
|
||||
|
||||
namespace DlpSrvrCommands {
|
||||
enum : u32 {
|
||||
IsChild = 0x000E0040
|
||||
IsChild = 0x000E0040,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -22,5 +23,5 @@ void DlpSrvrService::isChild(u32 messagePointer) {
|
|||
|
||||
mem.write32(messagePointer, IPC::responseHeader(0x0E, 2, 0));
|
||||
mem.write32(messagePointer + 4, Result::Success);
|
||||
mem.write32(messagePointer + 8, 0); // We are responsible adults
|
||||
mem.write32(messagePointer + 8, 0); // We are responsible adults
|
||||
}
|
|
@ -36,7 +36,7 @@ namespace DSPCommands {
|
|||
namespace Result {
|
||||
enum : u32 {
|
||||
HeadphonesNotInserted = 0,
|
||||
HeadphonesInserted = 1
|
||||
HeadphonesInserted = 1,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -85,7 +85,7 @@ void DSPService::convertProcessAddressFromDspDram(u32 messagePointer) {
|
|||
|
||||
mem.write32(messagePointer, IPC::responseHeader(0xC, 2, 0));
|
||||
mem.write32(messagePointer + 4, Result::Success);
|
||||
mem.write32(messagePointer + 8, converted); // Converted address
|
||||
mem.write32(messagePointer + 8, converted); // Converted address
|
||||
}
|
||||
|
||||
void DSPService::loadComponent(u32 messagePointer) {
|
||||
|
@ -109,9 +109,9 @@ void DSPService::loadComponent(u32 messagePointer) {
|
|||
|
||||
mem.write32(messagePointer, IPC::responseHeader(0x11, 2, 2));
|
||||
mem.write32(messagePointer + 4, Result::Success);
|
||||
mem.write32(messagePointer + 8, 1); // Component loaded
|
||||
mem.write32(messagePointer + 8, 1); // Component loaded
|
||||
mem.write32(messagePointer + 12, (size << 4) | 0xA);
|
||||
mem.write32(messagePointer + 16, mem.read32(messagePointer + 20)); // Component buffer
|
||||
mem.write32(messagePointer + 16, mem.read32(messagePointer + 20)); // Component buffer
|
||||
}
|
||||
|
||||
void DSPService::unloadComponent(u32 messagePointer) {
|
||||
|
@ -136,7 +136,7 @@ void DSPService::readPipeIfPossible(u32 messagePointer) {
|
|||
}
|
||||
|
||||
mem.write32(messagePointer + 4, Result::Success);
|
||||
mem.write16(messagePointer + 8, u16(data.size())); // Number of bytes read
|
||||
mem.write16(messagePointer + 8, u16(data.size())); // Number of bytes read
|
||||
}
|
||||
|
||||
void DSPService::recvData(u32 messagePointer) {
|
||||
|
@ -168,12 +168,10 @@ DSPService::DSPEvent& DSPService::getEventRef(u32 type, u32 pipe) {
|
|||
case 1: return interrupt1;
|
||||
|
||||
case 2:
|
||||
if (pipe >= pipeCount)
|
||||
Helpers::panic("Tried to access the event of an invalid pipe");
|
||||
if (pipe >= pipeCount) Helpers::panic("Tried to access the event of an invalid pipe");
|
||||
return pipeEvents[pipe];
|
||||
|
||||
default:
|
||||
Helpers::panic("Unknown type for DSP::getEventRef");
|
||||
default: Helpers::panic("Unknown type for DSP::getEventRef");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -185,8 +183,8 @@ void DSPService::registerInterruptEvents(u32 messagePointer) {
|
|||
|
||||
// The event handle being 0 means we're removing an event
|
||||
if (eventHandle == 0) {
|
||||
DSPEvent& e = getEventRef(interrupt, channel); // Get event
|
||||
if (e.has_value()) { // Remove if it exists
|
||||
DSPEvent& e = getEventRef(interrupt, channel); // Get event
|
||||
if (e.has_value()) { // Remove if it exists
|
||||
totalEventCount--;
|
||||
e = std::nullopt;
|
||||
}
|
||||
|
@ -227,7 +225,7 @@ void DSPService::getSemaphoreEventHandle(u32 messagePointer) {
|
|||
mem.write32(messagePointer, IPC::responseHeader(0x16, 1, 2));
|
||||
mem.write32(messagePointer + 4, Result::Success);
|
||||
// TODO: Translation descriptor here?
|
||||
mem.write32(messagePointer + 12, semaphoreEvent.value()); // Semaphore event handle
|
||||
mem.write32(messagePointer + 12, semaphoreEvent.value()); // Semaphore event handle
|
||||
kernel.signalEvent(semaphoreEvent.value());
|
||||
}
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ void FRDService::handleSyncRequest(u32 messagePointer, FRDService::Type type) {
|
|||
case FRDCommands::SetNotificationMask: setNotificationMask(messagePointer); break;
|
||||
case FRDCommands::UpdateGameModeDescription: updateGameModeDescription(messagePointer); break;
|
||||
|
||||
default:
|
||||
default:
|
||||
// FRD:A functions
|
||||
if (type == Type::A) {
|
||||
switch (command) {
|
||||
|
@ -89,17 +89,17 @@ void FRDService::getMyFriendKey(u32 messagePointer) {
|
|||
|
||||
mem.write32(messagePointer, IPC::responseHeader(0x5, 5, 0));
|
||||
mem.write32(messagePointer + 4, Result::Success);
|
||||
mem.write32(messagePointer + 8, 0); // Principal ID
|
||||
mem.write32(messagePointer + 12, 0); // Padding (?)
|
||||
mem.write32(messagePointer + 16, 0); // Local friend code
|
||||
mem.write32(messagePointer + 8, 0); // Principal ID
|
||||
mem.write32(messagePointer + 12, 0); // Padding (?)
|
||||
mem.write32(messagePointer + 16, 0); // Local friend code
|
||||
mem.write32(messagePointer + 20, 0);
|
||||
}
|
||||
|
||||
void FRDService::getFriendKeyList(u32 messagePointer) {
|
||||
log("FRD::GetFriendKeyList\n");
|
||||
|
||||
const u32 count = mem.read32(messagePointer + 8); // From what I understand this is a cap on the number of keys to receive?
|
||||
constexpr u32 friendCount = 0; // And this should be the number of friends whose keys were actually received?
|
||||
const u32 count = mem.read32(messagePointer + 8); // From what I understand this is a cap on the number of keys to receive?
|
||||
constexpr u32 friendCount = 0; // And this should be the number of friends whose keys were actually received?
|
||||
|
||||
mem.write32(messagePointer, IPC::responseHeader(0x11, 2, 2));
|
||||
mem.write32(messagePointer + 4, Result::Success);
|
||||
|
@ -147,11 +147,11 @@ void FRDService::getFriendAttributeFlags(u32 messagePointer) {
|
|||
}
|
||||
|
||||
void FRDService::getMyPresence(u32 messagePointer) {
|
||||
static constexpr u32 presenceSize = 0x12C; // A presence seems to be 12C bytes of data, not sure what it contains
|
||||
static constexpr u32 presenceSize = 0x12C; // A presence seems to be 12C bytes of data, not sure what it contains
|
||||
log("FRD::GetMyPresence\n");
|
||||
u32 buffer = mem.read32(messagePointer + 0x104); // Buffer to write presence info to.
|
||||
u32 buffer = mem.read32(messagePointer + 0x104); // Buffer to write presence info to.
|
||||
|
||||
for (u32 i = 0; i < presenceSize; i += 4) { // Clear presence info with 0s for now
|
||||
for (u32 i = 0; i < presenceSize; i += 4) { // Clear presence info with 0s for now
|
||||
mem.write32(buffer + i, 0);
|
||||
}
|
||||
|
||||
|
@ -168,15 +168,15 @@ void FRDService::getFriendPresence(u32 messagePointer) {
|
|||
}
|
||||
|
||||
void FRDService::getMyProfile(u32 messagePointer) {
|
||||
mem.write32(messagePointer, IPC::responseHeader(0x7, 3, 0)); // Not sure if the header here has the correct # of responses?
|
||||
mem.write32(messagePointer, IPC::responseHeader(0x7, 3, 0)); // Not sure if the header here has the correct # of responses?
|
||||
mem.write32(messagePointer + 4, Result::Success);
|
||||
|
||||
// TODO: Should maybe make these user-configurable. Not super important though
|
||||
mem.write8(messagePointer + 8, static_cast<u8>(Regions::USA)); // Region
|
||||
mem.write8(messagePointer + 9, static_cast<u8>(CountryCodes::US)); // Country
|
||||
mem.write8(messagePointer + 10, 2); // Area (this should be Washington)
|
||||
mem.write8(messagePointer + 11, static_cast<u8>(LanguageCodes::English)); // Language
|
||||
mem.write8(messagePointer + 12, 2); // Platform (always 2 for CTR)
|
||||
mem.write8(messagePointer + 8, static_cast<u8>(Regions::USA)); // Region
|
||||
mem.write8(messagePointer + 9, static_cast<u8>(CountryCodes::US)); // Country
|
||||
mem.write8(messagePointer + 10, 2); // Area (this should be Washington)
|
||||
mem.write8(messagePointer + 11, static_cast<u8>(LanguageCodes::English)); // Language
|
||||
mem.write8(messagePointer + 12, 2); // Platform (always 2 for CTR)
|
||||
|
||||
// Padding
|
||||
mem.write8(messagePointer + 13, 0);
|
||||
|
@ -226,7 +226,7 @@ void FRDService::getMyMii(u32 messagePointer) {
|
|||
void FRDService::getMyFavoriteGame(u32 messagePointer) {
|
||||
log("FRD::GetMyFavoriteGame (stubbed)\n");
|
||||
constexpr u64 titleID = 0;
|
||||
|
||||
|
||||
mem.write32(messagePointer, IPC::responseHeader(0xD, 3, 0));
|
||||
mem.write32(messagePointer + 4, Result::Success);
|
||||
mem.write64(messagePointer + 8, titleID);
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
#include "services/fs.hpp"
|
||||
#include "kernel/kernel.hpp"
|
||||
|
||||
#include "io_file.hpp"
|
||||
#include "ipc.hpp"
|
||||
#include "kernel/kernel.hpp"
|
||||
#include "result/result.hpp"
|
||||
|
||||
#ifdef CreateFile // windows.h defines CreateFile & DeleteFile because of course it does.
|
||||
#ifdef CreateFile // windows.h defines CreateFile & DeleteFile because of course it does.
|
||||
#undef CreateDirectory
|
||||
#undef CreateFile
|
||||
#undef DeleteFile
|
||||
|
@ -47,21 +48,18 @@ namespace FSCommands {
|
|||
};
|
||||
}
|
||||
|
||||
void FSService::reset() {
|
||||
priority = 0;
|
||||
}
|
||||
void FSService::reset() { priority = 0; }
|
||||
|
||||
// Creates directories for NAND, ExtSaveData, etc if they don't already exist. Should be executed after loading a new ROM.
|
||||
void FSService::initializeFilesystem() {
|
||||
const auto sdmcPath = IOFile::getAppData() / "SDMC"; // Create SDMC directory
|
||||
const auto sdmcPath = IOFile::getAppData() / "SDMC"; // Create SDMC directory
|
||||
const auto nandSharedpath = IOFile::getAppData() / ".." / "SharedFiles" / "NAND";
|
||||
|
||||
const auto savePath = IOFile::getAppData() / "SaveData"; // Create SaveData
|
||||
const auto formatPath = IOFile::getAppData() / "FormatInfo"; // Create folder for storing archive formatting info
|
||||
const auto savePath = IOFile::getAppData() / "SaveData"; // Create SaveData
|
||||
const auto formatPath = IOFile::getAppData() / "FormatInfo"; // Create folder for storing archive formatting info
|
||||
const auto systemSaveDataPath = IOFile::getAppData() / ".." / "SharedFiles" / "SystemSaveData";
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
|
||||
if (!fs::is_directory(nandSharedpath)) {
|
||||
fs::create_directories(nandSharedpath);
|
||||
}
|
||||
|
@ -89,30 +87,26 @@ ArchiveBase* FSService::getArchiveFromID(u32 id, const FSPath& archivePath) {
|
|||
case ArchiveID::SaveData: return &saveData;
|
||||
case ArchiveID::UserSaveData2: return &userSaveData2;
|
||||
|
||||
case ArchiveID::ExtSaveData:
|
||||
return &extSaveData_sdmc;
|
||||
case ArchiveID::ExtSaveData: return &extSaveData_sdmc;
|
||||
|
||||
case ArchiveID::SharedExtSaveData:
|
||||
return &sharedExtSaveData_nand;
|
||||
case ArchiveID::SharedExtSaveData: return &sharedExtSaveData_nand;
|
||||
|
||||
case ArchiveID::SystemSaveData: return &systemSaveData;
|
||||
case ArchiveID::SDMC: return &sdmc;
|
||||
case ArchiveID::SDMCWriteOnly: return &sdmcWriteOnly;
|
||||
case ArchiveID::SavedataAndNcch: return &ncch; // This can only access NCCH outside of FSPXI
|
||||
case ArchiveID::SavedataAndNcch: return &ncch; // This can only access NCCH outside of FSPXI
|
||||
|
||||
case ArchiveID::TwlPhoto: return &twlPhoto;
|
||||
case ArchiveID::TwlSound: return &twlSound;
|
||||
case ArchiveID::CardSPI: return &cardSpi;
|
||||
|
||||
default:
|
||||
Helpers::panic("Unknown archive. ID: %d\n", id);
|
||||
return nullptr;
|
||||
default: Helpers::panic("Unknown archive. ID: %d\n", id); return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<HorizonHandle> FSService::openFileHandle(ArchiveBase* archive, const FSPath& path, const FSPath& archivePath, const FilePerms& perms) {
|
||||
FileDescriptor opened = archive->openFile(path, perms);
|
||||
if (opened.has_value()) { // If opened doesn't have a value, we failed to open the file
|
||||
if (opened.has_value()) { // If opened doesn't have a value, we failed to open the file
|
||||
auto handle = kernel.makeObject(KernelObjectType::File);
|
||||
|
||||
auto& file = kernel.getObjects()[handle];
|
||||
|
@ -126,7 +120,7 @@ std::optional<HorizonHandle> FSService::openFileHandle(ArchiveBase* archive, con
|
|||
|
||||
Rust::Result<HorizonHandle, Result::HorizonResult> FSService::openDirectoryHandle(ArchiveBase* archive, const FSPath& path) {
|
||||
Rust::Result<DirectorySession, Result::HorizonResult> opened = archive->openDirectory(path);
|
||||
if (opened.isOk()) { // If opened doesn't have a value, we failed to open the directory
|
||||
if (opened.isOk()) { // If opened doesn't have a value, we failed to open the directory
|
||||
auto handle = kernel.makeObject(KernelObjectType::Directory);
|
||||
auto& object = kernel.getObjects()[handle];
|
||||
object.data = new DirectorySession(opened.unwrap());
|
||||
|
@ -152,8 +146,7 @@ Rust::Result<HorizonHandle, Result::HorizonResult> FSService::openArchiveHandle(
|
|||
archiveObject.data = new ArchiveSession(res.unwrap(), path);
|
||||
|
||||
return Ok(handle);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return Err(res.unwrapErr());
|
||||
}
|
||||
}
|
||||
|
@ -162,8 +155,7 @@ FSPath FSService::readPath(u32 type, u32 pointer, u32 size) {
|
|||
std::vector<u8> data;
|
||||
data.resize(size);
|
||||
|
||||
for (u32 i = 0; i < size; i++)
|
||||
data[i] = mem.read8(pointer + i);
|
||||
for (u32 i = 0; i < size; i++) data[i] = mem.read8(pointer + i);
|
||||
|
||||
return FSPath(type, data);
|
||||
}
|
||||
|
@ -222,7 +214,7 @@ void FSService::initializeWithSdkVersion(u32 messagePointer) {
|
|||
}
|
||||
|
||||
void FSService::closeArchive(u32 messagePointer) {
|
||||
const Handle handle = static_cast<u32>(mem.read64(messagePointer + 4)); // TODO: archive handles should be 64-bit
|
||||
const Handle handle = static_cast<u32>(mem.read64(messagePointer + 4)); // TODO: archive handles should be 64-bit
|
||||
const auto object = kernel.getObject(handle, KernelObjectType::Archive);
|
||||
log("FSService::CloseArchive(handle = %X)\n", handle);
|
||||
|
||||
|
@ -288,7 +280,7 @@ void FSService::openFile(u32 messagePointer) {
|
|||
mem.write32(messagePointer + 4, Result::FS::FileNotFound);
|
||||
} else {
|
||||
mem.write32(messagePointer + 4, Result::Success);
|
||||
mem.write32(messagePointer + 8, 0x10); // "Move handle descriptor"
|
||||
mem.write32(messagePointer + 8, 0x10); // "Move handle descriptor"
|
||||
mem.write32(messagePointer + 12, handle.value());
|
||||
}
|
||||
}
|
||||
|
@ -475,8 +467,9 @@ void FSService::formatSaveData(u32 messagePointer) {
|
|||
log("FS::FormatSaveData\n");
|
||||
|
||||
const u32 archiveID = mem.read32(messagePointer + 4);
|
||||
if (archiveID != ArchiveID::SaveData)
|
||||
if (archiveID != ArchiveID::SaveData) {
|
||||
Helpers::panic("FS::FormatSaveData: Archive is not SaveData");
|
||||
}
|
||||
|
||||
// Read path and path info
|
||||
const u32 pathType = mem.read32(messagePointer + 8);
|
||||
|
@ -486,24 +479,24 @@ void FSService::formatSaveData(u32 messagePointer) {
|
|||
// Size of a block. Seems to always be 0x200
|
||||
const u32 blockSize = mem.read32(messagePointer + 16);
|
||||
|
||||
if (blockSize != 0x200 && blockSize != 0x1000)
|
||||
if (blockSize != 0x200 && blockSize != 0x1000) {
|
||||
Helpers::panic("FS::FormatSaveData: Invalid SaveData block size");
|
||||
}
|
||||
|
||||
const u32 directoryNum = mem.read32(messagePointer + 20); // Max number of directories
|
||||
const u32 fileNum = mem.read32(messagePointer + 24); // Max number of files
|
||||
const u32 directoryBucketNum = mem.read32(messagePointer + 28); // Not sure what a directory bucket is...?
|
||||
const u32 fileBucketNum = mem.read32(messagePointer + 32); // Same here
|
||||
const u32 directoryNum = mem.read32(messagePointer + 20); // Max number of directories
|
||||
const u32 fileNum = mem.read32(messagePointer + 24); // Max number of files
|
||||
const u32 directoryBucketNum = mem.read32(messagePointer + 28); // Not sure what a directory bucket is...?
|
||||
const u32 fileBucketNum = mem.read32(messagePointer + 32); // Same here
|
||||
const bool duplicateData = mem.read8(messagePointer + 36) != 0;
|
||||
|
||||
ArchiveBase::FormatInfo info {
|
||||
ArchiveBase::FormatInfo info{
|
||||
.size = blockSize * 0x200,
|
||||
.numOfDirectories = directoryNum,
|
||||
.numOfFiles = fileNum,
|
||||
.duplicateData = duplicateData
|
||||
.duplicateData = duplicateData,
|
||||
};
|
||||
|
||||
saveData.format(path, info);
|
||||
|
||||
mem.write32(messagePointer, IPC::responseHeader(0x84C, 1, 0));
|
||||
mem.write32(messagePointer + 4, Result::Success);
|
||||
}
|
||||
|
@ -517,8 +510,8 @@ void FSService::deleteExtSaveData(u32 messagePointer) {
|
|||
log("FS::DeleteExtSaveData (media type = %d, saveID = %llx) (stubbed)\n", mediaType, saveID);
|
||||
|
||||
mem.write32(messagePointer, IPC::responseHeader(0x0852, 1, 0));
|
||||
// TODO: We can't properly implement this yet until we properly support title/save IDs. We will stub this and insert a warning for now. Required for Planet Robobot
|
||||
// When we properly implement it, it will just be a recursive directory deletion
|
||||
// TODO: We can't properly implement this yet until we properly support title/save IDs. We will stub this and insert a warning for now. Required
|
||||
// for Planet Robobot When we properly implement it, it will just be a recursive directory deletion
|
||||
mem.write32(messagePointer + 4, Result::Success);
|
||||
}
|
||||
|
||||
|
@ -526,7 +519,8 @@ void FSService::createExtSaveData(u32 messagePointer) {
|
|||
Helpers::warn("Stubbed call to FS::CreateExtSaveData!");
|
||||
// First 4 words of parameters are the ExtSaveData info
|
||||
// https://www.3dbrew.org/wiki/Filesystem_services#ExtSaveDataInfo
|
||||
// This creates the ExtSaveData with the specified saveid in the specified media type. It stores the SMDH as "icon" in the root of the created directory.
|
||||
// This creates the ExtSaveData with the specified saveid in the specified media type. It stores the SMDH as "icon" in the root of the created
|
||||
// directory.
|
||||
const u8 mediaType = mem.read8(messagePointer + 4);
|
||||
const u64 saveID = mem.read64(messagePointer + 8);
|
||||
const u32 numOfDirectories = mem.read32(messagePointer + 20);
|
||||
|
@ -546,18 +540,13 @@ void FSService::formatThisUserSaveData(u32 messagePointer) {
|
|||
log("FS::FormatThisUserSaveData\n");
|
||||
|
||||
const u32 blockSize = mem.read32(messagePointer + 4);
|
||||
const u32 directoryNum = mem.read32(messagePointer + 8); // Max number of directories
|
||||
const u32 fileNum = mem.read32(messagePointer + 12); // Max number of files
|
||||
const u32 directoryBucketNum = mem.read32(messagePointer + 16); // Not sure what a directory bucket is...?
|
||||
const u32 fileBucketNum = mem.read32(messagePointer + 20); // Same here
|
||||
const u32 directoryNum = mem.read32(messagePointer + 8); // Max number of directories
|
||||
const u32 fileNum = mem.read32(messagePointer + 12); // Max number of files
|
||||
const u32 directoryBucketNum = mem.read32(messagePointer + 16); // Not sure what a directory bucket is...?
|
||||
const u32 fileBucketNum = mem.read32(messagePointer + 20); // Same here
|
||||
const bool duplicateData = mem.read8(messagePointer + 24) != 0;
|
||||
|
||||
ArchiveBase::FormatInfo info {
|
||||
.size = blockSize * 0x200,
|
||||
.numOfDirectories = directoryNum,
|
||||
.numOfFiles = fileNum,
|
||||
.duplicateData = duplicateData
|
||||
};
|
||||
ArchiveBase::FormatInfo info{.size = blockSize * 0x200, .numOfDirectories = directoryNum, .numOfFiles = fileNum, .duplicateData = duplicateData};
|
||||
FSPath emptyPath;
|
||||
|
||||
mem.write32(messagePointer, IPC::responseHeader(0x080F, 1, 0));
|
||||
|
@ -583,18 +572,16 @@ void FSService::controlArchive(u32 messagePointer) {
|
|||
}
|
||||
|
||||
switch (action) {
|
||||
case 0: // Commit save data changes. Shouldn't need us to do anything
|
||||
case 0: // Commit save data changes. Shouldn't need us to do anything
|
||||
mem.write32(messagePointer + 4, Result::Success);
|
||||
break;
|
||||
|
||||
case 1: // Retrieves a file's last-modified timestamp. Seen in DDLC, stubbed for the moment
|
||||
case 1: // Retrieves a file's last-modified timestamp. Seen in DDLC, stubbed for the moment
|
||||
Helpers::warn("FS::ControlArchive: Tried to retrieve a file's last-modified timestamp");
|
||||
mem.write32(messagePointer + 4, Result::Success);
|
||||
break;
|
||||
|
||||
default:
|
||||
Helpers::panic("Unimplemented action for ControlArchive (action = %X)\n", action);
|
||||
break;
|
||||
default: Helpers::panic("Unimplemented action for ControlArchive (action = %X)\n", action); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -678,9 +665,9 @@ void FSService::getThisSaveDataSecureValue(u32 messagePointer) {
|
|||
|
||||
mem.write32(messagePointer, IPC::responseHeader(0x86F, 1, 0));
|
||||
mem.write32(messagePointer + 4, Result::Success);
|
||||
mem.write8(messagePointer + 8, 0); // Secure value does not exist
|
||||
mem.write8(messagePointer + 12, 1); // TODO: What is this?
|
||||
mem.write64(messagePointer + 16, 0); // Secure value
|
||||
mem.write8(messagePointer + 8, 0); // Secure value does not exist
|
||||
mem.write8(messagePointer + 12, 1); // TODO: What is this?
|
||||
mem.write64(messagePointer + 16, 0); // Secure value
|
||||
}
|
||||
|
||||
void FSService::setThisSaveDataSecureValue(u32 messagePointer) {
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
#include "services/ldr_ro.hpp"
|
||||
#include "ipc.hpp"
|
||||
#include "kernel.hpp"
|
||||
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
|
||||
#include "ipc.hpp"
|
||||
#include "kernel.hpp"
|
||||
|
||||
namespace LDRCommands {
|
||||
enum : u32 {
|
||||
Initialize = 0x000100C2,
|
||||
|
@ -66,10 +67,13 @@ namespace SegmentTable {
|
|||
|
||||
namespace SegmentID {
|
||||
enum : u32 {
|
||||
TEXT, RODATA, DATA, BSS,
|
||||
TEXT,
|
||||
RODATA,
|
||||
DATA,
|
||||
BSS,
|
||||
};
|
||||
}
|
||||
}
|
||||
} // namespace SegmentTable
|
||||
|
||||
namespace NamedExportTable {
|
||||
enum : u32 {
|
||||
|
@ -119,8 +123,8 @@ namespace RelocationPatch {
|
|||
enum : u32 {
|
||||
SegmentOffset = 0,
|
||||
PatchType = 4,
|
||||
IsLastEntry = 5, // For import patches
|
||||
SegmentIndex = 5, // For relocation patches
|
||||
IsLastEntry = 5, // For import patches
|
||||
SegmentIndex = 5, // For relocation patches
|
||||
IsResolved = 6,
|
||||
Addend = 8,
|
||||
};
|
||||
|
@ -130,7 +134,7 @@ namespace RelocationPatch {
|
|||
AbsoluteAddress = 2,
|
||||
};
|
||||
};
|
||||
};
|
||||
}; // namespace RelocationPatch
|
||||
|
||||
struct CROHeaderEntry {
|
||||
u32 offset, size;
|
||||
|
@ -145,12 +149,12 @@ static const std::string CRR_MAGIC("CRR0");
|
|||
class CRO {
|
||||
Memory &mem;
|
||||
|
||||
u32 croPointer; // Origin address of CRO in RAM
|
||||
u32 croPointer; // Origin address of CRO in RAM
|
||||
u32 oldDataSegmentOffset;
|
||||
|
||||
bool isCRO; // False if CRS
|
||||
bool isCRO; // False if CRS
|
||||
|
||||
public:
|
||||
public:
|
||||
CRO(Memory &mem, u32 croPointer, bool isCRO) : mem(mem), croPointer(croPointer), oldDataSegmentOffset(0), isCRO(isCRO) {}
|
||||
~CRO() = default;
|
||||
|
||||
|
@ -238,7 +242,7 @@ public:
|
|||
|
||||
for (u32 namedExport = 0; namedExport < namedExportTable.size; namedExport++) {
|
||||
const u32 nameOffset = mem.read32(namedExportTable.offset + 8 * namedExport + NamedExportTable::NameOffset);
|
||||
|
||||
|
||||
const std::string exportSymbolName = mem.readString(nameOffset, exportStringSize);
|
||||
|
||||
if (symbolName.compare(exportSymbolName) == 0) {
|
||||
|
@ -713,7 +717,7 @@ public:
|
|||
for (u32 namedImport = 0; namedImport < namedImportTable.size; namedImport++) {
|
||||
const u32 nameOffset = mem.read32(namedImportTable.offset + 8 * namedImport + NamedImportTable::NameOffset);
|
||||
const u32 relocationOffset = mem.read32(namedImportTable.offset + 8 * namedImport + NamedImportTable::RelocationOffset);
|
||||
|
||||
|
||||
const std::string symbolName = mem.readString(nameOffset, importStringSize);
|
||||
|
||||
if (symbolName.compare(std::string("__aeabi_atexit")) == 0) {
|
||||
|
@ -725,7 +729,7 @@ public:
|
|||
const u32 exportSymbolAddr = cro.getNamedExportSymbolAddr(std::string("nnroAeabiAtexit_"));
|
||||
if (exportSymbolAddr != 0) {
|
||||
patchBatch(relocationOffset, exportSymbolAddr);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -755,7 +759,7 @@ public:
|
|||
|
||||
if (isResolved == 0) {
|
||||
const u32 nameOffset = mem.read32(namedImportTable.offset + 8 * namedImport + NamedImportTable::NameOffset);
|
||||
|
||||
|
||||
const std::string symbolName = mem.readString(nameOffset, importStringSize);
|
||||
|
||||
// Check every loaded CRO for the symbol (the pain)
|
||||
|
@ -864,7 +868,7 @@ public:
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool clearModules() {
|
||||
const u32 onUnresolvedAddr = getOnUnresolvedAddr();
|
||||
|
||||
|
@ -879,7 +883,7 @@ public:
|
|||
if (indexedOffset == 0) {
|
||||
Helpers::panic("Indexed symbol offset is NULL");
|
||||
}
|
||||
|
||||
|
||||
const u32 relocationOffset = mem.read32(indexedOffset + 8 * indexedImport + IndexedImportTable::RelocationOffset);
|
||||
|
||||
patchBatch(relocationOffset, onUnresolvedAddr, true);
|
||||
|
@ -924,7 +928,7 @@ public:
|
|||
|
||||
if (isResolved == 0) {
|
||||
const u32 nameOffset = mem.read32(namedImportTable.offset + 8 * namedImport + NamedImportTable::NameOffset);
|
||||
|
||||
|
||||
const std::string symbolName = mem.readString(nameOffset, importStringSize);
|
||||
|
||||
// Check our current CRO for the symbol
|
||||
|
@ -988,7 +992,7 @@ public:
|
|||
u32 currentCROPointer = loadedCRS;
|
||||
while (currentCROPointer != 0) {
|
||||
CRO cro(mem, currentCROPointer, true);
|
||||
|
||||
|
||||
const u32 onUnresolvedAddr = cro.getOnUnresolvedAddr();
|
||||
|
||||
const u32 importStringSize = mem.read32(currentCROPointer + CROHeader::ImportStringSize);
|
||||
|
@ -1003,7 +1007,7 @@ public:
|
|||
|
||||
if (isResolved != 0) {
|
||||
const u32 nameOffset = mem.read32(namedImportTable.offset + 8 * namedImport + NamedImportTable::NameOffset);
|
||||
|
||||
|
||||
const std::string symbolName = mem.readString(nameOffset, importStringSize);
|
||||
|
||||
// Check our current CRO for the symbol
|
||||
|
@ -1111,7 +1115,7 @@ public:
|
|||
}
|
||||
|
||||
CRO crs(mem, loadedCRS, false);
|
||||
|
||||
|
||||
u32 headAddr = crs.getPrevCRO();
|
||||
if (autoLink) {
|
||||
headAddr = crs.getNextCRO();
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "services/mic.hpp"
|
||||
|
||||
#include "ipc.hpp"
|
||||
#include "kernel/kernel.hpp"
|
||||
|
||||
|
@ -127,9 +128,8 @@ void MICService::startSampling(u32 messagePointer) {
|
|||
u32 dataSize = mem.read32(messagePointer + 16);
|
||||
bool loop = mem.read8(messagePointer + 20);
|
||||
|
||||
log("MIC::StartSampling (encoding = %d, sample rate = %d, offset = %08X, size = %08X, loop: %s) (stubbed)\n",
|
||||
encoding, sampleRate, offset, dataSize, loop ? "yes" : "no"
|
||||
);
|
||||
log("MIC::StartSampling (encoding = %d, sample rate = %d, offset = %08X, size = %08X, loop: %s) (stubbed)\n", encoding, sampleRate, offset,
|
||||
dataSize, loop ? "yes" : "no");
|
||||
|
||||
currentlySampling = true;
|
||||
mem.write32(messagePointer, IPC::responseHeader(0x3, 1, 0));
|
||||
|
@ -139,7 +139,7 @@ void MICService::startSampling(u32 messagePointer) {
|
|||
void MICService::stopSampling(u32 messagePointer) {
|
||||
log("MIC::StopSampling\n");
|
||||
currentlySampling = false;
|
||||
|
||||
|
||||
mem.write32(messagePointer, IPC::responseHeader(0x5, 1, 0));
|
||||
mem.write32(messagePointer + 4, Result::Success);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "services/ndm.hpp"
|
||||
|
||||
#include "ipc.hpp"
|
||||
|
||||
namespace NDMCommands {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "ipc.hpp"
|
||||
#include "services/news_u.hpp"
|
||||
|
||||
#include "ipc.hpp"
|
||||
|
||||
namespace NewsCommands {
|
||||
enum : u32 {};
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "services/nfc.hpp"
|
||||
|
||||
#include "io_file.hpp"
|
||||
#include "ipc.hpp"
|
||||
#include "kernel.hpp"
|
||||
|
@ -166,7 +167,6 @@ void NFCService::communicationGetStatus(u32 messagePointer) {
|
|||
mem.write8(messagePointer + 8, static_cast<u32>(adapterStatus));
|
||||
}
|
||||
|
||||
|
||||
void NFCService::communicationGetResult(u32 messagePointer) {
|
||||
log("NFC::CommunicationGetResult\n");
|
||||
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
#include "services/nim.hpp"
|
||||
|
||||
#include "ipc.hpp"
|
||||
|
||||
namespace NIMCommands {
|
||||
enum : u32 {
|
||||
Initialize = 0x00210000
|
||||
Initialize = 0x00210000,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#include "services/nwm_uds.hpp"
|
||||
|
||||
#include "ipc.hpp"
|
||||
#include "kernel.hpp"
|
||||
#include "result/result.hpp"
|
||||
#include "services/nwm_uds.hpp"
|
||||
|
||||
namespace NWMCommands {
|
||||
enum : u32 {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "services/ssl.hpp"
|
||||
|
||||
#include "ipc.hpp"
|
||||
#include "result/result.hpp"
|
||||
#include "services/ssl.hpp"
|
||||
|
||||
namespace SSLCommands {
|
||||
enum : u32 {
|
||||
|
@ -31,10 +32,10 @@ void SSLService::initialize(u32 messagePointer) {
|
|||
|
||||
if (initialized) {
|
||||
Helpers::warn("SSL service initialized twice");
|
||||
}
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
rng.seed(std::random_device()()); // Seed rng via std::random_device
|
||||
rng.seed(std::random_device()()); // Seed rng via std::random_device
|
||||
|
||||
mem.write32(messagePointer + 4, Result::Success);
|
||||
}
|
||||
|
@ -48,7 +49,8 @@ void SSLService::generateRandomData(u32 messagePointer) {
|
|||
u32 data;
|
||||
|
||||
for (u32 i = 0; i < size; i++) {
|
||||
// We don't have an available random value since we're on a multiple of 4 bytes and our Twister is 32-bit, generate a new one from the Mersenne Twister
|
||||
// We don't have an available random value since we're on a multiple of 4 bytes and our Twister is 32-bit, generate a new one from the
|
||||
// Mersenne Twister
|
||||
if ((i & 3) == 0) {
|
||||
data = rng();
|
||||
}
|
||||
|
|
|
@ -337,7 +337,7 @@ void Y2RService::setStandardCoeff(u32 messagePointer) {
|
|||
log("Y2R::SetStandardCoeff (coefficient = %d)\n", coeff);
|
||||
mem.write32(messagePointer, IPC::responseHeader(0x20, 1, 0));
|
||||
|
||||
if (coeff > 3) { // Invalid coefficient, should have an error code
|
||||
if (coeff > 3) { // Invalid coefficient, should have an error code
|
||||
Helpers::panic("Y2R: Invalid standard coefficient (coefficient = %d)\n", coeff);
|
||||
}
|
||||
|
||||
|
@ -360,7 +360,7 @@ void Y2RService::getStandardCoefficientParams(u32 messagePointer) {
|
|||
|
||||
// Write standard coefficient parameters to output buffer
|
||||
for (int i = 0; i < 8; i++) {
|
||||
const u32 pointer = messagePointer + 8 + i * sizeof(u16); // Pointer to write parameter to
|
||||
const u32 pointer = messagePointer + 8 + i * sizeof(u16); // Pointer to write parameter to
|
||||
mem.write16(pointer, coeff[i]);
|
||||
}
|
||||
}
|
||||
|
@ -453,7 +453,7 @@ void Y2RService::startConversion(u32 messagePointer) {
|
|||
|
||||
void Y2RService::isFinishedSendingYUV(u32 messagePointer) {
|
||||
log("Y2R::IsFinishedSendingYUV");
|
||||
constexpr bool finished = true; // For now, Y2R transfers are instant
|
||||
constexpr bool finished = true; // For now, Y2R transfers are instant
|
||||
|
||||
mem.write32(messagePointer, IPC::responseHeader(0x14, 2, 0));
|
||||
mem.write32(messagePointer + 4, Result::Success);
|
||||
|
@ -489,7 +489,7 @@ void Y2RService::isFinishedSendingV(u32 messagePointer) {
|
|||
|
||||
void Y2RService::isFinishedReceiving(u32 messagePointer) {
|
||||
log("Y2R::IsFinishedSendingReceiving");
|
||||
constexpr bool finished = true; // For now, receiving components is also instant
|
||||
constexpr bool finished = true; // For now, receiving components is also instant
|
||||
|
||||
mem.write32(messagePointer, IPC::responseHeader(0x17, 2, 0));
|
||||
mem.write32(messagePointer + 4, Result::Success);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue