diff --git a/include/PSX/System/IOPorts/ioport.hpp b/include/PSX/System/IOPorts/ioport.hpp index 772a3589..bfe304aa 100644 --- a/include/PSX/System/IOPorts/ioport.hpp +++ b/include/PSX/System/IOPorts/ioport.hpp @@ -1,82 +1,88 @@ -#ifndef __JABYENGINE_IOPORT_HPP__ -#define __JABYENGINE_IOPORT_HPP__ -#include "../../Auxiliary/complex_bitmap.hpp" - -namespace JabyEngine { - template - class __no_align IOPort { - private: - T value; - - public: - //For easy access - constexpr T read() const { - return const_cast*>(this)->value; - } - - constexpr void write(T value) { - const_cast*>(this)->value = value; - } - - constexpr volatile T& ref() { - return const_cast*>(this)->value; - } - - constexpr const volatile T& ref() const { - return const_cast*>(this)->value; - } - }; - - struct __no_align ubus32_t { - ComplexBitMap low; - ComplexBitMap high; - - constexpr ubus32_t(uint32_t value) { - *this = value; - } - - constexpr operator uint32_t() const { - return ((this->high.raw << 16) | this->low.raw); - } - - operator uint32_t() const volatile { - return ((this->high.raw << 16) | this->low.raw); - } - - constexpr ubus32_t& operator=(uint32_t value) { - this->low.raw = (value & 0xFFFF); - this->high.raw = (value >> 16); - - return *this; - } - - constexpr void operator=(uint32_t value) volatile { - this->low.raw = (value & 0xFFFF); - this->high.raw = (value >> 16); - } - }; - static constexpr uintptr_t IO_Base_Mask = 0xF0000000; - static constexpr uintptr_t IO_Base_Adr = 0x10000000; - - #define __io_port_adr(adr) (IO_Base_Adr + (adr & ~IO_Base_Mask)) - #define __declare_io_port_global_raw(cv, type, name, adr) static __always_inline cv auto& name = *reinterpret_cast*>(__io_port_adr(adr)) - - #define __declare_io_port_global(type, name, adr) __declare_io_port_global_raw(, type, name, adr) - #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 __declare_io_port_global_struct(type, name, adr) static __always_inline auto& name = *reinterpret_cast(__io_port_adr(adr)) - - #define __io_port_inherit_complex_bit_map(name) \ - constexpr __always_inline name() = default; \ - constexpr __always_inline name(ComplexBitMap value) : ComplexBitMap(value) { \ - } \ - template \ - static constexpr __always_inline name with(ARGS...args) { \ - return {ComplexBitMap::with(args...)}; \ - }\ - template \ - constexpr void __always_inline operator=(ComplexBitMap value) volatile { \ - this->raw = value.raw; \ - } -} +#ifndef __JABYENGINE_IOPORT_HPP__ +#define __JABYENGINE_IOPORT_HPP__ +#include "../../Auxiliary/complex_bitmap.hpp" + +namespace JabyEngine { + template + class __no_align IOPort { + private: + T value; + + public: + //For easy access + constexpr T read() const { + return const_cast*>(this)->value; + } + + constexpr void write(T value) { + const_cast*>(this)->value = value; + } + + constexpr volatile T& ref() { + return const_cast*>(this)->value; + } + + constexpr const volatile T& ref() const { + return const_cast*>(this)->value; + } + + constexpr IOPort& operator=(T value) { + IOPort::write(value); + return *this; + } + }; + + struct __no_align ubus32_t { + ComplexBitMap low; + ComplexBitMap high; + + constexpr ubus32_t(uint32_t value) { + *this = value; + } + + constexpr operator uint32_t() const { + return ((this->high.raw << 16) | this->low.raw); + } + + operator uint32_t() const volatile { + return ((this->high.raw << 16) | this->low.raw); + } + + constexpr ubus32_t& operator=(uint32_t value) { + this->low.raw = (value & 0xFFFF); + this->high.raw = (value >> 16); + + return *this; + } + + constexpr void operator=(uint32_t value) volatile { + this->low.raw = (value & 0xFFFF); + this->high.raw = (value >> 16); + } + }; + static constexpr uintptr_t IO_Base_Mask = 0xF0000000; + static constexpr uintptr_t IO_Base_Adr = 0x10000000; + + #define __io_port_adr(adr) (IO_Base_Adr + (adr & ~IO_Base_Mask)) + #define __declare_io_port_global_raw(cv, type, name, adr) static __always_inline cv auto& name = *reinterpret_cast*>(__io_port_adr(adr)) + + #define __declare_io_port_global(type, name, adr) __declare_io_port_global_raw(, type, name, adr) + #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 __declare_io_port_global_struct(type, name, adr) static __always_inline auto& name = *reinterpret_cast(__io_port_adr(adr)) + + #define __io_port_inherit_complex_bit_map(name) \ + constexpr __always_inline name() = default; \ + constexpr __always_inline name(ComplexBitMap value) : ComplexBitMap(value) { \ + } \ + template \ + static constexpr __always_inline name with(ARGS...args) { \ + return {ComplexBitMap::with(args...)}; \ + }\ + template \ + constexpr void __always_inline operator=(ComplexBitMap value) volatile { \ + this->raw = value.raw; \ + } +} #endif //!__JABYENGINE_IOPORT_HPP__ \ No newline at end of file diff --git a/include/PSX/System/IOPorts/timer_io.hpp b/include/PSX/System/IOPorts/timer_io.hpp new file mode 100644 index 00000000..7fea31d1 --- /dev/null +++ b/include/PSX/System/IOPorts/timer_io.hpp @@ -0,0 +1,93 @@ +#ifndef __JABYENGINE_TIMER_IO_HPP__ +#define __JABYENGINE_TIMER_IO_HPP__ +#include "ioport.hpp" + +namespace JabyEngine { + namespace Timer { + enum struct SyncMode {}; + + struct __no_align CounterMode : public ComplexBitMap { + __io_port_inherit_complex_bit_map(CounterMode); + + static constexpr auto SyncEnable = Bit(0); + 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 IRQOneShot = !Bit(6); + static constexpr auto IRQEveryTime = Bit(6); + static constexpr auto IRQPulse = !Bit(7); + static constexpr auto IRQToggle = Bit(7); + 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); + }; + + struct __no_align CounterTarget : public ComplexBitMap { + __io_port_inherit_complex_bit_map(CounterTarget); + + static constexpr auto CounterTargetValue = BitRange::from_to(0, 15); + }; + + struct __no_align Timer { + IOPort counter_mode; + IOPort counter_target; + private: + uint32_t _unused[2]; + }; + + __declare_io_port_global_array(Timer, timer, 0x1F801104, 3); + static_assert(sizeof(Timer) == 0x10); + + namespace Counter0 { + 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); + }; + + 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); + }; + } + + namespace Counter1 { + 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); + }; + + 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); + }; + } + + namespace Counter2 { + 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); + }; + + 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); + }; + } + } +} + +#endif //!__JABYENGINE_TIMER_IO_HPP__ \ No newline at end of file diff --git a/src/Library/include/BootLoader/boot_loader.hpp b/src/Library/include/BootLoader/boot_loader.hpp index 8bc018e9..953688e1 100644 --- a/src/Library/include/BootLoader/boot_loader.hpp +++ b/src/Library/include/BootLoader/boot_loader.hpp @@ -20,5 +20,9 @@ namespace JabyEngine { namespace BootFile { JabyEngine::NextRoutine setup(); } + + namespace Timer { + void setup(); + } } #endif //!BOOT_LOADER_HPP \ No newline at end of file diff --git a/src/Library/src/BootLoader/timer_boot.cpp b/src/Library/src/BootLoader/timer_boot.cpp new file mode 100644 index 00000000..4446ed69 --- /dev/null +++ b/src/Library/src/BootLoader/timer_boot.cpp @@ -0,0 +1,14 @@ +#include + +namespace JabyEngine { + namespace Timer { + void setup() { + // Just testing around + static constexpr auto wuff = CounterMode::with(CounterMode::IRQAtMax, Counter0::SyncMode::Zero_At_Hblank); + + timer[0].counter_mode = wuff; + timer[0].counter_mode = wuff; + timer[0].counter_mode = wuff; + } + } +} \ No newline at end of file