From e471564f897556187e53d64f6aa63b967d6c2e90 Mon Sep 17 00:00:00 2001 From: Nathan Singer Date: Tue, 3 Jun 2025 20:51:25 -0400 Subject: [PATCH] cleaned up some log messages, polished up the kb driver a bit, etc --- Makefile | 3 ++ kernel/arch/idt/idt.c | 7 ++- kernel/arch/io/keyb.c | 92 +++++++++++++++++++++++++++++--- kernel/arch/pic/pic.c | 12 ++++- kernel/include/kernel/x86/keyb.h | 34 ++++++++---- util/bochsrc.txt | 11 ++++ 6 files changed, 138 insertions(+), 21 deletions(-) create mode 100644 util/bochsrc.txt diff --git a/Makefile b/Makefile index 69202fa..b211ee9 100644 --- a/Makefile +++ b/Makefile @@ -48,6 +48,9 @@ os.iso: kernel.elf run: os.iso $(TERM_EXEC) "gdb kernel.elf -x util/gdbcmds" & qemu-system-i386 -s -cdrom os.iso + +bochs: os.iso + bochs -f util/bochsrc.txt -q #TODO: when i inevitably do add libc, this is going to fail because they have the same name as the libk objects #TODO: so we'll need to do a batch rename on one of the two object files, diff --git a/kernel/arch/idt/idt.c b/kernel/arch/idt/idt.c index 9000381..8e211bf 100644 --- a/kernel/arch/idt/idt.c +++ b/kernel/arch/idt/idt.c @@ -16,6 +16,8 @@ static idtr_t idtr; static bool vectors[IDT_MAX_DESCRIPTORS]; +extern struct keyboard_state keyb_state; + void exception_handler(unsigned int i) { if (i <= 31) { // TODO: implement proper handling for each exception, also implement the proper gates & error code checking @@ -28,10 +30,7 @@ void exception_handler(unsigned int i) if (i == PIC_KEYB) { unsigned char in = inb(0x60); -#ifdef __TESTING__ - printf("scancode: %x\n", in); -#endif - + do_keypress(decode_scancode(in)); PIC_sendEOI(1); } } diff --git a/kernel/arch/io/keyb.c b/kernel/arch/io/keyb.c index b0deb4a..5851c99 100644 --- a/kernel/arch/io/keyb.c +++ b/kernel/arch/io/keyb.c @@ -40,19 +40,21 @@ void init_kb(void) #ifdef __TESTING__ puts("Initializing keyboard driver!"); #endif + keyb_state.ready = false; init_queue(&kb_cmd_queue); keyb_state.leds = 0; + keyb_state.flags = 0; queue_kb_command(KEYB_CMD_ENABLE_SCANNING); - queue_kb_command(KEYB_CMD_SET_DEFAULT_PARAMS); - - //queue_kb_command(KEYB_CMD_SET_TYPEMATIC); - //queue_kb_command(0x1F); + queue_kb_command(KEYB_CMD_SET_TYPEMATIC); + queue_kb_command(0x1F); send_kb_commands(); + keyb_state.ready = true; + #ifdef __TESTING__ puts("Initialized keyboard driver!"); @@ -89,7 +91,85 @@ void send_kb_commands(void) } -kb_key_press_t decode_scancode(uint8_t scancode) - {return (kb_key_press_t) scancode;} +kb_key_code_t decode_scancode(uint8_t scancode) + {return (kb_key_code_t) scancode;} + +key_press_t do_keypress(kb_key_code_t keycode) +{ + key_press_t packet; + + if (!keyb_state.ready) { + packet.key_code = KEY_NONE; + return packet; + } + if (keycode >= KEY_ESC_R) { + packet.key_code = keycode - KEY_PRESS_RELEASE_DIFF; + packet.release = true; + } else { + packet.key_code = keycode; + packet.release = false; + } + + switch (keycode) { + case KEY_LEFT_SHIFT: + keyb_state.flags |= (STATUS_FLAG_LSHIFT); + break; + case KEY_LEFT_SHIFT_R: + keyb_state.flags &= ~(STATUS_FLAG_LSHIFT); + break; + case KEY_RIGHT_SHIFT: + keyb_state.flags |= (STATUS_FLAG_RSHIFT); + break; + case KEY_RIGHT_SHIFT_R: + keyb_state.flags &= ~(STATUS_FLAG_RSHIFT); + break; + case KEY_LEFT_CTRL: + keyb_state.flags |= (STATUS_FLAG_CTRL); + break; + case KEY_LEFT_CTRL_R: + keyb_state.flags &= ~(STATUS_FLAG_CTRL); + break; + case KEY_LEFT_ALT: + keyb_state.flags |= (STATUS_FLAG_ALT); + break; + case KEY_LEFT_ALT_R: + keyb_state.flags &= ~(STATUS_FLAG_ALT); + break; + case KEY_CAPSLOCK: + keyb_state.flags ^= (STATUS_FLAG_CAPS_LOCK); + keyb_state.leds ^= (KEYB_LED_CAP_LCK); + queue_kb_command(KEYB_CMD_SET_LEDS); + queue_kb_command(keyb_state.leds); + break; + case KEY_NUMLOCK: + keyb_state.flags ^= (STATUS_FLAG_NUM_LOCK); + keyb_state.leds ^= (KEYB_LED_NUM_LCK); + queue_kb_command(KEYB_CMD_SET_LEDS); + queue_kb_command(keyb_state.leds); + break; + case KEY_SCROLLLOCK: + keyb_state.flags ^= (STATUS_FLAG_NUM_LOCK); + keyb_state.leds ^= (KEYB_LED_SCRL_LCK); + queue_kb_command(KEYB_CMD_SET_LEDS); + queue_kb_command(keyb_state.leds); + break; + // case KEY_INSERT TODO: this shit baby + default: + break; + } + + send_kb_commands(); + packet.flags = keyb_state.flags; + return packet; +} + +/** + * shift + * ctrl + * alt + * caps + * num + * scroll + */ diff --git a/kernel/arch/pic/pic.c b/kernel/arch/pic/pic.c index 330187d..00f05f0 100644 --- a/kernel/arch/pic/pic.c +++ b/kernel/arch/pic/pic.c @@ -56,7 +56,7 @@ void pic_disable(void) outb(PIC1_DATA, 0xFF); outb(PIC2_DATA, 0xFF); #ifdef __TESTING__ - kinfo("Disabled the PIC"); + kinfo("Masked off the PIC"); #endif } @@ -72,10 +72,14 @@ void IRQ_set_mask(uint8_t IRQline) // Masked IRQlines are ignored by the PIC, ma IRQline -= 8; } - printf("%x %x\n", port, IRQline); value = inb(port) | (1 << IRQline); outb(port, value); + +#ifdef __TESTING__ + kinfo("Masked IRQ line"); + printf("IRQ line: %d\n", IRQline); +#endif } void IRQ_clear_mask(uint8_t IRQline) @@ -92,6 +96,10 @@ void IRQ_clear_mask(uint8_t IRQline) value = inb(port) & ~(1 << IRQline); outb(port, value); +#ifdef __TESTING__ + kinfo("Cleared mask from IRQ line"); + printf("IRQ line: %d\n", IRQline); +#endif } static uint16_t __pic_get_irq_reg(int ocw3) diff --git a/kernel/include/kernel/x86/keyb.h b/kernel/include/kernel/x86/keyb.h index 836563c..50f5977 100644 --- a/kernel/include/kernel/x86/keyb.h +++ b/kernel/include/kernel/x86/keyb.h @@ -45,13 +45,24 @@ #define KEYB_RESP_RESEND (0xFE) #define KEYB_RESP_ERR_TWO (0xFF) + +#define STATUS_FLAG_RSHIFT (1 << 0) +#define STATUS_FLAG_LSHIFT (1 << 1) +#define STATUS_FLAG_CTRL (1 << 2) +#define STATUS_FLAG_ALT (1 << 3) +#define STATUS_FLAG_SCRL_LOCK (1 << 4) +#define STATUS_FLAG_NUM_LOCK (1 << 5) +#define STATUS_FLAG_CAPS_LOCK (1 << 6) +#define STATUS_FLAG_INSERT (1 << 7) + typedef enum { + KEY_NONE, KEY_ESC = 0x01, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_9, KEY_0, KEY_MINUS, KEY_EQUALS, KEY_BACKSPACE, KEY_TAB, KEY_Q, KEY_W, KEY_E, KEY_R, KEY_T, KEY_Y, KEY_U, KEY_I, KEY_O, KEY_P, - KEY_LEFT_BRACKET, KEY_RIGHT_BRACKET, KEY_ENTER, KET_LEFT_CTRL, + KEY_LEFT_BRACKET, KEY_RIGHT_BRACKET, KEY_ENTER, KEY_LEFT_CTRL, KEY_A, KEY_S, KEY_D, KEY_F, KEY_G, KEY_H, KEY_J, KEY_K, KEY_L, KEY_SEMICOLON, KEY_SINGLE_QUOTE, KEY_BACK_TICK, KEY_LEFT_SHIFT, KEY_BACKSLASH, KEY_Z, KEY_X, KEY_C, KEY_V, KEY_B, KEY_N, KEY_M, @@ -78,7 +89,7 @@ typedef enum { KEY_TAB_R, KEY_Q_R, KEY_W_R, KEY_E_R, KEY_R_R, KEY_T_R, KEY_Y_R, KEY_U_R, KEY_I_R, KEY_O_R, KEY_P_R, KEY_LEFT_BRACKET_R, KEY_RIGHT_BRACKET_R, - KEY_ENTER_R, KET_LEFT_CTRL_R, + KEY_ENTER_R, KEY_LEFT_CTRL_R, KEY_A_R, KEY_S_R, KEY_D_R, KEY_F_R, KEY_G_R, KEY_H_R, KEY_J_R, KEY_K_R, KEY_L_R, KEY_SEMICOLON_R, KEY_SINGLE_QUOTE_R, KEY_BACK_TICK_R, KEY_LEFT_SHIFT_R, KEY_BACKSLASH_R, KEY_Z_R, KEY_X_R, KEY_C_R, KEY_V_R, KEY_B_R, KEY_N_R, KEY_M_R, @@ -98,15 +109,20 @@ typedef enum { KEY_KP_PERIOD_R, KEY_F11_R = 0xD7, KEY_F12_R, -} kb_key_press_t; +} kb_key_code_t; -struct keypress { - kb_key_press_t key_code; - uint8_t -}; +#define KEY_PRESS_RELEASE_DIFF (KEY_ESC_R - KEY_ESC) + +typedef struct { + kb_key_code_t key_code; + uint8_t flags; + bool release; +} key_press_t ; struct keyboard_state { + bool ready; uint8_t leds; + uint8_t flags; }; @@ -116,7 +132,7 @@ void send_kb_commands(void); void queue_kb_command(uint8_t command); -kb_key_press_t decode_scancode(uint8_t scancode); -char decode_key_enum(kb_key_press_t keycode); +kb_key_code_t decode_scancode(uint8_t scancode); +key_press_t do_keypress(kb_key_code_t keycode); #endif diff --git a/util/bochsrc.txt b/util/bochsrc.txt new file mode 100644 index 0000000..cdc7dc5 --- /dev/null +++ b/util/bochsrc.txt @@ -0,0 +1,11 @@ +megs: 32 +display_library: sdl +romimage: file=/usr/share/bochs/BIOS-bochs-latest +vgaromimage: file=/usr/share/bochs/VGABIOS-lgpl-latest +ata0-master: type=cdrom, path=os.iso, status=inserted +boot: cdrom +log: bochslog.txt +clock: sync=realtime, time0=local +cpu: count=1, ips=10000000 +com1: enabled=1, mode=file, dev=com1.out +