mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-13 17:49:47 +12:00
Add CSND::ExecuteCommands
This commit is contained in:
parent
8ac22e35e9
commit
46cf049e3b
5 changed files with 44 additions and 2 deletions
|
@ -53,6 +53,7 @@ namespace Log {
|
||||||
static Logger<false> micLogger;
|
static Logger<false> micLogger;
|
||||||
static Logger<false> newsLogger;
|
static Logger<false> newsLogger;
|
||||||
static Logger<false> nfcLogger;
|
static Logger<false> nfcLogger;
|
||||||
|
static Logger<false> nwmUdsLogger;
|
||||||
static Logger<false> nimLogger;
|
static Logger<false> nimLogger;
|
||||||
static Logger<false> ndmLogger;
|
static Logger<false> ndmLogger;
|
||||||
static Logger<false> ptmLogger;
|
static Logger<false> ptmLogger;
|
||||||
|
|
|
@ -15,15 +15,22 @@ class CSNDService {
|
||||||
Kernel& kernel;
|
Kernel& kernel;
|
||||||
MAKE_LOG_FUNCTION(log, csndLogger)
|
MAKE_LOG_FUNCTION(log, csndLogger)
|
||||||
|
|
||||||
bool initialized = false;
|
u8* sharedMemory = nullptr;
|
||||||
std::optional<Handle> csndMutex = std::nullopt;
|
std::optional<Handle> csndMutex = std::nullopt;
|
||||||
|
size_t sharedMemSize = 0;
|
||||||
|
bool initialized = false;
|
||||||
|
|
||||||
// Service functions
|
// Service functions
|
||||||
void acquireSoundChannels(u32 messagePointer);
|
void acquireSoundChannels(u32 messagePointer);
|
||||||
|
void executeCommands(u32 messagePointer);
|
||||||
void initialize(u32 messagePointer);
|
void initialize(u32 messagePointer);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CSNDService(Memory& mem, Kernel& kernel) : mem(mem), kernel(kernel) {}
|
CSNDService(Memory& mem, Kernel& kernel) : mem(mem), kernel(kernel) {}
|
||||||
void reset();
|
void reset();
|
||||||
void handleSyncRequest(u32 messagePointer);
|
void handleSyncRequest(u32 messagePointer);
|
||||||
|
|
||||||
|
void setSharedMemory(u8* ptr) {
|
||||||
|
sharedMemory = ptr;
|
||||||
|
}
|
||||||
};
|
};
|
|
@ -103,6 +103,7 @@ class ServiceManager {
|
||||||
void sendGPUInterrupt(GPUInterrupt type) { gsp_gpu.requestInterrupt(type); }
|
void sendGPUInterrupt(GPUInterrupt type) { gsp_gpu.requestInterrupt(type); }
|
||||||
void setGSPSharedMem(u8* ptr) { gsp_gpu.setSharedMem(ptr); }
|
void setGSPSharedMem(u8* ptr) { gsp_gpu.setSharedMem(ptr); }
|
||||||
void setHIDSharedMem(u8* ptr) { hid.setSharedMem(ptr); }
|
void setHIDSharedMem(u8* ptr) { hid.setSharedMem(ptr); }
|
||||||
|
void setCSNDSharedMem(u8* ptr) { csnd.setSharedMemory(ptr); }
|
||||||
|
|
||||||
void signalDSPEvents() { dsp.signalEvents(); }
|
void signalDSPEvents() { dsp.signalEvents(); }
|
||||||
|
|
||||||
|
|
|
@ -139,7 +139,10 @@ void Kernel::mapMemoryBlock() {
|
||||||
mem.copySharedFont(ptr);
|
mem.copySharedFont(ptr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KernelHandles::CSNDSharedMemHandle: printf("Mapping CSND memory block\n"); break;
|
case KernelHandles::CSNDSharedMemHandle:
|
||||||
|
serviceManager.setCSNDSharedMem(ptr);
|
||||||
|
printf("Mapping CSND memory block\n");
|
||||||
|
break;
|
||||||
|
|
||||||
default: Helpers::panic("Mapping unknown shared memory block: %X", block);
|
default: Helpers::panic("Mapping unknown shared memory block: %X", block);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
namespace CSNDCommands {
|
namespace CSNDCommands {
|
||||||
enum : u32 {
|
enum : u32 {
|
||||||
Initialize = 0x00010140,
|
Initialize = 0x00010140,
|
||||||
|
ExecuteCommands = 0x00030040,
|
||||||
AcquireSoundChannels = 0x00050000,
|
AcquireSoundChannels = 0x00050000,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -14,6 +15,8 @@ namespace CSNDCommands {
|
||||||
void CSNDService::reset() {
|
void CSNDService::reset() {
|
||||||
csndMutex = std::nullopt;
|
csndMutex = std::nullopt;
|
||||||
initialized = false;
|
initialized = false;
|
||||||
|
sharedMemory = nullptr;
|
||||||
|
sharedMemSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSNDService::handleSyncRequest(u32 messagePointer) {
|
void CSNDService::handleSyncRequest(u32 messagePointer) {
|
||||||
|
@ -21,6 +24,7 @@ void CSNDService::handleSyncRequest(u32 messagePointer) {
|
||||||
|
|
||||||
switch (command) {
|
switch (command) {
|
||||||
case CSNDCommands::AcquireSoundChannels: acquireSoundChannels(messagePointer); break;
|
case CSNDCommands::AcquireSoundChannels: acquireSoundChannels(messagePointer); break;
|
||||||
|
case CSNDCommands::ExecuteCommands: executeCommands(messagePointer); break;
|
||||||
case CSNDCommands::Initialize: initialize(messagePointer); break;
|
case CSNDCommands::Initialize: initialize(messagePointer); break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -65,10 +69,36 @@ void CSNDService::initialize(u32 messagePointer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
initialized = true;
|
initialized = true;
|
||||||
|
sharedMemSize = blockSize;
|
||||||
|
|
||||||
mem.write32(messagePointer, IPC::responseHeader(0x1, 1, 3));
|
mem.write32(messagePointer, IPC::responseHeader(0x1, 1, 3));
|
||||||
mem.write32(messagePointer + 4, Result::Success);
|
mem.write32(messagePointer + 4, Result::Success);
|
||||||
mem.write32(messagePointer + 8, 0x4000000);
|
mem.write32(messagePointer + 8, 0x4000000);
|
||||||
mem.write32(messagePointer + 12, csndMutex.value());
|
mem.write32(messagePointer + 12, csndMutex.value());
|
||||||
mem.write32(messagePointer + 16, KernelHandles::CSNDSharedMemHandle);
|
mem.write32(messagePointer + 16, KernelHandles::CSNDSharedMemHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSNDService::executeCommands(u32 messagePointer) {
|
||||||
|
const u32 offset = mem.read32(messagePointer + 4);
|
||||||
|
log("CSND::ExecuteCommands (command offset = %X)\n", offset);
|
||||||
|
|
||||||
|
mem.write32(messagePointer, IPC::responseHeader(0x5, 2, 0));
|
||||||
|
|
||||||
|
if (!sharedMemory) {
|
||||||
|
Helpers::warn("CSND::Execute commands without shared memory");
|
||||||
|
mem.write32(messagePointer + 4, Result::FailurePlaceholder);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mem.write32(messagePointer + 4, Result::Success);
|
||||||
|
|
||||||
|
// This is initially zero when this command data is written by the user process, once the CSND module finishes processing the command this is set
|
||||||
|
// to 0x1. This flag is only set to value 1 for the first command(once processing for the entire command chain is finished) at the offset
|
||||||
|
// specified in the service command, not all type0 commands in the chain.
|
||||||
|
constexpr u32 commandListDoneOffset = 0x4;
|
||||||
|
|
||||||
|
// Make sure to not access OoB of the shared memory block when marking command list processing as finished
|
||||||
|
if (offset + commandListDoneOffset < sharedMemSize) {
|
||||||
|
sharedMemory[offset + commandListDoneOffset] = 1;
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Add table
Reference in a new issue