|
|
|
@ -5,13 +5,25 @@
|
|
|
|
|
|
|
|
|
|
inline void outb(std::uint16_t port, std::uint8_t val)
|
|
|
|
|
{
|
|
|
|
|
asm volatile("outb %b0, %w1" :: "a"(val), "Nd"(port) : "memory");
|
|
|
|
|
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 %w1, %b0" : "=a"(val) : "Nd"(port) : "memory");
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -20,5 +32,41 @@ 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
|
|
|
|
|
|
|
|
|
|