diff --git a/ext2_root/init.elf b/ext2_root/init.elf index 613b512..a45a19b 100755 Binary files a/ext2_root/init.elf and b/ext2_root/init.elf differ diff --git a/src/drivers/input/input.c b/src/drivers/input/input.c index 6c476f6..7342b72 100644 --- a/src/drivers/input/input.c +++ b/src/drivers/input/input.c @@ -5,17 +5,50 @@ #include #include "mm/memory.h" #include "libk/string.h" +#include /* ------------------------------------------------------------------ * * Event ring-buffer * ------------------------------------------------------------------ */ #define INPUT_BUF_SIZE 512 +#define CONSOLE_BUF_SIZE 256 + +static char s_console_buf[CONSOLE_BUF_SIZE]; +static size_t s_console_rpos = 0; +static size_t s_console_wpos = 0; static input_event_t s_buf[INPUT_BUF_SIZE]; static size_t s_rpos = 0; static size_t s_wpos = 0; static spinlock_t s_lock = SPINLOCK_INIT; +/* Called from IRQ context */ +void input_push_char(char c) +{ + spinlock_acquire_or_wait(&s_lock); + size_t next = (s_console_wpos + 1) % CONSOLE_BUF_SIZE; + if (next != s_console_rpos) { /* drop if full */ + s_console_buf[s_console_wpos] = c; + s_console_wpos = next; + } + spinlock_drop(&s_lock); +} + +int input_read_console(void *buf, size_t len) +{ + uint8_t *p = buf; + size_t count = 0; + + spinlock_acquire_or_wait(&s_lock); + while (count < len && s_console_rpos != s_console_wpos) { + p[count++] = s_console_buf[s_console_rpos]; + s_console_rpos = (s_console_rpos + 1) % CONSOLE_BUF_SIZE; + } + spinlock_drop(&s_lock); + + return (int)count; /* 0 = no data yet (non-blocking) */ +} + static void push_event(const input_event_t *ev) { spinlock_acquire_or_wait(&s_lock); diff --git a/src/drivers/input/input.h b/src/drivers/input/input.h index 2df6d07..fb93fb9 100644 --- a/src/drivers/input/input.h +++ b/src/drivers/input/input.h @@ -1,6 +1,7 @@ #pragma once #include #include +#include /* ------------------------------------------------------------------ * * Generic input event types @@ -53,6 +54,9 @@ void input_push_mouse_rel(int16_t dx, int16_t dy); void input_push_mouse_btn(uint8_t button, bool pressed); void input_push_mouse_wheel(int8_t delta); +void input_push_char(char c); +int input_read_console(void *buf, size_t len); + /* Consumer API */ bool input_poll(input_event_t *out); /* non-blocking; false if empty */ bool input_has_event(void); diff --git a/src/drivers/input/ps2.c b/src/drivers/input/ps2.c index cf54090..fcf0488 100644 --- a/src/drivers/input/ps2.c +++ b/src/drivers/input/ps2.c @@ -6,6 +6,7 @@ #include "arch/x86_64/sys/ioapic.h" #include "arch/x86_64/sys/apic.h" #include "libk/stdio.h" +#include "drivers/video/render.h" /* ── PS/2 I/O ports ───────────────────────────────────────────────────────── */ #define PS2_DATA_PORT 0x60 /* Read: scancode / Write: command data */ @@ -150,9 +151,15 @@ void ps2_kbd_handler(Registers *regs) /* ── Push event ──────────────────────────────────────────────────── */ input_push_key(scancode, ascii, pressed); - /* Optionally echo to debug port for development */ + if (pressed && ascii) { - /* e9_putc(ascii); ← uncomment if you have e9 debug output */ + input_push_char(ascii); + + if (ascii == '\b') { + backspace(); + } else { + putchar(ascii); + } } } diff --git a/src/fs/vfs.c b/src/fs/vfs.c index a0b2783..a496c34 100644 --- a/src/fs/vfs.c +++ b/src/fs/vfs.c @@ -5,6 +5,7 @@ #include "libk/stdio.h" #include "mm/memory.h" #include "libk/string.h" +#include "drivers/input/input.h" static spinlock_t s_vfs_lock = SPINLOCK_INIT; static vfs_file_t vfs_fd_table[VFS_MAX_FDS]; @@ -111,6 +112,10 @@ int VFS_Read_internal(fd_t fd, uint8_t* buf, size_t size) if (fd < 0 || fd >= VFS_MAX_FDS) return -1; + if (fd == VFS_FD_STDIN) { + return input_read_console(buf, size); + } + vfs_file_t* file = &vfs_fd_table[fd]; if (!file->used) diff --git a/user/build/init.elf b/user/build/init.elf index 613b512..a45a19b 100755 Binary files a/user/build/init.elf and b/user/build/init.elf differ diff --git a/user/build/init.o b/user/build/init.o index aaf3eea..119fe42 100644 Binary files a/user/build/init.o and b/user/build/init.o differ diff --git a/user/programs/init.c b/user/programs/init.c index bb8eeac..ddd1880 100644 --- a/user/programs/init.c +++ b/user/programs/init.c @@ -1,6 +1,7 @@ #include "../include/syscalls.h" -#define STDOUT 1 +#define STDIN 0 +#define STDOUT 1 unsigned strlen(const char* str) { @@ -13,6 +14,64 @@ unsigned strlen(const char* str) return len; } +static int strcmp(const char* a, const char* b) +{ + while (*a && (*a == *b)) { + a++; + b++; + } + return *(unsigned char*)a - *(unsigned char*)b; +} + +static void print(const char* s) +{ + syscall(SYS_WRITE, STDOUT, (unsigned long)s, strlen(s), 0, 0, 0); +} + +static void readline(char* buf, unsigned long max) +{ + unsigned long i = 0; + + while (i < max - 1) + { + char c; + long n = syscall(SYS_READ, STDIN, (unsigned long)&c, 1, 0, 0, 0); + + if (n <= 0) + continue; + + if (c == '\n') + break; + + if (c == '\b') { + if (i > 0) i--; + continue; + } + + buf[i++] = c; + } + + buf[i] = '\0'; +} + +static void cat(const char* path) +{ + unsigned char buf[256]; + + long fd = syscall(SYS_OPEN, (unsigned long)path, 0, 0, 0, 0, 0); + if (fd < 0) { + print("cat: cannot open file\n"); + return; + } + + long n = syscall(SYS_READ, fd, (unsigned long)buf, sizeof(buf), 0, 0, 0); + syscall(SYS_CLOSE, fd, 0, 0, 0, 0, 0); + + if (n > 0) + syscall(SYS_WRITE, STDOUT, (unsigned long)buf, n, 0, 0, 0); +} + + void main() { const unsigned char* path = "/qwerty.txt"; @@ -41,6 +100,30 @@ void main() // ── print buffer to stdout ─────────────── syscall(SYS_WRITE, STDOUT, (unsigned long)buf, n, 0, 0, 0); + char line[128]; + + while (1) + { + print("> "); + + readline(line, sizeof(line)); + + if (strcmp(line, "exit") == 0) + break; + + // simple "cat " + if (line[0] == 'c' && line[1] == 'a' && line[2] == 't' && line[3] == ' ') + { + cat(&line[4]); + continue; + } + + if (line[0] != '\0') + print("Unknown command\n"); + } + + while (1); + // ── done ──────────────────────────────── while (1); } \ No newline at end of file