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 0787face..bd723b2f 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 d1a07dde..0042d6e8 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/stivale.h>
#include <protos/stivale2.h>
@@ -589,7 +590,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
}
}
@@ -891,7 +892,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 fa6f50ec..3e2a1fe1 100644
--- a/common/protos/linux.c
+++ b/common/protos/linux.c
@@ -522,13 +522,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 dd3321d0..f53cf1a0 100644
--- a/common/protos/multiboot1.c
+++ b/common/protos/multiboot1.c
@@ -314,14 +314,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 {
@@ -358,14 +357,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
}
@@ -379,8 +377,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 a7309a0e..8f5c17e7 100644
--- a/common/protos/multiboot2.c
+++ b/common/protos/multiboot2.c
@@ -514,13 +514,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)
@@ -571,14 +570,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
}
