port.hpp 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  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. explicit port(uint16_t p)
  11. : mp(p)
  12. {
  13. }
  14. port_size_t operator*(void) const
  15. {
  16. static_assert(
  17. types::is_same<port_size_t, uint8_t>::value || 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. if constexpr (types::is_same<port_size_t, uint16_t>::value)
  25. asm("inw %1, %0"
  26. : "=a"(ret)
  27. : "d"(mp));
  28. return ret;
  29. }
  30. port_size_t operator=(port_size_t n) const
  31. {
  32. static_assert(
  33. types::is_same<port_size_t, uint8_t>::value || types::is_same<port_size_t, uint16_t>::value,
  34. "this type is not implemented yet.");
  35. if constexpr (types::is_same<port_size_t, uint8_t>::value)
  36. asm("outb %1, %0"
  37. :
  38. : "d"(mp), "a"(n));
  39. if constexpr (types::is_same<port_size_t, uint16_t>::value)
  40. asm("outw %1, %0"
  41. :
  42. : "d"(mp), "a"(n));
  43. return n;
  44. }
  45. };
  46. using p8 = port<uint8_t>;
  47. using p8r = port<uint8_t, true, false>;
  48. using p8w = port<uint8_t, false, true>;
  49. using p16 = port<uint16_t>;
  50. using p16r = port<uint16_t, true, false>;
  51. using p16w = port<uint16_t, false, true>;
  52. template <>
  53. uint8_t p8r::operator=(uint8_t n) const = delete;
  54. template <>
  55. uint8_t p8w::operator*(void) const = delete;
  56. template <>
  57. uint16_t p16r::operator=(uint16_t n) const = delete;
  58. template <>
  59. uint16_t p16w::operator*(void) const = delete;
  60. } // namespace hw