Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions kernel/include/tty.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <stdint.h>

#define TTY_MAX_SCREEN 4

#define VGA_MEMORY_BASE 0xB8000
#define VGA_WIDTH 80
#define VGA_HEIGHT 25
Expand All @@ -15,6 +16,8 @@ typedef struct {
size_t column;
uint8_t color;
uint16_t buf[VGA_BUFFER_SIZE];
uint8_t id;
size_t input_start;
} tty_t;

typedef enum vga_color {
Expand Down
36 changes: 26 additions & 10 deletions kernel/src/tty/tty.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@
#include "command.h"
#include "io.h"
#include "keyboard.h"
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>

#define TTY_PROMPT ">"

static tty_t ttys[4];
static tty_t* curr_tty = &ttys[0];
static uint16_t* vga_buf = (uint16_t*)VGA_MEMORY_BASE;
Expand All @@ -35,6 +34,8 @@ void tty_init() {
ttys[i].row = 0;
ttys[i].column = 0;
ttys[i].color = curr_tty->color;
ttys[i].id = i + 1;
ttys[i].input_start = 0;
memcpy(ttys[i].buf, vga_buf, VGA_BUFFER_SIZE);
}
}
Expand All @@ -53,6 +54,7 @@ void tty_putchar(unsigned char c) {
tty_putchar_at(c, curr_tty->column, curr_tty->row);
if (++curr_tty->column == VGA_WIDTH || c == '\n') {
curr_tty->column = 0;
curr_tty->input_start = 0;
if (++curr_tty->row == VGA_HEIGHT) {
scroll();
curr_tty->row -= 1;
Expand All @@ -77,7 +79,7 @@ void tty_clear() {
}

void tty_backspace() {
if (curr_tty->column <= strlen(TTY_PROMPT)) {
if (curr_tty->column <= curr_tty->input_start) {
return;
} else {
curr_tty->column--;
Expand Down Expand Up @@ -107,22 +109,36 @@ void tty_change_screen(size_t screen_number) {
void tty_print_prompt() {
if (curr_tty->column != 0)
return;
tty_putstr(TTY_PROMPT);

uint8_t fg = vga_get_color_fg(curr_tty->color);
uint8_t bg = vga_get_color_bg(curr_tty->color);

tty_set_color(VGA_COLOR_LIGHT_GREEN, bg);
printf("[%u] > ", curr_tty->id);
tty_set_color(fg, bg);
}

static void build_command(char* buf) {
size_t prompt_len = strlen(TTY_PROMPT);
const uint16_t* command = &vga_buf[curr_tty->row * VGA_WIDTH + prompt_len];
for (size_t i = 0; i < curr_tty->column - prompt_len; i++)
static bool try_build_command(char* buf) {
if (curr_tty->column <= curr_tty->input_start)
return false;

const uint16_t* command =
&vga_buf[curr_tty->row * VGA_WIDTH + curr_tty->input_start];

for (size_t i = 0; i < curr_tty->column - curr_tty->input_start; i++)
buf[i] = vga_get_char(command[i]);

return true;
}

void tty_handle_entry(char c) {
if (c == KC_ENTER) {
char buf[VGA_WIDTH] = {0};
build_command(buf);
bool valid_command = try_build_command(buf);
tty_putchar('\n');
cmd_handle(buf);
if (valid_command)
cmd_handle(buf);

tty_print_prompt();
return;
}
Expand Down