diff --git a/CMakeLists.txt b/CMakeLists.txt index f0acd3bc..9d8aba7e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -416,7 +416,7 @@ set(HEADER_FILES include/emulator.hpp include/helpers.hpp include/termcolor.hpp include/fs/archive_twl_sound.hpp include/fs/archive_card_spi.hpp include/services/ns.hpp include/audio/audio_device.hpp include/audio/audio_device_interface.hpp include/audio/libretro_audio_device.hpp include/services/ir/ir_types.hpp include/services/ir/ir_device.hpp include/services/ir/circlepad_pro.hpp include/services/service_intercept.hpp - include/screen_layout.hpp include/services/service_map.hpp + include/screen_layout.hpp include/services/service_map.hpp include/audio/dsp_binary.hpp ) if(IOS) diff --git a/include/audio/dsp_binary.hpp b/include/audio/dsp_binary.hpp new file mode 100644 index 00000000..6345903a --- /dev/null +++ b/include/audio/dsp_binary.hpp @@ -0,0 +1,29 @@ +#pragma once +#include "helpers.hpp" + +struct Dsp1 { + // All sizes are in bytes unless otherwise specified + u8 signature[0x100]; + u8 magic[4]; + u32 size; + u8 codeMemLayout; + u8 dataMemLayout; + u8 pad[3]; + u8 specialType; + u8 segmentCount; + u8 flags; + u32 specialStart; + u32 specialSize; + u64 zeroBits; + + struct Segment { + u32 offs; // Offset of the segment data + u32 dspAddr; // Start of the segment in 16-bit units + u32 size; + u8 pad[3]; + u8 type; + u8 hash[0x20]; + }; + + Segment segments[10]; +}; diff --git a/src/core/audio/hle_core.cpp b/src/core/audio/hle_core.cpp index 73d39adb..97a6211e 100644 --- a/src/core/audio/hle_core.cpp +++ b/src/core/audio/hle_core.cpp @@ -7,6 +7,7 @@ #include #include "audio/aac_decoder.hpp" +#include "audio/dsp_binary.hpp" #include "audio/dsp_simd.hpp" #include "config.hpp" #include "services/dsp.hpp" @@ -89,6 +90,36 @@ namespace Audio { Helpers::warn("Loading DSP component when already loaded"); } + // We load the DSP binary into DSP memory even though we don't use it in HLE, so that we can + // still see the DSP code in the DSP debugger + u8* dspCode = dspRam.rawMemory.data(); + u8* dspData = dspCode + 0x40000; + + Dsp1 dsp1; + std::memcpy(&dsp1, data.data(), sizeof(dsp1)); + + // TODO: verify DSP1 signature & hashes + // Load DSP segments to DSP RAM + for (uint i = 0; i < dsp1.segmentCount; i++) { + auto& segment = dsp1.segments[i]; + u32 addr = segment.dspAddr << 1; + u8* src = data.data() + segment.offs; + u8* dst = nullptr; + + switch (segment.type) { + case 0: + case 1: dst = dspCode + addr; break; + default: dst = dspData + addr; break; + } + + std::memcpy(dst, src, segment.size); + } + + bool loadSpecialSegment = (dsp1.flags >> 1) & 0x1; + if (loadSpecialSegment) { + log("LoadComponent: special segment not supported"); + } + loaded = true; scheduler.addEvent(Scheduler::EventType::RunDSP, scheduler.currentTimestamp + Audio::cyclesPerFrame); } diff --git a/src/core/audio/teakra_core.cpp b/src/core/audio/teakra_core.cpp index 7b73d5cd..e1476b83 100644 --- a/src/core/audio/teakra_core.cpp +++ b/src/core/audio/teakra_core.cpp @@ -5,6 +5,7 @@ #include #include +#include "audio/dsp_binary.hpp" #include "services/dsp.hpp" #undef Assert @@ -13,33 +14,6 @@ using namespace Audio; -struct Dsp1 { - // All sizes are in bytes unless otherwise specified - u8 signature[0x100]; - u8 magic[4]; - u32 size; - u8 codeMemLayout; - u8 dataMemLayout; - u8 pad[3]; - u8 specialType; - u8 segmentCount; - u8 flags; - u32 specialStart; - u32 specialSize; - u64 zeroBits; - - struct Segment { - u32 offs; // Offset of the segment data - u32 dspAddr; // Start of the segment in 16-bit units - u32 size; - u8 pad[3]; - u8 type; - u8 hash[0x20]; - }; - - Segment segments[10]; -}; - TeakraDSP::TeakraDSP(Memory& mem, Scheduler& scheduler, DSPService& dspService, EmulatorConfig& config) : DSPCore(mem, scheduler, dspService, config), pipeBaseAddr(0), running(false) { // Set up callbacks for Teakra