port.hpp 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. #pragma once
  2. #include <types/cplusplus.hpp>
  3. #include <types/stdint.h>
  4. namespace hw {
  5. template <typename port_size_t, bool r = true, bool w = true>
  6. class port {
  7. private:
  8. uint16_t mp;
  9. public:
  10. port(uint16_t p)
  11. : mp(p)
  12. {}
  13. port_size_t operator*(void) const
  14. {
  15. static_assert(
  16. types::is_same<port_size_t, uint8_t>::value ||
  17. types::is_same<port_size_t, uint16_t>::value,
  18. "this type is not implemented yet.");
  19. port_size_t ret;
  20. if constexpr (types::is_same<port_size_t, uint8_t>::value)
  21. asm("inb %1, %0"
  22. : "=a"(ret)
  23. : "d"(mp)
  24. );
  25. if constexpr (types::is_same<port_size_t, uint16_t>::value)
  26. asm("inw %1, %0"
  27. : "=a"(ret)
  28. : "d"(mp)
  29. );
  30. return ret;
  31. }
  32. port_size_t operator=(port_size_t n) const
  33. {
  34. static_assert(
  35. types::is_same<port_size_t, uint8_t>::value ||
  36. types::is_same<port_size_t, uint16_t>::value,
  37. "this type is not implemented yet.");
  38. if constexpr (types::is_same<port_size_t, uint8_t>::value)
  39. asm("outb %1, %0"
  40. : : "d"(mp), "a"(n)
  41. );
  42. if constexpr (types::is_same<port_size_t, uint16_t>::value)
  43. asm("outw %1, %0"
  44. : : "d"(mp), "a"(n)
  45. );
  46. return n;
  47. }
  48. };
  49. using p8 = port<uint8_t>;
  50. using p8r = port<uint8_t, true, false>;
  51. using p8w = port<uint8_t, false, true>;
  52. using p16 = port<uint16_t>;
  53. using p16r = port<uint16_t, true, false>;
  54. using p16w = port<uint16_t, false, true>;
  55. template <> uint8_t p8r::operator=(uint8_t n) const = delete;
  56. template <> uint8_t p8w::operator*(void) const = delete;
  57. template <> uint16_t p16r::operator=(uint16_t n) const = delete;
  58. template <> uint16_t p16w::operator*(void) const = delete;
  59. } // namespace hw