diff options
| author | Richard Qin <richard.qin.x@gmail.com> | 2026-01-04 14:05:49 +0800 |
|---|---|---|
| committer | Richard Qin <richard.qin.x@gmail.com> | 2026-01-04 14:05:49 +0800 |
| commit | d3cf3f08d1343d6b265516d5a79ce2d197b59d26 (patch) | |
| tree | a4bbae6cff94fa69eea30db865267b211eb4c86b /src/drivers/uart.cc | |
| parent | 210025560c80b48af4875af199f183ad709e3bf0 (diff) | |
| download | lume-d3cf3f08d1343d6b265516d5a79ce2d197b59d26.tar.gz lume-d3cf3f08d1343d6b265516d5a79ce2d197b59d26.tar.xz | |
feat(file-system): implement read and write FAT32 File System and basic shell
Diffstat (limited to 'src/drivers/uart.cc')
| -rw-r--r-- | src/drivers/uart.cc | 100 |
1 files changed, 47 insertions, 53 deletions
diff --git a/src/drivers/uart.cc b/src/drivers/uart.cc index 4064b16..55609ba 100644 --- a/src/drivers/uart.cc +++ b/src/drivers/uart.cc @@ -7,6 +7,15 @@ namespace Drivers { + struct + { + Spinlock lock; + char buf[128]; // Line buffer + uint32 r; // Read pointer (position taken by the user) + uint32 w; // Write pointer (position confirmed by Enter) + uint32 e; // Editing cursor (current typing position) + } cons; + // Circular buffer structure struct { @@ -21,6 +30,7 @@ namespace Drivers void uart_init() { uart_rx.lock.init("uart_rx"); + cons.lock.init("console"); uart_tx_lock.init("uart_tx"); uart_rx.r = 0; uart_rx.w = 0; @@ -119,88 +129,72 @@ namespace Drivers struct Proc *p = myproc(); int target_idx = 0; - uart_rx.lock.acquire(); + cons.lock.acquire(); while (target_idx < len) { + while (cons.r < cons.w) + { + char c = cons.buf[cons.r++ % sizeof(cons.buf)]; + cons.lock.release(); + + if (VM::copyout(p->pagetable, target + target_idx, &c, 1) < 0) + return -1; + + target_idx++; + if (c == '\n') + return target_idx; + if (target_idx == len) + return target_idx; + + cons.lock.acquire(); + } + + uart_rx.lock.acquire(); while (uart_rx.r == uart_rx.w) { - if (p->xstate != 0) + if (p->xstate) { uart_rx.lock.release(); + cons.lock.release(); return -1; } + cons.lock.release(); ProcManager::sleep(&uart_rx, &uart_rx.lock); + cons.lock.acquire(); } - char c = uart_rx.buf[uart_rx.r % UART_RX_BUF_SIZE]; - uart_rx.r++; - + char c = uart_rx.buf[uart_rx.r++ % UART_RX_BUF_SIZE]; uart_rx.lock.release(); - // 1. Handle Backspace (127 or \b) if (c == 127 || c == '\b') { - if (target_idx > 0) - { - // Erase character from screen: Backspace, Space, Backspace - uart_putc('\b'); - uart_putc(' '); - uart_putc('\b'); - target_idx--; - } - uart_rx.lock.acquire(); - continue; - } - - // 2. Handle Ctrl+U (Kill Line) - if (c == 0x15) - { - while (target_idx > 0) + if (cons.e != cons.w) { + cons.e--; uart_putc('\b'); uart_putc(' '); uart_putc('\b'); - target_idx--; } - uart_rx.lock.acquire(); - continue; } - - // 3. Handle Ctrl+L (Clear Screen) - if (c == 0x0C) + else { - uart_puts(ANSI_CLEAR); - uart_puts("$ "); - uart_rx.lock.acquire(); - continue; - } - - // 4. Handle Return (CR -> LF) - if (c == '\r') - { - c = '\n'; - } + if (c == '\r') + c = '\n'; - // Echo back to user - // uart_putc(c); + uart_putc(c); - if (VM::copyout(p->pagetable, target + target_idx, &c, 1) < 0) - { - return -1; - } - - target_idx++; + cons.buf[cons.e++ % sizeof(cons.buf)] = c; - if (c == '\n') - { - return target_idx; + if (c == '\n' || cons.e == cons.w + sizeof(cons.buf)) + { + cons.w = cons.e; + ProcManager::wakeup(&cons); + } } - - uart_rx.lock.acquire(); } - uart_rx.lock.release(); + cons.lock.release(); return target_idx; } }
\ No newline at end of file |
