From 28122a8e1cada76fb3324f6cfdca6b0c63fc8b3a Mon Sep 17 00:00:00 2001 From: Jaby Date: Sun, 11 Sep 2022 11:36:51 +0200 Subject: [PATCH] Making ComplexBitMap a POD part 1 --- include/PSX/Auxiliary/complex_bitmap.hpp | 300 +++++++++++++++++++++++ include/PSX/GPU/GPU_Types.hpp | 60 ++++- include/PSX/System/IOPorts/DMA_IO.hpp | 12 +- include/PSX/System/IOPorts/GPU_IO.hpp | 12 +- include/PSX/System/IOPorts/IOPort.hpp | 230 ++--------------- include/PSX/System/IOPorts/SPU_IO.hpp | 2 +- src/Library/include/GPU/GPU.h | 2 +- src/Library/src/BootLoader/gpu_boot.cpp | 4 +- src/Library/src/BootLoader/spu_boot.cpp | 2 +- 9 files changed, 386 insertions(+), 238 deletions(-) create mode 100644 include/PSX/Auxiliary/complex_bitmap.hpp diff --git a/include/PSX/Auxiliary/complex_bitmap.hpp b/include/PSX/Auxiliary/complex_bitmap.hpp new file mode 100644 index 00000000..2ea4fdeb --- /dev/null +++ b/include/PSX/Auxiliary/complex_bitmap.hpp @@ -0,0 +1,300 @@ +#ifndef __JABYENGINE_COMPLEX_BITMAP_HPP__ +#define __JABYENGINE_COMPLEX_BITMAP_HPP__ +#include "bits.hpp" + +struct ClearBitValue { + size_t bit; + + constexpr ClearBitValue(size_t bit) : bit(bit) { + } +}; + +template +struct Bit { + typedef T ValueType; + + size_t value; + + constexpr Bit(size_t value) : value(value) { + } + + constexpr operator size_t() const { + return this->value; + } + + constexpr ClearBitValue operator!() const { + return ClearBitValue(this->value); + } +}; + +template +struct BitRangeValue { + T value; + size_t begin; + size_t length; +}; + +template +struct BitRange { + typedef T ValueType; + + size_t begin; + size_t length; + + static constexpr BitRange from_to(size_t start, size_t end) { + return {start, (end - start + 1)}; + } + + constexpr BitRangeValue with(T value) const { + return {value, this->begin, this->length}; + } +}; + +template +static constexpr __always_inline BitRangeValue operator<<(const BitRange& range, T value) { + return BitRangeValue{value, range.begin, range.length}; +} + +template +class ComplexBitMap { +public: + T raw; + +private: + template + constexpr ComplexBitMap& set_va(const S& value) { + return this->set(value); + } + + template + constexpr ComplexBitMap& set_va(const S& value, const ARGS&...args) { + return this->set_va(value).set_va(args...); + } + +public: + template + static constexpr ComplexBitMap with(ARGS...args) { + return ComplexBitMap().set_va(args...); + } + + //Accesssing bits + template + constexpr ComplexBitMap& set_bit(S bit) { + this->raw = bit::set(this->raw, static_cast(bit)); + return *this; + } + + template + constexpr ComplexBitMap& clear_bit(S bit) { + this->raw = bit::clear(this->raw, static_cast(bit)); + return *this; + } + + template + constexpr bool is_bit_set(S bit) { + return bit::is_set(this->raw, static_cast(bit)); + } + + //Accessing values + template + constexpr ComplexBitMap& set_value(S value, const BitRange& range) { + this->raw = bit::value::set_normalized(this->raw, static_cast(value), range.begin, range.length); + return *this; + } + + template + constexpr ComplexBitMap& clear_value(const BitRange& range) { + this->raw = bit::value::clear_normalized(this->raw, range.begin, range.length); + return *this; + } + + template + constexpr S get_value(const BitRange& range) { + return static_cast(bit::value::get_normalized(this->raw, 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.begin, value.length}); + 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; + } +}; + +/*template +class ComplexBitMap { +public: + T value = 0; + +private: + template + constexpr ComplexBitMap& set_va(const S& value) { + return this->set(value); + } + + template + constexpr ComplexBitMap& set_va(const S& value, const ARGS&...args) { + return this->set_va(value).set_va(args...); + } + +public: + constexpr ComplexBitMap() = default; + constexpr ComplexBitMap(T value) : value(value) { + } + + template + static constexpr ComplexBitMap with(ARGS...args) { + return ComplexBitMap().set_va(args...); + } + + //Accesssing bits + template + constexpr ComplexBitMap& set_bit(S bit) { + this->value = bit::set(this->value, static_cast(bit)); + return *this; + } + + template + constexpr void set_bit(S bit) volatile { + this->value = bit::set(this->value, static_cast(bit)); + } + + template + constexpr ComplexBitMap& clear_bit(S bit) { + this->value = bit::clear(this->value, static_cast(bit)); + return *this; + } + + template + constexpr void clear_bit(S bit) volatile { + this->value = bit::clear(this->value, static_cast(bit)); + } + + template + constexpr bool is_bit_set(S bit) { + return bit::is_set(this->value, static_cast(bit)); + } + + template + constexpr bool is_bit_set(S bit) volatile { + return bit::is_set(this->value, static_cast(bit)); + } + + //Accessing values + template + 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; + } + + template + constexpr void set_value(S value, const BitRange& range) volatile { + this->value = bit::value::set_normalized(this->value, static_cast(value), range.begin, range.length); + } + + template + constexpr ComplexBitMap& clear_value(const BitRange& range) { + this->value = bit::value::clear_normalized(this->value, range.begin, range.length); + return *this; + } + + template + constexpr void clear_value(const BitRange& range) volatile { + this->value = bit::value::clear_normalized(this->value, range.begin, range.length); + } + + template + constexpr S get_value(const BitRange& range) { + return static_cast(bit::value::get_normalized(this->value, range.begin, range.length)); + } + + template + constexpr S get_value(const BitRange& range) volatile { + 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.begin, value.length}); + 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; + } +};*/ + +#endif //!__JABYENGINE_COMPLEX_BITMAP_HPP__ \ No newline at end of file diff --git a/include/PSX/GPU/GPU_Types.hpp b/include/PSX/GPU/GPU_Types.hpp index d662b1d6..b0b31c28 100644 --- a/include/PSX/GPU/GPU_Types.hpp +++ b/include/PSX/GPU/GPU_Types.hpp @@ -1,39 +1,73 @@ #ifndef __JABYENGINE_GPU_TYPES_HPP__ #define __JABYENGINE_GPU_TYPES_HPP__ #include "../jabyengine_defines.h" +#include "../Auxiliary/complex_bitmap.hpp" namespace GPU { - struct Color { + struct Color24 { uint8_t red = 0; uint8_t green = 0; uint8_t blue = 0; - constexpr Color() = default; - constexpr Color(uint8_t r, uint8_t g, uint8_t b) : blue(b), green(g), red(r) { + constexpr Color24() = default; + constexpr Color24(uint8_t r, uint8_t g, uint8_t b) : blue(b), green(g), red(r) { } constexpr uint32_t raw() const { return ((this->blue << 16) | (this->green << 8) | this->red); } - static constexpr Color Black() { - return Color(0, 0, 0); + static constexpr Color24 Black() { + return Color24(0, 0, 0); } - static constexpr Color White() { - return Color(0xFF, 0xFF, 0xFF); + static constexpr Color24 White() { + return Color24(0xFF, 0xFF, 0xFF); } - static constexpr Color Red() { - return Color(0xFF, 0x0, 0x0); + static constexpr Color24 Red() { + return Color24(0xFF, 0x0, 0x0); } - static constexpr Color Green() { - return Color(0x0, 0x0, 0xFF); + static constexpr Color24 Green() { + return Color24(0x0, 0x0, 0xFF); } - static constexpr Color Blue() { - return Color(0x0, 0x0, 0xFF); + static constexpr Color24 Blue() { + return Color24(0x0, 0x0, 0xFF); + } + }; + + class Color16 { + private: + static constexpr auto RedRange = BitRange::from_to(0, 4); + static constexpr auto BlueRange = BitRange::from_to(5, 9); + static constexpr auto GreenRange = BitRange::from_to(10, 14); + static constexpr auto SemiTransperancyBit = Bit(15); + + ComplexBitMap value = {0}; + + public: + constexpr Color16() = default; + constexpr Color16(uint8_t r, uint8_t g, uint8_t b) { + Color16::set_red(r); + Color16::set_green(g); + Color16::set_blue(b); + } + + constexpr Color16(const Color24& color) : Color16(color.red, color.green, color.blue) { + } + + constexpr void set_red(uint8_t red) { + this->value.set_value(static_cast(red), RedRange); + } + + constexpr void set_green(uint8_t green) { + this->value.set_value(static_cast(green), GreenRange); + } + + constexpr void set_blue(uint8_t blue) { + this->value.set_value(static_cast(blue), BlueRange); } }; diff --git a/include/PSX/System/IOPorts/DMA_IO.hpp b/include/PSX/System/IOPorts/DMA_IO.hpp index e5fc47e1..e179e973 100644 --- a/include/PSX/System/IOPorts/DMA_IO.hpp +++ b/include/PSX/System/IOPorts/DMA_IO.hpp @@ -58,27 +58,27 @@ namespace DMA { static constexpr auto ToMainRAM = !FromMainRAM; static constexpr CHCHR StartMDECin() { - return CHCHR(0x01000201); + return ComplexBitMap{0x01000201}; } static constexpr CHCHR StartMDECout() { - return CHCHR(0x01000200); + return ComplexBitMap{0x01000200}; } static constexpr CHCHR StartGPUReceive() { - return CHCHR(0x01000201); + return ComplexBitMap{0x01000201}; } static constexpr CHCHR StartCDROM() { - return CHCHR(0x11000000); + return ComplexBitMap{0x11000000}; } static constexpr CHCHR StartSPUReceive() { - return CHCHR(0x01000201); + return ComplexBitMap{0x01000201}; } static constexpr CHCHR StartOTC() { - return CHCHR(0x11000002); + return ComplexBitMap{0x11000002}; } }; diff --git a/include/PSX/System/IOPorts/GPU_IO.hpp b/include/PSX/System/IOPorts/GPU_IO.hpp index 79daa8ca..f18270df 100644 --- a/include/PSX/System/IOPorts/GPU_IO.hpp +++ b/include/PSX/System/IOPorts/GPU_IO.hpp @@ -46,16 +46,16 @@ namespace GPU { struct __no_align GP0 : public ComplexBitMap { __io_port_inherit_complex_bit_map(GP0); - static constexpr GP0 QuickFill(Color color) { - return {(0x02 << 24) | color.raw()}; + static constexpr GP0 QuickFill(Color24 color) { + return ComplexBitMap{(0x02 << 24) | color.raw()}; } static constexpr GP0 TopLeftPosition(uint16_t x, uint16_t y) { - return {(y << 16) | x}; + return ComplexBitMap{static_cast((y << 16) | x)}; } static constexpr GP0 WidthHeight(uint16_t w, uint16_t h) { - return {(h << 16) | w}; + return ComplexBitMap{static_cast((h << 16) | w)}; } }; @@ -67,11 +67,11 @@ namespace GPU { } static constexpr GP1 Reset() { - return {0}; + return ComplexBitMap{0}; } static constexpr GP1 SetDisplayState(DisplayState state) { - return {construct_cmd(0x03, static_cast(state))}; + return ComplexBitMap{construct_cmd(0x03, static_cast(state))}; } }; } diff --git a/include/PSX/System/IOPorts/IOPort.hpp b/include/PSX/System/IOPorts/IOPort.hpp index 9e9d6ad2..f4ab46b2 100644 --- a/include/PSX/System/IOPorts/IOPort.hpp +++ b/include/PSX/System/IOPorts/IOPort.hpp @@ -1,205 +1,6 @@ #ifndef __JABYENGINE_IOPORT_HPP__ #define __JABYENGINE_IOPORT_HPP__ -#include "../../Auxiliary/bits.hpp" - -struct ClearBitValue { - size_t bit; - - constexpr ClearBitValue(size_t bit) : bit(bit) { - } -}; - -template -struct Bit { - typedef T ValueType; - - size_t value; - - constexpr Bit(size_t value) : value(value) { - } - - constexpr operator size_t() const { - return this->value; - } - - constexpr ClearBitValue operator!() const { - return ClearBitValue(this->value); - } -}; - -template -struct BitRangeValue { - T value; - size_t begin; - size_t length; -}; - -template -struct BitRange { - typedef T ValueType; - - size_t begin; - size_t length; - - static constexpr BitRange from_to(size_t start, size_t end) { - return {start, (end - start + 1)}; - } - - constexpr BitRangeValue with(T value) const { - return {value, this->begin, this->length}; - } -}; - -template -static constexpr __always_inline BitRangeValue operator<<(const BitRange& range, T value) { - return BitRangeValue{value, range.begin, range.length}; -} - -template -class __no_align ComplexBitMap { -private: - T value = 0; - - template - constexpr ComplexBitMap& set_va(const S& value) { - return this->set(value); - } - - template - constexpr ComplexBitMap& set_va(const S& value, const ARGS&...args) { - return this->set_va(value).set_va(args...); - } - -public: - constexpr ComplexBitMap() = default; - constexpr ComplexBitMap(T value) : value(value) { - } - - template - static constexpr ComplexBitMap with(ARGS...args) { - return ComplexBitMap().set_va(args...); - } - - //Accesssing bits - template - constexpr ComplexBitMap& set_bit(S bit) { - this->value = bit::set(this->value, static_cast(bit)); - return *this; - } - - template - constexpr void set_bit(S bit) volatile { - this->value = bit::set(this->value, static_cast(bit)); - } - - template - constexpr ComplexBitMap& clear_bit(S bit) { - this->value = bit::clear(this->value, static_cast(bit)); - return *this; - } - - template - constexpr void clear_bit(S bit) volatile { - this->value = bit::clear(this->value, static_cast(bit)); - } - - template - constexpr bool is_bit_set(S bit) { - return bit::is_set(this->value, static_cast(bit)); - } - - template - constexpr bool is_bit_set(S bit) volatile { - return bit::is_set(this->value, static_cast(bit)); - } - - //Accessing values - template - 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; - } - - template - constexpr void set_value(S value, const BitRange& range) volatile { - this->value = bit::value::set_normalized(this->value, static_cast(value), range.begin, range.length); - } - - template - constexpr ComplexBitMap& clear_value(const BitRange& range) { - this->value = bit::value::clear_normalized(this->value, range.begin, range.length); - return *this; - } - - template - constexpr void clear_value(const BitRange& range) volatile { - this->value = bit::value::clear_normalized(this->value, range.begin, range.length); - } - - template - constexpr S get_value(const BitRange& range) { - return static_cast(bit::value::get_normalized(this->value, range.begin, range.length)); - } - - template - constexpr S get_value(const BitRange& range) volatile { - 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.begin, value.length}); - 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; - } -}; +#include "../../Auxiliary/complex_bitmap.hpp" template class __no_align IOPort { @@ -230,23 +31,23 @@ struct __no_align ubus32_t { } constexpr operator uint32_t() const { - return ((this->high << 16) | this->low); + return ((this->high.raw << 16) | this->low.raw); } - constexpr operator uint32_t() const volatile { - return ((this->high << 16) | this->low); + operator uint32_t() const volatile { + return ((this->high.raw << 16) | this->low.raw); } constexpr ubus32_t& operator=(uint32_t value) { - this->low = (value & 0xFFFF); - this->high = (value >> 16); + this->low.raw = (value & 0xFFFF); + this->high.raw = (value >> 16); return *this; } constexpr void operator=(uint32_t value) volatile { - this->low = (value & 0xFFFF); - this->high = (value >> 16); + this->low.raw = (value & 0xFFFF); + this->high.raw = (value >> 16); } }; static constexpr uintptr_t IO_Base_Mask = 0xF0000000; @@ -257,12 +58,25 @@ static constexpr uintptr_t IO_Base_Adr = 0x10000000; #define __declare_io_port_global_const(type, name, adr) __declare_io_port_global_raw(const, type, name, adr) #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_complex_bit_map(name) \ + constexpr name() = default; \ + constexpr name(ComplexBitMap value) : ComplexBitMap(value) { \ + } \ + template \ + static constexpr name with(ARGS...args) { \ + return {ComplexBitMap::with(args...)}; \ + }\ + template \ + constexpr void operator=(ComplexBitMap value) volatile { \ + this->raw = value.raw; \ + } + +/*\ using ComplexBitMap::operator=; \ constexpr name() = default; \ constexpr name(ComplexBitMap value) : ComplexBitMap(value) { \ }\ template \ constexpr name(ARGS...args) : ComplexBitMap(args...) {\ - } + }*/ #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 b2e87f6e..23994843 100644 --- a/include/PSX/System/IOPorts/SPU_IO.hpp +++ b/include/PSX/System/IOPorts/SPU_IO.hpp @@ -34,7 +34,7 @@ namespace SPU { //4096 == 44100Hz constexpr double Base = (4096.0 / 44100.0); - return ComplexBitMap(static_cast((freq*Base))); + return ComplexBitMap{static_cast((freq*Base))}; } }; diff --git a/src/Library/include/GPU/GPU.h b/src/Library/include/GPU/GPU.h index c6f4f2ab..6c59609b 100644 --- a/src/Library/include/GPU/GPU.h +++ b/src/Library/include/GPU/GPU.h @@ -4,7 +4,7 @@ #include namespace GPU { - static void quick_fill_fast(const Color& color, const PositionU16& pos, const SizeU16& size) { + static void quick_fill_fast(const Color24& color, const PositionU16& pos, const SizeU16& size) { Port::GP0.write(Port::Command::GP0::QuickFill(color)); Port::GP0.write(Port::Command::GP0::TopLeftPosition(pos.x, pos.y)); Port::GP0.write(Port::Command::GP0::WidthHeight(size.width, size.height)); diff --git a/src/Library/src/BootLoader/gpu_boot.cpp b/src/Library/src/BootLoader/gpu_boot.cpp index 811ace67..da2d0ade 100644 --- a/src/Library/src/BootLoader/gpu_boot.cpp +++ b/src/Library/src/BootLoader/gpu_boot.cpp @@ -6,13 +6,13 @@ namespace GPU { void display_logo() { Display::disable(); - quick_fill_fast(Color(0x0, 0x80, 0x80), PositionU16(0, 0), SizeU16(640, 480)); + quick_fill_fast(Color24(0x0, 0x80, 0x80), PositionU16(0, 0), SizeU16(640, 480)); Display::enable(); } void setup() { Port::GP1.write(Port::Command::GP1::Reset()); - quick_fill_fast(Color::Black(), PositionU16(0, 0), SizeU16(640, 480)); + quick_fill_fast(Color24::Black(), PositionU16(0, 0), SizeU16(640, 480)); } } \ No newline at end of file diff --git a/src/Library/src/BootLoader/spu_boot.cpp b/src/Library/src/BootLoader/spu_boot.cpp index e998eee6..6c07ea53 100644 --- a/src/Library/src/BootLoader/spu_boot.cpp +++ b/src/Library/src/BootLoader/spu_boot.cpp @@ -33,7 +33,7 @@ namespace SPU { voice.sampleRate.write(SampleRate()); voice.ad.write(AD()); voice.sr.write(SR()); - voice.currentVolume.write(SweepVolume()); + voice.currentVolume.write(SimpleVolume(0)); voice.adr.write(0x200); voice.repeatAdr.write(0x200);