:: commit 0f1d86e7e42695997e1e352f61600029945fc9d7

mintsuki <mintsuki@protonmail.com> — 2022-10-04 00:34

parents: 8849d08eeb

term: Tidy up VGA textmode wrapper code

diff --git a/common/drivers/vga_textmode.c b/common/drivers/vga_textmode.c
index d5da701c..aae281c5 100644
--- a/common/drivers/vga_textmode.c
+++ b/common/drivers/vga_textmode.c
@@ -20,24 +20,24 @@ static void draw_cursor(struct textmode_context *ctx) {
     ctx->video_mem[ctx->cursor_offset + 1] = ((pal & 0xf0) >> 4) | ((pal & 0x0f) << 4);
 }
 
-void text_save_state(struct term_context *_ctx) {
+static void text_save_state(struct term_context *_ctx) {
     struct textmode_context *ctx = (void *)_ctx;
     ctx->saved_state_text_palette = ctx->text_palette;
     ctx->saved_state_cursor_offset = ctx->cursor_offset;
 }
 
-void text_restore_state(struct term_context *_ctx) {
+static void text_restore_state(struct term_context *_ctx) {
     struct textmode_context *ctx = (void *)_ctx;
     ctx->text_palette = ctx->saved_state_text_palette;
     ctx->cursor_offset = ctx->saved_state_cursor_offset;
 }
 
-void text_swap_palette(struct term_context *_ctx) {
+static void text_swap_palette(struct term_context *_ctx) {
     struct textmode_context *ctx = (void *)_ctx;
     ctx->text_palette = (ctx->text_palette << 4) | (ctx->text_palette >> 4);
 }
 
-void text_scroll(struct term_context *_ctx) {
+static void text_scroll(struct term_context *_ctx) {
     struct textmode_context *ctx = (void *)_ctx;
 
     // move the text up by one row
@@ -53,7 +53,7 @@ void text_scroll(struct term_context *_ctx) {
     }
 }
 
-void text_revscroll(struct term_context *_ctx) {
+static void text_revscroll(struct term_context *_ctx) {
     struct textmode_context *ctx = (void *)_ctx;
 
     // move the text up by one row
@@ -71,7 +71,7 @@ void text_revscroll(struct term_context *_ctx) {
     }
 }
 
-void text_clear(struct term_context *_ctx, bool move) {
+static void text_clear(struct term_context *_ctx, bool move) {
     struct textmode_context *ctx = (void *)_ctx;
 
     for (size_t i = 0; i < VIDEO_BOTTOM; i += 2) {
@@ -83,13 +83,13 @@ void text_clear(struct term_context *_ctx, bool move) {
     }
 }
 
-void text_enable_cursor(struct term_context *_ctx) {
+static void text_enable_cursor(struct term_context *_ctx) {
     struct textmode_context *ctx = (void *)_ctx;
 
     ctx->cursor_status = true;
 }
 
-bool text_disable_cursor(struct term_context *_ctx) {
+static bool text_disable_cursor(struct term_context *_ctx) {
     struct textmode_context *ctx = (void *)_ctx;
 
     bool ret = ctx->cursor_status;
@@ -97,7 +97,7 @@ bool text_disable_cursor(struct term_context *_ctx) {
     return ret;
 }
 
-void text_full_refresh(struct term_context *_ctx) {
+static void text_full_refresh(struct term_context *_ctx) {
     struct textmode_context *ctx = (void *)_ctx;
 
     for (size_t i = 0; i < VD_ROWS * VD_COLS; i++) {
@@ -111,65 +111,7 @@ void text_full_refresh(struct term_context *_ctx) {
     }
 }
 
-void init_vga_textmode(size_t *_rows, size_t *_cols, bool managed) {
-    if (current_video_mode != 0x3) {
-        struct rm_regs r = {0};
-        r.eax = 0x0003;
-        rm_int(0x10, &r, &r);
-
-        current_video_mode = 0x3;
-    }
-
-    struct textmode_context *ctx = (void *)term;
-
-    if (ctx->back_buffer == NULL) {
-        ctx->back_buffer = ext_mem_alloc(VD_ROWS * VD_COLS);
-    } else {
-        memset(ctx->back_buffer, 0, VD_ROWS * VD_COLS);
-    }
-    if (ctx->front_buffer == NULL) {
-        ctx->front_buffer = ext_mem_alloc(VD_ROWS * VD_COLS);
-    } else {
-        memset(ctx->front_buffer, 0, VD_ROWS * VD_COLS);
-    }
-
-    ctx->cursor_offset = 0;
-    ctx->cursor_status = true;
-    ctx->text_palette = 0x07;
-
-    ctx->video_mem = (volatile uint8_t *)0xb8000;
-
-    text_clear(term, false);
-
-    *_rows = VD_ROWS;
-    *_cols = VD_COLS / 2;
-
-    // VGA cursor code taken from: https://wiki.osdev.org/Text_Mode_Cursor
-
-    if (!managed) {
-        text_disable_cursor(term);
-
-        outb(0x3d4, 0x0a);
-        outb(0x3d5, (inb(0x3d5) & 0xc0) | 14);
-        outb(0x3d4, 0x0b);
-        outb(0x3d5, (inb(0x3d5) & 0xe0) | 15);
-        outb(0x3d4, 0x0f);
-        outb(0x3d5, 0);
-        outb(0x3d4, 0x0e);
-        outb(0x3d5, 0);
-
-        struct rm_regs r = {0};
-        r.eax = 0x0200;
-        rm_int(0x10, &r, &r);
-    } else {
-        outb(0x3d4, 0x0a);
-        outb(0x3d5, 0x20);
-    }
-
-    text_double_buffer_flush(term);
-}
-
-void text_double_buffer_flush(struct term_context *_ctx) {
+static void text_double_buffer_flush(struct term_context *_ctx) {
     struct textmode_context *ctx = (void *)_ctx;
 
     if (ctx->cursor_status) {
@@ -198,14 +140,14 @@ void text_double_buffer_flush(struct term_context *_ctx) {
     }
 }
 
-void text_get_cursor_pos(struct term_context *_ctx, size_t *x, size_t *y) {
+static void text_get_cursor_pos(struct term_context *_ctx, size_t *x, size_t *y) {
     struct textmode_context *ctx = (void *)_ctx;
 
     *x = (ctx->cursor_offset % VD_COLS) / 2;
     *y = ctx->cursor_offset / VD_COLS;
 }
 
-void text_move_character(struct term_context *_ctx, size_t new_x, size_t new_y, size_t old_x, size_t old_y) {
+static void text_move_character(struct term_context *_ctx, size_t new_x, size_t new_y, size_t old_x, size_t old_y) {
     struct textmode_context *ctx = (void *)_ctx;
 
     if (old_x >= VD_COLS / 2 || old_y >= VD_ROWS
@@ -216,7 +158,7 @@ void text_move_character(struct term_context *_ctx, size_t new_x, size_t new_y,
     ctx->back_buffer[new_y * VD_COLS + new_x * 2] = ctx->back_buffer[old_y * VD_COLS + old_x * 2];
 }
 
-void text_set_cursor_pos(struct term_context *_ctx, size_t x, size_t y) {
+static void text_set_cursor_pos(struct term_context *_ctx, size_t x, size_t y) {
     struct textmode_context *ctx = (void *)_ctx;
 
     if (x >= VD_COLS / 2) {
@@ -238,37 +180,47 @@ void text_set_cursor_pos(struct term_context *_ctx, size_t x, size_t y) {
 
 static uint8_t ansi_colours[] = { 0, 4, 2, 6, 1, 5, 3, 7 };
 
-void text_set_text_fg(struct term_context *_ctx, size_t fg) {
+static void text_set_text_fg(struct term_context *_ctx, size_t fg) {
     struct textmode_context *ctx = (void *)_ctx;
     ctx->text_palette = (ctx->text_palette & 0xf0) | ansi_colours[fg];
 }
 
-void text_set_text_bg(struct term_context *_ctx, size_t bg) {
+static void text_set_text_bg(struct term_context *_ctx, size_t bg) {
     struct textmode_context *ctx = (void *)_ctx;
     ctx->text_palette = (ctx->text_palette & 0x0f) | (ansi_colours[bg] << 4);
 }
 
-void text_set_text_fg_bright(struct term_context *_ctx, size_t fg) {
+static void text_set_text_fg_bright(struct term_context *_ctx, size_t fg) {
     struct textmode_context *ctx = (void *)_ctx;
     ctx->text_palette = (ctx->text_palette & 0xf0) | (ansi_colours[fg] | (1 << 3));
 }
 
-void text_set_text_bg_bright(struct term_context *_ctx, size_t bg) {
+static void text_set_text_bg_bright(struct term_context *_ctx, size_t bg) {
     struct textmode_context *ctx = (void *)_ctx;
     ctx->text_palette = (ctx->text_palette & 0x0f) | ((ansi_colours[bg] | (1 << 3)) << 4);
 }
 
-void text_set_text_fg_default(struct term_context *_ctx) {
+static void text_set_text_fg_rgb(struct term_context *ctx, uint32_t n) {
+    (void)ctx;
+    (void)n;
+}
+
+static void text_set_text_bg_rgb(struct term_context *ctx, uint32_t n) {
+    (void)ctx;
+    (void)n;
+}
+
+static void text_set_text_fg_default(struct term_context *_ctx) {
     struct textmode_context *ctx = (void *)_ctx;
     ctx->text_palette = (ctx->text_palette & 0xf0) | 7;
 }
 
-void text_set_text_bg_default(struct term_context *_ctx) {
+static void text_set_text_bg_default(struct term_context *_ctx) {
     struct textmode_context *ctx = (void *)_ctx;
     ctx->text_palette &= 0x0f;
 }
 
-void text_putchar(struct term_context *_ctx, uint8_t c) {
+static void text_putchar(struct term_context *_ctx, uint8_t c) {
     struct textmode_context *ctx = (void *)_ctx;
 
     ctx->back_buffer[ctx->cursor_offset] = c;
@@ -286,4 +238,114 @@ void text_putchar(struct term_context *_ctx, uint8_t c) {
     }
 }
 
+static void text_deinit(struct term_context *_ctx, void (*_free)(void *, size_t)) {
+    struct textmode_context *ctx = (void *)_ctx;
+
+    if (ctx->back_buffer != NULL) {
+        _free(ctx->back_buffer, VD_ROWS * VD_COLS);
+        ctx->back_buffer = NULL;
+    }
+
+    if (ctx->front_buffer != NULL) {
+        _free(ctx->front_buffer, VD_ROWS * VD_COLS);
+        ctx->front_buffer = NULL;
+    }
+}
+
+void vga_textmode_init(bool managed) {
+    if (quiet || allocations_disallowed) {
+        return;
+    }
+
+    if (current_video_mode != 0x3) {
+        struct rm_regs r = {0};
+        r.eax = 0x0003;
+        rm_int(0x10, &r, &r);
+
+        current_video_mode = 0x3;
+    }
+
+    struct textmode_context *ctx = (void *)term;
+
+    if (ctx->back_buffer == NULL) {
+        ctx->back_buffer = ext_mem_alloc(VD_ROWS * VD_COLS);
+    } else {
+        memset(ctx->back_buffer, 0, VD_ROWS * VD_COLS);
+    }
+    if (ctx->front_buffer == NULL) {
+        ctx->front_buffer = ext_mem_alloc(VD_ROWS * VD_COLS);
+    } else {
+        memset(ctx->front_buffer, 0, VD_ROWS * VD_COLS);
+    }
+
+    ctx->cursor_offset = 0;
+    ctx->cursor_status = true;
+    ctx->text_palette = 0x07;
+
+    ctx->video_mem = (volatile uint8_t *)0xb8000;
+
+    text_clear(term, false);
+
+    // VGA cursor code taken from: https://wiki.osdev.org/Text_Mode_Cursor
+
+    if (!managed) {
+        text_disable_cursor(term);
+
+        outb(0x3d4, 0x0a);
+        outb(0x3d5, (inb(0x3d5) & 0xc0) | 14);
+        outb(0x3d4, 0x0b);
+        outb(0x3d5, (inb(0x3d5) & 0xe0) | 15);
+        outb(0x3d4, 0x0f);
+        outb(0x3d5, 0);
+        outb(0x3d4, 0x0e);
+        outb(0x3d5, 0);
+
+        struct rm_regs r = {0};
+        r.eax = 0x0200;
+        rm_int(0x10, &r, &r);
+    } else {
+        outb(0x3d4, 0x0a);
+        outb(0x3d5, 0x20);
+    }
+
+    text_double_buffer_flush(term);
+
+    if (serial) {
+        term->cols = term->cols > 80 ? 80 : term->cols;
+        term->rows = term->rows > 24 ? 24 : term->rows;
+    } else {
+        term->cols = 80;
+        term->rows = 25;
+    }
+
+    term->raw_putchar = text_putchar;
+    term->clear = text_clear;
+    term->enable_cursor = text_enable_cursor;
+    term->disable_cursor = text_disable_cursor;
+    term->set_cursor_pos = text_set_cursor_pos;
+    term->get_cursor_pos = text_get_cursor_pos;
+    term->set_text_fg = text_set_text_fg;
+    term->set_text_bg = text_set_text_bg;
+    term->set_text_fg_bright = text_set_text_fg_bright;
+    term->set_text_bg_bright = text_set_text_bg_bright;
+    term->set_text_fg_rgb = text_set_text_fg_rgb;
+    term->set_text_bg_rgb = text_set_text_bg_rgb;
+    term->set_text_fg_default = text_set_text_fg_default;
+    term->set_text_bg_default = text_set_text_bg_default;
+    term->move_character = text_move_character;
+    term->scroll = text_scroll;
+    term->revscroll = text_revscroll;
+    term->swap_palette = text_swap_palette;
+    term->save_state = text_save_state;
+    term->restore_state = text_restore_state;
+    term->double_buffer_flush = text_double_buffer_flush;
+    term->full_refresh = text_full_refresh;
+    term->deinit = text_deinit;
+
+    term_backend = TEXTMODE;
+    term_context_reinit(term);
+
+    term->in_bootloader = true;
+}
+
 #endif
diff --git a/common/drivers/vga_textmode.h b/common/drivers/vga_textmode.h
index 5d165c82..0f9b875c 100644
--- a/common/drivers/vga_textmode.h
+++ b/common/drivers/vga_textmode.h
@@ -23,29 +23,6 @@ struct textmode_context {
     size_t saved_state_cursor_offset;
 };
 
-void init_vga_textmode(size_t *rows, size_t *cols, bool managed);
-
-void text_putchar(struct term_context *ctx, uint8_t c);
-void text_clear(struct term_context *ctx, bool move);
-void text_enable_cursor(struct term_context *ctx);
-bool text_disable_cursor(struct term_context *ctx);
-void text_set_cursor_pos(struct term_context *ctx, size_t x, size_t y);
-void text_get_cursor_pos(struct term_context *ctx, size_t *x, size_t *y);
-void text_set_text_fg(struct term_context *ctx, size_t fg);
-void text_set_text_bg(struct term_context *ctx, size_t bg);
-void text_set_text_fg_bright(struct term_context *ctx, size_t fg);
-void text_set_text_bg_bright(struct term_context *ctx, size_t bg);
-void text_set_text_fg_default(struct term_context *ctx);
-void text_set_text_bg_default(struct term_context *ctx);
-bool text_scroll_disable(struct term_context *ctx);
-void text_scroll_enable(struct term_context *ctx);
-void text_move_character(struct term_context *ctx, size_t new_x, size_t new_y, size_t old_x, size_t old_y);
-void text_scroll(struct term_context *ctx);
-void text_revscroll(struct term_context *ctx);
-void text_swap_palette(struct term_context *ctx);
-void text_save_state(struct term_context *ctx);
-void text_restore_state(struct term_context *ctx);
-void text_double_buffer_flush(struct term_context *ctx);
-void text_full_refresh(struct term_context *ctx);
+void vga_textmode_init(bool managed);
 
 #endif
diff --git a/common/lib/term.c b/common/lib/term.c
index d6e42279..b7aa454f 100644
--- a/common/lib/term.c
+++ b/common/lib/term.c
@@ -259,50 +259,6 @@ void term_fallback(void) {
 extern void reset_term(void);
 extern void set_cursor_pos_helper(size_t x, size_t y);
 
-#if defined (BIOS)
-void term_textmode(void) {
-    term_notready();
-
-    if (quiet || allocations_disallowed) {
-        return;
-    }
-
-    init_vga_textmode(&term->rows, &term->cols, true);
-
-    if (serial) {
-        term->cols = term->cols > 80 ? 80 : term->cols;
-        term->rows = term->rows > 24 ? 24 : term->rows;
-    }
-
-    term->raw_putchar    = text_putchar;
-    term->clear          = text_clear;
-    term->enable_cursor  = text_enable_cursor;
-    term->disable_cursor = text_disable_cursor;
-    term->set_cursor_pos = text_set_cursor_pos;
-    term->get_cursor_pos = text_get_cursor_pos;
-    term->set_text_fg    = text_set_text_fg;
-    term->set_text_bg    = text_set_text_bg;
-    term->set_text_fg_bright = text_set_text_fg_bright;
-    term->set_text_bg_bright = text_set_text_bg_bright;
-    term->set_text_fg_default = text_set_text_fg_default;
-    term->set_text_bg_default = text_set_text_bg_default;
-    term->move_character = text_move_character;
-    term->scroll = text_scroll;
-    term->revscroll = text_revscroll;
-    term->swap_palette = text_swap_palette;
-    term->save_state = text_save_state;
-    term->restore_state = text_restore_state;
-    term->double_buffer_flush = text_double_buffer_flush;
-    term->full_refresh = text_full_refresh;
-    //term->deinit = text_deinit;
-
-    term_backend = TEXTMODE;
-    term_context_reinit(term);
-
-    term->in_bootloader = true;
-}
-#endif
-
 #if defined (__i386__)
 #define TERM_XFER_CHUNK 8192
 
diff --git a/common/lib/term.h b/common/lib/term.h
index 96d0d25b..4ba66268 100644
--- a/common/lib/term.h
+++ b/common/lib/term.h
@@ -37,7 +37,6 @@ inline void set_cursor_pos_helper(size_t x, size_t y) {
 }
 
 void term_fallback(void);
-void term_textmode(void);
 
 void _term_write(uint64_t buf, uint64_t count);
 
diff --git a/common/menu.c b/common/menu.c
index 8e042e00..33f99a1c 100644
--- a/common/menu.c
+++ b/common/menu.c
@@ -14,6 +14,7 @@
 #include <lib/uri.h>
 #include <mm/pmm.h>
 #include <drivers/vbe.h>
+#include <drivers/vga_textmode.h>
 #include <console.h>
 #include <protos/linux.h>
 #include <protos/chainload.h>
@@ -566,7 +567,7 @@ static void menu_init_term(void) {
         gterm_init(NULL, req_width, req_height);
     } else {
 #if defined (BIOS)
-        term_textmode();
+        vga_textmode_init(true);
 #endif
     }
 }
@@ -848,7 +849,7 @@ timeout_aborted:
                     gterm_init(NULL, 0, 0);
 #if defined (BIOS)
                     if (term_backend == FALLBACK) {
-                        term_textmode();
+                        vga_textmode_init(true);
                     }
 #endif
                 } else {
diff --git a/common/protos/chainload.c b/common/protos/chainload.c
index b2f0b716..e097f6f0 100644
--- a/common/protos/chainload.c
+++ b/common/protos/chainload.c
@@ -173,8 +173,7 @@ load:
 }
 
 void bios_chainload_volume(struct volume *p) {
-    size_t rows, cols;
-    init_vga_textmode(&rows, &cols, false);
+    vga_textmode_init(false);
 
     volume_read(p, (void *)0x7c00, 0, 512);
 
diff --git a/common/protos/linux.c b/common/protos/linux.c
index 8ff5c187..0750e17e 100644
--- a/common/protos/linux.c
+++ b/common/protos/linux.c
@@ -524,13 +524,12 @@ noreturn void linux_load(char *config, char *cmdline) {
         panic(true, "linux: Unable to set video mode");
 #elif defined (BIOS)
 set_textmode:;
-        size_t rows, cols;
-        init_vga_textmode(&rows, &cols, false);
+        vga_textmode_init(false);
 
         screen_info->orig_video_mode = 3;
         screen_info->orig_video_ega_bx = 3;
-        screen_info->orig_video_lines = rows;
-        screen_info->orig_video_cols = cols;
+        screen_info->orig_video_lines = term->rows;
+        screen_info->orig_video_cols = term->cols;
         screen_info->orig_video_points = 16;
 
         screen_info->orig_video_isVGA = VIDEO_TYPE_VGAC;
diff --git a/common/protos/multiboot1.c b/common/protos/multiboot1.c
index 0161f77e..8a6d609d 100644
--- a/common/protos/multiboot1.c
+++ b/common/protos/multiboot1.c
@@ -319,14 +319,13 @@ noreturn void multiboot1_load(char *config, char *cmdline) {
 #if defined (UEFI)
                 goto skip_modeset;
 #elif defined (BIOS)
-                size_t rows, cols;
-                init_vga_textmode(&rows, &cols, false);
+                vga_textmode_init(false);
 
                 multiboot1_info->fb_addr    = 0xb8000;
-                multiboot1_info->fb_width   = cols;
-                multiboot1_info->fb_height  = rows;
+                multiboot1_info->fb_width   = term->cols;
+                multiboot1_info->fb_height  = term->rows;
                 multiboot1_info->fb_bpp     = 16;
-                multiboot1_info->fb_pitch   = 2 * cols;
+                multiboot1_info->fb_pitch   = 2 * term->cols;
                 multiboot1_info->fb_type    = 2;
 #endif
             } else {
@@ -363,14 +362,13 @@ noreturn void multiboot1_load(char *config, char *cmdline) {
             multiboot1_info->fb_blue_mask_size   = fbinfo.blue_mask_size;
             multiboot1_info->fb_blue_mask_shift  = fbinfo.blue_mask_shift;
 #elif defined (BIOS)
-            size_t rows, cols;
-            init_vga_textmode(&rows, &cols, false);
+            vga_textmode_init(false);
 
             multiboot1_info->fb_addr    = 0xb8000;
-            multiboot1_info->fb_width   = cols;
-            multiboot1_info->fb_height  = rows;
+            multiboot1_info->fb_width   = term->cols;
+            multiboot1_info->fb_height  = term->rows;
             multiboot1_info->fb_bpp     = 16;
-            multiboot1_info->fb_pitch   = 2 * cols;
+            multiboot1_info->fb_pitch   = 2 * term->cols;
             multiboot1_info->fb_type    = 2;
 #endif
         }
@@ -384,8 +382,7 @@ skip_modeset:;
 #if defined (UEFI)
         panic(true, "multiboot1: Cannot use text mode with UEFI.");
 #elif defined (BIOS)
-        size_t rows, cols;
-        init_vga_textmode(&rows, &cols, false);
+        vga_textmode_init(false);
 #endif
     }
 
diff --git a/common/protos/multiboot2.c b/common/protos/multiboot2.c
index 0f221c05..98a98547 100644
--- a/common/protos/multiboot2.c
+++ b/common/protos/multiboot2.c
@@ -519,13 +519,12 @@ noreturn void multiboot2_load(char *config, char* cmdline) {
             struct fb_info fbinfo;
             if (!fb_init(&fbinfo, req_width, req_height, req_bpp)) {
 #if defined (BIOS)
-                size_t rows, cols;
-                init_vga_textmode(&rows, &cols, false);
+                vga_textmode_init(false);
 
                 tag->common.framebuffer_addr = 0xb8000;
-                tag->common.framebuffer_pitch = 2 * cols;
-                tag->common.framebuffer_width = cols;
-                tag->common.framebuffer_height = rows;
+                tag->common.framebuffer_pitch = 2 * term->cols;
+                tag->common.framebuffer_width = term->cols;
+                tag->common.framebuffer_height = term->rows;
                 tag->common.framebuffer_bpp = 16;
                 tag->common.framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT;
 #elif defined (UEFI)
@@ -576,14 +575,13 @@ noreturn void multiboot2_load(char *config, char* cmdline) {
             tag->framebuffer_blue_field_position = fbinfo.blue_mask_shift;
             tag->framebuffer_blue_mask_size = fbinfo.blue_mask_size;
 #elif defined (BIOS)
-            size_t rows, cols;
-            init_vga_textmode(&rows, &cols, false);
+            vga_textmode_init(false);
 
             tag->common.framebuffer_addr = 0xb8000;
-            tag->common.framebuffer_width = cols;
-            tag->common.framebuffer_height = rows;
+            tag->common.framebuffer_width = term->cols;
+            tag->common.framebuffer_height = term->rows;
             tag->common.framebuffer_bpp = 16;
-            tag->common.framebuffer_pitch = 2 * cols;
+            tag->common.framebuffer_pitch = 2 * term->cols;
             tag->common.framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT;
 #endif
         }
tab: 248 wrap: offon