From ad8ae808e6230fe6136866e26cae1b5a424b1a38 Mon Sep 17 00:00:00 2001 From: DualFroz Date: Tue, 25 Aug 2026 23:10:42 +0200 Subject: [PATCH] feat(drivers): add PS/2 keyboard driver --- include/keyboard.h | 11 +++++++ src/keyboard.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 include/keyboard.h create mode 100644 src/keyboard.c diff --git a/include/keyboard.h b/include/keyboard.h new file mode 100644 index 0000000..0bd9662 --- /dev/null +++ b/include/keyboard.h @@ -0,0 +1,11 @@ +#ifndef FROSTBYTE_KEYBOARD_H +#define FROSTBYTE_KEYBOARD_H + +#include "types.h" + +void keyboardInit(void); +void keyboardHandler(void); +bool keyboardHasChar(void); +char keyboardReadChar(void); + +#endif diff --git a/src/keyboard.c b/src/keyboard.c new file mode 100644 index 0000000..7a946d7 --- /dev/null +++ b/src/keyboard.c @@ -0,0 +1,77 @@ +#include "keyboard.h" +#include "ports.h" + +#define keyboardData 0x60 + +static const char scancodeLower[128] = { + 0, 27, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', + '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', + 0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', + 0, '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0, + '*', 0, ' ', 0 +}; + +static const char scancodeUpper[128] = { + 0, 27, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '\b', + '\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n', + 0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~', + 0, '|', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', 0, + '*', 0, ' ', 0 +}; + +#define keyBufferSize 128 +static volatile char keyBuffer[keyBufferSize]; +static volatile uint32 bufferHead; +static volatile uint32 bufferTail; +static bool shiftHeld; + +void keyboardInit(void) +{ + bufferHead = 0; + bufferTail = 0; + shiftHeld = false; +} + +static void pushChar(char c) +{ + uint32 next = (bufferHead + 1) % keyBufferSize; + if (next != bufferTail) { + keyBuffer[bufferHead] = c; + bufferHead = next; + } +} + +void keyboardHandler(void) +{ + uint8 scancode = inb(keyboardData); + + if (scancode == 0x2A || scancode == 0x36) { + shiftHeld = true; + return; + } + if (scancode == 0xAA || scancode == 0xB6) { + shiftHeld = false; + return; + } + if (scancode & 0x80) + return; + + char c = shiftHeld ? scancodeUpper[scancode] : scancodeLower[scancode]; + if (c) + pushChar(c); +} + +bool keyboardHasChar(void) +{ + return bufferHead != bufferTail; +} + +char keyboardReadChar(void) +{ + while (bufferHead == bufferTail) + __asm__ volatile("sti; hlt"); + + char c = keyBuffer[bufferTail]; + bufferTail = (bufferTail + 1) % keyBufferSize; + return c; +}