From dac33a77c6200e34f851e592c56e6c7bdc8fbeb3 Mon Sep 17 00:00:00 2001 From: jaby Date: Fri, 2 Sep 2022 11:02:56 +0200 Subject: [PATCH] Clear MainVolume and improve port code --- include/PSX/System/IOPorts/IOPort.hpp | 10 +- include/PSX/System/IOPorts/SPU_IO.hpp | 145 +++++++++++++----------- src/Library/src/BootLoader/boot_spu.cpp | 10 ++ 3 files changed, 95 insertions(+), 70 deletions(-) diff --git a/include/PSX/System/IOPorts/IOPort.hpp b/include/PSX/System/IOPorts/IOPort.hpp index 38ee92e0..462091e6 100644 --- a/include/PSX/System/IOPorts/IOPort.hpp +++ b/include/PSX/System/IOPorts/IOPort.hpp @@ -52,13 +52,13 @@ public: template constexpr IOPort& clear_bit(S bit) { - this->value = bit::set(this->value, static_cast(bit)); + this->value = bit::clear(this->value, static_cast(bit)); return *this; } template constexpr void clear_bit(S bit) volatile { - this->value = bit::set(this->value, static_cast(bit)); + this->value = bit::clear(this->value, static_cast(bit)); } template @@ -164,4 +164,10 @@ static constexpr uintptr_t IO_Base_Mask = 0xF0000000; static constexpr uintptr_t IO_Base_Adr = 0x10000000; #define __declare_io_port_global(type, name, adr) static __always_inline auto& name = *reinterpret_cast*>((IO_Base_Adr + (adr & ~IO_Base_Mask))) +#define __io_port_inherit(name) \ + using IOPort::operator=; \ + constexpr name() = default; \ + constexpr name(IOPort value) : IOPort(value) { \ + } + #endif //!__JABYENGINE_IOPORT_HPP__ \ No newline at end of file diff --git a/include/PSX/System/IOPorts/SPU_IO.hpp b/include/PSX/System/IOPorts/SPU_IO.hpp index 6768e8b9..b5d11337 100644 --- a/include/PSX/System/IOPorts/SPU_IO.hpp +++ b/include/PSX/System/IOPorts/SPU_IO.hpp @@ -4,83 +4,92 @@ #include namespace SPU { - enum struct SweepMode { - Linear = 0, - Exponential = 1, - }; + namespace Port { + enum struct SweepMode { + Linear = 0, + Exponential = 1, + }; - enum struct SweepDirection { - Increase = 0, - Decrease = 1, - }; + enum struct SweepDirection { + Increase = 0, + Decrease = 1, + }; - enum struct SweepPhase { - Posititve = 0, - Negative = 1, - }; + enum struct SweepPhase { + Posititve = 0, + Negative = 1, + }; - //0..0x1F = Fast..Slow - typedef uint8_t SweepShift; + //0..0x1F = Fast..Slow + typedef uint8_t SweepShift; - //0..3 = +7, +6, +5, +4 or -6, -7, -6, -5 - typedef uint8_t SweepStep; + //0..3 = +7, +6, +5, +4 or -6, -7, -6, -5 + typedef uint8_t SweepStep; - struct __no_align SampleRate : public IOPort { - using IOPort::IOPort; + struct __no_align SampleRate : public IOPort { + __io_port_inherit(SampleRate); - static constexpr SampleRate from_HZ(double freq) { - //4096 == 44100Hz - constexpr double Base = (4096.0 / 44100.0); + static constexpr SampleRate from_HZ(double freq) { + //4096 == 44100Hz + constexpr double Base = (4096.0 / 44100.0); - return static_cast((freq*Base)); + return IOPort(static_cast((freq*Base))); + } + }; + + struct __no_align SweepVolume : public IOPort { + __io_port_inherit(SweepVolume); + + // For Volume Mode + static constexpr Bit ModeBit = 15; // 0 Volume Mode; 1 Sweep Mode + static constexpr BitRange VolumeRange = BitRange::from_to(0, 14); + + // For Sweep Mode + static constexpr Bit SweepModeBit = 14; + static constexpr Bit SweepDirectionBit = 13; + static constexpr Bit SweepPhaseBit = 12; + static constexpr BitRange SweepShiftRange = BitRange::from_to(2, 6); + static constexpr BitRange SweepStepRange = BitRange::from_to(0, 1); + }; + + struct __no_align SR : public IOPort { + static constexpr Bit SustainModeBit = (31 - 16); + static constexpr Bit SustainDirectionBit = (30 - 16); + static constexpr BitRange SustainShiftRange = BitRange::from_to((24 - 16), (28 - 16)); + static constexpr BitRange SustainStepRange = BitRange::from_to((22 - 16), (23 - 16)); + static constexpr Bit ReleaseModeBit = (21 - 16); + static constexpr BitRange ReleaseShiftRange = BitRange::from_to((16 - 16), (20 - 16)); + }; + + struct __no_align AD : public IOPort { + static constexpr Bit AttackModeBit = 15; + static constexpr BitRange AttackShiftRange = BitRange::from_to(10, 14); + static constexpr BitRange AttackStepRange = BitRange::from_to(8, 9); + static constexpr BitRange DecayShiftRange = BitRange::from_to(4, 7); + static constexpr BitRange SustainLevelRange = BitRange::from_to(0, 3); + }; + + struct __no_align Voice { + SweepVolume volumeLeft; + SweepVolume volumeRight; + SampleRate sampleRate; + IOPort adr; + IOPort ad; + IOPort sr; + IOPort currentVolume; //Not used + IOPort repeatAdr; + }; + + namespace Key { + __declare_io_port_global(ubus32_t, on, 0x1F801D88); + __declare_io_port_global(ubus32_t, off, 0x1F801D8C); + __declare_io_port_global(ubus32_t, status, 0x1F801D9C); } - }; - struct __no_align SweepVolume : public IOPort { - // For Volume Mode - static constexpr Bit ModeBit = 15; // 0 Volume Mode; 1 Sweep Mode - static constexpr BitRange VolumeRange = BitRange::from_to(0, 14); - - // For Sweep Mode - static constexpr Bit SweepModeBit = 14; - static constexpr Bit SweepDirectionBit = 13; - static constexpr Bit SweepPhaseBit = 12; - static constexpr BitRange SweepShiftRange = BitRange::from_to(2, 6); - static constexpr BitRange SweepStepRange = BitRange::from_to(0, 1); - }; - - struct __no_align SR : public IOPort { - static constexpr Bit SustainModeBit = (31 - 16); - static constexpr Bit SustainDirectionBit = (30 - 16); - static constexpr BitRange SustainShiftRange = BitRange::from_to((24 - 16), (28 - 16)); - static constexpr BitRange SustainStepRange = BitRange::from_to((22 - 16), (23 - 16)); - static constexpr Bit ReleaseModeBit = (21 - 16); - static constexpr BitRange ReleaseShiftRange = BitRange::from_to((16 - 16), (20 - 16)); - }; - - struct __no_align AD : public IOPort { - static constexpr Bit AttackModeBit = 15; - static constexpr BitRange AttackShiftRange = BitRange::from_to(10, 14); - static constexpr BitRange AttackStepRange = BitRange::from_to(8, 9); - static constexpr BitRange DecayShiftRange = BitRange::from_to(4, 7); - static constexpr BitRange SustainLevelRange = BitRange::from_to(0, 3); - }; - - struct __no_align Voice { - SweepVolume volumeLeft; - SweepVolume volumeRight; - SampleRate sampleRate; - IOPort adr; - IOPort ad; - IOPort sr; - IOPort currentVolume; //Not used - IOPort repeatAdr; - }; - - namespace Key { - __declare_io_port_global(ubus32_t, on, 0x1F801D88); - __declare_io_port_global(ubus32_t, off, 0x1F801D8C); - __declare_io_port_global(ubus32_t, status, 0x1F801D9C); + namespace MainVolume { + __declare_io_port_global(SweepVolume, left, 0x1F801D80); + __declare_io_port_global(SweepVolume, right, 0x1F801D82); + } } } diff --git a/src/Library/src/BootLoader/boot_spu.cpp b/src/Library/src/BootLoader/boot_spu.cpp index 082a2a5b..b1badfe4 100644 --- a/src/Library/src/BootLoader/boot_spu.cpp +++ b/src/Library/src/BootLoader/boot_spu.cpp @@ -2,11 +2,21 @@ #include namespace SPU { + using namespace Port; + static void clear_key() { Key::off.write(UI32_MAX); } + static void clear_main_volume() { + static constexpr auto StartVol = SweepVolume().clear_bit(SweepVolume::ModeBit).set_value(static_cast(I16_MAX >> 2), SweepVolume::VolumeRange); + + MainVolume::left.write(StartVol); + MainVolume::right.write(StartVol); + } + void setup() { clear_key(); + clear_main_volume(); } } \ No newline at end of file