From 9812f3f58dc0be87288fd384943dea2d30ab86c5 Mon Sep 17 00:00:00 2001 From: Tom-on64 Date: Wed, 15 May 2024 20:06:38 +0200 Subject: [PATCH] Improved keyboard IRQ handler, added getc() function, improved read() --- include/keyboard/keyboard.h | 110 +++++++++++++----------------------- include/keyboard/keys.h | 40 +++++++++++++ src/kernel.c | 4 +- todo.txt | 4 +- 4 files changed, 84 insertions(+), 74 deletions(-) create mode 100644 include/keyboard/keys.h diff --git a/include/keyboard/keyboard.h b/include/keyboard/keyboard.h index 2ac69f0..01c8208 100644 --- a/include/keyboard/keyboard.h +++ b/include/keyboard/keyboard.h @@ -3,95 +3,65 @@ #include #include -#include #include -#include +#include #include -// Keycodes -#define LEFT_SHIFT_PRESS 0x2a -#define LEFT_SHIFT_RELEASE (LEFT_SHIFT_PRESS | 0x80) -#define RIGHT_SHIFT_PRESS 0x36 -#define RIGHT_SHIFT_RELEASE (RIGHT_SHIFT_PRESS | 0x80) -#define LEFT_CTRL_PRESS 0x1D -#define LEFT_CTRL_RELEASE (LEFT_CTRL_PRESS | 0x80) -#define RIGHT_CTRL_PRESS 0x1D -#define RIGHT_CTRL_RELEASE (RIGHT_CTRL_PRESS | 0x80) -#define LEFT_ALT_PRESS 0x38 -#define LEFT_ALT_RELEASE (LEFT_ALT_PRESS | 0x80) -#define RIGHT_ALT_PRESS 0x38 -#define RIGHT_ALT_RELEASE (RIGHT_ALT_PRESS | 0x80) +#define MAX_INPUT_LENGTH 256 -#define MAX_BUFFER_SIZE 256 +typedef struct { + char character; + uint8_t shift; +} keyboardState_t; -const char US_Keyboard[2][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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - '7', '8', '9', '-', '4', '5', '6', '+', '1', '2', '3', '0', '.', // Numpad - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }, - { - 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, '7', '8', '9', '-', '4', '5', '6', '+', '1', '2', '3', '0', '.', - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - } -}; +// TODO: Put at set address +keyboardState_t keyboard; -uint8_t shift = 0; - -uint16_t bufferLen = 0; -char buffer[MAX_BUFFER_SIZE + 1] = { 0 }; -bool echo = false; -bool canBackspace = false; - -// TODO: Refactor this __attribute__ ((interrupt)) void keyboardHandler(intFrame_t* iframe) { - uint8_t scancode; - scancode = inb(0x60); + uint8_t scancode = inb(0x60); + char c = US_Keyboard[keyboard.shift][scancode]; - if (scancode == LEFT_SHIFT_PRESS || scancode == RIGHT_SHIFT_PRESS) shift = 1; - else if (scancode == LEFT_SHIFT_RELEASE || scancode == RIGHT_SHIFT_RELEASE) shift = 0; - - char c = US_Keyboard[shift][scancode]; + if (scancode == LEFT_SHIFT_PRESS || scancode == RIGHT_SHIFT_PRESS) { + keyboard.shift = 1; + } else if (scancode == LEFT_SHIFT_RELEASE || scancode == RIGHT_SHIFT_RELEASE) { + keyboard.shift = 0; + } if (scancode & 0x80) { // Keyup - } else if (c != 0) { - if (!canBackspace && c == '\b') return; - if (echo) putc(c); - - buffer[bufferLen] = c; - - if (c == '\b') bufferLen--; - else bufferLen++; - - if (bufferLen > 0) canBackspace = true; - else canBackspace = false; + } else if (c != '\0') { + keyboard.character = c; } sendPicEOI(1); } -// TODO: Add a 'char readc();' function that returns a single read character and use it for read() -// Also this should be refactored to not use so many flag variables -char* read(char terminator) { - bufferLen = 0; - echo = true; +char getc() { + keyboard.character = '\0'; + while (keyboard.character == '\0') __asm__ volatile ("hlt"); + return keyboard.character; +} - while (buffer[bufferLen-1] != terminator && bufferLen < MAX_BUFFER_SIZE); +// Reads until a newline +char inputBuffer[MAX_INPUT_LENGTH]; +char* read() { + char c; + uint8_t len = 0; - echo = false; - canBackspace = false; - buffer[bufferLen] = '\0'; + while ((c = getc()) != '\n') { + if (c == '\b' && len > 0) { + len--; + putc(c); + } else if (len + 1 != MAX_INPUT_LENGTH) { // Check if we can add a new character + inputBuffer[len++] = c; + putc(c); + } + } - return buffer; + inputBuffer[len++] = c; // Add newline + putc(c); + inputBuffer[len] = '\0'; // Null terminate + return inputBuffer; } void setupKeyboard() { diff --git a/include/keyboard/keys.h b/include/keyboard/keys.h new file mode 100644 index 0000000..c29ca50 --- /dev/null +++ b/include/keyboard/keys.h @@ -0,0 +1,40 @@ +#ifndef KEYS_H +#define KEYS_H + +#include + +#define LEFT_SHIFT_PRESS 0x2a +#define LEFT_SHIFT_RELEASE (LEFT_SHIFT_PRESS | 0x80) +#define RIGHT_SHIFT_PRESS 0x36 +#define RIGHT_SHIFT_RELEASE (RIGHT_SHIFT_PRESS | 0x80) +#define LEFT_CTRL_PRESS 0x1D +#define LEFT_CTRL_RELEASE (LEFT_CTRL_PRESS | 0x80) +#define RIGHT_CTRL_PRESS 0x1D +#define RIGHT_CTRL_RELEASE (RIGHT_CTRL_PRESS | 0x80) +#define LEFT_ALT_PRESS 0x38 +#define LEFT_ALT_RELEASE (LEFT_ALT_PRESS | 0x80) +#define RIGHT_ALT_PRESS 0x38 +#define RIGHT_ALT_RELEASE (RIGHT_ALT_PRESS | 0x80) + +// Basic US Keyboard layout +static const char US_Keyboard[2][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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + '7', '8', '9', '-', '4', '5', '6', '+', '1', '2', '3', '0', '.', // Numpad + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { + 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, '7', '8', '9', '-', '4', '5', '6', '+', '1', '2', '3', '0', '.', + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + } +}; + +#endif diff --git a/src/kernel.c b/src/kernel.c index 520d30f..3dbd8b6 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -64,7 +64,7 @@ void main() { // TODO: Make it in another file while (1) { print(PROMPT); - char* input = read('\n'); + char* input = read(); if (input[0] == '\n') continue; @@ -169,7 +169,7 @@ void main() { drawCircle(1500, 600, 300, WHITE); fillCircle(950, 750, 75, rgb(0xa2, 0xd6, 0xf9)); - read('q'); // Wait until we get a 'q' + getc(); // Wait until we get a 'q' clear(); } else if (strcmp(input, "help") == 0) { print("Available Commands:\n"); diff --git a/todo.txt b/todo.txt index 776517e..e230abb 100644 --- a/todo.txt +++ b/todo.txt @@ -36,13 +36,13 @@ Legend: - [x] Rectange :) - [x] Circle! - [x] Filled verisons -- [ ] Interrupts +- [x] Interrupts - [x] IDT Setup (idt.h) - [x] Exception handling - [x] Hardware/software interrupts - [x] Syscalls! (int 0x80) - [x] IRQ 0 - PIT - - [ ] IRQ 1 - Keyboard + - [x] IRQ 1 - Keyboard - [x] IRQ 8 - CMOS Real time clock - [?] Other IRQs (idk which ones) - [ ] Math