#ifndef __JABYENGINE_IOPORT_HPP__ #define __JABYENGINE_IOPORT_HPP__ #include "../../Auxiliary/bits.hpp" struct BitRange { size_t begin; size_t length; static constexpr BitRange from_to(size_t start, size_t end) { return {start, (end - start + 1)}; } }; template class __no_align IOPort { private: T value = 0; public: constexpr IOPort() = default; constexpr IOPort(T value) : value(value) { } //Accesssing bits template constexpr IOPort& set_bit(S bit) { this->value = bit::set(this->value, static_cast(bit)); return *this; } template constexpr volatile IOPort& set_bit(S bit) volatile { this->value = bit::set(this->value, static_cast(bit)); return *this; } template constexpr IOPort& clear_bit(S bit) { this->value = bit::set(this->value, static_cast(bit)); return *this; } template constexpr volatile IOPort& clear_bit(S bit) volatile { this->value = bit::set(this->value, static_cast(bit)); return *this; } 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 IOPort& 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 volatile IOPort& set_value(S value, const BitRange& range) volatile { this->value = bit::value::set_normalized(this->value, static_cast(value), range.begin, range.length); return *this; } template constexpr IOPort& clear_value(const BitRange& range) { this->value = bit::value::clear_normalized(this->value, range.begin, range.length); return *this; } template constexpr volatile IOPort& clear_value(const BitRange& range) volatile { this->value = bit::value::clear_normalized(this->value, range.begin, range.length); return *this; } 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 raw access constexpr operator T() const { return this->value; } constexpr operator T() const volatile { return this->value; } constexpr void operator=(T value) { this->value = value; } constexpr void operator=(T value) volatile { this->value = value; } }; #endif //!__JABYENGINE_IOPORT_HPP__