refactor: improve on scrolling experience in lunaix console
authorMinep <zelong56@gmail.com>
Wed, 24 Aug 2022 16:18:24 +0000 (17:18 +0100)
committerMinep <zelong56@gmail.com>
Wed, 24 Aug 2022 16:18:24 +0000 (17:18 +0100)
fix: handle the strange scan code sequence on Virtualbox's PS/2 keyboard.
fix: incompatible pointer type passing in devfs.
chore: refactoring and clean up.

13 files changed:
README.md
lunaix-os/includes/lunaix/device.h
lunaix-os/includes/lunaix/ds/fifo.h
lunaix-os/includes/lunaix/tty/console.h
lunaix-os/includes/lunaix/tty/tty.h
lunaix-os/kernel/demos/input_test.c
lunaix-os/kernel/demos/simple_sh.c
lunaix-os/kernel/device/devfs.c
lunaix-os/kernel/device/device.c
lunaix-os/kernel/ds/fifo.c
lunaix-os/kernel/peripheral/ps2kbd.c
lunaix-os/kernel/tty/lxconsole.c [moved from lunaix-os/kernel/lxconsole.c with 68% similarity]
lunaix-os/kernel/tty/tty.c

index 1a71e5753cedf56bdbffe52481d6e55df8979526..35db0861698924676755b8b6bfdcee12ee1bb9ed 100644 (file)
--- a/README.md
+++ b/README.md
@@ -98,10 +98,6 @@ qemu-img create -f vdi machine/disk0.vdi 128M
 
 正常,**因为Bochs不支持SATA**。请使用QEMU或VirtualBox。
 
 
 正常,**因为Bochs不支持SATA**。请使用QEMU或VirtualBox。
 
-#### 问题#4:键盘的上下方向键(用于滚屏)在VirtualBox下有时不好使
-
-可以试试`Shift+<方向键>`,这个问题的解决需要重写键盘驱动的状态机。我会找时间去做,毕竟这不是燃眉之急。
-
 ## 参考教程
 
 **没有!!** 本教程以及该操作系统均为原创,没有基于任何市面上现行的操作系统开发教程,且并非是基于任何的开源内核的二次开发。
 ## 参考教程
 
 **没有!!** 本教程以及该操作系统均为原创,没有基于任何市面上现行的操作系统开发教程,且并非是基于任何的开源内核的二次开发。
index 81716002bbc166be8881a590f7078f3bf1c9bbb3..be6dc26705d3228dba0f36ce0797cba048461834 100644 (file)
@@ -52,12 +52,12 @@ struct device*
 device_getbyid(struct llist_header* devlist, dev_t id);
 
 struct device*
 device_getbyid(struct llist_header* devlist, dev_t id);
 
 struct device*
-device_getbyhname(struct llist_header* devlist, struct hstr* name);
+device_getbyhname(struct device* root_dev, struct hstr* name);
 
 struct device*
 
 struct device*
-device_getbyname(struct llist_header* devlist, const char* name, size_t len);
+device_getbyname(struct device* root_dev, const char* name, size_t len);
 
 struct device*
 
 struct device*
-device_getbyoffset(struct llist_header* devlist, int pos);
+device_getbyoffset(struct device* root_dev, int pos);
 
 #endif /* __LUNAIX_DEVICE_H */
 
 #endif /* __LUNAIX_DEVICE_H */
index 3a21824624220eab6e92a2c9260bb600550c451b..a7ac90bb8260d971c2dc86f495d1094f862f959f 100644 (file)
@@ -23,6 +23,15 @@ fifo_backone(struct fifo_buf* fbuf);
 size_t
 fifo_putone(struct fifo_buf* fbuf, uint8_t data);
 
 size_t
 fifo_putone(struct fifo_buf* fbuf, uint8_t data);
 
+size_t
+fifo_readone_async(struct fifo_buf* fbuf, uint8_t* data);
+
+void
+fifo_set_rdptr(struct fifo_buf* fbuf, size_t rdptr);
+
+void
+fifo_set_wrptr(struct fifo_buf* fbuf, size_t wrptr);
+
 void
 fifo_init(struct fifo_buf* buf, void* data_buffer, size_t buf_size, int flags);
 
 void
 fifo_init(struct fifo_buf* buf, void* data_buffer, size_t buf_size, int flags);
 
