feature: a lot of stuff and got to a working command line ish

This commit is contained in:
2021-02-01 22:31:21 +01:00
parent 468d5968a9
commit 9986d95dbb
22 changed files with 1511 additions and 76 deletions

View File

@@ -7,31 +7,142 @@
#include <drivers/ports.h>
#include <cpu/isr.h>
#include <libc/libc.h>
#include <libc/stdbool.h>
#include <libc/ringqueue.h>
#include <mem/mem.h>
char scancodes_ascii[] = {
0, 0,
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 0,
0, 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', 0,
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, // F1-F10
0, 0,
'7', '8', '9', '-',
'4', '5', '6', '+',
'1', '2', '3',
'0', 0,
0, // sysrq
0, 0, // weird
0, 0, // F11 F12
// weid
const char scancode_map_lowercase[] = {
0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 0, 0, 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
'o', 'p', '[', ']', 0, 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
};
const char scancode_map_uppercase[] = {
0, 0, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', 0, 0, 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I',
'O', 'P', '{', '}', 0, 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
};
//
//char scancodes_ascii[] = {
// 0, 0,
// '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 0,
// 0, 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', 0,
// 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, // F1-F10
// 0, 0,
// '7', '8', '9', '-',
// '4', '5', '6', '+',
// '1', '2', '3',
// '0', 0,
// 0, // sysrq
// 0, 0, // weird
// 0, 0, // F11 F12
// // weid
//};
struct {
u8 shift: 1;
u8 ctrl: 1;
u8 alt: 1;
u8 extended: 1;
} keyboard_state;
void *keyboard_event_buffer = NULL;
char *MSG_KEY = "Clicked on key 'x'\n";
void print_scancode(unsigned char scancode);
char getc() {
while (true) {
KeyEvent* event = get_next_event();
char retval = 0;
if (event == NULL) {
goto _getc_end;
}
if (event->is_release) {
goto _getc_end;
}
if (event->scancode == 0x1C) {
retval = '\n';
goto _getc_end;
}
if (event->ascii_code != 0) {
retval = event->ascii_code;
goto _getc_end;
}
_getc_end:
free_event(event);
if (retval != 0) {
return retval;
}
}
}
KeyEvent *get_next_event() {
KeyEvent *target = malloc(sizeof(KeyEvent));
if (!ring_buffer_get(keyboard_event_buffer, target)) {
free(target);
return NULL;
}
return target;
};
void free_event(KeyEvent *event) {
free(event);
}
//void print_scancode(unsigned char scancode);
void handle_modifier_keys(unsigned char scancode, bool is_release) {
switch (scancode) {
case 42:
case 54:
keyboard_state.shift = !is_release;
break;
case 29:
keyboard_state.ctrl = !is_release;
break;
case 56:
keyboard_state.alt = !is_release;
break;
default:
// not an modifier key
break;
}
}
void publish_key_event(unsigned char scan_code) {
bool is_release = false;
if (scan_code > 0x80) {
is_release = true;
scan_code -= 0x80;
}
handle_modifier_keys(scan_code, is_release);
char ascii_char = scancode_map_lowercase[scan_code];
if (keyboard_state.shift) {
if (scancode_map_uppercase[scan_code] != 0) {
ascii_char = scancode_map_uppercase[scan_code];
}
}
KeyEvent event = {
.scancode = scan_code,
.ascii_code = ascii_char,
.is_release = !is_release,
.shift = keyboard_state.shift,
.alt = keyboard_state.alt,
.ctrl = keyboard_state.ctrl,
};
ring_buffer_put(keyboard_event_buffer, &event);
}
static void keyboard_callback(registers_t regs) {
unsigned char status = port_byte_in(PORT_PS2_STATUS);
@@ -40,31 +151,37 @@ static void keyboard_callback(registers_t regs) {
return;
}
unsigned char scancode = port_byte_in(PORT_PS2_DATA);
print_scancode(scancode);
publish_key_event(scancode);
// print_scancode(scancode);
}
void init_keyboard() {
register_interrupt_handler(IRQ1, keyboard_callback);
keyboard_state.shift = 0;
keyboard_state.ctrl = 0;
keyboard_state.alt = 0;
keyboard_state.extended = 0;
keyboard_event_buffer = create_buffer(256, sizeof(KeyEvent));
}
void print_scancode(unsigned char scancode) {
char msg[256];
char release = 0;
if (scancode > 0x80) {
// release
release = 1;
scancode -= 0x80;
}
char code = scancodes_ascii[scancode];
if (code == 0) {
// special
} else {
if (release && code > 0x60 && code < 0x7B) {
code -= 0x20; // to lowercase
}
strcpy(msg, MSG_KEY);
msg[strlen(msg) - 3] = code;
kprint(msg);
}
}
//void print_scancode(unsigned char scancode) {
// char msg[256];
// char release = 0;
// if (scancode > 0x80) {
// // release
// release = 1;
// scancode -= 0x80;
// }
// char code = scancodes_ascii[scancode];
// if (code == 0) {
// // special
// } else {
// if (release && code > 0x60 && code < 0x7B) {
// code -= 0x20; // to lowercase
// }
//
// strcpy(msg, MSG_KEY);
// msg[strlen(msg) - 3] = code;
// kprint(msg);
// }
//}

View File

@@ -5,6 +5,26 @@
#ifndef MY_KERNEL_KEYBOARD_H
#define MY_KERNEL_KEYBOARD_H
#include <types.h>
typedef struct KeyEvent_t {
// KeyCode key;
u32 scancode;
char ascii_code;
u8 is_release: 1;
u8 shift: 1;
u8 alt: 1;
u8 ctrl: 1;
} KeyEvent;
char getc();
void init_keyboard();
//const char *key_code_to_string(KeyCode key);
KeyEvent *get_next_event();
void free_event(KeyEvent *event);
#endif //MY_KERNEL_KEYBOARD_H