diff --git a/include/PSX/SPU/spu.hpp b/include/PSX/SPU/spu.hpp index 235bfb5f..dd1a7fd4 100644 --- a/include/PSX/SPU/spu.hpp +++ b/include/PSX/SPU/spu.hpp @@ -11,7 +11,7 @@ namespace JabyEngine { // TODO: Rename to sample...? struct Voice { - size_t get_id() { + size_t get_id() const { return reinterpret_cast(this); } @@ -33,11 +33,22 @@ namespace JabyEngine { SPU_IO::Key::On.write(SPU_IO::KeyOn::for_specific(Voice::get_id())); } + void play_if_end() { + if(Voice::is_end()) { + Voice::play(); + } + } + void stop() { SPU_IO::Key::Off.write(SPU_IO::KeyOff::for_specific(Voice::get_id())); } + + bool is_end() const { + // TODO: Make work in XEBRA + return SPU_IO::Key::Status.read().is_set(Voice::get_id()); + } }; - extern Voice voice[SPU_IO::VoiceCount]; + static auto& voice = __new_declare_io_port_array(Voice, SPU_IO::VoiceCount, 0x0); } } \ No newline at end of file diff --git a/include/PSX/System/IOPorts/IOValues/spu_io_values.hpp b/include/PSX/System/IOPorts/IOValues/spu_io_values.hpp index d2a9bcbe..72865aee 100644 --- a/include/PSX/System/IOPorts/IOValues/spu_io_values.hpp +++ b/include/PSX/System/IOPorts/IOValues/spu_io_values.hpp @@ -4,23 +4,6 @@ namespace JabyEngine { namespace SPU_IO_Values { - namespace internal { - template - struct AliasUbus32IOPort : public IOPort { - T read() const { - return T{IOPort::read()}; - } - - void write(T value) { - IOPort::write(value.raw); - } - }; - - #define alias_ioport_ubus32(type) \ - template<> \ - struct IOPort : public SPU_IO_Values::internal::AliasUbus32IOPort {} - } - namespace MemoryMap { static constexpr uintptr_t ADPCM = 0x01000; } @@ -64,7 +47,7 @@ namespace JabyEngine { } }; - __declare_io_value(Echo, ubus32_t) { + __declare_io_value(Echo, uint32_t) { static constexpr auto EchoBits = BitRange::from_to(0, 23); static constexpr Echo AllOff() { @@ -72,27 +55,27 @@ namespace JabyEngine { } }; - __declare_io_value(KeyOff, ubus32_t) { + __declare_io_value(KeyOff, uint32_t) { static constexpr KeyOff for_specific(uint32_t id) { - return KeyOff{ubus32_t::from(1 << id)}; + return KeyOff{1u << id}; } static constexpr KeyOff all() { - return KeyOff{ubus32_t::from(UI32_MAX)}; + return KeyOff{UI32_MAX}; } }; - __declare_io_value(KeyOn, ubus32_t) { + __declare_io_value(KeyOn, uint32_t) { static constexpr KeyOn for_specific(uint32_t id) { - return KeyOn{ubus32_t::from(1 << id)}; + return KeyOn{1u << id}; } static constexpr KeyOn all() { - return KeyOn{ubus32_t::from(UI32_MAX)}; + return KeyOn{UI32_MAX}; } }; - __declare_io_value(KeyStatus, ubus32_t) { + __declare_io_value(KeyStatus, uint32_t) { }; __declare_io_value(Noise, uint16_t) { @@ -103,7 +86,7 @@ namespace JabyEngine { } }; - __declare_io_value(PitchModulation, ubus32_t) { + __declare_io_value(PitchModulation, uint32_t) { static constexpr auto EnableBits = BitRange::from_to(1, 23); static constexpr PitchModulation AllOff() { @@ -228,10 +211,4 @@ namespace JabyEngine { } }; } - alias_ioport_ubus32(SPU_IO_Values::Echo); - alias_ioport_ubus32(SPU_IO_Values::Noise); - alias_ioport_ubus32(SPU_IO_Values::KeyOff); - alias_ioport_ubus32(SPU_IO_Values::KeyOn); - alias_ioport_ubus32(SPU_IO_Values::KeyStatus); - alias_ioport_ubus32(SPU_IO_Values::PitchModulation); } \ No newline at end of file diff --git a/include/PSX/System/IOPorts/ioport.hpp b/include/PSX/System/IOPorts/ioport.hpp index d3033589..264af11b 100644 --- a/include/PSX/System/IOPorts/ioport.hpp +++ b/include/PSX/System/IOPorts/ioport.hpp @@ -65,15 +65,6 @@ namespace JabyEngine { }; } - struct ubus32_t { - uint16_t low; - uint16_t high; - - static constexpr ubus32_t from(uint32_t value) { - return {.low = static_cast(value & 0xFFFF), .high = static_cast(value >> 16)}; - } - }; - template struct IOPort { using Value = T; @@ -89,25 +80,34 @@ namespace JabyEngine { }; template<> - struct IOPort { - using Value = ubus32_t; - ubus32_t value; + struct IOPort; - ubus32_t read() const { - auto*const cv_this = const_cast*>(this); - - return {.low = cv_this->value.low, .high = cv_this->value.high}; + template + struct IOPort32 { + union ValueHelper { + struct { + uint16_t low; + uint16_t high; + }; + T value; + }; + using Value = T; + T value; + + T read() const { + const auto* cast_this = reinterpret_cast*>(this); + const volatile auto* cv_this = const_cast(cast_this); + + return ValueHelper{.low = cv_this->value.low, .high = cv_this->value.high}.value; } - void write(ubus32_t value) { - auto*const cv_this = const_cast*>(this); + void write(T value) { + const auto new_value = ValueHelper{.value = value}; + auto* cast_this = reinterpret_cast*>(this); + volatile auto* v_this = const_cast(cast_this); - cv_this->value.low = value.low; - cv_this->value.high = value.high; - } - - void write(uint32_t value) { - IOPort::write(ubus32_t::from(value)); + v_this->value.low = new_value.low; + v_this->value.high = new_value.high; } }; diff --git a/include/PSX/System/IOPorts/spu_io.hpp b/include/PSX/System/IOPorts/spu_io.hpp index ebf834fd..72279b27 100644 --- a/include/PSX/System/IOPorts/spu_io.hpp +++ b/include/PSX/System/IOPorts/spu_io.hpp @@ -20,12 +20,12 @@ namespace JabyEngine { using ADIO = IOPort; using DataTransferControlIO = IOPort; - using EchoIO = IOPort; - using KeyOffIO = IOPort; - using KeyOnIO = IOPort; - using KeyStatusIO = IOPort; + using EchoIO = IOPort32; + using KeyOffIO = IOPort32; + using KeyOnIO = IOPort32; + using KeyStatusIO = IOPort32; using NoiseIO = IOPort; - using PitchModulationIO = IOPort; + using PitchModulationIO = IOPort32; using SampleRateIO = IOPort; using SimpleVolumeIO = IOPort; using StatusRegisterIO = IOPort; diff --git a/src/Library/internal-include/SPU/spu_mmu.hpp b/src/Library/internal-include/SPU/spu_mmu.hpp index 58103f4e..7ed0560d 100644 --- a/src/Library/internal-include/SPU/spu_mmu.hpp +++ b/src/Library/internal-include/SPU/spu_mmu.hpp @@ -3,6 +3,7 @@ namespace JabyEngine { namespace SPU_MMU { + // TODO: Make this work with words? Word align? const uint8_t* allocate(uint8_t voice, size_t size); void deallocate(uint8_t voice); } diff --git a/src/Library/src/BootLoader/start_boot.cpp b/src/Library/src/BootLoader/start_boot.cpp index ba68fea0..177250bd 100644 --- a/src/Library/src/BootLoader/start_boot.cpp +++ b/src/Library/src/BootLoader/start_boot.cpp @@ -59,7 +59,7 @@ namespace JabyEngine { 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 + // TODO: More tests } namespace boot { diff --git a/src/Library/src/File/Processor/vag_processor.cpp b/src/Library/src/File/Processor/vag_processor.cpp index ff429dd8..3d256035 100644 --- a/src/Library/src/File/Processor/vag_processor.cpp +++ b/src/Library/src/File/Processor/vag_processor.cpp @@ -52,11 +52,14 @@ namespace JabyEngine { static Progress parse_header(State::Configuration& config, VAGState& state) { if(config.data_bytes >= sizeof(VAGHeader)) { const auto& header = *reinterpret_cast(config.data_adr); - const auto bytes = header.get_sample_size(); + const auto words = bytes_to_words(header.get_sample_size()); + const auto bytes = words_to_bytes(words); - state.words_left = bytes_to_words(bytes); + state.words_left = words; - auto sram_adr = SPU::voice[state.voice_id].allocate(SPU_IO::SampleRate::from_HZ(header.get_sample_frequency()), words_to_bytes(state.words_left)); + auto sram_adr = SPU::voice[state.voice_id].allocate(SPU_IO::SampleRate::from_HZ(header.get_sample_frequency()), bytes); + // TODO: Keep this as optional? + printf("SPU: Allocated %i @0x%p to 0x%p (%i bytes)\n", state.voice_id, sram_adr.raw, (sram_adr.raw + bytes), bytes); SPU::voice[state.voice_id].set_volume(state.inital_vol, state.inital_vol); config.processed(sizeof(VAGHeader));