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
