From 0a78020aec36b0b21d7349053336f47373662174 Mon Sep 17 00:00:00 2001 From: Jaby Date: Thu, 22 Aug 2024 20:13:07 +0200 Subject: [PATCH] Move voice memory manager code into brand new SPU MMU --- include/PSX/SPU/spu.hpp | 4 - src/Library/internal-include/SPU/spu_mmu.hpp | 9 ++ src/Library/src/BootLoader/start_boot.cpp | 9 +- src/Library/src/SPU/spu.cpp | 119 +----------------- src/Library/src/SPU/spu_mmu.cpp | 125 +++++++++++++++++++ 5 files changed, 140 insertions(+), 126 deletions(-) create mode 100644 src/Library/internal-include/SPU/spu_mmu.hpp create mode 100644 src/Library/src/SPU/spu_mmu.cpp diff --git a/include/PSX/SPU/spu.hpp b/include/PSX/SPU/spu.hpp index a6f280d7..64e60eca 100644 --- a/include/PSX/SPU/spu.hpp +++ b/include/PSX/SPU/spu.hpp @@ -3,9 +3,5 @@ namespace JabyEngine { namespace SPU { - const uint8_t* allocate_voice(uint8_t voice, size_t size); - void deallocate_voice(uint8_t voice); - - void dump(); } } \ No newline at end of file diff --git a/src/Library/internal-include/SPU/spu_mmu.hpp b/src/Library/internal-include/SPU/spu_mmu.hpp new file mode 100644 index 00000000..58103f4e --- /dev/null +++ b/src/Library/internal-include/SPU/spu_mmu.hpp @@ -0,0 +1,9 @@ +#pragma once +#include + +namespace JabyEngine { + namespace SPU_MMU { + const uint8_t* allocate(uint8_t voice, size_t size); + void deallocate(uint8_t voice); + } +} \ No newline at end of file diff --git a/src/Library/src/BootLoader/start_boot.cpp b/src/Library/src/BootLoader/start_boot.cpp index 9d47eec3..ba68fea0 100644 --- a/src/Library/src/BootLoader/start_boot.cpp +++ b/src/Library/src/BootLoader/start_boot.cpp @@ -2,6 +2,7 @@ #include "../../internal-include/GPU/gpu_internal.hpp" #include +#include "../../internal-include/SPU/spu_mmu.hpp" #include #include #include @@ -53,10 +54,10 @@ namespace JabyEngine { }; printf("=== SPU test ===\n"); - simple_assert(0, SPU::allocate_voice(0, 0x600), calculate_spu_adr(0x0)); - simple_assert(1, SPU::allocate_voice(1, 0x800), calculate_spu_adr(0x600)); - simple_assert(2, SPU::allocate_voice(0, 0x300), calculate_spu_adr(0x0)); - simple_assert(3, SPU::allocate_voice(2, 0x300), calculate_spu_adr(0x300)); + simple_assert(0, SPU_MMU::allocate(0, 0x600), calculate_spu_adr(0x0)); + simple_assert(1, SPU_MMU::allocate(1, 0x800), calculate_spu_adr(0x600)); + simple_assert(2, SPU_MMU::allocate(0, 0x300), calculate_spu_adr(0x0)); + simple_assert(3, SPU_MMU::allocate(2, 0x300), calculate_spu_adr(0x300)); // TODO: More tests } diff --git a/src/Library/src/SPU/spu.cpp b/src/Library/src/SPU/spu.cpp index 06544f74..40e88543 100644 --- a/src/Library/src/SPU/spu.cpp +++ b/src/Library/src/SPU/spu.cpp @@ -1,127 +1,10 @@ #include "../../internal-include/SPU/spu_internal.hpp" +#include "../../internal-include/SPU/spu_mmu.hpp" #include -#include #include #include -#include - namespace JabyEngine { namespace SPU { - namespace SPU_MemoryMap = SPU_IO::MemoryMap; - - struct SPUMemory { - const uint8_t* adr; - size_t size; - - static SPUMemory create(size_t size) { - return SPUMemory{.adr = reinterpret_cast(SPU_MemoryMap::ADPCM), .size = size}; - } - - constexpr void clear() { - this->adr = nullptr; - this->size = 0; - } - - constexpr const uint8_t* get_end_adr() const { - return (this->adr + this->size); - } - - constexpr bool is_free() const { - return this->adr == nullptr; - } - - constexpr bool intersects(const SPUMemory& other) const { - const auto* min = max_of(this->adr, other.adr); - const auto* max = min_of(this->get_end_adr(), other.get_end_adr()); - return min < max; - } - }; - - struct AllocatedVoice { - SPUMemory memory; - AllocatedVoice* next_entry; - }; - - struct VoiceManager { - struct Iterator { - AllocatedVoice* *prev_voice; - AllocatedVoice* current_voice; - - void next() { - this->prev_voice = &this->current_voice->next_entry; - this->current_voice = this->current_voice->next_entry; - } - - bool has_next() const { - return this->current_voice; - } - - operator bool() const { - return Iterator::has_next(); - } - }; - - AllocatedVoice allocated_voice_buffer[SPU_IO::VoiceCount + SPU_IO::ReverbCount] = {0}; - AllocatedVoice* first_allocated_voice = nullptr; - - Iterator iterator() { - return Iterator{.prev_voice = &this->first_allocated_voice, .current_voice = this->first_allocated_voice}; - } - - AllocatedVoice& get_voice(uint8_t id) { - return this->allocated_voice_buffer[id]; - } - }; - - static VoiceManager voice_mgr; - - using MemoryFoundCallback = const uint8_t* (AllocatedVoice& new_entry, AllocatedVoice* &prev_entry, AllocatedVoice* next_entry); - - static const uint8_t* verify_and_add(AllocatedVoice& new_entry, AllocatedVoice* &prev_entry, AllocatedVoice* next_entry) { - // TODO: Verify that we are not crashing into reverb or that we are higher then SPU - prev_entry = &new_entry; - new_entry.next_entry = next_entry; - - return new_entry.memory.adr; - } - - static const uint8_t* find_first_fit(AllocatedVoice &new_entry, MemoryFoundCallback memory_found) { - auto iterator = voice_mgr.iterator(); - while(iterator) { - if(!iterator.current_voice->memory.intersects(new_entry.memory)) { - break; - } - new_entry.memory.adr = iterator.current_voice->memory.get_end_adr(); - iterator.next(); - } - - return memory_found(new_entry, *iterator.prev_voice, iterator.current_voice); - } - - const uint8_t* allocate_voice(uint8_t voice, size_t size) { - auto& voice_entry = voice_mgr.get_voice(voice); - if(!voice_entry.memory.is_free()) { - deallocate_voice(voice); - } - - voice_entry.memory = SPUMemory::create(size); - return find_first_fit(voice_entry, verify_and_add); - // TODO: Set memory adr for voice in SPU - } - - void deallocate_voice(uint8_t voice) { - auto* voice_adr = &voice_mgr.get_voice(voice); - auto iterator = voice_mgr.iterator(); - - voice_adr->memory.clear(); - while(iterator) { - if(iterator.current_voice == voice_adr) { - *iterator.prev_voice = voice_adr->next_entry; - break; - } - iterator.next(); - } - } } } \ No newline at end of file diff --git a/src/Library/src/SPU/spu_mmu.cpp b/src/Library/src/SPU/spu_mmu.cpp new file mode 100644 index 00000000..967d8b83 --- /dev/null +++ b/src/Library/src/SPU/spu_mmu.cpp @@ -0,0 +1,125 @@ +#include "../../internal-include/SPU/spu_mmu.hpp" +#include +#include +#include +#include + +namespace JabyEngine { + namespace SPU_MMU { + namespace SPU_MemoryMap = SPU_IO::MemoryMap; + + struct SPUMemory { + // TODO: v change to uint16_t?? + const uint8_t* adr; + size_t size; + + static SPUMemory create(size_t size) { + return SPUMemory{.adr = reinterpret_cast(SPU_MemoryMap::ADPCM), .size = size}; + } + + constexpr void clear() { + this->adr = nullptr; + this->size = 0; + } + + constexpr const uint8_t* get_end_adr() const { + return (this->adr + this->size); + } + + constexpr bool is_free() const { + return this->adr == nullptr; + } + + constexpr bool intersects(const SPUMemory& other) const { + const auto* min = max_of(this->adr, other.adr); + const auto* max = min_of(this->get_end_adr(), other.get_end_adr()); + return min < max; + } + }; + + struct AllocatedVoice { + SPUMemory memory; + AllocatedVoice* next_entry; + }; + + struct VoiceManager { + struct Iterator { + AllocatedVoice* *prev_voice; + AllocatedVoice* current_voice; + + void next() { + this->prev_voice = &this->current_voice->next_entry; + this->current_voice = this->current_voice->next_entry; + } + + bool has_next() const { + return this->current_voice; + } + + operator bool() const { + return Iterator::has_next(); + } + }; + + AllocatedVoice allocated_voice_buffer[SPU_IO::VoiceCount + SPU_IO::ReverbCount] = {0}; + AllocatedVoice* first_allocated_voice = nullptr; + + Iterator iterator() { + return Iterator{.prev_voice = &this->first_allocated_voice, .current_voice = this->first_allocated_voice}; + } + + AllocatedVoice& get_voice(uint8_t id) { + return this->allocated_voice_buffer[id]; + } + }; + + static VoiceManager voice_mgr; + + using MemoryFoundCallback = const uint8_t* (AllocatedVoice& new_entry, AllocatedVoice* &prev_entry, AllocatedVoice* next_entry); + + static const uint8_t* verify_and_add(AllocatedVoice& new_entry, AllocatedVoice* &prev_entry, AllocatedVoice* next_entry) { + // TODO: Verify that we are not crashing into reverb or that we are higher then SPU + prev_entry = &new_entry; + new_entry.next_entry = next_entry; + + return new_entry.memory.adr; + } + + static const uint8_t* find_first_fit(AllocatedVoice &new_entry, MemoryFoundCallback memory_found) { + auto iterator = voice_mgr.iterator(); + while(iterator) { + if(!iterator.current_voice->memory.intersects(new_entry.memory)) { + break; + } + new_entry.memory.adr = iterator.current_voice->memory.get_end_adr(); + iterator.next(); + } + + return memory_found(new_entry, *iterator.prev_voice, iterator.current_voice); + } + + const uint8_t* allocate(uint8_t voice, size_t size) { + auto& voice_entry = voice_mgr.get_voice(voice); + if(!voice_entry.memory.is_free()) { + deallocate(voice); + } + + voice_entry.memory = SPUMemory::create(size); + return find_first_fit(voice_entry, verify_and_add); + } + + void deallocate(uint8_t voice) { + auto* voice_adr = &voice_mgr.get_voice(voice); + auto iterator = voice_mgr.iterator(); + + voice_adr->memory.clear(); + while(iterator) { + if(iterator.current_voice == voice_adr) { + *iterator.prev_voice = voice_adr->next_entry; + break; + } + iterator.next(); + } + } + } +} \ No newline at end of file