From 2d0a37f6a505b7394bf432687da6d9f88447dd50 Mon Sep 17 00:00:00 2001 From: Aren Elchinyan Date: Mon, 25 Dec 2023 22:34:54 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D1=80=D0=B0=D0=B1=D0=BE=D1=82?= =?UTF-8?q?=D0=BA=D0=B0=20=D0=BC=D0=BE=D0=B4=D1=83=D0=BB=D1=8F=20Ps/2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/arch/idt.c | 2 +- kernel/fb.c | 1 + kernel/mod.c | 1 + modlib/types.h | 3 + modules/ps2/keymap.h | 165 ++++++++++++++++++++++++++++++++++++++++++ modules/ps2/main.c | 131 +++++++++++++++++++++++++++++---- modules/ps2/special.h | 18 +++++ 7 files changed, 306 insertions(+), 15 deletions(-) create mode 100644 modules/ps2/keymap.h create mode 100644 modules/ps2/special.h diff --git a/kernel/arch/idt.c b/kernel/arch/idt.c index fe74e23..082a2de 100644 --- a/kernel/arch/idt.c +++ b/kernel/arch/idt.c @@ -53,7 +53,7 @@ static void exception_handler(struct frame state) { void isr_generic(struct frame state) { if (state.int_number > 255) { return; } - if (state.int_number != 32) { LOG("Обработка прерывания %u\n", state.int_number); } + // if (state.int_number != 32) { LOG("Обработка прерывания %u\n", state.int_number); } if (state.int_number < 32) { exception_handler(state); diff --git a/kernel/fb.c b/kernel/fb.c index da09af1..a7d0e8d 100644 --- a/kernel/fb.c +++ b/kernel/fb.c @@ -112,6 +112,7 @@ void scroll_fb( ) { // Вывод одного символа static void fb_putchar(char c) { + if (c == '\0') { return; } if (c == '\t') { pos_x += FONT_6X8_SLIM_CHAR_WIDTH * 4; } else if (c == '\n') { diff --git a/kernel/mod.c b/kernel/mod.c index 3370799..d6db0e8 100644 --- a/kernel/mod.c +++ b/kernel/mod.c @@ -116,6 +116,7 @@ void mod_init( ) { module_list[modules_count].name = ret.name; module_list[modules_count].message = ret.message; module_list[modules_count].data_size = ret.data_size; + module_list[modules_count].get_func = ret.get_func; if (ret.data_size != 0) { module_list[modules_count].data = ret.data; } if (ret.irq != 0) { diff --git a/modlib/types.h b/modlib/types.h index 7d8980e..51565fd 100644 --- a/modlib/types.h +++ b/modlib/types.h @@ -10,6 +10,9 @@ #define TYPES_H #define NULL ((void *)0) +#define bool _Bool +#define false 0 +#define true 1 typedef unsigned char uint8_t; typedef unsigned short uint16_t; diff --git a/modules/ps2/keymap.h b/modules/ps2/keymap.h new file mode 100644 index 0000000..0613776 --- /dev/null +++ b/modules/ps2/keymap.h @@ -0,0 +1,165 @@ +#include "special.h" + +static char en_chars_lower[] = { + 0, 27, '1', '2', '3', '4', '5', '6', '7', '8', /* 9 */ + '9', '0', '-', '=', '\b', /* Backspace */ + '\t', /* Tab */ + 'q', 'w', 'e', 'r', /* 19 */ + 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', /* Enter */ + 0, /* Control */ + 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', /* 39 */ + '\'', '`', 0, /* Left shift */ + '\\', 'z', 'x', 'c', 'v', 'b', 'n', /* 49 */ + 'm', ',', '.', '/', 0, /* Right shift */ + '*', 0, /* Alt */ + ' ', /* Space bar */ + 0, /* Caps lock */ + 0, /* 59 - F1 */ + 0, /* F2 */ + 0, /* F3 */ + 0, /* F4 */ + 0, /* F5 */ + 0, /* F6 */ + 0, /* F7 */ + 0, /* F8 */ + 0, /* F9 */ + 0, /* F10 */ + 0, /* 69 - Num lock*/ + 0, /* Scroll Lock */ + 0, /* Home */ + 0, /* Up Arrow */ + 0, /* Page Up */ + '-', 0, /* Left Arrow */ + 0, 0, /* Right Arrow */ + '+', 0, /* 79 - End */ + 0, /* Down Arrow */ + 0, /* Page Down */ + 0, /* Insert */ + 0, /* Delete */ + 0, 0, 0, 0, /* F11 */ + 0, /* F12 */ + 0, /* NULL */ +}; + +static char en_chars_shifted[] = { + 0, 27, '!', '@', '#', '$', '%', '^', '&', '*', /* 9 */ + '(', ')', '_', '+', '\b', /* Backspace */ + '\t', /* Tab */ + 'Q', 'W', 'E', 'R', /* 19 */ + 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n', /* Enter */ + 0, /* 29 - Control */ + 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', /* 39 */ + '"', '~', 0, /* Left shift */ + '|', 'Z', 'X', 'C', 'V', 'B', 'N', /* 49 */ + 'M', '<', '>', '?', 0, /* Right shift */ + '*', 0, /* Alt */ + ' ', /* Space bar */ + 0, /* Caps lock */ + 0, /* 59 - F1 */ + 0, /* F2 */ + 0, /* F3 */ + 0, /* F4 */ + 0, /* F5 */ + 0, /* F6 */ + 0, /* F7 */ + 0, /* F8 */ + 0, /* F9 */ + 0, /* F10 */ + 0, /* 69 - Num lock*/ + 0, /* Scroll Lock */ + 0, /* Home */ + 0, /* Up Arrow */ + 0, /* Page Up */ + '-', 0, /* Left Arrow */ + 0, 0, /* Right Arrow */ + '+', 0, /* 79 - End */ + 0, /* Down Arrow */ + 0, /* Page Down */ + 0, /* Insert */ + 0, /* Delete */ + 0, 0, 0, 0, /* F11 */ + 0, /* F12 */ + 0, /* NULL */ +}; + +static char ru_chars_lower[] = { + 0, 27, '1', '2', '3', '4', '5', '6', '7', '8', /* 9 */ + '9', '0', '-', '=', '\b', /* Backspace */ + '\t', /* Tab */ + 'й', 'ц', 'у', 'к', /* 19 */ + 'е', 'н', 'г', 'ш', 'щ', 'з', 'х', 'ъ', '\n', /* Enter */ + 0, /* Control */ + 'ф', 'ы', 'в', 'а', 'п', 'р', 'о', 'л', 'д', 'ж', /* 39 */ + 'э', 'ё', 0, /* Left shift */ + '\\', 'я', 'ч', 'с', 'м', 'и', 'т', /* 49 */ + 'ь', 'б', 'ю', '.', 0, /* Right shift */ + '*', 0, /* Alt */ + ' ', /* Space bar */ + 0, /* Caps lock */ + 0, /* 59 - F1 */ + 0, /* F2 */ + 0, /* F3 */ + 0, /* F4 */ + 0, /* F5 */ + 0, /* F6 */ + 0, /* F7 */ + 0, /* F8 */ + 0, /* F9 */ + 0, /* F10 */ + 0, /* 69 - Num lock*/ + 0, /* Scroll Lock */ + 0, /* Home */ + 0, /* Up Arrow */ + 0, /* Page Up */ + '-', 0, /* Left Arrow */ + 0, 0, /* Right Arrow */ + '+', 0, /* 79 - End */ + 0, /* Down Arrow */ + 0, /* Page Down */ + 0, /* Insert */ + 0, /* Delete */ + 0, 0, 0, 0, /* F11 */ + 0, /* F12 */ + 0, /* NULL */ +}; + +static char ru_chars_shifted[] = { + 0, 27, '!', '\"', '№', ';', '%', ':', '?', '*', /* 9 */ + '(', ')', '_', '+', '\b', /* Backspace */ + '\t', /* Tab */ + 'Й', 'Ц', 'У', 'К', /* 19 */ + 'Е', 'Н', 'Г', 'Ш', 'Щ', 'З', 'Х', 'Ъ', '\n', /* Enter */ + 0, /* 29 - Control */ + 'Ф', 'Ы', 'В', 'А', 'П', 'Р', 'О', 'Л', 'Д', 'Ж', /* 39 */ + 'Э', 'Ё', 0, /* Left shift */ + '\\', 'Я', 'Ч', 'С', 'М', 'И', 'Т', /* 49 */ + 'Ь', 'Б', 'Ю', ',', 0, /* Right shift */ + '*', 0, /* Alt */ + ' ', /* Space bar */ + 0, /* Caps lock */ + 0, /* 59 - F1 */ + 0, /* F2 */ + 0, /* F3 */ + 0, /* F4 */ + 0, /* F5 */ + 0, /* F6 */ + 0, /* F7 */ + 0, /* F8 */ + 0, /* F9 */ + 0, /* F10 */ + 0, /* 69 - Num lock*/ + 0, /* Scroll Lock */ + 0, /* Home */ + 0, /* Up Arrow */ + 0, /* Page Up */ + '-', 0, /* Left Arrow */ + 0, 0, /* Right Arrow */ + '+', 0, /* 79 - End */ + 0, /* Down Arrow */ + 0, /* Page Down */ + 0, /* Insert */ + 0, /* Delete */ + 0, 0, 0, 0, /* F11 */ + 0, /* F12 */ + 0, /* NULL */ +}; \ No newline at end of file diff --git a/modules/ps2/main.c b/modules/ps2/main.c index 390f911..00296ce 100644 --- a/modules/ps2/main.c +++ b/modules/ps2/main.c @@ -1,5 +1,12 @@ +#include "keymap.h" #include +static uint8_t current_state; +static bool kbd_free = false; +static int ru = 1; +static char c_char = '\0'; +static key_event_t keyboard_buffer; + static inline void virt_exit( ) { fb_printf("Выход для Bochs\n"); outw(0xB004, 0x2000); @@ -14,41 +21,137 @@ static inline void virt_exit( ) { outw(0x600, 0x34); } -static void handler( ) { - fb_printf("Получено прерывание, обработка\n"); +static void wait_irq( ) { + while (!kbd_free) { asm volatile("pause"); } + kbd_free = false; +} +static char getc( ) { + wait_irq( ); + return c_char; +} + +static void *__get_func(uint64_t func) { + switch (func) { + case 0: return wait_irq; + case 1: return getc; + default: return NULL; + } +} + +static uint8_t keyboard_to_ascii(uint8_t key) {} + +static void after_interrupt( ) { + uint8_t status = inb(0x61) | 1; + outb(0x61, status); +} + +static int is_shift(uint8_t scancode) { + switch (scancode) { + case 0x2A: // Левый SHIFT + return 1; + case 0x36: // Правый SHIFT + return 1; + case 0xAA: // Левый SHIFT отпущен + return -1; + case 0xB6: // Правый SHIFT отпущен + return -1; + default: // Другой символ + return 0; + } +} + +static int is_ctrl(uint8_t scancode) { + if (current_state == PREFIX_STATE) { + switch (scancode) { + case 0x1D: // Правый CTRL + return 1; + case 0x9D: // Правый CTRL отпущен + return -1; + default: // Другой символ + return 0; + } + } + switch (scancode) { + case 0x1D: // Левый CTRL + return 1; + case 0x9D: // Левый CTRL отпущен + return -1; + default: // Другой символ + return 0; + } +} + +static void handler( ) { while (!(inb(0x64) & 1)) { asm volatile("pause"); } - uint64_t byte = inb(0x60); + uint8_t scancode = inb(0x60); + char c = ' \0'; - if (byte == 0) { return; } + if (scancode == 0xE0) { + current_state = PREFIX_STATE; + after_interrupt( ); + return; + } - fb_printf("Символ: %c, %u, %x\n", byte, byte, byte); + if (scancode < 0) { + after_interrupt( ); + return; + } - switch (byte) { + if (is_shift(scancode) != 0) { + keyboard_buffer->shift_pressed = is_shift(scancode); + after_interrupt( ); + return; + } + + if (is_ctrl(scancode) != 0) { + keyboard_buffer->ctrl_pressed = is_ctrl(scancode); + after_interrupt( ); + return; + } + + if (current_state == PREFIX_STATE) { current_state = NORMAL_STATE; } + + + if (ru) { + if (keyboard_buffer.shift_pressed) { + c = ru_chars_shifted[scancode]; + } else { + c = ru_chars_lower[scancode]; + } + } else { + if (keyboard_buffer.shift_pressed) { + c = en_chars_shifted[scancode]; + } else { + c = en_chars_lower[scancode]; + } + } + + c_char = c; + kbd_free = true; + + switch (scancode) { case 0x01: virt_exit( ); break; // Клавиша "ESCAPE" case 0x4F: // Клавиша "END" asm volatile("int $32"); break; default: break; } - - uint8_t status = inb(0x61) | 1; - - outb(0x61, status); + after_interrupt( ); } module_info_t __attribute__((section(".minit"))) init(env_t *env) { init_env(env); - + current_state = NORMAL_STATE; return (module_info_t){ .name = (char *)"[KEYBOARD]", .message = (char *)"PS/2 драйвер", .type = 0, - .data_size = 0, - .data = (void *)0, + .data_size = MAX_KEY_BUFFER_SIZE, + .data = (void *)&keyboard_buffer, .err_code = 0, .module_id = 0, .irq = 33, .irq_handler = handler, - .get_func = 0 }; + .get_func = __get_func }; } \ No newline at end of file diff --git a/modules/ps2/special.h b/modules/ps2/special.h new file mode 100644 index 0000000..73e78d9 --- /dev/null +++ b/modules/ps2/special.h @@ -0,0 +1,18 @@ +#include + +#define MAX_KEY_BUFFER_SIZE 1 +#define NORMAL_STATE 0 +#define PREFIX_STATE 1 + +typedef struct { + uint8_t code; + bool ctrl_pressed; + bool alt_pressed; + bool shift_pressed; + bool sys_menu_pressed; +} key_event_t; + +typedef struct { + uint8_t code; + uint8_t c; +} keyboard_char_t; \ No newline at end of file