diff --git a/headers/drivers.h b/headers/drivers.h index 9291720..2038849 100644 --- a/headers/drivers.h +++ b/headers/drivers.h @@ -1,6 +1,8 @@ #pragma once #include "interrupts.h" +#define NEWLINE 0 +#define READING 1 void load_drivers(void); void keyboard_handler(struct registers *regs); diff --git a/headers/shell.h b/headers/shell.h index d029e27..462878c 100644 --- a/headers/shell.h +++ b/headers/shell.h @@ -2,4 +2,5 @@ #define PROMPT "> " -void shell_init(); \ No newline at end of file +void shell_init(void); +void auto_complete(void); diff --git a/headers/terminal.h b/headers/terminal.h index 6fca460..2717d95 100644 --- a/headers/terminal.h +++ b/headers/terminal.h @@ -57,4 +57,5 @@ void set_color_level(int level); void terminal_set_default_fg_color(uint8_t fg_color); void terminal_set_default_bg_color(uint8_t fg_color); void terminal_change_default_fg_color(uint8_t color); -uint8_t terminal_get_default_color(void); \ No newline at end of file +uint8_t terminal_get_default_color(void); +uint8_t terminal_get_char(int column, int row); diff --git a/src/drivers/keyboard.c b/src/drivers/keyboard.c index ff0aa51..a7b3776 100644 --- a/src/drivers/keyboard.c +++ b/src/drivers/keyboard.c @@ -1,10 +1,45 @@ +#include "drivers.h" #include "interrupts.h" #include "kprintf.h" +#include "shell.h" +#include "string.h" #include "terminal.h" #include +extern struct screen *screen; + +int line_status = READING; + void keyboard_handler(struct registers *regs) { + size_t i = 0; + struct key_event ev; + (void)regs; - terminal_putchar(terminal_getkey().c); + ev = terminal_getkey(); + char *buf = screen->line; + i = strlen(screen->line); + if (ev.c == '\n') { + kprintf("\n"); + screen->line[i] = '\0'; + line_status = NEWLINE; + return; + } + const size_t size = sizeof(screen->line); + if (ev.scan_code == KEY_BACKSPACE && i) { + buf[--i] = '\0'; + move_cursor(LEFT); + terminal_putchar(' '); + move_cursor(LEFT); + } else if (ev.scan_code == KEY_TAB && i) { + auto_complete(); + } else if (ev.c && i < size - 1) { + kprintf("%c", ev.c); + buf[i++] = ev.c; + } + if (i >= size) { + kprintf("\n"); + screen->line[i] = '\0'; + line_status = NEWLINE; + } } diff --git a/src/kernel.c b/src/kernel.c index 929e655..6b1a52b 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -29,7 +29,5 @@ void kernel_main(void) init_idt(); init_memory(); load_drivers(); - while (42) - ; - /* shell_init(); */ + shell_init(); } diff --git a/src/shell/exec.c b/src/shell/exec.c index bb1853b..65c471c 100644 --- a/src/shell/exec.c +++ b/src/shell/exec.c @@ -2,6 +2,7 @@ #include "alloc.h" #include "commands.h" +#include "drivers.h" #include "kprintf.h" #include "shell.h" #include "string.h" @@ -33,6 +34,7 @@ const struct shell_command cmds[] = { #define NB_CMDS ARRAY_SIZE(cmds) extern struct screen *screen; +extern int line_status; void help_cmd(char *arg) { @@ -53,7 +55,7 @@ void help_cmd(char *arg) kprintf("%s\n", BORDER); } -static void auto_complete(void) +void auto_complete(void) { const size_t len = strlen(screen->line); int nb_matches = 0; @@ -73,45 +75,12 @@ static void auto_complete(void) } } -static void read_line(void) +void shell_init(void) { - size_t i = 0; - struct key_event ev; - uint8_t prev_scan_code = 0; - + kprintf(PROMPT); while (1) { - ev = terminal_getkey(); - if (ev.c == '\n') - break; - char *buf = screen->line; - i = strlen(screen->line); - const size_t size = sizeof(screen->line); - if (prev_scan_code != ev.scan_code && ev.scan_code) { - if (ev.scan_code == KEY_BACKSPACE && i) { - buf[--i] = '\0'; - move_cursor(LEFT); - terminal_putchar(' '); - move_cursor(LEFT); - } else if (ev.scan_code == KEY_TAB && i) { - auto_complete(); - } else if (ev.c && i < size - 1) { - kprintf("%c", ev.c); - buf[i++] = ev.c; - } - if (i >= size) - break; - } - prev_scan_code = ev.scan_code; - } - kprintf("\n"); - screen->line[i] = '\0'; -} - -void shell_init() -{ - while (1) { - kprintf(PROMPT); - read_line(); + if (line_status != NEWLINE) + continue; bool invalid = true; for (unsigned i = 0; i < NB_CMDS; i++) { if (!strncmp(cmds[i].name, screen->line, @@ -128,5 +97,7 @@ void shell_init() kprintf(KERN_WARNING "invalid command: %s\n", screen->line); memset(screen->line, '\0', sizeof(screen->line)); + line_status = READING; + kprintf(PROMPT); } } diff --git a/src/terminal/put.c b/src/terminal/put.c index bc8faaf..a1486ff 100644 --- a/src/terminal/put.c +++ b/src/terminal/put.c @@ -80,6 +80,11 @@ uint8_t terminal_get_default_color(void) return screen->default_color; } +uint8_t terminal_get_char(int column, int row) +{ + return screen->buffer[row * VGA_WIDTH + column]; +} + void terminal_putentryat(char c, uint8_t color, size_t x, size_t y) { const size_t index = y * VGA_WIDTH + x;