index e5eaa34b940ad7c9ce1295250858918639bca89d..24d088fbd3f6665580e53fe8c4e32112292b319c 100644 (file)
@@ -9,8 +9,8 @@ struct console
     struct lx_timer* flush_timer;
     struct fifo_buf output;
     struct fifo_buf input;
     struct lx_timer* flush_timer;
     struct fifo_buf output;
     struct fifo_buf input;
-    unsigned int erd_pos;
-    unsigned int lines;
+    size_t wnd_start;
+    size_t lines;
 };
 
 #endif /* __LUNAIX_CONSOLE_H */
 };
 
 #endif /* __LUNAIX_CONSOLE_H */
index 518d3760a8def0797976d627417ddeb38b60400d..96fe4859c5a1fe3ece1c6579bbc9025b98f8133b 100644 (file)
@@ -1,5 +1,8 @@
 #ifndef __LUNAIX_TTY_H
 #define __LUNAIX_TTY_H
 #ifndef __LUNAIX_TTY_H
 #define __LUNAIX_TTY_H
+
+#include <lunaix/ds/fifo.h>
+
 typedef unsigned short vga_attribute;
 
 #define VGA_COLOR_BLACK 0
 typedef unsigned short vga_attribute;
 
 #define VGA_COLOR_BLACK 0
@@ -31,8 +34,8 @@ tty_set_theme(vga_attribute fg, vga_attribute bg);
 vga_attribute
 tty_get_theme();
 
 vga_attribute
 tty_get_theme();
 
-size_t
-tty_flush_buffer(char* data, size_t pos, size_t limit, size_t buf_size);
+void
+tty_flush_buffer(struct fifo_buf* buf);
 
 void
 tty_clear_line(int line_num);
 
 void
 tty_clear_line(int line_num);
index b85f85191afec1c559cc0a809cd10ee62c7e2306..5f2a9048b8677e4e6a49ecbfc37480aa9e58e9ee 100644 (file)
@@ -2,6 +2,7 @@
 #include <lunaix/foptions.h>
 #include <lunaix/input.h>
 #include <lunaix/lunistd.h>
 #include <lunaix/foptions.h>
 #include <lunaix/input.h>
 #include <lunaix/lunistd.h>
+#include <lunaix/proc.h>
 #include <ulibc/stdio.h>
 
 #define STDIN 1
 #include <ulibc/stdio.h>
 
 #define STDIN 1
@@ -13,7 +14,7 @@ input_test()
     int fd = open("/dev/input/i8042-kbd", 0);
 
     if (fd < 0) {
     int fd = open("/dev/input/i8042-kbd", 0);
 
     if (fd < 0) {
-        printf("fail to open (%d)", fd);
+        printf("fail to open (%d)", geterrno());
         return;
     }
 
         return;
     }
 
@@ -27,7 +28,7 @@ input_test()
             action = "release";
         }
 
             action = "release";
         }
 
