peredOS/drivers/keyboard.c

137 lines
5.3 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "keyboard.h"
#include "serial.h"
#include "vga.h"
#include "../kernel/io.h"
// Состояние модификаторов клавиатуры
static int is_e0 = 0;
static int shift_pressed = 0;
static int caps_lock_active = 0;
// Скан-коды управления (Set 1)
#define SCAN_LSHIFT 0x2A
#define SCAN_RSHIFT 0x36
#define SCAN_CAPS_LOCK 0x3A
// Скан-коды стрелок (после 0xE0)
#define SCAN_UP 0x48
#define SCAN_DOWN 0x50
#define SCAN_LEFT 0x4B
#define SCAN_RIGHT 0x4D
// Таблица 1: Обычные символы (без Shift)
static const char kbdus_lower[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, '-', 0, 0, 0, '+', 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
// Таблица 2: Символы при зажатом Shift
static const char kbdus_upper[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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, '_', 0, 0, 0, '+', 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
void keyboard_init(void) {
shift_pressed = 0;
caps_lock_active = 0;
is_e0 = 0;
kprint_serial("[INFO] Full keyboard driver with Modifiers initialized.\n");
}
void keyboard_handler(void) {
uint8_t scancode = inb(0x60);
// 1. Ловим префикс расширенных кодов
if (scancode == 0xE0) {
is_e0 = 1;
return;
}
// 2. Обработка ОТПУСКАНИЯ клавиш (Key Release / Break code)
// В Set 1 код отпускания — это код нажатия + 0x80 (установлен старший бит)
if (scancode & 0x80) {
uint8_t released_code = scancode & 0x7F; // Получаем чистый код нажатия
if (is_e0) {
is_e0 = 0; // Для расширенных кодов просто сбрасываем флаг
return;
}
// Если отпустили левый или правый Shift — выключаем режим шифта
if (released_code == SCAN_LSHIFT || released_code == SCAN_RSHIFT) {
shift_pressed = 0;
kprint_serial("[KEY] Shift Released\n");
}
return;
}
// 3. Обработка НАЖАТИЯ клавиш (Key Press / Make code)
if (is_e0) {
// Обработка расширенных клавиш (стрелочки)
switch (scancode) {
case SCAN_UP: kprint_serial("[KEY] UP\n"); break;
case SCAN_DOWN: kprint_serial("[KEY] DOWN\n"); break;
case SCAN_LEFT: kprint_serial("[KEY] LEFT\n"); break;
case SCAN_RIGHT: kprint_serial("[KEY] RIGHT\n"); break;
default: break;
}
is_e0 = 0; // Сбрасываем префикс после обработки
return;
}
// Обработка обычных управляющих клавиш
if (scancode == SCAN_LSHIFT || scancode == SCAN_RSHIFT) {
shift_pressed = 1;
kprint_serial("[KEY] Shift Pressed\n");
return;
}
if (scancode == SCAN_CAPS_LOCK) {
caps_lock_active = !caps_lock_active; // Инвертируем состояние
kprint_serial("[KEY] Caps Lock Toggled\n");
return;
}
// Печать символов из таблиц
if (scancode < 128) {
char c = 0;
// Определяем, какую таблицу использовать и нужно ли менять регистр букв
// Логика для букв: Shift XOR CapsLock (если нажат Shift и включен Caps, буквы будут маленькими)
int use_upper = shift_pressed;
// Проверяем, является ли символ буквой, чтобы к нему применялся Caps Lock
char base_char = kbdus_lower[scancode];
int is_alpha = (base_char >= 'a' && base_char <= 'z');
if (is_alpha && caps_lock_active) {
use_upper = !use_upper; // Caps Lock инвертирует поведение Shift для букв
}
// Выбираем символ из нужной матрицы
if (use_upper) {
c = kbdus_upper[scancode];
} else {
c = kbdus_lower[scancode];
}
// Если символ есть в раскладке — выводим
if (c != 0) {
vga_putchar(c);
// Дублируем в сериал отладку
char str[2] = {c, 0};
kprint_serial(str);
}
}
}