From 4070bea697984b13e9a32128f5c2f04ab2c2ff5c Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Fri, 5 Apr 2024 01:31:56 +0300 Subject: [PATCH] HLE DSP: Add region handling --- include/audio/hle_core.hpp | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/include/audio/hle_core.hpp b/include/audio/hle_core.hpp index ae3c29cf..c9d36c11 100644 --- a/include/audio/hle_core.hpp +++ b/include/audio/hle_core.hpp @@ -18,11 +18,31 @@ namespace Audio { DSPState dspState; std::array, pipeCount> pipeData; // The data of each pipe - std::array dspRam; + Audio::HLE::DspMemory dspRam; void resetAudioPipe(); bool loaded = false; // Have we loaded a component? + // Get the index for the current region we'll be reading. Returns the region with the highest frame counter + // Accounting for whether one of the frame counters has wrapped around + usize readRegionIndex() const { + const auto counter0 = dspRam.region0.frameCounter; + const auto counter1 = dspRam.region1.frameCounter; + + // Handle wraparound cases first + if (counter0 == 0xffff && counter1 != 0xfffe) { + return 1; + } else if (counter1 == 0xffff && counter0 != 0xfffe) { + return 0; + } else { + return counter0 > counter1 ? 0 : 0; + } + } + + // DSP shared memory is double buffered; One region is being written to while the other one is being read from + Audio::HLE::SharedMemory& readRegion() { return readRegionIndex() == 0 ? dspRam.region0 : dspRam.region1; } + Audio::HLE::SharedMemory& writeRegion() { return readRegionIndex() == 0 ? dspRam.region1 : dspRam.region0; } + public: HLE_DSP(Memory& mem, Scheduler& scheduler, DSPService& dspService) : DSPCore(mem, scheduler, dspService) {} ~HLE_DSP() override {} @@ -30,7 +50,7 @@ namespace Audio { void reset() override; void runAudioFrame() override; - u8* getDspMemory() override { return dspRam.data(); } + u8* getDspMemory() override { return dspRam.rawMemory.data(); } u16 recvData(u32 regId) override; bool recvDataIsReady(u32 regId) override { return true; } // Treat data as always ready