mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-17 19:21:30 +12:00
[DSP service] ReadPipeIfPossible
This commit is contained in:
parent
1bcdf7f18d
commit
a3431e7c9c
2 changed files with 143 additions and 1 deletions
|
@ -3,11 +3,60 @@
|
||||||
#include "logger.hpp"
|
#include "logger.hpp"
|
||||||
#include "memory.hpp"
|
#include "memory.hpp"
|
||||||
|
|
||||||
|
// Stub for DSP audio pipe
|
||||||
|
class DSPPipe {
|
||||||
|
// Hardcoded responses for now
|
||||||
|
static constexpr std::array<u16, 16> pipeData = {
|
||||||
|
0x000F, //Number of responses
|
||||||
|
0xBFFF,
|
||||||
|
0x9E8E,
|
||||||
|
0x8680,
|
||||||
|
0xA78E,
|
||||||
|
0x9430,
|
||||||
|
0x8400,
|
||||||
|
0x8540,
|
||||||
|
0x948E,
|
||||||
|
0x8710,
|
||||||
|
0x8410,
|
||||||
|
0xA90E,
|
||||||
|
0xAA0E,
|
||||||
|
0xAACE,
|
||||||
|
0xAC4E,
|
||||||
|
0xAC58
|
||||||
|
};
|
||||||
|
uint index = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void reset() {
|
||||||
|
index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read without checking if the pipe has overflowed
|
||||||
|
u16 readUnchecked() {
|
||||||
|
return pipeData[index++];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool empty() {
|
||||||
|
return index >= pipeData.size();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class DSPService {
|
class DSPService {
|
||||||
Handle handle = KernelHandles::DSP;
|
Handle handle = KernelHandles::DSP;
|
||||||
Memory& mem;
|
Memory& mem;
|
||||||
MAKE_LOG_FUNCTION(log, dspServiceLogger)
|
MAKE_LOG_FUNCTION(log, dspServiceLogger)
|
||||||
|
|
||||||
|
DSPPipe audioPipe;
|
||||||
|
|
||||||
|
// Service functions
|
||||||
|
void getSemaphoreHandle(u32 messagePointer);
|
||||||
|
void loadComponent(u32 messagePointer);
|
||||||
|
void readPipeIfPossible(u32 messagePointer);
|
||||||
|
void registerInterruptEvents(u32 messagePointer);
|
||||||
|
void setSemaphore(u32 messagePointer);
|
||||||
|
void setSemaphoreMask(u32 messagePointer);
|
||||||
|
void writeProcessPipe(u32 messagePointer);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DSPService(Memory& mem) : mem(mem) {}
|
DSPService(Memory& mem) : mem(mem) {}
|
||||||
void reset();
|
void reset();
|
||||||
|
|
|
@ -2,6 +2,13 @@
|
||||||
|
|
||||||
namespace DSPCommands {
|
namespace DSPCommands {
|
||||||
enum : u32 {
|
enum : u32 {
|
||||||
|
ReadPipeIfPossible = 0x001000C0,
|
||||||
|
LoadComponent = 0x001100C2,
|
||||||
|
RegisterInterruptEvents = 0x00150082,
|
||||||
|
GetSemaphoreHandle = 0x00160000,
|
||||||
|
SetSemaphoreMask = 0x00170040,
|
||||||
|
SetSemaphore = 0x00070040,
|
||||||
|
WriteProcessPipe = 0x000D0082
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,11 +18,97 @@ namespace Result {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSPService::reset() {}
|
void DSPService::reset() {
|
||||||
|
audioPipe.reset();
|
||||||
|
}
|
||||||
|
|
||||||
void DSPService::handleSyncRequest(u32 messagePointer) {
|
void DSPService::handleSyncRequest(u32 messagePointer) {
|
||||||
const u32 command = mem.read32(messagePointer);
|
const u32 command = mem.read32(messagePointer);
|
||||||
switch (command) {
|
switch (command) {
|
||||||
|
case DSPCommands::GetSemaphoreHandle: getSemaphoreHandle(messagePointer); break;
|
||||||
|
case DSPCommands::LoadComponent: loadComponent(messagePointer); break;
|
||||||
|
case DSPCommands::ReadPipeIfPossible: readPipeIfPossible(messagePointer); break;
|
||||||
|
case DSPCommands::RegisterInterruptEvents: registerInterruptEvents(messagePointer); break;
|
||||||
|
case DSPCommands::SetSemaphore: setSemaphore(messagePointer); break;
|
||||||
|
case DSPCommands::SetSemaphoreMask: setSemaphoreMask(messagePointer); break;
|
||||||
|
case DSPCommands::WriteProcessPipe: [[likely]] writeProcessPipe(messagePointer); break;
|
||||||
default: Helpers::panic("DSP service requested. Command: %08X\n", command);
|
default: Helpers::panic("DSP service requested. Command: %08X\n", command);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DSPService::loadComponent(u32 messagePointer) {
|
||||||
|
u32 size = mem.read32(messagePointer + 4);
|
||||||
|
u32 programMask = mem.read32(messagePointer + 8);
|
||||||
|
u32 dataMask = mem.read32(messagePointer + 12);
|
||||||
|
|
||||||
|
log("DSP::LoadComponent (size = %08X, program mask = %X, data mask = %X\n", size, programMask, dataMask);
|
||||||
|
mem.write32(messagePointer + 4, Result::Success);
|
||||||
|
mem.write32(messagePointer + 8, 1); // Component loaded
|
||||||
|
mem.write32(messagePointer + 12, (size << 4) | 0xA);
|
||||||
|
mem.write32(messagePointer + 16, mem.read32(messagePointer + 20)); // Component buffer
|
||||||
|
}
|
||||||
|
|
||||||
|
void DSPService::readPipeIfPossible(u32 messagePointer) {
|
||||||
|
u32 channel = mem.read32(messagePointer + 4);
|
||||||
|
u32 peer = mem.read32(messagePointer + 8);
|
||||||
|
u16 size = mem.read16(messagePointer + 12);
|
||||||
|
u32 buffer = mem.read32(messagePointer + 0x100 + 4);
|
||||||
|
log("DSP::ReadPipeIfPossible (channel = %d, peer = %d, size = %04X, buffer = %08X)\n", channel, peer, size, buffer);
|
||||||
|
|
||||||
|
if (size & 1) Helpers::panic("Tried to read odd amount of bytes from DSP pipe");
|
||||||
|
if (channel != 2) Helpers::panic("Read from non-audio pipe");
|
||||||
|
|
||||||
|
DSPPipe& pipe = audioPipe;
|
||||||
|
|
||||||
|
uint i; // Number of bytes transferred
|
||||||
|
for (i = 0; i < size; i += 2) {
|
||||||
|
if (pipe.empty()) {
|
||||||
|
printf("Tried to read from empty pipe\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
mem.write16(buffer + i, pipe.readUnchecked());
|
||||||
|
}
|
||||||
|
|
||||||
|
mem.write32(messagePointer + 4, Result::Success);
|
||||||
|
mem.write16(messagePointer + 8, i); // Number of bytes read
|
||||||
|
}
|
||||||
|
|
||||||
|
void DSPService::registerInterruptEvents(u32 messagePointer) {
|
||||||
|
u32 interrupt = mem.read32(messagePointer + 4);
|
||||||
|
u32 channel = mem.read32(messagePointer + 8);
|
||||||
|
u32 event = mem.read32(messagePointer + 16);
|
||||||
|
|
||||||
|
log("DSP::RegisterInterruptEvents (interrupt = %d, channel = %d, event = %d)\n", interrupt, channel, event);
|
||||||
|
mem.write32(messagePointer + 4, Result::Success);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DSPService::getSemaphoreHandle(u32 messagePointer) {
|
||||||
|
log("DSP::GetSemaphoreHandle\n");
|
||||||
|
|
||||||
|
mem.write32(messagePointer + 4, Result::Success);
|
||||||
|
mem.write32(messagePointer + 12, 0xF9991234); // Semaphore handle (stubbed with random, obvious number)
|
||||||
|
}
|
||||||
|
|
||||||
|
void DSPService::setSemaphore(u32 messagePointer) {
|
||||||
|
const u16 value = mem.read16(messagePointer + 4);
|
||||||
|
log("DSP::SetSemaphore(value = %04X)\n", value);
|
||||||
|
|
||||||
|
mem.write32(messagePointer + 4, Result::Success);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DSPService::setSemaphoreMask(u32 messagePointer) {
|
||||||
|
const u16 mask = mem.read16(messagePointer + 4);
|
||||||
|
log("DSP::SetSemaphoreMask(mask = %04X)\n", mask);
|
||||||
|
|
||||||
|
mem.write32(messagePointer + 4, Result::Success);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DSPService::writeProcessPipe(u32 messagePointer) {
|
||||||
|
u32 channel = mem.read32(messagePointer + 4);
|
||||||
|
u32 size = mem.read32(messagePointer + 8);
|
||||||
|
u32 buffer = mem.read32(messagePointer + 16);
|
||||||
|
|
||||||
|
log("DSP::writeProcessPipe (channel = %d, size = %X, buffer = %08X)\n", channel, size, buffer);
|
||||||
|
mem.write32(messagePointer + 4, Result::Success);
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue