mirror of
https://github.com/subhobhai943/SUB-OS.git
synced 2026-10-25 16:52:29 +00:00
fix(userland): Fix 'clear' command, backspace keycodes (0x7F/0x08), serial keyboard input & make run target
- Add 'clear' and 'cls' builtin handlers in LazyBox shell - Output ANSI \033[2J\033[H sequence on tty_clear() to clear serial/UART terminals - Support both ASCII 0x7F (DEL) and 0x08 (BS) for Backspace in shell and nano editor - Connect 16550 serial input to keyboard_get_key() on x86_64 for headless terminals - Add ANSI escape sequence decoding for arrow keys (Up/Down/Left/Right/Home/End/Del) - Update Makefile 'make run' and 'make qemu' with -display none for smooth terminal execution - Add 'make run-gui' target for optional graphical SDL/GTK window
This commit is contained in:
1 parent
f5dbc1453c
commit
6ad90542ac
7 files changed
+118
-23
No files matched your search
+74
-8
@@ -2,6 +2,14 @@
|
||||
#include <drivers/tty.h>
|
||||
#include <arch/arch.h>
|
||||
|
||||
#if defined(__x86_64__)
|
||||
#include <drivers/serial.h>
|
||||
#elif defined(__aarch64__)
|
||||
#include <arch/aarch64/uart.h>
|
||||
#elif defined(__arm__) || defined(__armv8i__)
|
||||
#include <arch/armv8i/uart.h>
|
||||
#endif
|
||||
|
||||
#define KEYBOARD_DATA_PORT 0x60
|
||||
#define KEYBOARD_STATUS_PORT 0x64
|
||||
#define KEYBOARD_BUFFER_SIZE 128
|
||||
@@ -123,14 +131,10 @@ void keyboard_init(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(__aarch64__)
|
||||
#include <arch/aarch64/uart.h>
|
||||
#elif defined(__arm__) || defined(__armv8i__)
|
||||
#include <arch/armv8i/uart.h>
|
||||
#endif
|
||||
|
||||
bool keyboard_has_key(void) {
|
||||
#if defined(__aarch64__) || defined(__arm__) || defined(__armv8i__)
|
||||
#if defined(__x86_64__)
|
||||
if (serial_received()) return true;
|
||||
#elif defined(__aarch64__) || defined(__arm__) || defined(__armv8i__)
|
||||
if (uart_pl011_has_data()) return true;
|
||||
#endif
|
||||
return buffer_head != buffer_tail;
|
||||
@@ -140,13 +144,75 @@ uint16_t keyboard_get_key(void) {
|
||||
while (!keyboard_has_key()) {
|
||||
arch_halt();
|
||||
}
|
||||
#if defined(__aarch64__) || defined(__arm__) || defined(__armv8i__)
|
||||
|
||||
#if defined(__x86_64__)
|
||||
if (serial_received()) {
|
||||
char c = serial_read_char();
|
||||
if ((uint8_t)c == 0x1B) { // Escape sequence
|
||||
for (volatile int t = 0; t < 2000; t++) {
|
||||
if (serial_received()) {
|
||||
char c2 = serial_read_char();
|
||||
if (c2 == '[') {
|
||||
for (volatile int t2 = 0; t2 < 2000; t2++) {
|
||||
if (serial_received()) {
|
||||
char c3 = serial_read_char();
|
||||
if (c3 == 'A') return KEY_UP;
|
||||
if (c3 == 'B') return KEY_DOWN;
|
||||
if (c3 == 'C') return KEY_RIGHT;
|
||||
if (c3 == 'D') return KEY_LEFT;
|
||||
if (c3 == 'H') return KEY_HOME;
|
||||
if (c3 == 'F') return KEY_END;
|
||||
if (c3 == '3') {
|
||||
if (serial_received() && serial_read_char() == '~') return KEY_DELETE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0x1B;
|
||||
}
|
||||
if (c == '\r') c = '\n';
|
||||
if ((uint8_t)c == 0x7F || c == 0x08) c = '\b';
|
||||
return (uint16_t)(uint8_t)c;
|
||||
}
|
||||
#elif defined(__aarch64__) || defined(__arm__) || defined(__armv8i__)
|
||||
if (uart_pl011_has_data()) {
|
||||
char c = uart_pl011_getc();
|
||||
if ((uint8_t)c == 0x1B) { // Escape sequence
|
||||
for (volatile int t = 0; t < 2000; t++) {
|
||||
if (uart_pl011_has_data()) {
|
||||
char c2 = uart_pl011_getc();
|
||||
if (c2 == '[') {
|
||||
for (volatile int t2 = 0; t2 < 2000; t2++) {
|
||||
if (uart_pl011_has_data()) {
|
||||
char c3 = uart_pl011_getc();
|
||||
if (c3 == 'A') return KEY_UP;
|
||||
if (c3 == 'B') return KEY_DOWN;
|
||||
if (c3 == 'C') return KEY_RIGHT;
|
||||
if (c3 == 'D') return KEY_LEFT;
|
||||
if (c3 == 'H') return KEY_HOME;
|
||||
if (c3 == 'F') return KEY_END;
|
||||
if (c3 == '3') {
|
||||
if (uart_pl011_has_data() && uart_pl011_getc() == '~') return KEY_DELETE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0x1B;
|
||||
}
|
||||
if (c == '\r') c = '\n';
|
||||
if ((uint8_t)c == 0x7F || c == 0x08) c = '\b';
|
||||
return (uint16_t)(uint8_t)c;
|
||||
}
|
||||
#endif
|
||||
|
||||
uint16_t key = key_buffer[buffer_tail];
|
||||
buffer_tail = (buffer_tail + 1) % KEYBOARD_BUFFER_SIZE;
|
||||
return key;
|
||||
|
||||
+24
-7
@@ -1,6 +1,7 @@
|
||||
#include <drivers/tty.h>
|
||||
#include <drivers/vga.h>
|
||||
#include <lib/string.h>
|
||||
#include <kernel/printk.h>
|
||||
|
||||
typedef struct {
|
||||
uint16_t buffer[TTY_HEIGHT][TTY_WIDTH];
|
||||
@@ -42,7 +43,7 @@ static void tty_scroll(tty_t* t) {
|
||||
}
|
||||
}
|
||||
for (int x = 0; x < TTY_WIDTH; x++) {
|
||||
t->buffer[TTY_HEIGHT - 1][x] = vga_entry(' ', t->current_color);
|
||||
t->buffer[TTY_HEIGHT - 1][x] = vga_entry(' ', t->current_color ? t->current_color : 0x07);
|
||||
}
|
||||
t->cursor_row = TTY_HEIGHT - 1;
|
||||
}
|
||||
@@ -51,12 +52,15 @@ void tty_clear(void) {
|
||||
tty_t* t = &ttys[current_tty];
|
||||
for (int y = 0; y < TTY_HEIGHT; y++) {
|
||||
for (int x = 0; x < TTY_WIDTH; x++) {
|
||||
t->buffer[y][x] = vga_entry(' ', t->current_color);
|
||||
t->buffer[y][x] = vga_entry(' ', t->current_color ? t->current_color : 0x07);
|
||||
}
|
||||
}
|
||||
t->cursor_row = 0;
|
||||
t->cursor_col = 0;
|
||||
tty_render_current();
|
||||
|
||||
// Send standard ANSI terminal clear screen sequence to serial / UART
|
||||
printk("\033[2J\033[H");
|
||||
}
|
||||
|
||||
void tty_set_cursor(int row, int col) {
|
||||
@@ -74,7 +78,7 @@ void tty_write(const char* data, size_t size) {
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
char c = data[i];
|
||||
|
||||
// Basic ANSI escape sequence parser (e.g. \033[31m)
|
||||
// ANSI escape sequence parser
|
||||
if (c == '\033' && i + 1 < size && data[i + 1] == '[') {
|
||||
i += 2;
|
||||
int code = 0;
|
||||
@@ -91,7 +95,7 @@ void tty_write(const char* data, size_t size) {
|
||||
else if (code == 35) t->current_color = 0x05; // Magenta
|
||||
else if (code == 36) t->current_color = 0x03; // Cyan
|
||||
else if (code == 37) t->current_color = 0x07; // White
|
||||
else if (code == 90) t->current_color = 0x08; // Bright Black (Dark Grey)
|
||||
else if (code == 90) t->current_color = 0x08; // Bright Black
|
||||
else if (code == 91) t->current_color = 0x0C; // Bright Red
|
||||
else if (code == 92) t->current_color = 0x0A; // Bright Green
|
||||
else if (code == 93) t->current_color = 0x0E; // Bright Yellow
|
||||
@@ -102,8 +106,21 @@ void tty_write(const char* data, size_t size) {
|
||||
} else if (i < size && data[i] == 'K') {
|
||||
// Clear from cursor to end of line
|
||||
for (int x = t->cursor_col; x < TTY_WIDTH; x++) {
|
||||
t->buffer[t->cursor_row][x] = vga_entry(' ', t->current_color);
|
||||
t->buffer[t->cursor_row][x] = vga_entry(' ', t->current_color ? t->current_color : 0x07);
|
||||
}
|
||||
} else if (i < size && data[i] == 'J') {
|
||||
// Clear entire screen buffer
|
||||
for (int y = 0; y < TTY_HEIGHT; y++) {
|
||||
for (int x = 0; x < TTY_WIDTH; x++) {
|
||||
t->buffer[y][x] = vga_entry(' ', t->current_color ? t->current_color : 0x07);
|
||||
}
|
||||
}
|
||||
t->cursor_row = 0;
|
||||
t->cursor_col = 0;
|
||||
} else if (i < size && data[i] == 'H') {
|
||||
// Cursor Home
|
||||
t->cursor_row = 0;
|
||||
t->cursor_col = 0;
|
||||
} else if (i < size && data[i] == 'D') {
|
||||
// Move cursor left
|
||||
if (t->cursor_col > 0) t->cursor_col--;
|
||||
@@ -132,10 +149,10 @@ void tty_write(const char* data, size_t size) {
|
||||
} else if (c == '\b') {
|
||||
if (t->cursor_col > 0) {
|
||||
t->cursor_col--;
|
||||
t->buffer[t->cursor_row][t->cursor_col] = vga_entry(' ', t->current_color);
|
||||
t->buffer[t->cursor_row][t->cursor_col] = vga_entry(' ', t->current_color ? t->current_color : 0x07);
|
||||
}
|
||||
} else {
|
||||
t->buffer[t->cursor_row][t->cursor_col] = vga_entry(c, t->current_color);
|
||||
t->buffer[t->cursor_row][t->cursor_col] = vga_entry(c, t->current_color ? t->current_color : 0x07);
|
||||
if (++t->cursor_col >= TTY_WIDTH) {
|
||||
t->cursor_col = 0;
|
||||
if (++t->cursor_row >= TTY_HEIGHT) {
|
||||
|
||||
Reference in new issue
Block a user