From 5574addb293a2f4acd86d015af0f8e64bd17df1f Mon Sep 17 00:00:00 2001 From: Jaby Date: Mon, 5 Sep 2022 20:58:33 +0200 Subject: [PATCH] Improve IOPort code --- include/PSX/System/IOPorts/DMA_IO.hpp | 20 ++-- include/PSX/System/IOPorts/IOPort.hpp | 119 +++++++++++++++--------- include/PSX/System/IOPorts/SPU_IO.hpp | 40 ++++---- src/Library/src/BootLoader/boot_spu.cpp | 5 +- 4 files changed, 106 insertions(+), 78 deletions(-) diff --git a/include/PSX/System/IOPorts/DMA_IO.hpp b/include/PSX/System/IOPorts/DMA_IO.hpp index 8b787ed6..b93961d7 100644 --- a/include/PSX/System/IOPorts/DMA_IO.hpp +++ b/include/PSX/System/IOPorts/DMA_IO.hpp @@ -3,14 +3,14 @@ #include "IOPort.hpp" namespace DMA { - struct __no_align MADR : public IOPort { - __io_port_inherit(MADR); + struct __no_align MADR : public ComplexBitMap { + __io_port_inherit_complex_bit_map(MADR); static constexpr BitRange MemoryAdr = BitRange::from_to(0, 23); }; - struct __no_align BCR : public IOPort { - __io_port_inherit(BCR); + struct __no_align BCR : public ComplexBitMap { + __io_port_inherit_complex_bit_map(BCR); struct __no_align SyncMode0 { static constexpr BitRange NumberOfWords = BitRange::from_to(0, 15); @@ -26,8 +26,8 @@ namespace DMA { }; }; - struct __no_align CHCHR : public IOPort { - __io_port_inherit(CHCHR); + struct __no_align CHCHR : public ComplexBitMap { + __io_port_inherit_complex_bit_map(CHCHR); enum _SyncMode { Sync0 = 0, //Start immediately, @@ -92,8 +92,8 @@ namespace DMA { static constexpr Priority HighestPriority = 0; static constexpr Priority LowestPriority = 7; - struct __no_align DMAControlRegister : public IOPort { - __io_port_inherit(DMAControlRegister); + struct __no_align DMAControlRegister : public ComplexBitMap { + __io_port_inherit_complex_bit_map(DMAControlRegister); static constexpr Bit OTCEnable = 27; static constexpr BitRange OTCPriority = BitRange::from_to(24, 26); @@ -117,8 +117,8 @@ namespace DMA { static constexpr BitRange MDECinPriority = BitRange::from_to(0, 2); }; - struct __no_align DMAInterruptRegister : public IOPort { - __io_port_inherit(DMAInterruptRegister); + struct __no_align DMAInterruptRegister : public ComplexBitMap { + __io_port_inherit_complex_bit_map(DMAInterruptRegister); static constexpr Bit MasterEnable = 31; static constexpr BitRange Flags = BitRange::from_to(24, 30); diff --git a/include/PSX/System/IOPorts/IOPort.hpp b/include/PSX/System/IOPorts/IOPort.hpp index d0777453..efa21bcc 100644 --- a/include/PSX/System/IOPorts/IOPort.hpp +++ b/include/PSX/System/IOPorts/IOPort.hpp @@ -54,18 +54,18 @@ static constexpr __always_inline BitRangeValue operator<<(const BitRange& } template -class __no_align IOPort { +class __no_align ComplexBitMap { private: T value = 0; public: - constexpr IOPort() = default; - constexpr IOPort(T value) : value(value) { + constexpr ComplexBitMap() = default; + constexpr ComplexBitMap(T value) : value(value) { } //Accesssing bits template - constexpr IOPort& set_bit(S bit) { + constexpr ComplexBitMap& set_bit(S bit) { this->value = bit::set(this->value, static_cast(bit)); return *this; } @@ -76,7 +76,7 @@ public: } template - constexpr IOPort& clear_bit(S bit) { + constexpr ComplexBitMap& clear_bit(S bit) { this->value = bit::clear(this->value, static_cast(bit)); return *this; } @@ -98,7 +98,7 @@ public: //Accessing values template - constexpr IOPort& set_value(S value, const BitRange& range) { + constexpr ComplexBitMap& set_value(S value, const BitRange& range) { this->value = bit::value::set_normalized(this->value, static_cast(value), range.begin, range.length); return *this; } @@ -109,7 +109,7 @@ public: } template - constexpr IOPort& clear_value(const BitRange& range) { + constexpr ComplexBitMap& clear_value(const BitRange& range) { this->value = bit::value::clear_normalized(this->value, range.begin, range.length); return *this; } @@ -129,6 +129,67 @@ public: return static_cast(bit::value::get_normalized(this->value, range.begin, range.length)); } + // For easier constructing + constexpr ComplexBitMap& set(const BitRange& range, T value) { + this->set_value(value, range); + return *this; + } + + constexpr ComplexBitMap& set(const BitRangeValue& value) { + this->set_value(value.value, value.range); + return *this; + } + + constexpr ComplexBitMap& set(const Bit& bit) { + this->set_bit(bit.value); + return *this; + } + + constexpr ComplexBitMap& set(const ClearBitValue& value) { + this->clear_bit(value.bit); + return *this; + } + + constexpr ComplexBitMap& operator|(const BitRangeValue& value) { + this->set_value(value.value, value.range); + return *this; + } + + constexpr ComplexBitMap& operator|(const Bit& bit) { + this->set_bit(bit.value); + return *this; + } + + constexpr ComplexBitMap& operator|(const ClearBitValue& value) { + this->clear_bit(value.bit); + return *this; + } + + //For raw access + constexpr operator T() const { + return this->value; + } + + constexpr operator T() const volatile { + return this->value; + } + + constexpr ComplexBitMap& operator=(T value) { + this->value = value; + return *this; + } + + constexpr void operator=(T value) volatile { + this->value = value; + } +}; + +template +class __no_align IOPort { +private: + T value; + +public: //For easy access constexpr T read() const { return const_cast*>(this)->value; @@ -141,45 +202,11 @@ public: constexpr volatile T& ref() { return const_cast*>(this)->value; } - - //For raw access - constexpr operator T() const { - return this->value; - } - - constexpr operator T() const volatile { - return this->value; - } - - constexpr IOPort& operator=(T value) { - this->value = value; - return *this; - } - - constexpr void operator=(T value) volatile { - this->value = value; - } - - // For easier constructing - constexpr IOPort& operator|(const BitRangeValue& value) { - this->set_value(value.value, value.range); - return *this; - } - - constexpr IOPort& operator|(const Bit& bit) { - this->set_bit(bit.value); - return *this; - } - - constexpr IOPort& operator|(const ClearBitValue& value) { - this->clear_bit(value.bit); - return *this; - } }; struct __no_align ubus32_t { - IOPort low; - IOPort high; + ComplexBitMap low; + ComplexBitMap high; constexpr ubus32_t(uint32_t value) { *this = value; @@ -210,10 +237,10 @@ 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 __declare_io_port_global_array(type, name, adr, size) static __always_inline auto& name = reinterpret_cast(*reinterpret_cast((IO_Base_Adr + (adr & ~IO_Base_Mask)))); -#define __io_port_inherit(name) \ - using IOPort::operator=; \ +#define __io_port_inherit_complex_bit_map(name) \ + using ComplexBitMap::operator=; \ constexpr name() = default; \ - constexpr name(IOPort value) : IOPort(value) { \ + constexpr name(ComplexBitMap value) : ComplexBitMap(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 03316642..f56a2aeb 100644 --- a/include/PSX/System/IOPorts/SPU_IO.hpp +++ b/include/PSX/System/IOPorts/SPU_IO.hpp @@ -26,19 +26,19 @@ namespace SPU { //0..3 = +7, +6, +5, +4 or -6, -7, -6, -5 typedef uint8_t Step; - struct __no_align SampleRate : public IOPort { - __io_port_inherit(SampleRate); + struct __no_align SampleRate : public ComplexBitMap { + __io_port_inherit_complex_bit_map(SampleRate); static constexpr SampleRate from_HZ(double freq) { //4096 == 44100Hz constexpr double Base = (4096.0 / 44100.0); - return IOPort(static_cast((freq*Base))); + return ComplexBitMap(static_cast((freq*Base))); } }; - struct __no_align SweepVolume : public IOPort { - __io_port_inherit(SweepVolume); + struct __no_align SweepVolume : public ComplexBitMap { + __io_port_inherit_complex_bit_map(SweepVolume); // For Volume Mode static constexpr Bit SweepEnable = 15; // 0 Volume Mode; 1 Sweep Mode @@ -52,8 +52,8 @@ namespace SPU { static constexpr BitRange SweepStep = BitRange::from_to(0, 1); }; - struct __no_align SR : public IOPort { - __io_port_inherit(SR); + struct __no_align SR : public ComplexBitMap { + __io_port_inherit_complex_bit_map(SR); static constexpr Bit SustainMode = (31 - 16); static constexpr Bit SustainDirection = (30 - 16); @@ -63,8 +63,8 @@ namespace SPU { static constexpr BitRange ReleaseShift = BitRange::from_to((16 - 16), (20 - 16)); }; - struct __no_align AD : public IOPort { - __io_port_inherit(AD); + struct __no_align AD : public ComplexBitMap { + __io_port_inherit_complex_bit_map(AD); static constexpr Bit AttackMode = 15; static constexpr BitRange AttackShift = BitRange::from_to(10, 14); @@ -74,9 +74,9 @@ namespace SPU { }; struct __no_align Voice { - SweepVolume volumeLeft; //Offset: 0x0 - SweepVolume volumeRight; //Offset: 0x2 - SampleRate sampleRate; //Offset: 0x4; + IOPort volumeLeft; //Offset: 0x0 + IOPort volumeRight; //Offset: 0x2 + IOPort sampleRate; //Offset: 0x4; IOPort adr; //Offset: 0x6 IOPort ad; //Offset: 0x8 IOPort sr; //Offset: 0xA @@ -84,8 +84,8 @@ namespace SPU { IOPort repeatAdr; //Offset: 0xE }; - struct __no_align ControlRegister : public IOPort { - __io_port_inherit(ControlRegister); + struct __no_align ControlRegister : public ComplexBitMap { + __io_port_inherit_complex_bit_map(ControlRegister); enum RAMTransferMode { Stop = 0, @@ -107,20 +107,20 @@ namespace SPU { static constexpr Bit CDAudioEnable = 0; }; - struct __no_align PitchModFlags : public IOPort { - __io_port_inherit(PitchModFlags); + struct __no_align PitchModFlags : public ComplexBitMap { + __io_port_inherit_complex_bit_map(PitchModFlags); static constexpr BitRange EnableBits = BitRange::from_to(1, 23); }; - struct __no_align NoiseGenerator : public IOPort { - __io_port_inherit(NoiseGenerator); + struct __no_align NoiseGenerator : public ComplexBitMap { + __io_port_inherit_complex_bit_map(NoiseGenerator); static constexpr BitRange NoiseBits = BitRange::from_to(0, 23); }; - struct __no_align EchoOn : public IOPort { - __io_port_inherit(EchoOn); + struct __no_align EchoOn : public ComplexBitMap { + __io_port_inherit_complex_bit_map(EchoOn); static constexpr BitRange EchoBits = BitRange::from_to(0, 23); }; diff --git a/src/Library/src/BootLoader/boot_spu.cpp b/src/Library/src/BootLoader/boot_spu.cpp index 4510aff8..833e94e8 100644 --- a/src/Library/src/BootLoader/boot_spu.cpp +++ b/src/Library/src/BootLoader/boot_spu.cpp @@ -10,7 +10,7 @@ namespace SPU { } static void clear_main_volume() { - static constexpr auto StartVol = SweepVolume() | !SweepVolume::SweepEnable | (SweepVolume::Volume << static_cast(I16_MAX >> 2)); + static constexpr auto StartVol = SweepVolume().set(!SweepVolume::SweepEnable).set(SweepVolume::Volume, I16_MAX >> 2); MainVolume::left.write(StartVol); MainVolume::right.write(StartVol); @@ -58,7 +58,7 @@ namespace SPU { } static void setup_control_register() { - static constexpr auto SetupValue = ControlRegister() | ControlRegister::Enable | ControlRegister::Unmute | ControlRegister::CDAudioEnable; + static constexpr auto SetupValue = ControlRegister().set(ControlRegister::Enable).set(ControlRegister::Unmute).set(ControlRegister::CDAudioEnable); Control.write(SetupValue); } @@ -84,5 +84,6 @@ namespace SPU { // Enable SPU DMA DPCR.write(DPCR.read() | DMAControlRegister::SPUEnable); + while(!DPCR.read().is_bit_set(DMAControlRegister::SPUEnable)); } } \ No newline at end of file