:: commit 072c54b9d26a3ab05fdc7b7aed2bc234fc768b0f

mintsuki <mintsuki@protonmail.com> — 2022-02-07 01:10

parents: 79781941e7

misc: Misc output fixes for serial support

diff --git a/common/lib/blib.h b/common/lib/blib.h
index ee19df71..da84fb21 100644
--- a/common/lib/blib.h
+++ b/common/lib/blib.h
@@ -33,7 +33,7 @@ extern struct volume *boot_volume;
 extern bool stage3_loaded;
 #endif
 
-extern bool verbose, quiet;
+extern bool verbose, quiet, serial;
 
 bool parse_resolution(size_t *width, size_t *height, size_t *bpp, const char *buf);
 
diff --git a/common/lib/blib.s2.c b/common/lib/blib.s2.c
index 3158b2a0..09e84006 100644
--- a/common/lib/blib.s2.c
+++ b/common/lib/blib.s2.c
@@ -5,6 +5,7 @@
 
 bool verbose = true;
 bool quiet = false;
+bool serial = false;
 
 uint8_t bcd_to_int(uint8_t val) {
     return (val & 0x0f) + ((val & 0xf0) >> 4) * 10;
diff --git a/common/lib/print.s2.c b/common/lib/print.s2.c
index 4b0d5dc1..fc685f29 100644
--- a/common/lib/print.s2.c
+++ b/common/lib/print.s2.c
@@ -140,6 +140,11 @@ void print(const char *fmt, ...) {
 
 static char print_buf[PRINT_BUF_MAX];
 
+static void serial_out(uint8_t b) {
+    while ((inb(0x3f8 + 5) & 0x20) == 0);
+    outb(0x3f8, b);
+}
+
 void vprint(const char *fmt, va_list args) {
     static bool com_initialised = false;
 
@@ -227,13 +232,20 @@ out:
         if (E9_OUTPUT) {
             outb(0xe9, print_buf[i]);
         }
-        if (COM_OUTPUT) {
-            if (print_buf[i] == '\n') {
-                while ((inb(0x3f8 + 5) & 0x20) == 0);
-                outb(0x3f8, '\r');
+        if (serial || COM_OUTPUT) {
+            switch (print_buf[i]) {
+                case '\n':
+                    serial_out('\r');
+                    serial_out('\n');
+                    continue;
+                case '\e':
+                    serial_out('\e');
+                    continue;
+            }
+            if (!isprint(print_buf[i])) {
+                continue;
             }
-            while ((inb(0x3f8 + 5) & 0x20) == 0);
-            outb(0x3f8, print_buf[i]);
+            serial_out(print_buf[i]);
         }
     }
 }
diff --git a/common/lib/readline.c b/common/lib/readline.c
index 38fdc935..1f1cfe2c 100644
--- a/common/lib/readline.c
+++ b/common/lib/readline.c
@@ -239,9 +239,9 @@ static void reprint_string(int x, int y, const char *s) {
     size_t orig_x, orig_y;
     disable_cursor();
     get_cursor_pos(&orig_x, &orig_y);
-    set_cursor_pos(x, y);
-    term_write((uintptr_t)s, strlen(s));
-    set_cursor_pos(orig_x, orig_y);
+    set_cursor_pos_helper(x, y);
+    print("%s", s);
+    set_cursor_pos_helper(orig_x, orig_y);
     enable_cursor();
 }
 
@@ -254,7 +254,7 @@ static void cursor_back(void) {
         y--;
         x = term_cols - 1;
     }
-    set_cursor_pos(x, y);
+    set_cursor_pos_helper(x, y);
 }
 
 static void cursor_fwd(void) {
@@ -266,7 +266,7 @@ static void cursor_fwd(void) {
         y++;
         x = 0;
     }
-    set_cursor_pos(x, y);
+    set_cursor_pos_helper(x, y);
 }
 
 void readline(const char *orig_str, char *buf, size_t limit) {
@@ -280,7 +280,7 @@ void readline(const char *orig_str, char *buf, size_t limit) {
     size_t orig_x, orig_y;
     get_cursor_pos(&orig_x, &orig_y);
 
-    term_write((uintptr_t)orig_str, orig_str_len);
+    print("%s", orig_str);
 
     for (size_t i = orig_str_len; ; ) {
         term_double_buffer_flush();
@@ -319,7 +319,7 @@ void readline(const char *orig_str, char *buf, size_t limit) {
                 }
                 continue;
             case '\n':
-                term_write((uintptr_t)"\n", 1);
+                print("\n");
                 goto out;
             case GETCHAR_END:
                 for (size_t j = 0; j < strlen(buf) - i; j++) {
diff --git a/common/lib/term.c b/common/lib/term.c
index d5c37cbf..871bc294 100644
--- a/common/lib/term.c
+++ b/common/lib/term.c
@@ -11,6 +11,7 @@
 #include <mm/pmm.h>
 
 extern void reset_term(void);
+extern void set_cursor_pos_helper(size_t x, size_t y);
 
 bool early_term = false;
 
@@ -38,6 +39,11 @@ void term_vbe(size_t width, size_t height) {
         return;
     }
 
+    if (serial) {
+        term_cols = 80;
+        term_rows = 24;
+    }
+
     term_reinit();
 
     raw_putchar    = gterm_putchar;
@@ -138,8 +144,8 @@ void term_notready(void) {
     term_context_restore = notready_uint64_t;
     term_full_refresh = notready_void;
 
-    term_rows = 100;
-    term_cols = 100;
+    term_cols = 80;
+    term_rows = 24;
 }
 
 #if bios == 1
@@ -351,6 +357,11 @@ void term_textmode(void) {
 
     init_vga_textmode(&term_rows, &term_cols, true);
 
+    if (serial) {
+        term_cols = 80;
+        term_rows = 24;
+    }
+
     term_reinit();
 
     raw_putchar    = text_putchar;
diff --git a/common/lib/term.h b/common/lib/term.h
index c113f669..c20547ba 100644
--- a/common/lib/term.h
+++ b/common/lib/term.h
@@ -5,6 +5,7 @@
 #include <stdint.h>
 #include <stdbool.h>
 #include <lib/image.h>
+#include <lib/print.h>
 
 #define TERM_TABSIZE (8)
 #define MAX_ESC_VALUES (16)
@@ -109,8 +110,12 @@ extern bool term_autoflush;
 inline void reset_term(void) {
     term_autoflush = true;
     enable_cursor();
-    clear(true);
+    print("\e[2J\e[H");
     term_double_buffer_flush();
 }
 
+inline void set_cursor_pos_helper(size_t x, size_t y) {
+    print("\e[%u;%uH", (int)y + 1, (int)x + 1);
+}
+
 #endif
diff --git a/common/menu.c b/common/menu.c
index 09f36d95..550a83a1 100644
--- a/common/menu.c
+++ b/common/menu.c
@@ -190,7 +190,7 @@ char *config_entry_editor(const char *title, const char *orig_entry) {
 
     enable_cursor();
 
-    clear(true);
+    print("\e[2J\e[H");
 
     size_t cursor_offset  = 0;
     size_t entry_size     = strlen(orig_entry);
@@ -225,25 +225,25 @@ char *config_entry_editor(const char *title, const char *orig_entry) {
 refresh:
     invalid_syntax = false;
 
-    clear(true);
+    print("\e[2J\e[H");
     disable_cursor();
     {
         size_t x, y;
         print("\n");
         get_cursor_pos(&x, &y);
-        set_cursor_pos(term_cols / 2 - DIV_ROUNDUP(strlen(menu_branding), 2), y);
+        set_cursor_pos_helper(term_cols / 2 - DIV_ROUNDUP(strlen(menu_branding), 2), y);
         print("\e[3%sm%s\e[37m", menu_branding_colour, menu_branding);
         print("\n\n");
     }
 
-    print("    \e[32mESC\e[0m Discard and Exit    \e[32mF10\e[0m Boot\n");
+    print("    \e[32mESC\e[0m Discard and Exit    \e[32mF10\e[0m Boot\n\n");
 
-    print("\n\xda");
+    print(serial ? "/" : "\xda");
     for (size_t i = 0; i < term_cols - 2; i++) {
         switch (i) {
             case 1: case 2: case 3:
                 if (window_offset > 0) {
-                    print("\x18");
+                    print(serial ? "^" : "\x18");
                     break;
                 }
                 // FALLTHRU
@@ -253,12 +253,17 @@ refresh:
                     print("%s", title);
                     i += title_length - 1;
                 } else {
-                    print("\xc4");
+                    print(serial ? "-" : "\xc4");
                 }
             }
         }
     }
-    print("\xbf\xb3");
+    size_t tmpx, tmpy;
+
+    get_cursor_pos(&tmpx, &tmpy);
+    print(serial ? "\\" : "\xbf");
+    set_cursor_pos_helper(0, tmpy + 1);
+    print(serial ? "|" : "\xb3");
 
     size_t cursor_x, cursor_y;
     size_t current_line = 0, line_offset = 0, window_size = _window_size;
@@ -277,11 +282,18 @@ refresh:
                 cursor_y = y;
                 printed_cursor = true;
             }
-            set_cursor_pos(term_cols - 1, y);
-            if (current_line == window_offset + window_size - 1)
-                print("\xb3\xc0");
-            else
-                print("\xb3\xb3");
+            set_cursor_pos_helper(term_cols - 1, y);
+            if (current_line == window_offset + window_size - 1) {
+                get_cursor_pos(&tmpx, &tmpy);
+                print(serial ? "|" : "\xb3");
+                set_cursor_pos_helper(0, tmpy + 1);
+                print(serial ? "\\" : "\xc0");
+            } else {
+                get_cursor_pos(&tmpx, &tmpy);
+                print(serial ? "|" : "\xb3");
+                set_cursor_pos_helper(0, tmpy + 1);
+                print(serial ? "|" : "\xb3");
+            }
             line_offset = 0;
             token_type = validate_line(buffer + i + 1);
             current_line++;
@@ -306,10 +318,15 @@ refresh:
                 printed_early = true;
                 size_t x, y;
                 get_cursor_pos(&x, &y);
-                if (y == term_rows - 3)
-                    print("\x1a\xc0");
-                else
-                    print("\x1a\x1b\x1b");
+                if (y == term_rows - 3) {
+                    print(serial ? ">" : "\x1a");
+                    set_cursor_pos_helper(0, y + 1);
+                    print(serial ? "\\" : "\xc0");
+                } else {
+                    print(serial ? ">" : "\x1a");
+                    set_cursor_pos_helper(0, y + 1);
+                    print(serial ? "<" : "\x1b\x1b");
+                }
             }
             window_size--;
         }
@@ -366,7 +383,7 @@ refresh:
     if (validation_enabled) {
         size_t x, y;
         get_cursor_pos(&x, &y);
-        set_cursor_pos(0, term_rows-1);
+        set_cursor_pos_helper(0, term_rows-1);
         scroll_disable();
         if (invalid_syntax) {
             print("\e[31mConfiguration is INVALID.\e[0m");
@@ -374,34 +391,40 @@ refresh:
             print("\e[32mConfiguration is valid.\e[0m");
         }
         scroll_enable();
-        set_cursor_pos(x, y);
+        set_cursor_pos_helper(x, y);
     }
 
     if (current_line - window_offset < window_size) {
         size_t x, y;
         for (size_t i = 0; i < (window_size - (current_line - window_offset)) - 1; i++) {
             get_cursor_pos(&x, &y);
-            set_cursor_pos(term_cols - 1, y);
-            print("\xb3\xb3");
+            set_cursor_pos_helper(term_cols - 1, y);
+            print(serial ? "|" : "\xb3");
+            set_cursor_pos_helper(0, y + 1);
+            print(serial ? "|" : "\xb3");
         }
         get_cursor_pos(&x, &y);
-        set_cursor_pos(term_cols - 1, y);
-        print("\xb3\xc0");
+        set_cursor_pos_helper(term_cols - 1, y);
+        print(serial ? "|" : "\xb3");
+        set_cursor_pos_helper(0, y + 1);
+        print(serial ? "\\" : "\xc0");
     }
 
     for (size_t i = 0; i < term_cols - 2; i++) {
         switch (i) {
             case 1: case 2: case 3:
                 if (current_line - window_offset >= window_size) {
-                    print("\x19");
+                    print(serial ? "v" : "\x19");
                     break;
                 }
                 // FALLTHRU
             default:
-                print("\xc4");
+                print(serial ? "-" : "\xc4");
         }
     }
-    print("\xd9");
+    get_cursor_pos(&tmpx, &tmpy);
+    print(serial ? "/" : "\xd9");
+    set_cursor_pos_helper(0, tmpy + 1);
 
     if (display_overflow_error) {
         scroll_disable();
@@ -411,7 +434,7 @@ refresh:
     }
 
     // Hack to redraw the cursor
-    set_cursor_pos(cursor_x, cursor_y);
+    set_cursor_pos_helper(cursor_x, cursor_y);
     enable_cursor();
 
     term_double_buffer_flush();
@@ -501,21 +524,21 @@ static size_t print_tree(const char *shift, size_t level, size_t base_index, siz
                 for (size_t j = 0; j < i; j++)
                     actual_parent = actual_parent->parent;
                 if (actual_parent->next != NULL) {
-                    if (!no_print) print(" \xb3");
+                    if (!no_print) print(serial ? " |" : " \xb3");
                 } else {
                     if (!no_print) print("  ");
                 }
             }
             if (current_entry->next == NULL) {
-                if (!no_print) print(" \xc0");
+                if (!no_print) print(serial ? " `" : " \xc0");
             } else {
-                if (!no_print) print(" \xc3");
+                if (!no_print) print(serial ? " |" : " \xc3");
             }
         }
         if (current_entry->sub) {
             if (!no_print) print(current_entry->expanded ? "[-]" : "[+]");
         } else if (level) {
-            if (!no_print) print("\xc4> ");
+            if (!no_print) print(serial ? "-> " : "\xc4> ");
         } else {
             if (!no_print) print("   ");
         }
@@ -639,6 +662,9 @@ static noreturn void _menu(bool timeout_enabled) {
     char *verbose_str = config_get_value(NULL, 0, "VERBOSE");
     verbose = verbose_str != NULL && strcmp(verbose_str, "yes") == 0;
 
+    char *serial_str = config_get_value(NULL, 0, "SERIAL");
+    serial = serial_str != NULL && strcmp(serial_str, "yes") == 0;
+
     menu_branding = config_get_value(NULL, 0, "MENU_BRANDING");
     if (menu_branding == NULL)
         menu_branding = "Limine " LIMINE_VERSION;
@@ -716,12 +742,12 @@ refresh:
 
     disable_cursor();
 
-    clear(true);
+    print("\e[2J\e[H");
     {
         size_t x, y;
         print("\n");
         get_cursor_pos(&x, &y);
-        set_cursor_pos(term_cols / 2 - DIV_ROUNDUP(strlen(menu_branding), 2), y);
+        set_cursor_pos_helper(term_cols / 2 - DIV_ROUNDUP(strlen(menu_branding), 2), y);
         print("\e[3%sm%s\e[37m", menu_branding_colour, menu_branding);
         print("\n\n\n\n");
     }
@@ -741,44 +767,45 @@ refresh:
         size_t x, y;
         get_cursor_pos(&x, &y);
 
-        print("\xda");
+        print(serial ? "/" : "\xda");
         for (size_t i = 0; i < term_cols - 2; i++) {
-            print("\xc4");
+            print(serial ? "-" : "\xc4");
         }
-        print("\xbf");
+        print(serial ? "\\" : "\xbf");
 
         for (size_t i = y + 1; i < term_rows - 2; i++) {
-            set_cursor_pos(0, i);
-            print("\xb3");
-            set_cursor_pos(term_cols - 1, i);
-            print("\xb3");
+            set_cursor_pos_helper(0, i);
+            print(serial ? "|" : "\xb3");
+            set_cursor_pos_helper(term_cols - 1, i);
+            print(serial ? "|" : "\xb3");
         }
+        set_cursor_pos_helper(0, term_rows - 2);
 
-        print("\xc0");
+        print(serial ? "\\" : "\xc0");
         for (size_t i = 0; i < term_cols - 2; i++) {
-            print("\xc4");
+            print(serial ? "-" : "\xc4");
         }
-        print("\xd9");
+        print(serial ? "/" : "\xd9");
 
-        set_cursor_pos(x, y + 2);
+        set_cursor_pos_helper(x, y + 2);
     }
 
-    size_t max_entries = print_tree("\xb3   ", 0, 0, selected_entry, menu_tree,
+    size_t max_entries = print_tree(serial ? "|   " : "\xb3   ", 0, 0, selected_entry, menu_tree,
                                  &selected_menu_entry);
 
     {
         size_t x, y;
         get_cursor_pos(&x, &y);
-        set_cursor_pos(0, 3);
+        set_cursor_pos_helper(0, 3);
         if (editor_enabled && selected_menu_entry->sub == NULL) {
             print("    \e[32mARROWS\e[0m Select    \e[32mENTER\e[0m Boot    \e[32mE\e[0m Edit");
         } else {
             print("    \e[32mARROWS\e[0m Select    \e[32mENTER\e[0m %s",
                   selected_menu_entry->expanded ? "Collapse" : "Expand");
         }
-        set_cursor_pos(term_cols - 12, 3);
+        set_cursor_pos_helper(term_cols - 12, 3);
         print("\e[32mC\e[0m Console");
-        set_cursor_pos(x, y);
+        set_cursor_pos_helper(x, y);
     }
 
     if (selected_menu_entry->sub != NULL)
@@ -789,7 +816,7 @@ refresh:
     if (skip_timeout == false) {
         print("\n\n");
         for (size_t i = timeout; i; i--) {
-            set_cursor_pos(0, term_rows - 1);
+            set_cursor_pos_helper(0, term_rows - 1);
             scroll_disable();
             print("\e[2K\e[32mBooting automatically in \e[92m%u\e[32m, press any key to stop the countdown...\e[0m", i);
             scroll_enable();
@@ -809,7 +836,7 @@ refresh:
         goto autoboot;
     }
 
-    set_cursor_pos(0, term_rows - 1);
+    set_cursor_pos_helper(0, term_rows - 1);
     if (selected_menu_entry->comment != NULL) {
         scroll_disable();
         print("\e[36m%s\e[0m", selected_menu_entry->comment);
diff --git a/test/limine.cfg b/test/limine.cfg
index dc340159..ee3e93ff 100644
--- a/test/limine.cfg
+++ b/test/limine.cfg
@@ -11,6 +11,7 @@ THEME_BACKGROUND=50000000
 BACKGROUND_PATH=${BACKGROUND_PATH}
 BACKGROUND_STYLE=stretched
 BACKDROP_COLOUR=008080
+SERIAL=yes
 
 :Stivale2 Test
 
tab: 248 wrap: offon