feature: functional shell with help and merdella commands
TOOD: reboot, poweroff, echo, color
This commit is contained in:
12
src/kernel.c
12
src/kernel.c
@ -1,4 +1,5 @@
|
||||
#include "kprintf.h"
|
||||
#include "gdt.h"
|
||||
#include "shell.h"
|
||||
#include "terminal.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
@ -21,11 +22,6 @@ void kernel_main(void)
|
||||
/* Initialize terminal interface */
|
||||
terminal_initialize();
|
||||
|
||||
/* Newline support is left as an exercise. */
|
||||
for (int i = 100; i; i--)
|
||||
kprintf(0, "%d\n", i);
|
||||
void initGdt();
|
||||
kprintf(0, "mange ta mere avec ton argument a kprintf fdp\n");
|
||||
while (true)
|
||||
terminal_getkey();
|
||||
/* initGdt(); */
|
||||
shell_init();
|
||||
}
|
||||
|
111
src/shell/exec.c
111
src/shell/exec.c
@ -0,0 +1,111 @@
|
||||
#include "kprintf.h"
|
||||
#include "shell.h"
|
||||
#include "string.h"
|
||||
#include "terminal.h"
|
||||
|
||||
extern struct screen *screen;
|
||||
|
||||
static CMD_TOK find_command(char *line)
|
||||
{
|
||||
size_t i = 0;
|
||||
bool uwu = false;
|
||||
CMD_TOK command = ERROR;
|
||||
|
||||
if (!line[0])
|
||||
return command;
|
||||
while (line[i]) {
|
||||
if (line[i] == ' ') {
|
||||
uwu = true;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
line[i] = '\0';
|
||||
if (!strcmp(line, "help"))
|
||||
command = HELP;
|
||||
else if (!strcmp(line, "reboot"))
|
||||
command = REBOOT;
|
||||
else if (!strcmp(line, "poweroff"))
|
||||
command = POWEROFF;
|
||||
else if (!strcmp(line, "echo"))
|
||||
command = ECHO;
|
||||
else if (!strcmp(line, "color"))
|
||||
command = COLOR;
|
||||
else if (!strcmp(line, "merdella"))
|
||||
command = MERDELLA;
|
||||
else
|
||||
kprintf(0, "invalid command: %s\n", line);
|
||||
if (uwu)
|
||||
line[i] = ' ';
|
||||
return command;
|
||||
}
|
||||
|
||||
static void read_line(char *buf, size_t size)
|
||||
{
|
||||
size_t i = 0;
|
||||
struct key_event ev;
|
||||
uint8_t prev_scan_code = 0;
|
||||
|
||||
while (1) {
|
||||
ev = terminal_getkey();
|
||||
if (ev.c == '\n')
|
||||
break;
|
||||
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);
|
||||
}
|
||||
if (ev.c && i < size - 1) {
|
||||
kprintf(0, "%c", ev.c);
|
||||
buf[i++] = ev.c;
|
||||
}
|
||||
if (i >= size)
|
||||
break;
|
||||
}
|
||||
prev_scan_code = ev.scan_code;
|
||||
}
|
||||
kprintf(0, "\n");
|
||||
buf[i] = '\0';
|
||||
}
|
||||
|
||||
void shell_init(void)
|
||||
{
|
||||
while (1) {
|
||||
kprintf(0, PROMPT);
|
||||
read_line(screen->line, sizeof(screen->line));
|
||||
switch (find_command(screen->line)) {
|
||||
case HELP:
|
||||
kprintf(0, "Welcome to bozOShell, the shell of "
|
||||
"bozOS\nAvailable commands: help, reboot, "
|
||||
"poweroff, echo, color, merdella\n");
|
||||
break;
|
||||
case REBOOT:
|
||||
kprintf(0, "rebooting\n");
|
||||
break;
|
||||
case POWEROFF:
|
||||
kprintf(0, "powering off\n");
|
||||
break;
|
||||
case ECHO:
|
||||
kprintf(0, "echoing\n");
|
||||
break;
|
||||
case COLOR:
|
||||
kprintf(0, "coloring\n");
|
||||
break;
|
||||
case MERDELLA: {
|
||||
kprintf(0, POOP);
|
||||
if (!strcmp("--credits", strchr(screen->line, ' ') + 1))
|
||||
kprintf(
|
||||
0,
|
||||
"\nThis ascii masterpiece has been created "
|
||||
"by Targon (/)\n");
|
||||
break;
|
||||
}
|
||||
case ERROR:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,31 +1,32 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "keyboard.h"
|
||||
#include "kprintf.h"
|
||||
#include "sys/io.h"
|
||||
#include "terminal.h"
|
||||
|
||||
uint8_t terminal_getkey(void)
|
||||
struct key_event terminal_getkey(void)
|
||||
{
|
||||
static bool caps_mode = false;
|
||||
static uint8_t prev_scan_code = 0;
|
||||
struct key_event ev = {0};
|
||||
uint8_t scan_code;
|
||||
|
||||
scan_code = inb(KEYBOARD_PORT);
|
||||
if (scan_code == 0x3A || scan_code == 0x58) {
|
||||
caps_mode = !caps_mode;
|
||||
outb(0xED, (caps_mode << 2)); // turn on/off capslock led
|
||||
}
|
||||
else if (scan_code == KEY_RIGHT_SHIFT || scan_code == KET_LEFT_SHIFT)
|
||||
} else if (scan_code == KEY_RIGHT_SHIFT || scan_code == KEY_LEFT_SHIFT)
|
||||
caps_mode = true;
|
||||
else if (scan_code == KEY_RIGHT_SHIFT + 128 || scan_code == KET_LEFT_SHIFT + 128)
|
||||
else if (scan_code == KEY_RIGHT_SHIFT + 128 ||
|
||||
scan_code == KEY_LEFT_SHIFT + 128)
|
||||
caps_mode = false;
|
||||
else if (scan_code != prev_scan_code && prev_scan_code != 0) {
|
||||
if (scan_code < 128 && keymap[scan_code])
|
||||
kprintf(0, "%c", keymap[scan_code][caps_mode]);
|
||||
ev.c = keymap[scan_code][caps_mode];
|
||||
if (scan_code >= KEY_F1 && scan_code <= KEY_F10)
|
||||
terminal_set_screen(scan_code - KEY_F1);
|
||||
}
|
||||
prev_scan_code = scan_code;
|
||||
return scan_code;
|
||||
ev.scan_code = scan_code;
|
||||
return ev;
|
||||
}
|
||||
|
@ -129,3 +129,46 @@ void update_cursor(void)
|
||||
outb(0x3D4, 0x0E);
|
||||
outb(0x3D5, (pos >> 8) & 0xFF);
|
||||
}
|
||||
|
||||
void move_cursor(int direction)
|
||||
{
|
||||
|
||||
switch (direction) {
|
||||
case LEFT:
|
||||
if (screen->column) {
|
||||
screen->column--;
|
||||
} else if (screen->row) {
|
||||
screen->column = VGA_WIDTH - 1;
|
||||
screen->row--;
|
||||
}
|
||||
break;
|
||||
case RIGHT:
|
||||
if (screen->column < VGA_WIDTH - 1) {
|
||||
screen->column++;
|
||||
} else if (screen->row < VGA_HEIGHT - 1) {
|
||||
screen->column = 0;
|
||||
screen->row++;
|
||||
} else {
|
||||
terminal_new_line();
|
||||
}
|
||||
break;
|
||||
case UP:
|
||||
break;
|
||||
case DOWN:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
uint16_t pos = screen->row * VGA_WIDTH + screen->column;
|
||||
|
||||
outb(0x3D4, 0x0F);
|
||||
outb(0x3D5, pos & 0xFF);
|
||||
outb(0x3D4, 0x0E);
|
||||
outb(0x3D5, (pos >> 8) & 0xFF);
|
||||
}
|
||||
|
||||
struct screen *get_screen(void)
|
||||
{
|
||||
return screen;
|
||||
}
|
||||
|
Reference in New Issue
Block a user