-        printf("%u: %s '%c', class=0x%x, scan=%d\n",
+        printf("%u: %s '%c', class=0x%x, scan=%x\n",
                event.timestamp,
                action,
                event.sys_code & 0xff,
                event.timestamp,
                action,
                event.sys_code & 0xff,
index 036550a4fe0ab6ccb7363e83bbdde3cc6c79f3f8..8243ae1d85352141c36274a0462942a1b1354c0d 100644 (file)
@@ -67,9 +67,11 @@ sh_main()
     char buf[512];
     char *cmd, *argpart;
 
     char buf[512];
     char *cmd, *argpart;
 
+    printf("\n Simple shell. Use <PG_UP> or <PG_DOWN> to scroll.\n\n");
+
     while (1) {
         getcwd(pwd, 512);
     while (1) {
         getcwd(pwd, 512);
-        printf("%s> ", pwd);
+        printf("%s$ ", pwd);
         size_t sz = read(stdin, buf, 512);
         if (sz < 0) {
             printf("fail to read user input (%d)\n", geterrno());
         size_t sz = read(stdin, buf, 512);
         if (sz < 0) {
             printf("fail to read user input (%d)\n", geterrno());
@@ -77,6 +79,9 @@ sh_main()
         }
         buf[sz - 1] = '\0';
         parse_cmdline(buf, &cmd, &argpart);
         }
         buf[sz - 1] = '\0';
         parse_cmdline(buf, &cmd, &argpart);
+        if (cmd[0] == 0) {
+            goto cont;
+        }
         if (streq(cmd, "cd")) {
             if (chdir(argpart) < 0) {
                 sh_printerr();
         if (streq(cmd, "cd")) {
             if (chdir(argpart) < 0) {
                 sh_printerr();
@@ -100,6 +105,7 @@ sh_main()
         } else {
             printf("unknow command");
         }
         } else {
             printf("unknow command");
         }
+    cont:
         printf("\n");
     }
 }
\ No newline at end of file
         printf("\n");
     }
 }
\ No newline at end of file
index ac674b4ac77ebb4e5f4b5cee6f1b4794c2c92ad0..af2a5f7f41de687e7a1f6fd4a2a9ac126af8b385 100644 (file)
@@ -74,7 +74,8 @@ devfs_mknod(struct v_dnode* dnode, struct device* dev)
 int
 devfs_dirlookup(struct v_inode* this, struct v_dnode* dnode)
 {
 int
 devfs_dirlookup(struct v_inode* this, struct v_dnode* dnode)
 {
-    struct device* dev = device_getbyhname(this->data, &dnode->name);
+    struct device* dev =
+      device_getbyhname((struct device*)this->data, &dnode->name);
     if (!dev) {
         return ENOENT;
     }
     if (!dev) {
         return ENOENT;
     }
@@ -84,9 +85,8 @@ devfs_dirlookup(struct v_inode* this, struct v_dnode* dnode)
 int
 devfs_readdir(struct v_file* file, struct dir_context* dctx)
 {
 int
 devfs_readdir(struct v_file* file, struct dir_context* dctx)
 {
-    struct device* holder = (struct device*)(file->inode->data);
     struct device* dev =
     struct device* dev =
-      device_getbyoffset(holder ? &holder->children : NULL, dctx->index);
+      device_getbyoffset((struct device*)(file->inode->data), dctx->index);
     if (!dev) {
         return 0;
     }
     if (!dev) {
         return 0;
     }
index 282f44d27603a49670e7de65a4633440bdd0939e..beb1f18050b15097bb02d5696b037a8a8f32e5a6 100644 (file)
@@ -93,9 +93,9 @@ device_getbyid(struct llist_header* devlist, dev_t id)
 }
 
 struct device*
 }
 
 struct device*
-device_getbyhname(struct llist_header* devlist, struct hstr* name)
+device_getbyhname(struct device* root_dev, struct hstr* name)
 {
 {
-    devlist = devlist ? devlist : &root_list;
+    struct llist_header* devlist = root_dev ? &root_dev->children : &root_list;
     struct device *pos, *n;
     llist_for_each(pos, n, devlist, siblings)
     {
     struct device *pos, *n;
     llist_for_each(pos, n, devlist, siblings)
     {
@@ -108,12 +108,12 @@ device_getbyhname(struct llist_header* devlist, struct hstr* name)
 }
 
 struct device*
 }
 
 struct device*
-device_getbyname(struct llist_header* devlist, const char* name, size_t len)
+device_getbyname(struct device* root_dev, const char* name, size_t len)
 {
     struct hstr hname = HSTR(name, len);
     hstr_rehash(&hname, HSTR_FULL_HASH);
 
 {
     struct hstr hname = HSTR(name, len);
     hstr_rehash(&hname, HSTR_FULL_HASH);
 
-    return device_getbyhname(devlist, &hname);
+    return device_getbyhname(root_dev, &hname);
 }
 
 void
 }
 
 void
@@ -124,9 +124,9 @@ device_remove(struct device* dev)
 }
 
 struct device*
 }
 
 struct device*
-device_getbyoffset(struct llist_header* devlist, int offset)
+device_getbyoffset(struct device* root_dev, int offset)
 {
 {
-    devlist = devlist ? devlist : &root_list;
+    struct llist_header* devlist = root_dev ? &root_dev->children : &root_list;
     struct device *pos, *n;
     int off = 0;
     llist_for_each(pos, n, devlist, siblings)
     struct device *pos, *n;
     int off = 0;
     llist_for_each(pos, n, devlist, siblings)
index 1e72e8da4b7d401d94812596da15f8447e12a3bf..7f34bf63132900953a890e1795c44050b478adf5 100644 (file)
@@ -53,6 +53,43 @@ fifo_putone(struct fifo_buf* fbuf, uint8_t data)
     return 1;
 }
 
     return 1;
 }
 
+size_t
+fifo_readone_async(struct fifo_buf* fbuf, uint8_t* data)
+{
+    if (fbuf->free_len == fbuf->size) {
+        return 0;
+    }
+
+    uint8_t* dest = fbuf->data;
+    *data = dest[fbuf->rd_pos];
+    fbuf->rd_pos = (fbuf->rd_pos + 1) % fbuf->size;
+    fbuf->free_len++;
+
+    return 1;
+}
+
+void
+fifo_set_rdptr(struct fifo_buf* fbuf, size_t rdptr)
+{
+    fbuf->rd_pos = rdptr;
+    if (rdptr <= fbuf->wr_pos) {
+        fbuf->free_len = fbuf->size - fbuf->wr_pos + rdptr;
+    } else {
+        fbuf->free_len = rdptr - fbuf->wr_pos;
+    }
+}
+
+void
+fifo_set_wrptr(struct fifo_buf* fbuf, size_t wrptr)
+{
+    fbuf->wr_pos = wrptr;
+    if (wrptr <= fbuf->rd_pos) {
+        fbuf->free_len = fbuf->size - fbuf->rd_pos + wrptr;
+    } else {
+        fbuf->free_len = wrptr - fbuf->rd_pos;
+    }
+}
+
 size_t
 fifo_write(struct fifo_buf* fbuf, void* data, size_t count)
 {
 size_t
 fifo_write(struct fifo_buf* fbuf, void* data, size_t count)
 {
index 5065ef697d8ca3a99adfa950147784b7809b7a23..04debc8e6cdf1de575269f86e4d153ac78aa523d 100644 (file)
@@ -74,9 +74,12 @@ static struct input_device* kbd_idev;
 #define KBD_STATE_KWAIT 0x00
 #define KBD_STATE_KSPECIAL 0x01
 #define KBD_STATE_KRELEASED 0x02
 #define KBD_STATE_KWAIT 0x00
 #define KBD_STATE_KSPECIAL 0x01
 #define KBD_STATE_KRELEASED 0x02
+#define KBD_STATE_E012 0x03
+#define KBD_STATE_KRELEASED_E0 0x04
 #define KBD_STATE_CMDPROCS 0x40
 
 #define KBD_STATE_CMDPROCS 0x40
 
-#define KBD_ENABLE_SPIRQ_FIX
+// #define KBD_ENABLE_SPIRQ_FIX
+#define KBD_ENABLE_SPIRQ_FIX2
 // #define KBD_DBGLOG
 
 void
 // #define KBD_DBGLOG
 
 void
@@ -336,6 +339,12 @@ intr_ps2_kbd_handler(const isr_param* param)
     }
 #endif
 
     }
 #endif
 
+#ifdef KBD_ENABLE_SPIRQ_FIX2
+    if (scancode == PS2_RESULT_ACK || scancode == PS2_RESULT_NAK) {
+        return;
+    }
+#endif
+
 #ifdef KBD_DBGLOG
     kprintf(KDEBUG "%x\n", scancode & 0xff);
 #endif
 #ifdef KBD_DBGLOG
     kprintf(KDEBUG "%x\n", scancode & 0xff);
 #endif
@@ -353,8 +362,10 @@ intr_ps2_kbd_handler(const isr_param* param)
             }
             break;
         case KBD_STATE_KSPECIAL:
             }
             break;
         case KBD_STATE_KSPECIAL:
-            if (scancode == 0xf0) { // release code
-                kbd_state.state = KBD_STATE_KRELEASED;
+            if (scancode == 0x12) {
+                kbd_state.state = KBD_STATE_E012;
+            } else if (scancode == 0xf0) { // release code
+                kbd_state.state = KBD_STATE_KRELEASED_E0;
             } else {
                 key = kbd_state.translation_table[scancode];
                 kbd_buffer_key_event(key, scancode, KBD_KEY_FPRESSED);
             } else {
                 key = kbd_state.translation_table[scancode];
                 kbd_buffer_key_event(key, scancode, KBD_KEY_FPRESSED);
@@ -363,10 +374,23 @@ intr_ps2_kbd_handler(const isr_param* param)
                 kbd_state.translation_table = scancode_set2;
             }
             break;
                 kbd_state.translation_table = scancode_set2;
             }
             break;
+        // handle the '0xE0, 0x12, 0xE0, xx' sequence
+        case KBD_STATE_E012:
+            if (scancode == 0xe0) {
+                kbd_state.state = KBD_STATE_KSPECIAL;
+                kbd_state.translation_table = scancode_set2_ex;
+            }
+            break;
+        case KBD_STATE_KRELEASED_E0:
+            if (scancode == 0x12) {
+                goto escape_release;
+            }
+            // fall through
         case KBD_STATE_KRELEASED:
             key = kbd_state.translation_table[scancode];
             kbd_buffer_key_event(key, scancode, KBD_KEY_FRELEASED);
 
         case KBD_STATE_KRELEASED:
             key = kbd_state.translation_table[scancode];
             kbd_buffer_key_event(key, scancode, KBD_KEY_FRELEASED);
 
+        escape_release:
             // reset the translation table to scancode_set2
             kbd_state.state = KBD_STATE_KWAIT;
             kbd_state.translation_table = scancode_set2;
             // reset the translation table to scancode_set2
             kbd_state.state = KBD_STATE_KWAIT;
             kbd_state.translation_table = scancode_set2;
similarity index 68%
rename from lunaix-os/kernel/lxconsole.c
rename to lunaix-os/kernel/tty/lxconsole.c
index 77949c897822c699c733fc03ac683b493e48a44f..92deb498d1dd3faa6fbf1786adbd298bf2b13bf4 100644 (file)
@@ -27,9 +27,9 @@ __lxconsole_listener(struct input_device* dev)
     uint32_t keycode = dev->current_pkt.sys_code;
     uint32_t type = dev->current_pkt.pkt_type;
     if (type == PKT_PRESS) {
     uint32_t keycode = dev->current_pkt.sys_code;
     uint32_t type = dev->current_pkt.pkt_type;
     if (type == PKT_PRESS) {
-        if (keycode == KEY_UP) {
+        if (keycode == KEY_PG_UP) {
             console_view_up();
             console_view_up();
-        } else if (keycode == KEY_DOWN) {
+        } else if (keycode == KEY_PG_DOWN) {
             console_view_down();
         }
         goto done;
             console_view_down();
         }
         goto done;
@@ -50,7 +50,7 @@ void
 lxconsole_init()
 {
     memset(&lx_console, 0, sizeof(lx_console));
 lxconsole_init()
 {
     memset(&lx_console, 0, sizeof(lx_console));
-    fifo_init(&lx_console.output, vzalloc(8192), 8192, 0);
+    fifo_init(&lx_console.output, valloc(8192), 8192, 0);
     fifo_init(&lx_console.input, valloc(4096), 4096, 0);
 
     lx_console.flush_timer = NULL;
     fifo_init(&lx_console.input, valloc(4096), 4096, 0);
 
     lx_console.flush_timer = NULL;
@@ -103,36 +103,43 @@ console_schedule_flush()
     // TODO make the flush on-demand rather than periodic
 }
 
     // TODO make the flush on-demand rather than periodic
 }
 
-void
-console_view_up()
+size_t
+__find_next_line(size_t start)
 {
 {
+    size_t p = start - 1;
     struct fifo_buf* buffer = &lx_console.output;
     struct fifo_buf* buffer = &lx_console.output;
-    mutex_lock(&buffer->lock);
-    size_t p = lx_console.erd_pos - 2;
-    while (p < lx_console.erd_pos && p != buffer->wr_pos &&
-           ((char*)buffer->data)[p] != '\n') {
+    do {
+        p = (p + 1) % buffer->size;
+    } while (p != buffer->wr_pos && ((char*)buffer->data)[p] != '\n');
+    return p + (((char*)buffer->data)[p] == '\n');
+}
+
+size_t
+__find_prev_line(size_t start)
+{
+    size_t p = start - 1;
+    struct fifo_buf* buffer = &lx_console.output;
+    do {
         p--;
         p--;
-    }
-    p++;
+    } while (p < lx_console.wnd_start && p != buffer->wr_pos &&
+             ((char*)buffer->data)[p] != '\n');
 
 
-    if (p > lx_console.erd_pos) {
-        p = 0;
+    if (p > lx_console.wnd_start) {
+        return 0;
     }
     }
+    return p + 1;
+}
 
 
+void
+console_view_up()
+{
+    struct fifo_buf* buffer = &lx_console.output;
+    mutex_lock(&buffer->lock);
+    fifo_set_rdptr(buffer, __find_prev_line(buffer->rd_pos));
     buffer->flags |= FIFO_DIRTY;
     buffer->flags |= FIFO_DIRTY;
-    lx_console.erd_pos = p;
     mutex_unlock(&buffer->lock);
     mutex_unlock(&buffer->lock);
-}
 
 
-size_t
-__find_next_line(size_t start)
-{
-    size_t p = start;
-    while (p != lx_console.output.wr_pos &&
-           ((char*)lx_console.output.data)[p] != '\n') {
-        p = (p + 1) % lx_console.output.size;
-    }
-    return p + 1;
+    console_flush();
 }
 
 void
 }
 
 void
@@ -141,9 +148,13 @@ console_view_down()
     struct fifo_buf* buffer = &lx_console.output;
     mutex_lock(&buffer->lock);
 
     struct fifo_buf* buffer = &lx_console.output;
     mutex_lock(&buffer->lock);
 
-    lx_console.erd_pos = __find_next_line(lx_console.erd_pos);
+    size_t wnd = lx_console.wnd_start;
+    size_t p = __find_next_line(buffer->rd_pos);
+    fifo_set_rdptr(buffer, p > wnd ? wnd : p);
     buffer->flags |= FIFO_DIRTY;
     mutex_unlock(&buffer->lock);
     buffer->flags |= FIFO_DIRTY;
     mutex_unlock(&buffer->lock);
+
+    console_flush();
 }
 
 void
 }
 
 void
@@ -156,52 +167,49 @@ console_flush()
         return;
     }
 
         return;
     }
 
