Stub GPU DMA, fix up some FS stuff. horribly wrong savedata implementation

This commit is contained in:
wheremyfoodat 2022-10-15 13:28:29 +03:00
parent b6a1da21a9
commit 5d15efe72c
13 changed files with 169 additions and 35 deletions

View file

@ -4,8 +4,10 @@
namespace FSCommands {
enum : u32 {
Initialize = 0x08010002,
OpenFile = 0x080201C2,
OpenFileDirectly = 0x08030204,
OpenArchive = 0x080C00C2
OpenArchive = 0x080C00C2,
CloseArchive = 0x080E0080
};
}
@ -66,8 +68,10 @@ std::optional<Handle> FSService::openArchiveHandle(u32 archiveID, const FSPath&
void FSService::handleSyncRequest(u32 messagePointer) {
const u32 command = mem.read32(messagePointer);
switch (command) {
case FSCommands::CloseArchive: closeArchive(messagePointer); break;
case FSCommands::Initialize: initialize(messagePointer); break;
case FSCommands::OpenArchive: openArchive(messagePointer); break;
case FSCommands::OpenFile: openFile(messagePointer); break;
case FSCommands::OpenFileDirectly: openFileDirectly(messagePointer); break;
default: Helpers::panic("FS service requested. Command: %08X\n", command);
}
@ -78,6 +82,20 @@ void FSService::initialize(u32 messagePointer) {
mem.write32(messagePointer + 4, Result::Success);
}
void FSService::closeArchive(u32 messagePointer) {
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);
if (object == nullptr) {
log("FSService::CloseArchive: Tried to close invalid archive %X\n", handle);
mem.write32(messagePointer + 4, Result::Failure);
} else {
object->getData<ArchiveSession>()->isOpen = false;
mem.write32(messagePointer + 4, Result::Success);
}
}
void FSService::openArchive(u32 messagePointer) {
const u32 archiveID = mem.read32(messagePointer + 4);
const u32 archivePathType = mem.read32(messagePointer + 8);
@ -85,7 +103,7 @@ void FSService::openArchive(u32 messagePointer) {
const u32 archivePathPointer = mem.read32(messagePointer + 20);
FSPath archivePath{ .type = archivePathType, .size = archivePathSize, .pointer = archivePathPointer };
log("FS::OpenArchive (archive ID = %d, archive path type = %d)\n", archiveID, archivePathType);
log("FS::OpenArchive(archive ID = %d, archive path type = %d)\n", archiveID, archivePathType);
std::optional<Handle> handle = openArchiveHandle(archiveID, archivePath);
if (handle.has_value()) {
@ -97,6 +115,37 @@ void FSService::openArchive(u32 messagePointer) {
}
}
void FSService::openFile(u32 messagePointer) {
const u32 archiveHandle = mem.read64(messagePointer + 8);
const u32 filePathType = mem.read32(messagePointer + 16);
const u32 filePathSize = mem.read32(messagePointer + 20);
const u32 openFlags = mem.read32(messagePointer + 24);
const u32 attributes = mem.read32(messagePointer + 28);
const u32 filePathPointer = mem.read32(messagePointer + 36);
log("FS::OpenFile\n");
auto archiveObject = kernel.getObject(archiveHandle, KernelObjectType::Archive);
if (archiveObject == nullptr) [[unlikely]] {
log("FS::OpenFile: Invalid archive handle %d\n", archiveHandle);
mem.write32(messagePointer + 4, Result::Failure);
return;
}
ArchiveBase* archive = archiveObject->getData<ArchiveSession>()->archive;
FSPath filePath{ .type = filePathType, .size = filePathSize, .pointer = filePathPointer };
std::optional<Handle> handle = openFileHandle(archive, filePath);
if (!handle.has_value()) {
Helpers::panic("OpenFile: Failed to open file with given path");
}
else {
mem.write32(messagePointer + 4, Result::Success);
mem.write32(messagePointer + 8, 0x10); // "Move handle descriptor"
mem.write32(messagePointer + 12, handle.value());
}
}
void FSService::openFileDirectly(u32 messagePointer) {
const u32 archiveID = mem.read32(messagePointer + 8);
const u32 archivePathType = mem.read32(messagePointer + 12);

View file

@ -17,6 +17,7 @@ namespace ServiceCommands {
// Commands written to shared memory and processed by TriggerCmdReqQueue
namespace GXCommands {
enum : u32 {
TriggerDMARequest = 0,
ProcessCommandList = 1,
MemoryFill = 2,
TriggerDisplayTransfer = 3,
@ -223,6 +224,7 @@ void GPUService::processCommandBuffer() {
case GXCommands::ProcessCommandList: processCommandList(cmd); break;
case GXCommands::MemoryFill: memoryFill(cmd); break;
case GXCommands::TriggerDisplayTransfer: triggerDisplayTransfer(cmd); break;
case GXCommands::TriggerDMARequest: triggerDMARequest(cmd); break;
case GXCommands::FlushCacheRegions: flushCacheRegions(cmd); break;
default: Helpers::panic("GSP::GPU::ProcessCommands: Unknown cmd ID %d", cmdID);
}
@ -262,6 +264,16 @@ void GPUService::triggerDisplayTransfer(u32* cmd) {
requestInterrupt(GPUInterrupt::PPF); // Send "Display transfer finished" interrupt
}
void GPUService::triggerDMARequest(u32* cmd) {
u32 source = cmd[1];
u32 dest = cmd[2];
u32 size = cmd[3];
bool flush = cmd[7] == 1;
log("GSP::GPU::TriggerDMARequest (source = %08X, dest = %08X, size = %08X) (Unimplemented)\n", source, dest, size);
requestInterrupt(GPUInterrupt::DMA);
}
void GPUService::flushCacheRegions(u32* cmd) {
log("GSP::GPU::FlushCacheRegions (Stubbed)\n");
}