aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClyne Sullivan <clyne@bitgloo.com>2024-09-28 10:26:46 -0400
committerClyne Sullivan <clyne@bitgloo.com>2024-09-28 10:26:46 -0400
commitba5683581d00d9f02d470f4cde881293cc838a91 (patch)
tree772863e39677ae02b84a06f233d0a713d44d2f22
parent376d7ec265085ae3a77664356a2ad35921cfccaf (diff)
basic keyboard support
-rw-r--r--Makefile3
-rw-r--r--idt.cpp7
-rw-r--r--kernel.cpp49
-rw-r--r--keyboard.cpp65
-rw-r--r--keyboard.hpp7
-rw-r--r--vgaterminal.cpp13
6 files changed, 116 insertions, 28 deletions
diff --git a/Makefile b/Makefile
index deb1bac..c8fb67f 100644
--- a/Makefile
+++ b/Makefile
@@ -2,9 +2,10 @@ CXXFLAGS := -m32 -ggdb -g3 -O0 -fno-pic -ffreestanding -fno-rtti -fno-exceptions
LDFLAGS := -m32 -static -T link.ld -ffreestanding -nostdlib
CXXFILES := acpi.cpp \
- boot.cpp \
+ boot.cpp \
gdt.cpp \
idt.cpp \
+ keyboard.cpp \
memory.cpp \
multiboot.cpp \
pic.cpp \
diff --git a/idt.cpp b/idt.cpp
index cacac97..0dc0f73 100644
--- a/idt.cpp
+++ b/idt.cpp
@@ -40,8 +40,11 @@ void interruptGeneralHandler(Registers regs)
}
if (inum < callbacks.size()) {
- if (auto cb = callbacks[inum]; cb)
- cb(regs);
+ if (auto cb = callbacks[inum]; cb) {
+ asm volatile("cli");
+ cb(regs);
+ asm volatile("sti");
+ }
}
}
diff --git a/kernel.cpp b/kernel.cpp
index bf754eb..0cb581f 100644
--- a/kernel.cpp
+++ b/kernel.cpp
@@ -1,10 +1,12 @@
#include "acpi.hpp"
#include "gdt.hpp"
#include "idt.hpp"
+#include "keyboard.hpp"
#include "memory.hpp"
#include "multiboot.hpp"
#include "pic.hpp"
#include "pit.hpp"
+#include "portio.hpp"
#include "tasking.hpp"
#include "vgaterminal.hpp"
@@ -33,39 +35,40 @@ void kernel_main(void)
pic_initialize();
idt_initialize();
pit_initialize();
+ keyboard_initialize();
asm volatile("sti");
tasking_initialize();
term.write("Tasking enabled.\n");
- tasking_spawn([] {
- for (;;) {
- do pit_delay_ms(1);
- while (termBusy);
+ //tasking_spawn([] {
+ // for (;;) {
+ // do pit_delay_ms(1);
+ // while (termBusy);
- termBusy = true;
- term.write('B');
- termBusy = false;
- }
- }, 256);
+ // termBusy = true;
+ // term.write('B');
+ // termBusy = false;
+ // }
+ //}, 256);
- tasking_spawn([] {
- for (;;) {
- do pit_delay_ms(1);
- while (termBusy);
+ //tasking_spawn([] {
+ // for (;;) {
+ // do pit_delay_ms(1);
+ // while (termBusy);
- termBusy = true;
- term.write('C');
- termBusy = false;
- }
- }, 256);
+ // termBusy = true;
+ // term.write('C');
+ // termBusy = false;
+ // }
+ //}, 256);
for (;;) {
- do pit_delay_ms(1);
- while (termBusy);
+ pit_delay_ms(100);
+ //while (termBusy);
- termBusy = true;
- term.write('A');
- termBusy = false;
+ //termBusy = true;
+ //term.write('A');
+ //termBusy = false;
}
}
diff --git a/keyboard.cpp b/keyboard.cpp
new file mode 100644
index 0000000..18d7acd
--- /dev/null
+++ b/keyboard.cpp
@@ -0,0 +1,65 @@
+#include "idt.hpp"
+#include "portio.hpp"
+#include "vgaterminal.hpp"
+
+#include <array>
+#include <cstdint>
+
+#define K_CONTROL_L -1
+#define K_SHIFT_L -2
+#define K_ALT_L -3
+#define K_CAPS -4
+#define K_NUM -5
+#define K_SCROLL -6
+#define K_SHIFT_R -7
+#define K_ESCAPE -8
+#define K_F1 -10
+#define K_F2 -11
+#define K_F3 -12
+#define K_F4 -13
+#define K_F5 -14
+#define K_F6 -15
+#define K_F7 -16
+#define K_F8 -17
+#define K_F9 -18
+#define K_F10 -19
+#define K_F11 -20
+#define K_F12 -21
+
+extern TextOutput& term;
+
+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 constexpr bool isReleased(auto ch) {
+ return ch & 0x80;
+}
+
+static constexpr auto keycode(auto ch) {
+ return ch & 0x7F;
+}
+
+void keyboard_initialize()
+{
+ idt_register_callback(33, [](auto& regs) {
+ const auto kc = inb(0x60);
+
+ if (!isReleased(kc)) {
+ const auto ch = ScanCodeSet1[keycode(kc)];
+ if (ch > 0)
+ term.write(ch);
+ }
+ });
+}
+
diff --git a/keyboard.hpp b/keyboard.hpp
new file mode 100644
index 0000000..40b57c9
--- /dev/null
+++ b/keyboard.hpp
@@ -0,0 +1,7 @@
+#ifndef KEYBOARD_HPP
+#define KEYBOARD_HPP
+
+void keyboard_initialize();
+
+#endif // KEYBOARD_HPP
+
diff --git a/vgaterminal.cpp b/vgaterminal.cpp
index 8158b14..5f86081 100644
--- a/vgaterminal.cpp
+++ b/vgaterminal.cpp
@@ -8,7 +8,16 @@
void VGATerminal::write(char c) noexcept
{
+ checkpos();
+
switch (c) {
+ case '\b':
+ if (offset % Width) {
+ --offset;
+ put(' ');
+ --offset;
+ }
+ break;
case '\n':
offset += Width;
[[fallthrough]];
@@ -16,11 +25,11 @@ void VGATerminal::write(char c) noexcept
offset -= offset % Width;
break;
default:
- checkpos();
put(c);
- updatecursor();
break;
}
+
+ updatecursor();
}
void VGATerminal::put(char c) noexcept