-    tty_flush_buffer(lx_console.output.data,
-                     lx_console.erd_pos,
-                     lx_console.output.wr_pos,
-                     lx_console.output.size);
+    size_t rdpos_save = lx_console.output.rd_pos;
+    tty_flush_buffer(&lx_console.output);
+    fifo_set_rdptr(&lx_console.output, rdpos_save);
+
     lx_console.output.flags &= ~FIFO_DIRTY;
 }
 
 void
 console_write(struct console* console, uint8_t* data, size_t size)
 {
     lx_console.output.flags &= ~FIFO_DIRTY;
 }
 
 void
 console_write(struct console* console, uint8_t* data, size_t size)
 {
+    struct fifo_buf* fbuf = &console->output;
     mutex_lock(&console->output.lock);
     mutex_lock(&console->output.lock);
-    uint8_t* buffer = console->output.data;
-    uintptr_t ptr = console->output.wr_pos;
-    uintptr_t rd_ptr = console->output.rd_pos;
+    fifo_set_rdptr(fbuf, console->wnd_start);
+
+    uint8_t* buffer = fbuf->data;
+    uintptr_t ptr = fbuf->wr_pos;
+    uintptr_t rd_ptr = fbuf->rd_pos;
 
     char c;
 
     char c;
-    int lines = 0;
     int j = 0;
     for (size_t i = 0; i < size; i++) {
         c = data[i];
         if (!c) {
             continue;
         }
     int j = 0;
     for (size_t i = 0; i < size; i++) {
         c = data[i];
         if (!c) {
             continue;
         }
-        buffer[(ptr + j) % console->output.size] = c;
-        lines += (c == '\n');
+        if (c == '\n') {
+            console->lines++;
+        }
+        buffer[(ptr + j) % fbuf->size] = c;
         j++;
     }
 
         j++;
     }
 
-    size = j;
-
-    uintptr_t new_ptr = (ptr + size) % console->output.size;
-    console->output.wr_pos = new_ptr;
-
-    if (console->lines > TTY_HEIGHT && lines > 0) {
-        console->output.rd_pos =
-          __find_next_line((size + rd_ptr) % console->output.size);
-    }
+    fifo_set_wrptr(fbuf, (ptr + j) % fbuf->size);
 
 
-    if (new_ptr < ptr + size && new_ptr > rd_ptr) {
-        console->output.rd_pos = new_ptr;
+    while (console->lines >= TTY_HEIGHT) {
+        rd_ptr = __find_next_line(rd_ptr);
+        console->lines--;
     }
 
     }
 
-    console->lines += lines;
-    console->erd_pos = console->output.rd_pos;
-    console->output.flags |= FIFO_DIRTY;
-    mutex_unlock(&console->output.lock);
+    fifo_set_rdptr(&lx_console.output, rd_ptr);
+    console->wnd_start = rd_ptr;
+    fbuf->flags |= FIFO_DIRTY;
+    mutex_unlock(&fbuf->lock);
 }
 
 void
 }
 
 void
