#ifndef PORTIO_HPP #define PORTIO_HPP #include 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 struct Port { Port() = default; template 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 operator T() const noexcept { if constexpr (sizeof(T) == 1) return inb(Addr); else if constexpr (sizeof(T) == 2) return inw(Addr); } template bool operator==(T val) const noexcept { T dat = *this; return dat == val; } template auto operator&(T val) const noexcept { T dat = *this; return dat & val; } }; #endif // PORTIO_HPP