mirror of
https://github.com/citra-emu/citra.git
synced 2024-12-18 20:50:05 +00:00
audio_core/lle: implement GetDspMemory and SetServiceToInterrupt
This commit is contained in:
parent
df8aaee965
commit
9ab4e3c686
@ -5,6 +5,7 @@
|
|||||||
#include "audio_core/lle/lle.h"
|
#include "audio_core/lle/lle.h"
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/swap.h"
|
#include "common/swap.h"
|
||||||
|
#include "core/hle/service/dsp/dsp_dsp.h"
|
||||||
#include "teakra/teakra.h"
|
#include "teakra/teakra.h"
|
||||||
|
|
||||||
namespace AudioCore {
|
namespace AudioCore {
|
||||||
@ -33,6 +34,9 @@ struct DspLle::Impl final {
|
|||||||
Teakra::Teakra teakra;
|
Teakra::Teakra teakra;
|
||||||
u16 pipe_base_waddr = 0;
|
u16 pipe_base_waddr = 0;
|
||||||
|
|
||||||
|
bool semaphore_signaled = false;
|
||||||
|
bool data_signaled = false;
|
||||||
|
|
||||||
static constexpr unsigned TeakraSlice = 20000;
|
static constexpr unsigned TeakraSlice = 20000;
|
||||||
void RunTeakraSlice() {
|
void RunTeakraSlice() {
|
||||||
teakra.Run(TeakraSlice);
|
teakra.Run(TeakraSlice);
|
||||||
@ -178,6 +182,57 @@ void DspLle::PipeWrite(DspPipe pipe_number, const std::vector<u8>& buffer) {
|
|||||||
impl->WritePipe(static_cast<u8>(pipe_number), buffer);
|
impl->WritePipe(static_cast<u8>(pipe_number), buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::array<u8, Memory::DSP_RAM_SIZE>& DspLle::GetDspMemory() {
|
||||||
|
return impl->teakra.GetDspMemory();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DspLle::SetServiceToInterrupt(std::weak_ptr<Service::DSP::DSP_DSP> dsp) {
|
||||||
|
impl->teakra.SetRecvDataHandler(0, [dsp]() {
|
||||||
|
if (auto locked = dsp.lock()) {
|
||||||
|
locked->SignalInterrupt(Service::DSP::DSP_DSP::InterruptType::Zero,
|
||||||
|
static_cast<DspPipe>(0));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
impl->teakra.SetRecvDataHandler(1, [dsp]() {
|
||||||
|
if (auto locked = dsp.lock()) {
|
||||||
|
locked->SignalInterrupt(Service::DSP::DSP_DSP::InterruptType::One,
|
||||||
|
static_cast<DspPipe>(0));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
auto ProcessPipeEvent = [this, dsp](bool event_from_data) {
|
||||||
|
auto& teakra = impl->teakra;
|
||||||
|
if (event_from_data) {
|
||||||
|
impl->data_signaled = true;
|
||||||
|
} else {
|
||||||
|
if ((teakra.GetSemaphore() & 0x8000) == 0)
|
||||||
|
return;
|
||||||
|
impl->semaphore_signaled = true;
|
||||||
|
}
|
||||||
|
if (impl->semaphore_signaled && impl->data_signaled) {
|
||||||
|
impl->semaphore_signaled = impl->data_signaled = false;
|
||||||
|
u16 slot = teakra.RecvData(2);
|
||||||
|
u16 side = slot % 2;
|
||||||
|
u16 pipe = slot / 2;
|
||||||
|
ASSERT(pipe < 16);
|
||||||
|
if (side != static_cast<u16>(PipeDirection::DSPtoCPU))
|
||||||
|
return;
|
||||||
|
if (pipe == 0) {
|
||||||
|
// pipe 0 is for debug. 3DS automatically drains this pipe and discards the data
|
||||||
|
impl->ReadPipe(pipe, impl->GetPipeReadableSize(pipe));
|
||||||
|
} else {
|
||||||
|
if (auto locked = dsp.lock()) {
|
||||||
|
locked->SignalInterrupt(Service::DSP::DSP_DSP::InterruptType::Pipe,
|
||||||
|
static_cast<DspPipe>(pipe));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
impl->teakra.SetRecvDataHandler(2, [ProcessPipeEvent]() { ProcessPipeEvent(true); });
|
||||||
|
impl->teakra.SetSemaphoreHandler([ProcessPipeEvent]() { ProcessPipeEvent(false); });
|
||||||
|
}
|
||||||
|
|
||||||
DspLle::DspLle() : impl(std::make_unique<Impl>()) {}
|
DspLle::DspLle() : impl(std::make_unique<Impl>()) {}
|
||||||
DspLle::~DspLle() = default;
|
DspLle::~DspLle() = default;
|
||||||
|
|
||||||
|
@ -20,6 +20,10 @@ public:
|
|||||||
std::size_t GetPipeReadableSize(DspPipe pipe_number) const override;
|
std::size_t GetPipeReadableSize(DspPipe pipe_number) const override;
|
||||||
void PipeWrite(DspPipe pipe_number, const std::vector<u8>& buffer) override;
|
void PipeWrite(DspPipe pipe_number, const std::vector<u8>& buffer) override;
|
||||||
|
|
||||||
|
std::array<u8, Memory::DSP_RAM_SIZE>& GetDspMemory() override;
|
||||||
|
|
||||||
|
void SetServiceToInterrupt(std::weak_ptr<Service::DSP::DSP_DSP> dsp) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Impl;
|
struct Impl;
|
||||||
friend struct Impl;
|
friend struct Impl;
|
||||||
|
Loading…
Reference in New Issue
Block a user