diff options
Diffstat (limited to 'src/portio.hpp')
-rw-r--r-- | src/portio.hpp | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/src/portio.hpp b/src/portio.hpp new file mode 100644 index 0000000..7636c14 --- /dev/null +++ b/src/portio.hpp @@ -0,0 +1,72 @@ +#ifndef PORTIO_HPP +#define PORTIO_HPP + +#include <cstdint> + +inline void outb(std::uint16_t port, std::uint8_t val) +{ + asm volatile("out %%al, %%dx" :: "a"(val), "Nd"(port) : "memory"); +} + +inline std::uint8_t inb(std::uint16_t port) +{ + std::uint8_t val; + asm volatile("inb %%dx" : "=a"(val) : "Nd"(port) : "memory"); + return val; +} + +inline void outw(std::uint16_t port, std::uint16_t val) +{ + asm volatile("out %%ax, %%dx" :: "a"(val), "Nd"(port) : "memory"); +} + +inline std::uint16_t inw(std::uint16_t port) +{ + std::uint16_t val; + asm volatile("inw %%dx" : "=a"(val) : "Nd"(port) : "memory"); + return val; +} + +inline void io_wait() +{ + outb(0x80, 0); +} + +template<std::uint16_t Addr> +struct Port +{ + Port() = default; + + template<typename T> + auto operator=(T val) noexcept { + if constexpr (sizeof(T) == 1) + outb(Addr, val); + else if constexpr (sizeof(T) == 2) + outw(Addr, val); + + return *this; + } + + template<typename T> + operator T() const noexcept { + if constexpr (sizeof(T) == 1) + return inb(Addr); + else if constexpr (sizeof(T) == 2) + return inw(Addr); + } + + template<typename T> + bool operator==(T val) const noexcept { + T dat = *this; + return dat == val; + } + + template<typename T> + auto operator&(T val) const noexcept { + T dat = *this; + return dat & val; + } +}; + +#endif // PORTIO_HPP + |