diff --git a/include/PSX/System/IOPorts/ioport.hpp b/include/PSX/System/IOPorts/ioport.hpp index d6d95578..72880b16 100644 --- a/include/PSX/System/IOPorts/ioport.hpp +++ b/include/PSX/System/IOPorts/ioport.hpp @@ -53,19 +53,23 @@ namespace JabyEngine { }; #define __declare_new_io_port(name, adr) \ - typedef name##_io_base name##_v; \ - typedef name##_io_base name##_t; \ static auto& name = *reinterpret_cast(adr) +/*constexpr name##_io_base() = default; \ + \ + constexpr name##_io_base(type value) : raw_value(value) {} \ + \*/ + #define __declare_io_type(name, type, ...) \ template typename T> \ struct name##_io_base { \ T::Value raw_value = 0; \ \ - constexpr name##_io_base() = default; \ - \ - constexpr name##_io_base(type value) : raw_value(value) {} \ __VA_ARGS__ \ + template \ + static constexpr name##_io_base from(const ARGS&...args) { \ + return name##_io_base().set_va(args...); \ + } \ \ constexpr name##_io_base& set(IOBitSet bit) { \ this->raw_value = bit::set(this->raw_value, bit.pos); \ @@ -87,7 +91,15 @@ namespace JabyEngine { return *this; \ } \ \ - type get(IOValueSet bits) const { \ + template \ + constexpr name##_io_base& set_va(const S& head) { \ + return this->set(head); \ + } \ + template \ + constexpr name##_io_base& set_va(const S& head, const ARGS&...tail) { \ + return this->set(head).set_va(tail...); \ + } \ + constexpr type get(IOValueSet bits) const { \ return bit::value::get_normalized(this->raw_value, bits.pos, bits.length); \ } \ \ @@ -98,22 +110,25 @@ namespace JabyEngine { } \ \ \ - bool is_set(IOBitSet bit) const { \ + constexpr bool is_set(IOBitSet bit) const { \ return bit::is_set(this->raw_value, bit.pos); \ } \ \ \ - void operator=(type value) { \ + constexpr void operator=(type value) { \ this->raw_value = value; \ } \ \ - type operator*() const { \ + constexpr type operator*() const { \ return this->raw_value; \ } \ - } + }; \ + \ + typedef name##_io_base name##_v; \ + typedef name##_io_base name##_t \ template - struct __attribute__((deprecated)) VolatilePOD { + struct VolatilePOD { volatile T raw; constexpr T read() const { @@ -127,7 +142,7 @@ namespace JabyEngine { // For use with ComplexBitMaps or what else satisfies this API template - struct __attribute__((deprecated)) VolatileBitMapPOD { + struct VolatileBitMapPOD { typedef typename T::UnderlyingType Raw; VolatilePOD pod; diff --git a/include/PSX/System/IOPorts/timer_io.hpp b/include/PSX/System/IOPorts/timer_io.hpp index c8ff6e96..8343f70b 100644 --- a/include/PSX/System/IOPorts/timer_io.hpp +++ b/include/PSX/System/IOPorts/timer_io.hpp @@ -4,94 +4,108 @@ namespace JabyEngine { namespace Timer_IO { - struct CounterMode : public ComplexBitMap { - static constexpr auto SyncEnable = Bit(0); + __declare_io_type(CounterMode, uint32_t, + static constexpr auto SyncEnable = IOBitSet(0); static constexpr auto FreeRun = !SyncEnable; - static constexpr auto SyncMode = BitRange::from_to(1, 2); - static constexpr auto ResetAfterTarget = Bit(3); - static constexpr auto IRQAtTarget = Bit(4); - static constexpr auto IRQAtMax = Bit(5); - static constexpr auto IRQEveryTime = Bit(6); + static constexpr auto SyncMode = IOValueSet::from_to(1, 2); + static constexpr auto ResetAfterTarget = IOBitSet(3); + static constexpr auto IRQAtTarget = IOBitSet(4); + static constexpr auto IRQAtMax = IOBitSet(5); + static constexpr auto IRQEveryTime = IOBitSet(6); static constexpr auto IRQOneShot = !IRQEveryTime; - static constexpr auto IRQToggle = Bit(7); + static constexpr auto IRQToggle = IOBitSet(7); static constexpr auto IRQPulse = !IRQToggle; - static constexpr auto ClockSource = BitRange::from_to(8, 9); - static constexpr auto HasIRQRequest = Bit(10); - static constexpr auto IsTargetReached = Bit(11); - static constexpr auto IsMaxReached = Bit(12); - }; + static constexpr auto ClockSource = IOValueSet::from_to(8, 9); + static constexpr auto HasIRQRequest = IOBitSet(10); + static constexpr auto IsTargetReached = IOBitSet(11); + static constexpr auto IsMaxReached = IOBitSet(12); + ); - struct CounterTarget : public ComplexBitMap { - static constexpr auto CounterTargetValue = BitRange::from_to(0, 15); - }; + __declare_io_type(CounterTarget, uint32_t, + static constexpr auto CounterTargetValue = IOValueSet::from_to(0, 15); + ); - struct CounterValue : public ComplexBitMap { - static constexpr auto Value = BitRange::from_to(0, 15); - }; + __declare_io_type(CounterValue, uint32_t, + static constexpr auto Value = IOValueSet::from_to(0, 15); + ); struct __no_align Counter { - VolatileBitMapPOD value; - VolatileBitMapPOD mode; - VolatileBitMapPOD target; + CounterValue_v value; + CounterMode_v mode; + CounterTarget_v target; + private: uint32_t _unused; + + public: + constexpr uint16_t get_current_value() const { + return this->value.get(CounterValue_v::Value); + } + + constexpr void set_target_value(uint16_t value) { + this->target.set(CounterTarget_v::CounterTargetValue, value); + } + + constexpr void set_mode(CounterMode_t mode) { + this->mode = *mode; + } }; static constexpr uintptr_t counter_base_adr(size_t ID) { return (0x1F801100 + (ID*0x10)); } - struct __no_align Counter0 : public Counter { + struct __no_align Counter0_v : public Counter { struct SyncMode { - static constexpr auto Pause_During_Hblank = CounterMode::SyncMode.with(0); - static constexpr auto Zero_At_Hblank = CounterMode::SyncMode.with(1); - static constexpr auto Zero_At_Hblank_Pause_Outside_Hblank = CounterMode::SyncMode.with(2); - static constexpr auto Pause_Until_Hblank_Then_Freerun = CounterMode::SyncMode.with(3); + static constexpr auto Pause_During_Hblank = CounterMode_v::SyncMode.with(0u); + static constexpr auto Zero_At_Hblank = CounterMode_v::SyncMode.with(1u); + static constexpr auto Zero_At_Hblank_Pause_Outside_Hblank = CounterMode_v::SyncMode.with(2u); + static constexpr auto Pause_Until_Hblank_Then_Freerun = CounterMode_v::SyncMode.with(3u); }; struct Source { - static constexpr auto System_Clock = CounterMode::ClockSource.with(0); - static constexpr auto Dot_Clock = CounterMode::ClockSource.with(1); - static constexpr auto System_Clock_Too = CounterMode::ClockSource.with(2); - static constexpr auto Dot_Clock_Too = CounterMode::ClockSource.with(3); + static constexpr auto System_Clock = CounterMode_v::ClockSource.with(0u); + static constexpr auto Dot_Clock = CounterMode_v::ClockSource.with(1u); + static constexpr auto System_Clock_Too = CounterMode_v::ClockSource.with(2u); + static constexpr auto Dot_Clock_Too = CounterMode_v::ClockSource.with(3u); }; }; - struct __no_align Counter1 : public Counter { + struct __no_align Counter1_v : public Counter { struct SyncMode { - static constexpr auto Pause_During_Vblank = CounterMode::SyncMode.with(0); - static constexpr auto Zero_At_Vblank = CounterMode::SyncMode.with(1); - static constexpr auto Zero_At_Vblank_Pause_Outside_Vblank = CounterMode::SyncMode.with(2); - static constexpr auto Pause_Until_Vblank_Then_Freerun = CounterMode::SyncMode.with(3); + static constexpr auto Pause_During_Vblank = CounterMode_v::SyncMode.with(0u); + static constexpr auto Zero_At_Vblank = CounterMode_v::SyncMode.with(1u); + static constexpr auto Zero_At_Vblank_Pause_Outside_Vblank = CounterMode_v::SyncMode.with(2u); + static constexpr auto Pause_Until_Vblank_Then_FreeRun = CounterMode_v::SyncMode.with(3u); }; struct Source { - static constexpr auto System_Clock = CounterMode::ClockSource.with(0); - static constexpr auto Hblank = CounterMode::ClockSource.with(1); - static constexpr auto System_Clock_Too = CounterMode::ClockSource.with(2); - static constexpr auto Hblank_Too = CounterMode::ClockSource.with(3); + static constexpr auto System_Clock = CounterMode_v::ClockSource.with(0u); + static constexpr auto Hblank = CounterMode_v::ClockSource.with(1u); + static constexpr auto System_Clock_Too = CounterMode_v::ClockSource.with(2u); + static constexpr auto Hblank_Too = CounterMode_v::ClockSource.with(3u); }; }; - struct __no_align Counter2 : public Counter { + struct __no_align Counter2_v : public Counter { struct SyncMode { - static constexpr auto Stop_Counter = CounterMode::SyncMode.with(0); - static constexpr auto Freerun = CounterMode::SyncMode.with(1); - static constexpr auto Freerun_Too = CounterMode::SyncMode.with(2); - static constexpr auto Stop_Counter_Too = CounterMode::SyncMode.with(3); + static constexpr auto Stop_Counter = CounterMode_v::SyncMode.with(0u); + static constexpr auto FreeRun = CounterMode_v::SyncMode.with(1u); + static constexpr auto FreeRun_Too = CounterMode_v::SyncMode.with(2u); + static constexpr auto Stop_Counter_Too = CounterMode_v::SyncMode.with(3u); }; struct Source { - static constexpr auto System_Clock = CounterMode::ClockSource.with(0); - static constexpr auto System_Clock_Too = CounterMode::ClockSource.with(1); - static constexpr auto System_Clock_Div_8 = CounterMode::ClockSource.with(2); - static constexpr auto System_Clock_Div_8_Too = CounterMode::ClockSource.with(3); + static constexpr auto System_Clock = CounterMode_v::ClockSource.with(0u); + static constexpr auto System_Clock_Too = CounterMode_v::ClockSource.with(1u); + static constexpr auto System_Clock_Div_8 = CounterMode_v::ClockSource.with(2u); + static constexpr auto System_Clock_Div_8_Too = CounterMode_v::ClockSource.with(3u); }; }; - __declare_io_port_global_struct(struct Counter0, Counter0, counter_base_adr(0)); - __declare_io_port_global_struct(struct Counter1, Counter1, counter_base_adr(1)); - __declare_io_port_global_struct(struct Counter2, Counter2, counter_base_adr(2)); + __declare_new_io_port(Counter0, counter_base_adr(0)); + __declare_new_io_port(Counter1, counter_base_adr(1)); + __declare_new_io_port(Counter2, counter_base_adr(2)); } } diff --git a/include/PSX/Timer/high_res_timer.hpp b/include/PSX/Timer/high_res_timer.hpp index 7cb78e5c..9ae8141d 100644 --- a/include/PSX/Timer/high_res_timer.hpp +++ b/include/PSX/Timer/high_res_timer.hpp @@ -66,7 +66,7 @@ namespace JabyEngine { ~HighResTime() = delete; static TimeStamp get_time_stamp() { - return TimeStamp(HighResTime::global_counter_10ms, Timer_IO::Counter2.value.read(Timer_IO::CounterValue::Value)); + return TimeStamp(HighResTime::global_counter_10ms, Timer_IO::Counter2.get_current_value()); } }; #endif //JABYENGINE_USE_HIGH_PERCISION_TIMER diff --git a/src/Library/src/BootLoader/timer_boot.cpp b/src/Library/src/BootLoader/timer_boot.cpp index 0d348a79..201e41ba 100644 --- a/src/Library/src/BootLoader/timer_boot.cpp +++ b/src/Library/src/BootLoader/timer_boot.cpp @@ -18,7 +18,7 @@ void setup() { using namespace Timer_IO; - static constexpr auto Mode = CounterMode::with(CounterMode::FreeRun, Counter2::SyncMode::Freerun, CounterMode::ResetAfterTarget, CounterMode::IRQAtTarget, CounterMode::IRQEveryTime, CounterMode::IRQPulse, Counter2::Source::System_Clock_Div_8); + static constexpr auto Mode = CounterMode_t::from(CounterMode_t::FreeRun, Counter2_v::SyncMode::FreeRun, CounterMode_t::ResetAfterTarget, CounterMode_t::IRQAtTarget, CounterMode_t::IRQEveryTime, CounterMode_t::IRQPulse, Counter2_v::Source::System_Clock_Div_8); Interrupt::disable_irq(Interrupt::Timer2); @@ -26,8 +26,8 @@ __syscall_SysEnqIntRP(Timer2Irq, &IRQCallback); __syscall_ExitCriticalSection(); - Counter2.target.write(CounterTarget::CounterTargetValue.with(HighResTime::TicksFor10ms)); - Counter2.mode.write({Mode}); + Counter2.set_target_value(HighResTime::TicksFor10ms); + Counter2.set_mode(Mode); Interrupt::enable_irq(Interrupt::Timer2); }