index d4ac8d07c4746340846fdb4aefcd318585996938..6db2417a7d81c5524e2c66f0c3460c3aeed4ab11 100644 (file)
@@ -10,18 +10,21 @@ vga_attribute* tty_vga_buffer = (vga_attribute*)VGA_BUFFER_PADDR;
 
 vga_attribute tty_theme_color = VGA_COLOR_BLACK;
 
 
 vga_attribute tty_theme_color = VGA_COLOR_BLACK;
 
-#define TTY_CLEAR                                                              \
-    asm volatile("rep stosw" ::"D"(tty_vga_buffer),                            \
-                 "c"(TTY_HEIGHT * TTY_WIDTH),                                  \
-                 "a"(tty_theme_color)                                          \
+inline void
+tty_clear()
+{
+    asm volatile("rep stosw" ::"D"(tty_vga_buffer),
+                 "c"(TTY_HEIGHT * TTY_WIDTH),
+                 "a"(tty_theme_color)
                  : "memory");
                  : "memory");
+}
 
 void
 tty_init(void* vga_buf)
 {
     tty_vga_buffer = (vga_attribute*)vga_buf;
 
 
 void
 tty_init(void* vga_buf)
 {
     tty_vga_buffer = (vga_attribute*)vga_buf;
 
-    TTY_CLEAR
+    tty_clear();
 
     io_outb(0x3D4, 0x0A);
     io_outb(0x3D5, (io_inb(0x3D5) & 0xC0) | 13);
 
     io_outb(0x3D4, 0x0A);
     io_outb(0x3D5, (io_inb(0x3D5) & 0xC0) | 13);
@@ -36,23 +39,19 @@ tty_set_theme(vga_attribute fg, vga_attribute bg)
     tty_theme_color = (bg << 4 | fg) << 8;
 }
 
     tty_theme_color = (bg << 4 | fg) << 8;
 }
 
-size_t
-tty_flush_buffer(char* data, size_t pos, size_t limit, size_t buf_size)
+void
+tty_flush_buffer(struct fifo_buf* buf)
 {
     int x = 0, y = 0;
 
     // Clear screen
 {
     int x = 0, y = 0;
 
     // Clear screen
-    TTY_CLEAR
+    tty_clear();
 
 
+    char chr;
     int state = 0;
     int g[2] = { 0, 0 };
     vga_attribute current_theme = tty_theme_color;
     int state = 0;
     int g[2] = { 0, 0 };
     vga_attribute current_theme = tty_theme_color;
-    while (1) {
-        size_t ptr = pos % buf_size;
-        if (pos == limit) {
-            break;
-        }
-        char chr = data[pos];
+    while (fifo_readone_async(buf, &chr)) {
         if (state == 0 && chr == '\033') {
             state = 1;
         } else if (state == 1 && chr == '[') {
         if (state == 0 && chr == '\033') {
             state = 1;
         } else if (state == 1 && chr == '[') {
@@ -105,10 +104,8 @@ tty_flush_buffer(char* data, size_t pos, size_t limit, size_t buf_size)
                 break;
             }
         }
                 break;
             }
         }
-        pos++;
     }
     tty_set_cursor(x, y);
     }
     tty_set_cursor(x, y);
-    return pos;
 }
 
 void
 }
 
 void