mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-20 20:49:12 +12:00
[DSP] Add other pipes for Picross 3D
This commit is contained in:
parent
cf35491fb1
commit
ccd7ef3a23
3 changed files with 75 additions and 60 deletions
|
@ -2,6 +2,8 @@
|
|||
#include "ipc.hpp"
|
||||
#include "kernel.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace DSPCommands {
|
||||
enum : u32 {
|
||||
RecvData = 0x00010040,
|
||||
|
@ -30,7 +32,11 @@ namespace Result {
|
|||
}
|
||||
|
||||
void DSPService::reset() {
|
||||
audioPipe.reset();
|
||||
for (auto& e : pipeData)
|
||||
e.clear();
|
||||
|
||||
// Note: Reset audio pipe AFTER resetting all pipes, otherwise the new data will be yeeted
|
||||
resetAudioPipe();
|
||||
totalEventCount = 0;
|
||||
dspState = DSPState::Off;
|
||||
|
||||
|
@ -43,6 +49,40 @@ void DSPService::reset() {
|
|||
}
|
||||
}
|
||||
|
||||
void DSPService::resetAudioPipe() {
|
||||
// Hardcoded responses for now
|
||||
// These are DSP DRAM offsets for various variables
|
||||
// https://www.3dbrew.org/wiki/DSP_Memory_Region
|
||||
static constexpr std::array<u16, 16> responses = {
|
||||
0x000F, // Number of responses
|
||||
0xBFFF, // Frame counter
|
||||
0x9E92, // Source configs
|
||||
0x8680, // Source statuses
|
||||
0xA792, // ADPCM coefficients
|
||||
0x9430, // DSP configs
|
||||
0x8400, // DSP status
|
||||
0x8540, // Final samples
|
||||
0x9492, // Intermediate mix samples
|
||||
0x8710, // Compressor
|
||||
0x8410, // Debug
|
||||
0xA912, // ??
|
||||
0xAA12, // ??
|
||||
0xAAD2, // ??
|
||||
0xAC52, // Surround sound biquad filter 1
|
||||
0xAC5C // Surround sound biquad filter 2
|
||||
};
|
||||
|
||||
std::vector<u8>& audioPipe = pipeData[DSPPipeType::Audio];
|
||||
audioPipe.resize(responses.size() * sizeof(u16));
|
||||
|
||||
// Push back every response to the audio pipe
|
||||
size_t index = 0;
|
||||
for (auto e : responses) {
|
||||
audioPipe[index++] = e & 0xff;
|
||||
audioPipe[index++] = e >> 8;
|
||||
}
|
||||
}
|
||||
|
||||
void DSPService::handleSyncRequest(u32 messagePointer) {
|
||||
const u32 command = mem.read32(messagePointer);
|
||||
switch (command) {
|
||||
|
@ -93,31 +133,43 @@ void DSPService::unloadComponent(u32 messagePointer) {
|
|||
mem.write32(messagePointer + 4, Result::Success);
|
||||
}
|
||||
|
||||
std::vector<u8> DSPService::readPipe(u32 pipe, u32 size) {
|
||||
if (size & 1) Helpers::panic("Tried to read odd amount of bytes from DSP pipe");
|
||||
if (pipe >= pipeCount || size > 0xffff) {
|
||||
return {};
|
||||
}
|
||||
|
||||
if (pipe != DSPPipeType::Audio) {
|
||||
Helpers::warn("Reading from non-audio pipe! This might be broken, might need to check what pipe is being read from and implement writing to it\n");
|
||||
}
|
||||
|
||||
std::vector<u8>& data = pipeData[pipe];
|
||||
size = std::min<u32>(size, data.size()); // Clamp size to the maximum available data size
|
||||
|
||||
if (size == 0)
|
||||
return {};
|
||||
|
||||
// Return "size" bytes from the audio pipe and erase them
|
||||
std::vector<u8> out(data.begin(), data.begin() + size);
|
||||
data.erase(data.begin(), data.begin() + size);
|
||||
return out;
|
||||
}
|
||||
|
||||
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);
|
||||
mem.write32(messagePointer, IPC::responseHeader(0x10, 2, 2));
|
||||
|
||||
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());
|
||||
std::vector<u8> data = readPipe(channel, size);
|
||||
for (uint i = 0; i < data.size(); i++) {
|
||||
mem.write8(buffer + i, data[i]);
|
||||
}
|
||||
|
||||
mem.write32(messagePointer, IPC::responseHeader(0x10, 2, 2));
|
||||
mem.write32(messagePointer + 4, Result::Success);
|
||||
mem.write16(messagePointer + 8, i); // Number of bytes read
|
||||
mem.write16(messagePointer + 8, data.size()); // Number of bytes read
|
||||
}
|
||||
|
||||
void DSPService::recvData(u32 messagePointer) {
|
||||
|
@ -130,7 +182,7 @@ void DSPService::recvData(u32 messagePointer) {
|
|||
|
||||
mem.write32(messagePointer, IPC::responseHeader(0x01, 2, 0));
|
||||
mem.write32(messagePointer + 4, Result::Success);
|
||||
mem.write16(messagePointer + 8, ret); // Always return that the DSP is on
|
||||
mem.write16(messagePointer + 8, ret);
|
||||
}
|
||||
|
||||
void DSPService::recvDataIsReady(u32 messagePointer) {
|
||||
|
@ -257,7 +309,7 @@ void DSPService::writeProcessPipe(u32 messagePointer) {
|
|||
case StateChange::Initialize:
|
||||
// TODO: Other initialization stuff here
|
||||
dspState = DSPState::On;
|
||||
audioPipe.reset();
|
||||
resetAudioPipe();
|
||||
break;
|
||||
|
||||
case StateChange::Shutdown:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue