From eeea3b2d869d19f443cc64abd38d028a65cda2a1 Mon Sep 17 00:00:00 2001 From: David Goeke Date: Fri, 13 Jun 2025 19:53:54 -0500 Subject: [PATCH] Espresso 0.0.0f --- drivers/irq.c | 19 ++++++++- drivers/ps2_keyboard.c | 70 +++++++++++++++++++++++++++++++- drivers/tty.c | 74 ++++++++++++++++++++++++++++++++-- include/drivers/ps2_keyboard.h | 1 + include/tty.h | 6 +-- kernel/intro.c | 12 +++--- kernel/kernel.c | 8 +++- 7 files changed, 174 insertions(+), 16 deletions(-) diff --git a/drivers/irq.c b/drivers/irq.c index baa9442..f72ad7e 100644 --- a/drivers/irq.c +++ b/drivers/irq.c @@ -1,9 +1,24 @@ - +#include +#include #include +static void pit_handler(void) +{ +} void irq_handler(uint8_t irq_number) { - + switch (irq_number) + { + case 0: + pit_handler(); + break; + case 1: + keyboard_handler(); + break; + default: + printf("Unhandled IRQ %u\n", irq_number); + break; + } } diff --git a/drivers/ps2_keyboard.c b/drivers/ps2_keyboard.c index 87a0396..fa1c6ad 100644 --- a/drivers/ps2_keyboard.c +++ b/drivers/ps2_keyboard.c @@ -1,5 +1,6 @@ #include #include +#include #include @@ -16,7 +17,74 @@ 0x64 Write Command Register */ +/* + Note: + The interrupt number for keyboard input in 1. +*/ + +#define PS2_DATA_PORT 0x60 +#define PS2_STATUS_PORT 0x64 + +#define KEYBOARD_IRQ 1 + + +/* State for shift key */ +static bool shift_pressed = false; + +static const char scancode_map[128] = { + 0, 27, '1','2','3','4','5','6','7','8','9','0','-','=','\b', /* Backspace */ + '\t', // Tab + 'q','w','e','r','t','y','u','i','o','p','[',']','\n', /* Enter */ + 0, /* Control */ + 'a','s','d','f','g','h','j','k','l',';','\'','`', + 0, /* Left shift */ + '\\','z','x','c','v','b','n','m',',','.','/', + 0, /* Right shift */ + '*', + 0, /* Alt */ + ' ', /* Spacebar */ + 0, /* Caps lock */ + /* The rest are function and control keys */ +}; + + void keyboard_init(void) { - + outb(0x64, 0xAE); /* Enable keyboard interface (often optional, but here for safety) */ +} + +void keyboard_handler(void) { + uint8_t scancode = inb(PS2_DATA_PORT); + + /* Handle shift press/release */ + if (scancode == 0x2A || scancode == 0x36) + { + shift_pressed = true; + return; + } + else if (scancode == 0xAA || scancode == 0xB6) + { + shift_pressed = false; + return; + } + + if (scancode & 0x80) + { + /* Key release event, ignore for now */ + } else + { + char c = scancode_map[scancode]; + if (shift_pressed && c >= 'a' && c <= 'z') { + c -= 32; /* Convert to uppercase */ + } + else if (shift_pressed) + { + c = (char) terminal_get_shifted((unsigned char) c); + } + + if (c) + { + printf("%c", c); + } + } } diff --git a/drivers/tty.c b/drivers/tty.c index 4d46a38..16ddb6f 100644 --- a/drivers/tty.c +++ b/drivers/tty.c @@ -1,8 +1,6 @@ -#include - #include -#include #include + #include static size_t terminal_row; @@ -80,6 +78,28 @@ void terminal_putchar(const char c) return; } + else if (uc == '\b') + { + if (terminal_column == 0) + { + terminal_row -= 1; + + if (terminal_row <= -1) + { + terminal_row = 0; + } + + terminal_column = VGA_WIDTH; + + terminal_putentryat(' ', terminal_getcolor(), (size_t)terminal_column, (size_t)terminal_row); + } + else + { + terminal_putentryat(' ', terminal_getcolor(), (size_t)--terminal_column, (size_t)terminal_row); + } + + return; + } terminal_putentryat(uc, terminal_color, terminal_column, terminal_row); @@ -178,3 +198,51 @@ void terminal_scroll(void) terminal_buffer[index] = (terminal_color << 8) | ' '; } } + +unsigned char terminal_get_shifted(unsigned char uc) +{ + unsigned char lowerc[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '\0' }; + unsigned char upperc[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '\0' }; + unsigned char nums[] = { '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '\0' }; + unsigned char nsyms[] = { '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '\0' }; + unsigned char syms1[] = { ',', '.', '/', ';', '\'', '[', ']', '`', '-', '=', '\\', '\0' }; + unsigned char syms2[] = { '<', '>', '?', ':', '\"', '{', '}', '~', '_', '+', '|', '\0' }; + + for (int32_t i = 0; i < (int32_t)(strlen((char*)lowerc) - 1); ++i) + { + if (uc == lowerc[i]) + { + return upperc[i]; + } + else if (uc == upperc[i]) + { + return lowerc[i]; + } + } + + for (int32_t i = 0; i < (int32_t)(strlen((char*)nums) - 1); ++i) + { + if (uc == nums[i]) + { + return nsyms[i]; + } + else if (uc == nsyms[i]) + { + return nums[i]; + } + } + + for (int32_t i = 0; i < (int32_t)(strlen((char*)syms1) - 1); ++i) + { + if (uc == syms1[i]) + { + return syms2[i]; + } + else if (uc == syms2[i]) + { + return syms1[i]; + } + } + + return '\0'; +} diff --git a/include/drivers/ps2_keyboard.h b/include/drivers/ps2_keyboard.h index e6c349b..6743f36 100644 --- a/include/drivers/ps2_keyboard.h +++ b/include/drivers/ps2_keyboard.h @@ -4,5 +4,6 @@ #include void keyboard_init(void); +void keyboard_handler(void); #endif diff --git a/include/tty.h b/include/tty.h index 856a518..33d3f2f 100644 --- a/include/tty.h +++ b/include/tty.h @@ -1,9 +1,7 @@ #ifndef _TTY_H #define _TTY_H -#include -#include -#include +#include static const size_t VGA_WIDTH = 80; static const size_t VGA_HEIGHT = 25; @@ -25,4 +23,6 @@ void terminal_clear(void); void terminal_clearl(size_t num_lines); void terminal_scroll(void); +unsigned char terminal_get_shifted(unsigned char uc); + #endif diff --git a/kernel/intro.c b/kernel/intro.c index be46eb1..a33c86e 100644 --- a/kernel/intro.c +++ b/kernel/intro.c @@ -5,11 +5,13 @@ #include -void delay_us(uint32_t microseconds, uint32_t cpu_mhz) { - uint32_t count = cpu_mhz * microseconds; - while (count--) { - asm volatile ("nop" ::: "memory"); - } +void delay_us(uint32_t microseconds, uint32_t cpu_mhz) +{ + uint32_t count = cpu_mhz * microseconds; + while (count--) + { + asm volatile ("nop" ::: "memory"); + } } diff --git a/kernel/kernel.c b/kernel/kernel.c index 4303bed..a96df78 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -50,7 +50,7 @@ void kernel_main(multiboot_info_t* mbd, unsigned int magic) /* --- BEGIN INITIALIZATION SECTION --- */ - const char* espresso_kernel_version = "0.0.0e"; + const char* espresso_kernel_version = "0.0.0f"; /* We need to initialize the terminal so that any error/debuging messages show. */ terminal_initialize(); @@ -106,6 +106,10 @@ void kernel_main(multiboot_info_t* mbd, unsigned int magic) printd("SSE test succeeded\n"); } + printd("Initializing the PS/2 keyboard...\n"); + keyboard_init(); + printd("PS/2 Keyboard initialized\n"); + /* printd("Initalizing AHCI...\n"); ahci_init(); @@ -138,7 +142,7 @@ void kernel_main(multiboot_info_t* mbd, unsigned int magic) /*sleep(1000);*/ - begin_anim(espresso_kernel_version); + //begin_anim(espresso_kernel_version); printf("Guten tag and welcome to Espresso\n");