port.hpp 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. #pragma once
  2. #include <stdint.h>
  3. #include <types/cplusplus.hpp>
  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 volatile(
  22. "inb %1, %0"
  23. : "=a"(ret)
  24. : "d"(mp));
  25. if constexpr (types::is_same<port_size_t, uint16_t>::value)
  26. asm volatile(
  27. "inw %1, %0"
  28. : "=a"(ret)
  29. : "d"(mp));
  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 || types::is_same<port_size_t, uint16_t>::value,
  36. "this type is not implemented yet.");
  37. if constexpr (types::is_same<port_size_t, uint8_t>::value)
  38. asm volatile(
  39. "outb %1, %0"
  40. :
  41. : "d"(mp), "a"(n));
  42. if constexpr (types::is_same<port_size_t, uint16_t>::value)
  43. asm volatile(
  44. "outw %1, %0"
  45. :
  46. : "d"(mp), "a"(n));
  47. return n;
  48. }
  49. };
  50. using p8 = port<uint8_t>;
  51. using p8r = port<uint8_t, true, false>;
  52. using p8w = port<uint8_t, false, true>;
  53. using p16 = port<uint16_t>;
  54. using p16r = port<uint16_t, true, false>;
  55. using p16w = port<uint16_t, false, true>;
  56. template <>
  57. uint8_t p8r::operator=(uint8_t n) const = delete;
  58. template <>
  59. uint8_t p8w::operator*(void) const = delete;
  60. template <>
  61. uint16_t p16r::operator=(uint16_t n) const = delete;
  62. template <>
  63. uint16_t p16w::operator*(void) const = delete;
  64. } // namespace hw