aboutsummaryrefslogtreecommitdiffstats
path: root/src/keyboard.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/keyboard.cpp')
-rw-r--r--src/keyboard.cpp64
1 files changed, 64 insertions, 0 deletions
diff --git a/src/keyboard.cpp b/src/keyboard.cpp
new file mode 100644
index 0000000..48dad02
--- /dev/null
+++ b/src/keyboard.cpp
@@ -0,0 +1,64 @@
+#include "circularbuffer.hpp"
+#include "idt.hpp"
+#include "keyboard.hpp"
+#include "portio.hpp"
+#include "vgaterminal.hpp"
+
+#include <array>
+#include <cstdint>
+
+extern TextOutput& term;
+
+static CircularBuffer<char> keyboardBuffer;
+static Port<0x60> keyboardPort;
+
+static const std::array<char, 0x59> ScanCodeSet1 {{
+ 0, K_ESCAPE,
+ '1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
+ '-', '=', '\b', '\t',
+ 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '[', ']', '\n', K_CONTROL_L,
+ 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', '\'', '`', K_SHIFT_L, '\\',
+ 'Z', 'X', 'C', 'V', 'B', 'N', 'M', ',', '.', '/',
+ K_SHIFT_R, '*', K_ALT_L, ' ', K_CAPS,
+ K_F1, K_F2, K_F3, K_F4, K_F5, K_F6, K_F7, K_F8, K_F9, K_F10,
+ K_NUM, K_SCROLL, '7', '8', '9', '-', '4', '5', '6', '+', '1', '2', '3', '0', '.',
+ 0, 0, 0, // non-existant
+ K_F11, K_F12
+}};
+
+static inline bool isReleased(auto ch) {
+ return ch & 0x80;
+}
+
+static inline auto keycode(auto ch) {
+ return ch & 0x7F;
+}
+
+void keyboard_initialize()
+{
+ keyboardBuffer = CircularBuffer<char>(128);
+
+ idt_register_callback(33, [](auto&) {
+ const std::uint8_t kc = keyboardPort;
+
+ if (!isReleased(kc)) {
+ const auto ch = ScanCodeSet1[keycode(kc)];
+ //if (ch > 0)
+ // term.write(ch);
+
+ keyboardBuffer.push_back(ch);
+ }
+ });
+}
+
+std::optional<char> keyboard_read()
+{
+ if (keyboardBuffer.empty()) {
+ return {};
+ } else {
+ const auto ch = keyboardBuffer.front();
+ keyboardBuffer.pop_front();
+ return ch;
+ }
+}
+