term: Mass backport changes done in Vinix upstream

This commit is contained in:
mintsuki 2021-08-16 18:02:28 +02:00
parent 993a602afb
commit c7a46830f6
22 changed files with 1163 additions and 607 deletions

View File

@ -61,6 +61,7 @@ INTERNAL_CFLAGS := \
-fno-omit-frame-pointer \
-fno-lto \
-fno-pic \
-Wno-stringop-overflow \
-Wno-address-of-packed-member \
-Wshadow \
-mno-80387 \

View File

@ -2,24 +2,33 @@
#define __DRIVERS__VGA_TEXTMODE_H__
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
void init_vga_textmode(int *rows, int *cols, bool managed);
void init_vga_textmode(size_t *rows, size_t *cols, bool managed);
void text_putchar(uint8_t c);
void text_clear(bool move);
void text_enable_cursor(void);
bool text_disable_cursor(void);
void text_set_cursor_pos(int x, int y);
void text_get_cursor_pos(int *x, int *y);
void text_set_text_fg(int fg);
void text_set_text_bg(int bg);
void text_set_cursor_pos(size_t x, size_t y);
void text_get_cursor_pos(size_t *x, size_t *y);
void text_set_text_fg(size_t fg);
void text_set_text_bg(size_t bg);
void text_set_text_fg_bright(size_t fg);
void text_set_text_fg_default(void);
void text_set_text_bg_default(void);
bool text_scroll_disable(void);
void text_scroll_enable(void);
void text_move_character(int new_x, int new_y, int old_x, int old_y);
void text_move_character(size_t new_x, size_t new_y, size_t old_x, size_t old_y);
void text_scroll(void);
void text_swap_palette(void);
void text_double_buffer(bool state);
void text_double_buffer_flush(void);
uint64_t text_context_size(void);
void text_context_save(uint64_t ptr);
void text_context_restore(uint64_t ptr);
#endif

View File

@ -7,6 +7,7 @@
#include <sys/cpu.h>
#include <lib/real.h>
#include <lib/libc.h>
#include <lib/blib.h>
#include <lib/term.h>
#include <mm/pmm.h>
@ -14,16 +15,25 @@
#define VD_COLS (80 * 2)
#define VD_ROWS 25
static uint8_t *back_buffer = NULL;
static uint8_t *front_buffer = NULL;
static uint8_t *video_mem = (uint8_t *)0xb8000;
static uint8_t *current_buffer;
static uint8_t *back_buffer = NULL;
static uint8_t *front_buffer = NULL;
static size_t cursor_offset;
static int cursor_status;
static uint8_t text_palette;
static uint8_t cursor_palette;
static struct context {
uint8_t *current_buffer;
#define current_buffer context.current_buffer
size_t cursor_offset;
#define cursor_offset context.cursor_offset
bool cursor_status;
#define cursor_status context.cursor_status
uint8_t text_palette;
#define text_palette context.text_palette
uint8_t cursor_palette;
#define cursor_palette context.cursor_palette
bool scroll_enabled;
#define scroll_enabled context.scroll_enabled
} context;
static void clear_cursor(void) {
if (cursor_status) {
@ -37,7 +47,9 @@ static void draw_cursor(void) {
}
}
static bool scroll_enabled = true;
void text_swap_palette(void) {
text_palette = (text_palette << 4) | (text_palette >> 4);
}
bool text_scroll_disable(void) {
bool ret = scroll_enabled;
@ -49,20 +61,22 @@ void text_scroll_enable(void) {
scroll_enabled = true;
}
static void scroll(void) {
void text_scroll(void) {
// move the text up by one row
for (size_t i = 0; i <= VIDEO_BOTTOM - VD_COLS; i++) {
for (size_t i = term_context.scroll_top_margin * VD_COLS;
i < (term_context.scroll_bottom_margin - 1) * VD_COLS; i++) {
current_buffer[i] = current_buffer[i + VD_COLS];
if (current_buffer == front_buffer)
video_mem[i] = current_buffer[i + VD_COLS];
}
// clear the last line of the screen
for (size_t i = VIDEO_BOTTOM; i > VIDEO_BOTTOM - VD_COLS; i -= 2) {
current_buffer[i] = text_palette;
current_buffer[i - 1] = ' ';
for (size_t i = (term_context.scroll_bottom_margin - 1) * VD_COLS;
i < term_context.scroll_bottom_margin * VD_COLS; i += 2) {
current_buffer[i] = ' ';
current_buffer[i + 1] = text_palette;
if (current_buffer == front_buffer) {
video_mem[i] = text_palette;
video_mem[i - 1] = ' ';
video_mem[i] = ' ';
video_mem[i + 1] = text_palette;
}
}
}
@ -84,19 +98,55 @@ void text_clear(bool move) {
}
void text_enable_cursor(void) {
cursor_status = 1;
cursor_status = true;
draw_cursor();
return;
}
bool text_disable_cursor(void) {
bool ret = cursor_status != 0;
bool ret = cursor_status;
clear_cursor();
cursor_status = 0;
cursor_status = false;
return ret;
}
void init_vga_textmode(int *_rows, int *_cols, bool managed) {
uint64_t text_context_size(void) {
uint64_t ret = 0;
ret += sizeof(struct context);
ret += VD_ROWS * VD_COLS; // back buffer
ret += VD_ROWS * VD_COLS; // front buffer
return ret;
}
void text_context_save(uint64_t ptr) {
memcpy32to64(ptr, (uint64_t)(uintptr_t)&context, sizeof(struct context));
ptr += sizeof(struct context);
memcpy32to64(ptr, (uint64_t)(uintptr_t)back_buffer, VD_ROWS * VD_COLS);
ptr += VD_ROWS * VD_COLS;
memcpy32to64(ptr, (uint64_t)(uintptr_t)front_buffer, VD_ROWS * VD_COLS);
}
void text_context_restore(uint64_t ptr) {
memcpy32to64((uint64_t)(uintptr_t)&context, ptr, sizeof(struct context));
ptr += sizeof(struct context);
memcpy32to64((uint64_t)(uintptr_t)back_buffer, ptr, VD_ROWS * VD_COLS);
ptr += VD_ROWS * VD_COLS;
memcpy32to64((uint64_t)(uintptr_t)front_buffer, ptr, VD_ROWS * VD_COLS);
for (size_t i = 0; i < VD_ROWS * VD_COLS; i++) {
video_mem[i] = current_buffer[i];
}
draw_cursor();
}
void init_vga_textmode(size_t *_rows, size_t *_cols, bool managed) {
if (current_video_mode != -1) {
struct rm_regs r = {0};
r.eax = 0x0003;
@ -105,15 +155,17 @@ void init_vga_textmode(int *_rows, int *_cols, bool managed) {
current_video_mode = -1;
}
back_buffer = ext_mem_alloc(VD_ROWS * VD_COLS);
front_buffer = ext_mem_alloc(VD_ROWS * VD_COLS);
if (back_buffer == NULL)
back_buffer = ext_mem_alloc(VD_ROWS * VD_COLS);
if (front_buffer == NULL)
front_buffer = ext_mem_alloc(VD_ROWS * VD_COLS);
current_buffer = front_buffer;
cursor_offset = 0;
cursor_status = 1;
cursor_status = true;
text_palette = 0x07;
cursor_palette = 0x70;
text_double_buffer(false);
scroll_enabled = true;
text_clear(false);
@ -165,48 +217,49 @@ void text_double_buffer_flush(void) {
draw_cursor();
}
static int text_get_cursor_pos_y(void) {
return cursor_offset / VD_COLS;
}
void text_get_cursor_pos(int *x, int *y) {
void text_get_cursor_pos(size_t *x, size_t *y) {
*x = (cursor_offset % VD_COLS) / 2;
*y = cursor_offset / VD_COLS;
}
void text_move_character(int new_x, int new_y, int old_x, int old_y) {
void text_move_character(size_t new_x, size_t new_y, size_t old_x, size_t old_y) {
if (old_x >= VD_COLS / 2 || old_y >= VD_ROWS
|| new_x >= VD_COLS / 2 || new_y >= VD_ROWS) {
return;
}
current_buffer[new_y * VD_COLS + new_x * 2] = current_buffer[old_y * VD_COLS + old_x * 2];
if (current_buffer == front_buffer) {
video_mem[new_y * VD_COLS + new_x * 2] = current_buffer[old_y * VD_COLS + old_x * 2];
}
}
void text_set_cursor_pos(int x, int y) {
void text_set_cursor_pos(size_t x, size_t y) {
clear_cursor();
if (x < 0) {
x = 0;
} else if (x >= VD_COLS / 2) {
if (x >= VD_COLS / 2) {
x = VD_COLS / 2 - 1;
}
if (y < 0) {
y = 0;
} else if (y >= VD_ROWS) {
if (y >= VD_ROWS) {
y = VD_ROWS - 1;
}
cursor_offset = y * VD_COLS + x * 2;
draw_cursor();
}
static uint8_t ansi_colours[] = { 0, 4, 2, 0x0e, 1, 5, 3, 7 };
static uint8_t ansi_colours[] = { 0, 4, 2, 6, 1, 5, 3, 7 };
void text_set_text_fg(int fg) {
void text_set_text_fg(size_t fg) {
text_palette = (text_palette & 0xf0) | ansi_colours[fg];
}
void text_set_text_bg(int bg) {
void text_set_text_bg(size_t bg) {
text_palette = (text_palette & 0x0f) | (ansi_colours[bg] << 4);
}
void text_set_text_fg_bright(size_t fg) {
text_palette = (text_palette & 0xf0) | (ansi_colours[fg] | (1 << 3));
}
void text_set_text_fg_default(void) {
text_palette = (text_palette & 0xf0) | 7;
}
@ -216,46 +269,25 @@ void text_set_text_bg_default(void) {
}
void text_putchar(uint8_t c) {
switch (c) {
case '\b':
if (cursor_offset) {
clear_cursor();
cursor_offset -= 2;
draw_cursor();
}
break;
case '\r':
text_set_cursor_pos(0, text_get_cursor_pos_y());
break;
case '\n':
if (text_get_cursor_pos_y() == (VD_ROWS - 1)) {
if (scroll_enabled) {
clear_cursor();
scroll();
text_set_cursor_pos(0, (VD_ROWS - 1));
}
} else {
text_set_cursor_pos(0, (text_get_cursor_pos_y() + 1));
}
break;
default:
clear_cursor();
current_buffer[cursor_offset] = c;
current_buffer[cursor_offset+1] = text_palette;
if (current_buffer == front_buffer) {
video_mem[cursor_offset] = c;
video_mem[cursor_offset+1] = text_palette;
}
if (cursor_offset >= (VIDEO_BOTTOM - 1)) {
if (scroll_enabled) {
scroll();
cursor_offset = VIDEO_BOTTOM - (VD_COLS - 1);
}
} else {
cursor_offset += 2;
}
draw_cursor();
clear_cursor();
current_buffer[cursor_offset] = c;
current_buffer[cursor_offset + 1] = text_palette;
if (current_buffer == front_buffer) {
video_mem[cursor_offset] = c;
video_mem[cursor_offset + 1] = text_palette;
}
if (cursor_offset / VD_COLS == term_context.scroll_bottom_margin - 1
&& cursor_offset % VD_COLS == VD_COLS - 2) {
if (scroll_enabled) {
text_scroll();
cursor_offset -= cursor_offset % VD_COLS;
}
} else if (cursor_offset >= (VIDEO_BOTTOM - 1)) {
cursor_offset -= cursor_offset % VD_COLS;
} else {
cursor_offset += 2;
}
draw_cursor();
}
#endif

View File

@ -20,13 +20,13 @@ UINTN efi_mmap_size = 0, efi_desc_size = 0, efi_desc_ver = 0;
bool verbose = false;
bool parse_resolution(int *width, int *height, int *bpp, const char *buf) {
int res[3] = {0};
bool parse_resolution(size_t *width, size_t *height, size_t *bpp, const char *buf) {
size_t res[3] = {0};
const char *first = buf;
for (int i = 0; i < 3; i++) {
for (size_t i = 0; i < 3; i++) {
const char *last;
int x = strtoui(first, &last, 10);
size_t x = strtoui(first, &last, 10);
if (first == last)
break;
res[i] = x;

View File

@ -6,6 +6,7 @@
#include <stdbool.h>
#include <fs/file.h>
#include <lib/part.h>
#include <lib/libc.h>
#if uefi == 1
# include <efi.h>
#endif
@ -30,7 +31,7 @@ extern bool stage3_loaded;
extern bool verbose;
bool parse_resolution(int *width, int *height, int *bpp, const char *buf);
bool parse_resolution(size_t *width, size_t *height, size_t *bpp, const char *buf);
uint64_t sqrt(uint64_t a_nInput);
size_t get_trailing_zeros(uint64_t val);
@ -44,6 +45,12 @@ int pit_sleep_and_quit_on_keypress(int seconds);
uint64_t strtoui(const char *s, const char **end, int base);
#if defined (__i386__)
void memcpy32to64(uint64_t, uint64_t, uint64_t);
#elif defined (__x86_64__)
# define memcpy32to64(X, Y, Z) memcpy((void *)(uintptr_t)(X), (void *)(uintptr_t)(Y), Z)
#endif
#define DIV_ROUNDUP(a, b) (((a) + ((b) - 1)) / (b))
#define ALIGN_UP(x, a) ({ \

View File

@ -31,7 +31,7 @@ static uint32_t ansi_colours[8];
static uint32_t ansi_bright_colours[8];
static uint32_t default_fg, default_bg;
static int frame_height, frame_width;
static size_t frame_height, frame_width;
static struct image *background;
@ -49,12 +49,22 @@ static uint32_t text_fg, text_bg;
static bool cursor_status = true;
static int cursor_x;
static int cursor_y;
static size_t cursor_x;
static size_t cursor_y;
static int rows;
static int cols;
static int margin_gradient;
static size_t rows;
static size_t cols;
static size_t margin_gradient;
void gterm_swap_palette(void) {
uint32_t tmp = text_bg;
text_bg = text_fg;
if (tmp == 0xffffffff) {
text_fg = default_bg;
} else {
text_fg = tmp;
}
}
#define A(rgb) (uint8_t)(rgb >> 24)
#define R(rgb) (uint8_t)(rgb >> 16)
@ -73,14 +83,14 @@ static inline uint32_t colour_blend(uint32_t fg, uint32_t bg) {
return ARGB(0, r, g, b);
}
void gterm_plot_px(int x, int y, uint32_t hex) {
void gterm_plot_px(size_t x, size_t y, uint32_t hex) {
size_t fb_i = x + (gterm_pitch / sizeof(uint32_t)) * y;
gterm_framebuffer[fb_i] = hex;
}
static uint32_t blend_gradient_from_box(int x, int y, uint32_t bg_px, uint32_t hex) {
int distance, x_distance, y_distance;
static uint32_t blend_gradient_from_box(size_t x, size_t y, uint32_t bg_px, uint32_t hex) {
size_t distance, x_distance, y_distance;
if (x < frame_width)
x_distance = frame_width - x;
@ -110,22 +120,22 @@ static uint32_t blend_gradient_from_box(int x, int y, uint32_t bg_px, uint32_t h
return colour_blend((hex & 0xffffff) | (new_alpha << 24), bg_px);
}
typedef int fixedp6; // the last 6 bits are the fixed point part
static int fixedp6_to_int(fixedp6 value) { return value / 64; }
static fixedp6 int_to_fixedp6(int value) { return value * 64; }
typedef size_t fixedp6; // the last 6 bits are the fixed point part
static size_t fixedp6_to_int(fixedp6 value) { return value / 64; }
static fixedp6 int_to_fixedp6(size_t value) { return value * 64; }
// Draw rect at coordinates, copying from the image to the fb and canvas, applying fn on every pixel
__attribute__((always_inline)) static inline void genloop(int xstart, int xend, int ystart, int yend, uint32_t (*blend)(int x, int y, uint32_t orig)) {
__attribute__((always_inline)) static inline void genloop(size_t xstart, size_t xend, size_t ystart, size_t yend, uint32_t (*blend)(size_t x, size_t y, uint32_t orig)) {
uint8_t *img = background->img;
const int img_width = background->img_width, img_height = background->img_height, img_pitch = background->pitch, colsize = background->bpp / 8;
const size_t img_width = background->img_width, img_height = background->img_height, img_pitch = background->pitch, colsize = background->bpp / 8;
switch (background->type) {
case IMAGE_TILED:
for (int y = ystart; y < yend; y++) {
int image_y = y % img_height, image_x = xstart % img_width;
for (size_t y = ystart; y < yend; y++) {
size_t image_y = y % img_height, image_x = xstart % img_width;
const size_t off = img_pitch * (img_height - 1 - image_y);
int canvas_off = gterm_width * y, fb_off = gterm_pitch / 4 * y;
for (int x = xstart; x < xend; x++) {
size_t canvas_off = gterm_width * y, fb_off = gterm_pitch / 4 * y;
for (size_t x = xstart; x < xend; x++) {
uint32_t img_pixel = *(uint32_t*)(img + image_x * colsize + off);
uint32_t i = blend(x, y, img_pixel);
bg_canvas[canvas_off + x] = i; gterm_framebuffer[fb_off + x] = i;
@ -135,20 +145,20 @@ __attribute__((always_inline)) static inline void genloop(int xstart, int xend,
break;
case IMAGE_CENTERED:
for (int y = ystart; y < yend; y++) {
int image_y = y - background->y_displacement;
for (size_t y = ystart; y < yend; y++) {
size_t image_y = y - background->y_displacement;
const size_t off = img_pitch * (img_height - 1 - image_y);
int canvas_off = gterm_width * y, fb_off = gterm_pitch / 4 * y;
if ((image_y < 0) || (image_y >= background->y_size)) { /* external part */
for (int x = xstart; x < xend; x++) {
size_t canvas_off = gterm_width * y, fb_off = gterm_pitch / 4 * y;
if (image_y >= background->y_size) { /* external part */
for (size_t x = xstart; x < xend; x++) {
uint32_t i = blend(x, y, background->back_colour);
bg_canvas[canvas_off + x] = i; gterm_framebuffer[fb_off + x] = i;
}
}
else { /* internal part */
for (int x = xstart; x < xend; x++) {
int image_x = (x - background->x_displacement);
bool x_external = (image_x < 0) || (image_x >= background->x_size);
for (size_t x = xstart; x < xend; x++) {
size_t image_x = (x - background->x_displacement);
bool x_external = image_x >= background->x_size;
uint32_t img_pixel = *(uint32_t*)(img + image_x * colsize + off);
uint32_t i = blend(x, y, x_external ? background->back_colour : img_pixel);
bg_canvas[canvas_off + x] = i; gterm_framebuffer[fb_off + x] = i;
@ -160,14 +170,14 @@ __attribute__((always_inline)) static inline void genloop(int xstart, int xend,
// hence x = xstart * ratio + i * ratio
// so you can set x = xstart * ratio, and increment by ratio at each iteration
case IMAGE_STRETCHED:
for (int y = ystart; y < yend; y++) {
int img_y = (y * img_height) / gterm_height; // calculate Y with full precision
int off = img_pitch * (img_height - 1 - img_y);
int canvas_off = gterm_width * y, fb_off = gterm_pitch / 4 * y;
for (size_t y = ystart; y < yend; y++) {
size_t img_y = (y * img_height) / gterm_height; // calculate Y with full precision
size_t off = img_pitch * (img_height - 1 - img_y);
size_t canvas_off = gterm_width * y, fb_off = gterm_pitch / 4 * y;
size_t ratio = int_to_fixedp6(img_width) / gterm_width;
fixedp6 img_x = ratio * xstart;
for (int x = xstart; x < xend; x++) {
for (size_t x = xstart; x < xend; x++) {
uint32_t img_pixel = *(uint32_t*)(img + fixedp6_to_int(img_x) * colsize + off);
uint32_t i = blend(x, y, img_pixel);
bg_canvas[canvas_off + x] = i; gterm_framebuffer[fb_off + x] = i;
@ -177,18 +187,18 @@ __attribute__((always_inline)) static inline void genloop(int xstart, int xend,
break;
}
}
static uint32_t blend_external(int x, int y, uint32_t orig) { (void)x; (void)y; return orig; }
static uint32_t blend_internal(int x, int y, uint32_t orig) { (void)x; (void)y; return colour_blend(default_bg, orig); }
static uint32_t blend_margin(int x, int y, uint32_t orig) { return blend_gradient_from_box(x, y, orig, default_bg); }
static uint32_t blend_external(size_t x, size_t y, uint32_t orig) { (void)x; (void)y; return orig; }
static uint32_t blend_internal(size_t x, size_t y, uint32_t orig) { (void)x; (void)y; return colour_blend(default_bg, orig); }
static uint32_t blend_margin(size_t x, size_t y, uint32_t orig) { return blend_gradient_from_box(x, y, orig, default_bg); }
static void loop_external(int xstart, int xend, int ystart, int yend) { genloop(xstart, xend, ystart, yend, blend_external); }
static void loop_margin(int xstart, int xend, int ystart, int yend) { genloop(xstart, xend, ystart, yend, blend_margin); }
static void loop_internal(int xstart, int xend, int ystart, int yend) { genloop(xstart, xend, ystart, yend, blend_internal); }
static void loop_external(size_t xstart, size_t xend, size_t ystart, size_t yend) { genloop(xstart, xend, ystart, yend, blend_external); }
static void loop_margin(size_t xstart, size_t xend, size_t ystart, size_t yend) { genloop(xstart, xend, ystart, yend, blend_margin); }
static void loop_internal(size_t xstart, size_t xend, size_t ystart, size_t yend) { genloop(xstart, xend, ystart, yend, blend_internal); }
void gterm_generate_canvas(void) {
if (background) {
const int frame_height_end = frame_height + VGA_FONT_HEIGHT * rows, frame_width_end = frame_width + VGA_FONT_WIDTH * cols;
const int fheight = frame_height - margin_gradient, fheight_end = frame_height_end + margin_gradient,
const size_t frame_height_end = frame_height + VGA_FONT_HEIGHT * rows, frame_width_end = frame_width + VGA_FONT_WIDTH * cols;
const size_t fheight = frame_height - margin_gradient, fheight_end = frame_height_end + margin_gradient,
fwidth = frame_width - margin_gradient, fwidth_end = frame_width_end + margin_gradient;
loop_external(0, gterm_width, 0, fheight);
@ -205,8 +215,8 @@ void gterm_generate_canvas(void) {
loop_internal(frame_width, frame_width_end, frame_height, frame_height_end);
} else {
for (int y = 0; y < gterm_height; y++) {
for (int x = 0; x < gterm_width; x++) {
for (size_t y = 0; y < gterm_height; y++) {
for (size_t x = 0; x < gterm_width; x++) {
bg_canvas[y * gterm_width + x] = default_bg;
gterm_plot_px(x, y, default_bg);
}
@ -220,12 +230,12 @@ struct gterm_char {
uint32_t bg;
};
void gterm_plot_char(struct gterm_char *c, int x, int y) {
void gterm_plot_char(struct gterm_char *c, size_t x, size_t y) {
bool *glyph = &vga_font_bool[c->c * VGA_FONT_HEIGHT * VGA_FONT_WIDTH];
for (int i = 0; i < VGA_FONT_HEIGHT; i++) {
for (size_t i = 0; i < VGA_FONT_HEIGHT; i++) {
uint32_t *fb_line = gterm_framebuffer + x + (y + i) * (gterm_pitch / 4);
uint32_t *canvas_line = bg_canvas + x + (y + i) * gterm_width;
for (int j = 0; j < VGA_FONT_WIDTH; j++) {
for (size_t j = 0; j < VGA_FONT_WIDTH; j++) {
uint32_t bg = c->bg == 0xffffffff ? canvas_line[j] : c->bg;
bool draw = glyph[i * VGA_FONT_WIDTH + j];
fb_line[j] = draw ? c->fg : bg;
@ -233,13 +243,13 @@ void gterm_plot_char(struct gterm_char *c, int x, int y) {
}
}
void gterm_plot_char_fast(struct gterm_char *old, struct gterm_char *c, int x, int y) {
void gterm_plot_char_fast(struct gterm_char *old, struct gterm_char *c, size_t x, size_t y) {
bool *new_glyph = &vga_font_bool[c->c * VGA_FONT_HEIGHT * VGA_FONT_WIDTH];
bool *old_glyph = &vga_font_bool[old->c * VGA_FONT_HEIGHT * VGA_FONT_WIDTH];
for (int i = 0; i < VGA_FONT_HEIGHT; i++) {
for (size_t i = 0; i < VGA_FONT_HEIGHT; i++) {
uint32_t *fb_line = gterm_framebuffer + x + (y + i) * (gterm_pitch / 4);
uint32_t *canvas_line = bg_canvas + x + (y + i) * gterm_width;
for (int j = 0; j < VGA_FONT_WIDTH; j++) {
for (size_t j = 0; j < VGA_FONT_WIDTH; j++) {
uint32_t bg = c->bg == 0xffffffff ? canvas_line[j] : c->bg;
bool old_draw = old_glyph[i * VGA_FONT_WIDTH + j];
bool new_draw = new_glyph[i * VGA_FONT_WIDTH + j];
@ -250,11 +260,11 @@ void gterm_plot_char_fast(struct gterm_char *old, struct gterm_char *c, int x, i
}
}
static void plot_char_grid_force(struct gterm_char *c, int x, int y) {
static void plot_char_grid_force(struct gterm_char *c, size_t x, size_t y) {
gterm_plot_char(c, frame_width + x * VGA_FONT_WIDTH, frame_height + y * VGA_FONT_HEIGHT);
}
static void plot_char_grid(struct gterm_char *c, int x, int y) {
static void plot_char_grid(struct gterm_char *c, size_t x, size_t y) {
if (!double_buffer_enabled) {
struct gterm_char *old = &grid[x + y * cols];
@ -302,10 +312,11 @@ void gterm_scroll_enable(void) {
scroll_enabled = true;
}
static void scroll(void) {
void gterm_scroll(void) {
clear_cursor();
for (int i = cols; i < rows * cols; i++) {
for (size_t i = (term_context.scroll_top_margin + 1) * cols;
i < term_context.scroll_bottom_margin * cols; i++) {
if (!compare_char(&grid[i], &grid[i - cols]))
plot_char_grid(&grid[i], (i - cols) % cols, (i - cols) / cols);
}
@ -315,7 +326,8 @@ static void scroll(void) {
empty.c = ' ';
empty.fg = text_fg;
empty.bg = text_bg;
for (int i = rows * cols - cols; i < rows * cols; i++) {
for (size_t i = (term_context.scroll_bottom_margin - 1) * cols;
i < term_context.scroll_bottom_margin * cols; i++) {
if (!compare_char(&grid[i], &empty))
plot_char_grid(&empty, i % cols, i / cols);
}
@ -330,7 +342,7 @@ void gterm_clear(bool move) {
empty.c = ' ';
empty.fg = text_fg;
empty.bg = text_bg;
for (int i = 0; i < rows * cols; i++) {
for (size_t i = 0; i < rows * cols; i++) {
plot_char_grid(&empty, i % cols, i / cols);
}
@ -354,16 +366,12 @@ bool gterm_disable_cursor(void) {
return ret;
}
void gterm_set_cursor_pos(int x, int y) {
void gterm_set_cursor_pos(size_t x, size_t y) {
clear_cursor();
if (x < 0) {
x = 0;
} else if (x >= cols) {
if (x >= cols) {
x = cols - 1;
}
if (y < 0) {
y = 0;
} else if (y >= rows) {
if (y >= rows) {
y = rows - 1;
}
cursor_x = x;
@ -371,12 +379,17 @@ void gterm_set_cursor_pos(int x, int y) {
draw_cursor();
}
void gterm_get_cursor_pos(int *x, int *y) {
void gterm_get_cursor_pos(size_t *x, size_t *y) {
*x = cursor_x;
*y = cursor_y;
}
void gterm_move_character(int new_x, int new_y, int old_x, int old_y) {
void gterm_move_character(size_t new_x, size_t new_y, size_t old_x, size_t old_y) {
if (old_x >= cols || old_y >= rows
|| new_x >= cols || new_y >= rows) {
return;
}
if (!double_buffer_enabled) {
gterm_plot_char(&grid[old_x + old_y * cols],
frame_width + new_x * VGA_FONT_WIDTH,
@ -385,19 +398,19 @@ void gterm_move_character(int new_x, int new_y, int old_x, int old_y) {
grid[new_x + new_y * cols] = grid[old_x + old_y * cols];
}
void gterm_set_text_fg(int fg) {
void gterm_set_text_fg(size_t fg) {
text_fg = ansi_colours[fg];
}
void gterm_set_text_bg(int bg) {
void gterm_set_text_bg(size_t bg) {
text_bg = ansi_colours[bg];
}
void gterm_set_text_fg_bright(int fg) {
void gterm_set_text_fg_bright(size_t fg) {
text_fg = ansi_bright_colours[fg];
}
void gterm_set_text_bg_bright(int bg) {
void gterm_set_text_bg_bright(size_t bg) {
text_bg = ansi_bright_colours[bg];
}
@ -416,8 +429,8 @@ void gterm_double_buffer_flush(void) {
front_grid[i] = grid[i];
int x = i % cols;
int y = i / cols;
size_t x = i % cols;
size_t y = i / cols;
gterm_plot_char(&grid[i], x * VGA_FONT_WIDTH + frame_width,
y * VGA_FONT_HEIGHT + frame_height);
@ -440,54 +453,24 @@ void gterm_double_buffer(bool state) {
}
void gterm_putchar(uint8_t c) {
switch (c) {
case '\b':
if (cursor_x || cursor_y) {
clear_cursor();
if (cursor_x) {
cursor_x--;
} else {
cursor_y--;
cursor_x = cols - 1;
}
draw_cursor();
}
break;
case '\r':
gterm_set_cursor_pos(0, cursor_y);
break;
case '\n':
if (cursor_y == (rows - 1)) {
if (scroll_enabled) {
gterm_set_cursor_pos(0, rows - 1);
scroll();
}
} else {
gterm_set_cursor_pos(0, cursor_y + 1);
}
break;
default: {
clear_cursor();
struct gterm_char ch;
ch.c = c;
ch.fg = text_fg;
ch.bg = text_bg;
plot_char_grid(&ch, cursor_x++, cursor_y);
if (cursor_x == cols && (cursor_y < rows - 1 || scroll_enabled)) {
cursor_x = 0;
cursor_y++;
}
if (cursor_y == rows) {
cursor_y--;
scroll();
}
draw_cursor();
break;
}
clear_cursor();
struct gterm_char ch;
ch.c = c;
ch.fg = text_fg;
ch.bg = text_bg;
plot_char_grid(&ch, cursor_x++, cursor_y);
if (cursor_x == cols && ((size_t)cursor_y < term_context.scroll_bottom_margin - 1 || scroll_enabled)) {
cursor_x = 0;
cursor_y++;
}
if ((size_t)cursor_y == term_context.scroll_bottom_margin) {
cursor_y--;
gterm_scroll();
}
draw_cursor();
}
bool gterm_init(int *_rows, int *_cols, int width, int height) {
bool gterm_init(size_t *_rows, size_t *_cols, size_t width, size_t height) {
if (current_video_mode >= 0
&& fbinfo.default_res == true
&& width == 0
@ -518,7 +501,7 @@ bool gterm_init(int *_rows, int *_cols, int width, int height) {
return false;
// default scheme
int margin = 64;
size_t margin = 64;
margin_gradient = 4;
default_bg = 0x00000000; // background (black)
@ -538,7 +521,7 @@ bool gterm_init(int *_rows, int *_cols, int width, int height) {
colours = config_get_value(NULL, 0, "THEME_COLORS");
if (colours != NULL) {
const char *first = colours;
int i;
size_t i;
for (i = 0; i < 10; i++) {
const char *last;
uint32_t col = strtoui(first, &last, 16);
@ -571,7 +554,7 @@ bool gterm_init(int *_rows, int *_cols, int width, int height) {
bright_colours = config_get_value(NULL, 0, "THEME_BRIGHT_COLORS");
if (bright_colours != NULL) {
const char *first = bright_colours;
int i;
size_t i;
for (i = 0; i < 8; i++) {
const char *last;
uint32_t col = strtoui(first, &last, 16);
@ -672,8 +655,8 @@ bool gterm_init(int *_rows, int *_cols, int width, int height) {
for (size_t i = 0; i < VGA_FONT_GLYPHS; i++) {
uint8_t *glyph = &vga_font_bits[i * VGA_FONT_HEIGHT];
for (int y = 0; y < VGA_FONT_HEIGHT; y++) {
for (int x = 0; x < VGA_FONT_WIDTH; x++) {
for (size_t y = 0; y < VGA_FONT_HEIGHT; y++) {
for (size_t x = 0; x < VGA_FONT_WIDTH; x++) {
size_t offset = i * VGA_FONT_HEIGHT * VGA_FONT_WIDTH + y * VGA_FONT_WIDTH + x;
if ((glyph[y] & (0x80 >> x))) {
vga_font_bool[offset] = true;

View File

@ -8,23 +8,25 @@
extern struct fb_info fbinfo;
bool gterm_init(int *_rows, int *_cols, int width, int height);
bool gterm_init(size_t *_rows, size_t *_cols, size_t width, size_t height);
void gterm_putchar(uint8_t c);
void gterm_clear(bool move);
void gterm_enable_cursor(void);
bool gterm_disable_cursor(void);
void gterm_set_cursor_pos(int x, int y);
void gterm_get_cursor_pos(int *x, int *y);
void gterm_set_text_fg(int fg);
void gterm_set_text_bg(int bg);
void gterm_set_text_fg_bright(int fg);
void gterm_set_text_bg_bright(int bg);
void gterm_set_cursor_pos(size_t x, size_t y);
void gterm_get_cursor_pos(size_t *x, size_t *y);
void gterm_set_text_fg(size_t fg);
void gterm_set_text_bg(size_t bg);
void gterm_set_text_fg_bright(size_t fg);
void gterm_set_text_bg_bright(size_t bg);
void gterm_set_text_fg_default(void);
void gterm_set_text_bg_default(void);
bool gterm_scroll_disable(void);
void gterm_scroll_enable(void);
void gterm_move_character(int new_x, int new_y, int old_x, int old_y);
void gterm_move_character(size_t new_x, size_t new_y, size_t old_x, size_t old_y);
void gterm_scroll(void);
void gterm_swap_palette(void);
void gterm_double_buffer_flush(void);
void gterm_double_buffer(bool state);

View File

@ -6,16 +6,16 @@
struct image {
struct file_handle *file;
int x_size;
int y_size;
size_t x_size;
size_t y_size;
int type;
uint8_t *img;
int bpp;
int pitch;
int img_width; // x_size = scaled size, img_width = bitmap size
int img_height;
int x_displacement;
int y_displacement;
size_t img_width; // x_size = scaled size, img_width = bitmap size
size_t img_height;
size_t x_displacement;
size_t y_displacement;
uint32_t back_colour;
};

View File

@ -55,3 +55,38 @@ __divmoddi4:
mov dword [ecx+4], 0
xor edx, edx
ret
global memcpy32to64
memcpy32to64:
bits 32
push ebp
mov ebp, esp
push esi
push edi
push 0x28
call .p1
.p1:
add dword [esp], .mode64 - .p1
retfd
bits 64
.mode64:
mov rdi, [rbp + 8]
mov rsi, [rbp + 16]
mov rcx, [rbp + 24]
rep movsb
push 0x18
call .p2
.p2:
add qword [rsp], .mode32 - .p2
retfq
bits 32
.mode32:
pop edi
pop esi
pop ebp
ret

View File

@ -184,7 +184,7 @@ void vprint(const char *fmt, va_list args) {
}
out:
term_write(print_buf, print_buf_i);
term_write((uint64_t)(uintptr_t)print_buf, print_buf_i);
for (size_t i = 0; i < print_buf_i; i++) {
if (E9_OUTPUT) {

View File

@ -143,98 +143,3 @@ again:
return ret;
}
#endif
static void reprint_string(int x, int y, const char *s) {
int orig_x, orig_y;
disable_cursor();
get_cursor_pos(&orig_x, &orig_y);
set_cursor_pos(x, y);
term_write(s, strlen(s));
set_cursor_pos(orig_x, orig_y);
enable_cursor();
}
static void cursor_back(void) {
int x, y;
get_cursor_pos(&x, &y);
if (x) {
x--;
} else if (y) {
y--;
x = term_cols - 1;
}
set_cursor_pos(x, y);
}
static void cursor_fwd(void) {
int x, y;
get_cursor_pos(&x, &y);
if (x < term_cols - 1) {
x++;
} else if (y < term_rows - 1) {
y++;
x = 0;
}
set_cursor_pos(x, y);
}
void readline(const char *orig_str, char *buf, size_t limit) {
size_t orig_str_len = strlen(orig_str);
memmove(buf, orig_str, orig_str_len);
buf[orig_str_len] = 0;
int orig_x, orig_y;
get_cursor_pos(&orig_x, &orig_y);
term_write(orig_str, orig_str_len);
for (size_t i = orig_str_len; ; ) {
int c = getchar();
switch (c) {
case GETCHAR_CURSOR_LEFT:
if (i) {
i--;
cursor_back();
}
continue;
case GETCHAR_CURSOR_RIGHT:
if (i < strlen(buf)) {
i++;
cursor_fwd();
}
continue;
case '\b':
if (i) {
i--;
cursor_back();
case GETCHAR_DELETE:;
size_t j;
for (j = i; ; j++) {
buf[j] = buf[j+1];
if (!buf[j]) {
buf[j] = ' ';
break;
}
}
reprint_string(orig_x, orig_y, buf);
buf[j] = 0;
}
continue;
case '\n':
term_write("\n", 1);
return;
default:
if (strlen(buf) < limit - 1) {
for (size_t j = strlen(buf); ; j--) {
buf[j+1] = buf[j];
if (j == i)
break;
}
buf[i] = c;
i++;
cursor_fwd();
reprint_string(orig_x, orig_y, buf);
}
}
}
}

View File

@ -8,7 +8,7 @@
bool early_term = false;
void term_vbe(int width, int height) {
void term_vbe(size_t width, size_t height) {
term_backend = NOT_READY;
if (!gterm_init(&term_rows, &term_cols, width, height)) {
@ -19,6 +19,8 @@ void term_vbe(int width, int height) {
return;
}
term_reinit();
raw_putchar = gterm_putchar;
clear = gterm_clear;
enable_cursor = gterm_enable_cursor;
@ -34,6 +36,8 @@ void term_vbe(int width, int height) {
scroll_disable = gterm_scroll_disable;
scroll_enable = gterm_scroll_enable;
term_move_character = gterm_move_character;
term_scroll = gterm_scroll;
term_swap_palette = gterm_swap_palette;
term_double_buffer = gterm_double_buffer;
term_double_buffer_flush = gterm_double_buffer_flush;

View File

@ -2,35 +2,35 @@
#define __LIB__TERM_H__
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <lib/image.h>
extern void (*raw_putchar)(uint8_t c);
extern void (*clear)(bool move);
extern void (*enable_cursor)(void);
extern bool (*disable_cursor)(void);
extern void (*set_cursor_pos)(int x, int y);
extern void (*get_cursor_pos)(int *x, int *y);
extern void (*set_text_fg)(int fg);
extern void (*set_text_bg)(int bg);
extern void (*set_text_fg_bright)(int fg);
extern void (*set_text_bg_bright)(int bg);
extern void (*set_text_fg_default)(void);
extern void (*set_text_bg_default)(void);
extern bool (*scroll_disable)(void);
extern void (*scroll_enable)(void);
extern void (*term_move_character)(int new_x, int new_y, int old_x, int old_y);
#define TERM_TABSIZE (8)
#define MAX_ESC_VALUES (16)
extern void (*term_double_buffer)(bool status);
extern void (*term_double_buffer_flush)(void);
void term_vbe(int width, int height);
void term_textmode(void);
void term_write(const char *buf, size_t count);
void term_deinit(void);
extern int term_rows, term_cols;
extern struct term_context {
bool control_sequence;
bool csi;
bool escape;
bool rrr;
bool discard_next;
bool bold;
bool reverse_video;
bool dec_private;
bool insert_mode;
uint8_t g_select;
uint8_t charsets[2];
size_t current_charset;
size_t escape_offset;
size_t esc_values_i;
size_t saved_cursor_x;
size_t saved_cursor_y;
size_t current_primary;
size_t scroll_top_margin;
size_t scroll_bottom_margin;
uint32_t esc_values[MAX_ESC_VALUES];
} term_context;
enum {
NOT_READY,
@ -38,9 +38,52 @@ enum {
TEXTMODE
};
extern int term_backend;
extern int current_video_mode;
extern int term_backend;
extern size_t term_rows, term_cols;
extern bool term_runtime;
extern bool early_term;
void term_reinit(void);
void term_deinit(void);
void term_vbe(size_t width, size_t height);
void term_textmode(void);
void term_putchar(uint8_t c);
void term_write(uint64_t buf, uint64_t count);
extern void (*raw_putchar)(uint8_t c);
extern void (*clear)(bool move);
extern void (*enable_cursor)(void);
extern bool (*disable_cursor)(void);
extern void (*set_cursor_pos)(size_t x, size_t y);
extern void (*get_cursor_pos)(size_t *x, size_t *y);
extern void (*set_text_fg)(size_t fg);
extern void (*set_text_bg)(size_t bg);
extern void (*set_text_fg_bright)(size_t fg);
extern void (*set_text_bg_bright)(size_t bg);
extern void (*set_text_fg_default)(void);
extern void (*set_text_bg_default)(void);
extern bool (*scroll_disable)(void);
extern void (*scroll_enable)(void);
extern void (*term_move_character)(size_t new_x, size_t new_y, size_t old_x, size_t old_y);
extern void (*term_scroll)(void);
extern void (*term_swap_palette)(void);
extern void (*term_double_buffer)(bool status);
extern void (*term_double_buffer_flush)(void);
extern uint64_t (*term_context_size)(void);
extern void (*term_context_save)(uint64_t ptr);
extern void (*term_context_restore)(uint64_t ptr);
#define TERM_CB_DEC 10
#define TERM_CB_BELL 20
#define TERM_CB_PRIVATE_ID 30
#define TERM_CTX_SIZE ((uint64_t)(-1))
#define TERM_CTX_SAVE ((uint64_t)(-2))
#define TERM_CTX_RESTORE ((uint64_t)(-3))
extern void (*term_callback)(uint64_t type, uint64_t extra, uint64_t esc_val_count, uint64_t esc_values);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -117,7 +117,7 @@ static int validate_line(const char *buffer) {
if (buffer[0] == '#')
return TOK_COMMENT;
char keybuf[64];
int i;
size_t i;
for (i = 0; buffer[i] && i < 64; i++) {
if (buffer[i] == '=') goto found_equals;
keybuf[i] = buffer[i];
@ -176,7 +176,7 @@ refresh:
clear(true);
disable_cursor();
{
int x, y;
size_t x, y;
print("\n");
get_cursor_pos(&x, &y);
set_cursor_pos(term_cols / 2 - DIV_ROUNDUP(strlen(menu_branding), 2), y);
@ -187,7 +187,7 @@ refresh:
print(" \e[32mESC\e[0m Discard and Exit \e[32mF10\e[0m Boot\n");
print("\n\xda");
for (int i = 0; i < term_cols - 2; i++) {
for (size_t i = 0; i < term_cols - 2; i++) {
switch (i) {
case 1: case 2: case 3:
if (window_offset > 0) {
@ -196,7 +196,7 @@ refresh:
}
// FALLTHRU
default: {
int title_length = strlen(title);
size_t title_length = strlen(title);
if (i == (term_cols / 2) - DIV_ROUNDUP(title_length, 2) - 1) {
print("%s", title);
i += title_length - 1;
@ -208,7 +208,7 @@ refresh:
}
print("\xbf\xb3");
int cursor_x, cursor_y;
size_t cursor_x, cursor_y;
size_t current_line = 0, line_offset = 0, window_size = _window_size;
bool printed_cursor = false;
int token_type = validate_line(buffer);
@ -217,7 +217,7 @@ refresh:
if (buffer[i] == '\n'
&& current_line < window_offset + window_size
&& current_line >= window_offset) {
int x, y;
size_t x, y;
get_cursor_pos(&x, &y);
if (i == cursor_offset) {
cursor_x = x;
@ -305,7 +305,7 @@ refresh:
// syntax error alert
if (validation_enabled) {
int x, y;
size_t x, y;
get_cursor_pos(&x, &y);
set_cursor_pos(0, term_rows-1);
scroll_disable();
@ -319,7 +319,7 @@ refresh:
}
if (current_line - window_offset < window_size) {
int x, y;
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);
@ -330,7 +330,7 @@ refresh:
print("\xb3\xc0");
}
for (int i = 0; i < term_cols - 2; i++) {
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) {
@ -419,10 +419,10 @@ refresh:
goto refresh;
}
static int print_tree(const char *shift, int level, int base_index, int selected_entry,
static size_t print_tree(const char *shift, size_t level, size_t base_index, size_t selected_entry,
struct menu_entry *current_entry,
struct menu_entry **selected_menu_entry) {
int max_entries = 0;
size_t max_entries = 0;
bool no_print = false;
if (shift == NULL) {
@ -434,15 +434,18 @@ static int print_tree(const char *shift, int level, int base_index, int selected
break;
if (!no_print) print("%s", shift);
if (level) {
for (int i = level - 1; i > 0; i--) {
for (size_t i = level - 1; ; i--) {
struct menu_entry *actual_parent = current_entry;
for (int j = 0; j < i; j++)
for (size_t j = 0; j < i; j++)
actual_parent = actual_parent->parent;
if (actual_parent->next != NULL) {
if (!no_print) print(" \xb3");
} else {
if (!no_print) print(" ");
}
if (i == 0) {
break;
}
}
if (current_entry->next == NULL) {
if (!no_print) print(" \xc0");
@ -482,7 +485,7 @@ char *menu(char **cmdline) {
bool skip_timeout = false;
struct menu_entry *selected_menu_entry = NULL;
int selected_entry = 0;
size_t selected_entry = 0;
char *default_entry = config_get_value(NULL, 0, "DEFAULT_ENTRY");
if (default_entry != NULL) {
selected_entry = strtoui(default_entry, NULL, 10);
@ -490,7 +493,7 @@ char *menu(char **cmdline) {
selected_entry--;
}
int timeout = 5;
size_t timeout = 5;
char *timeout_config = config_get_value(NULL, 0, "TIMEOUT");
if (timeout_config != NULL) {
if (!strcmp(timeout_config, "no"))
@ -522,7 +525,7 @@ char *menu(char **cmdline) {
char *graphics = "yes";
#endif
if (graphics != NULL && !strcmp(graphics, "yes")) {
int req_width = 0, req_height = 0, req_bpp = 0;
size_t req_width = 0, req_height = 0, req_bpp = 0;
char *menu_resolution = config_get_value(NULL, 0, "MENU_RESOLUTION");
if (menu_resolution != NULL)
@ -538,7 +541,7 @@ char *menu(char **cmdline) {
refresh:
clear(true);
{
int x, y;
size_t x, y;
print("\n");
get_cursor_pos(&x, &y);
set_cursor_pos(term_cols / 2 - DIV_ROUNDUP(strlen(menu_branding), 2), y);
@ -563,16 +566,16 @@ refresh:
}
{ // Draw box around boot menu
int x, y;
size_t x, y;
get_cursor_pos(&x, &y);
print("\xda");
for (int i = 0; i < term_cols - 2; i++) {
for (size_t i = 0; i < term_cols - 2; i++) {
print("\xc4");
}
print("\xbf");
for (int i = y + 1; i < term_rows - 2; i++) {
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);
@ -580,7 +583,7 @@ refresh:
}
print("\xc0");
for (int i = 0; i < term_cols - 2; i++) {
for (size_t i = 0; i < term_cols - 2; i++) {
print("\xc4");
}
print("\xd9");
@ -588,11 +591,11 @@ refresh:
set_cursor_pos(x, y + 2);
}
int max_entries = print_tree("\xb3 ", 0, 0, selected_entry, menu_tree,
size_t max_entries = print_tree("\xb3 ", 0, 0, selected_entry, menu_tree,
&selected_menu_entry);
{
int x, y;
size_t x, y;
get_cursor_pos(&x, &y);
set_cursor_pos(0, 3);
if (editor_enabled && selected_menu_entry->sub == NULL) {
@ -611,7 +614,7 @@ refresh:
if (skip_timeout == false) {
print("\n\n");
for (int i = timeout; i; i--) {
for (size_t i = timeout; i; i--) {
set_cursor_pos(0, term_rows - 1);
scroll_disable();
print("\e[32mBooting automatically in \e[92m%u\e[32m, press any key to stop the countdown...\e[0m", i);
@ -641,8 +644,10 @@ refresh:
timeout_aborted:
switch (c) {
case GETCHAR_CURSOR_UP:
if (--selected_entry == -1)
if (selected_entry == 0)
selected_entry = max_entries - 1;
else
selected_entry--;
goto refresh;
case GETCHAR_CURSOR_DOWN:
if (++selected_entry == max_entries)

View File

@ -97,7 +97,7 @@ void chainload(char *config) {
drive = val;
}
int rows, cols;
size_t rows, cols;
init_vga_textmode(&rows, &cols, false);
struct volume *p = volume_get_by_coord(false, drive, part);
@ -131,7 +131,7 @@ void chainload(char *config) {
term_deinit();
int req_width = 0, req_height = 0, req_bpp = 0;
size_t req_width = 0, req_height = 0, req_bpp = 0;
char *resolution = config_get_value(config, 0, "RESOLUTION");
if (resolution != NULL)

View File

@ -488,7 +488,7 @@ void linux_load(char *config, char *cmdline) {
struct screen_info *screen_info = &boot_params->screen_info;
int req_width = 0, req_height = 0, req_bpp = 0;
size_t req_width = 0, req_height = 0, req_bpp = 0;
char *resolution = config_get_value(config, 0, "RESOLUTION");
if (resolution != NULL)

View File

@ -180,9 +180,9 @@ void multiboot1_load(char *config, char *cmdline) {
term_deinit();
if (header.flags & (1 << 2)) {
int req_width = header.fb_width;
int req_height = header.fb_height;
int req_bpp = header.fb_bpp;
size_t req_width = header.fb_width;
size_t req_height = header.fb_height;
size_t req_bpp = header.fb_bpp;
if (header.fb_mode == 0) {
char *resolution = config_get_value(config, 0, "RESOLUTION");
@ -209,7 +209,7 @@ void multiboot1_load(char *config, char *cmdline) {
#if uefi == 1
panic("multiboot1: Cannot use text mode with UEFI.");
#elif bios == 1
int rows, cols;
size_t rows, cols;
init_vga_textmode(&rows, &cols, false);
multiboot1_info.fb_addr = 0xB8000;
@ -228,7 +228,7 @@ void multiboot1_load(char *config, char *cmdline) {
#if uefi == 1
panic("multiboot1: Cannot use text mode with UEFI.");
#elif bios == 1
int rows, cols;
size_t rows, cols;
init_vga_textmode(&rows, &cols, false);
#endif
}

View File

@ -249,9 +249,9 @@ void stivale_load(char *config, char *cmdline) {
term_deinit();
if (stivale_hdr.flags & (1 << 0)) {
int req_width = stivale_hdr.framebuffer_width;
int req_height = stivale_hdr.framebuffer_height;
int req_bpp = stivale_hdr.framebuffer_bpp;
size_t req_width = stivale_hdr.framebuffer_width;
size_t req_height = stivale_hdr.framebuffer_height;
size_t req_bpp = stivale_hdr.framebuffer_bpp;
char *resolution = config_get_value(config, 0, "RESOLUTION");
if (resolution != NULL)
@ -281,7 +281,7 @@ void stivale_load(char *config, char *cmdline) {
#if uefi == 1
panic("stivale: Cannot use text mode with UEFI.");
#elif bios == 1
int rows, cols;
size_t rows, cols;
init_vga_textmode(&rows, &cols, false);
#endif
}

View File

@ -57,7 +57,8 @@ static void *get_tag(struct stivale2_header *s, uint64_t id) {
#if defined (__i386__)
extern symbol stivale2_term_write_entry;
void *stivale2_rt_stack = NULL;
void *stivale2_term_buf = NULL;
uint64_t stivale2_term_callback_ptr = 0;
void stivale2_term_callback(uint64_t, uint64_t, uint64_t, uint64_t);
#endif
void stivale2_load(char *config, char *cmdline, bool pxe, void *efi_system_table) {
@ -381,7 +382,7 @@ failed_to_load_header_section:
struct stivale2_header_tag_framebuffer *hdrtag = get_tag(&stivale2_hdr, STIVALE2_HEADER_TAG_FRAMEBUFFER_ID);
int req_width = 0, req_height = 0, req_bpp = 0;
size_t req_width = 0, req_height = 0, req_bpp = 0;
if (hdrtag != NULL) {
req_width = hdrtag->framebuffer_width;
@ -393,20 +394,42 @@ failed_to_load_header_section:
parse_resolution(&req_width, &req_height, &req_bpp, resolution);
}
char *textmode_str = config_get_value(config, 0, "TEXTMODE");
bool textmode = textmode_str != NULL && strcmp(textmode_str, "yes") == 0;
struct stivale2_header_tag_terminal *terminal_hdr_tag = get_tag(&stivale2_hdr, STIVALE2_HEADER_TAG_TERMINAL_ID);
if (bits == 64 && terminal_hdr_tag != NULL && hdrtag != NULL) {
term_vbe(req_width, req_height);
if (bits == 64 && terminal_hdr_tag != NULL && (hdrtag != NULL || textmode)) {
if (textmode) {
#if bios == 1
term_textmode();
#elif uefi == 1
panic("stivale2: Text mode not supported on UEFI");
#endif
} else {
term_vbe(req_width, req_height);
if (current_video_mode < 0) {
panic("stivale2: Failed to initialise terminal");
if (current_video_mode < 0) {
panic("stivale2: Failed to initialise terminal");
}
fb = &fbinfo;
}
fb = &fbinfo;
struct stivale2_struct_tag_terminal *tag = ext_mem_alloc(sizeof(struct stivale2_struct_tag_terminal));
tag->tag.identifier = STIVALE2_STRUCT_TAG_TERMINAL_ID;
if (terminal_hdr_tag->flags & (1 << 0)) {
// We provide callback
tag->flags |= (1 << 2);
#if defined (__i386__)
term_callback = stivale2_term_callback;
stivale2_term_callback_ptr = terminal_hdr_tag->callback;
#elif defined (__x86_64__)
term_callback = (void *)terminal_hdr_tag->callback;
#endif
}
// We provide max allowed string length
tag->flags |= (1 << 1);
@ -415,15 +438,13 @@ failed_to_load_header_section:
stivale2_rt_stack = ext_mem_alloc(8192);
}
stivale2_term_buf = ext_mem_alloc(8192);
tag->term_write = (uintptr_t)(void *)stivale2_term_write_entry;
tag->max_length = 8192;
#elif defined (__x86_64__)
tag->term_write = (uintptr_t)term_write;
tag->max_length = 0;
#endif
tag->max_length = 0;
// We provide rows and cols
tag->flags |= (1 << 0);
tag->cols = term_cols;
@ -431,7 +452,13 @@ failed_to_load_header_section:
append_tag(&stivale2_struct, (struct stivale2_tag *)tag);
goto skip_modeset;
if (textmode) {
#if bios == 1
goto have_tm_tag;
#endif
} else {
goto have_fb_tag;
}
} else {
fb = &_fb;
}
@ -441,7 +468,7 @@ failed_to_load_header_section:
term_deinit();
if (fb_init(fb, req_width, req_height, req_bpp)) {
skip_modeset:;
have_fb_tag:;
struct stivale2_struct_tag_framebuffer *tag = ext_mem_alloc(sizeof(struct stivale2_struct_tag_framebuffer));
tag->tag.identifier = STIVALE2_STRUCT_TAG_FRAMEBUFFER_ID;
@ -468,9 +495,10 @@ skip_modeset:;
#if uefi == 1
panic("stivale2: Cannot use text mode with UEFI.");
#elif bios == 1
int rows, cols;
size_t rows, cols;
init_vga_textmode(&rows, &cols, false);
have_tm_tag:;
struct stivale2_struct_tag_textmode *tmtag = ext_mem_alloc(sizeof(struct stivale2_struct_tag_textmode));
tmtag->tag.identifier = STIVALE2_STRUCT_TAG_TEXTMODE_ID;
@ -628,7 +656,9 @@ skip_modeset:;
}
// Clear terminal for kernels that will use the stivale2 terminal
term_write("\e[2J\e[H", 7);
term_write((uint64_t)(uintptr_t)("\e[2J\e[H"), 7);
term_runtime = true;
stivale_spinup(bits, want_5lv, &pagemap, entry_point,
REPORTED_ADDR((uint64_t)(uintptr_t)&stivale2_struct),

View File

@ -8,17 +8,64 @@ user_ds: resq 1
user_es: resq 1
user_ss: resq 1
%define MAX_TERM_BUF 8192
section .text
extern term_write
extern stivale2_term_buf
extern stivale2_rt_stack
extern stivale2_term_callback_ptr
global stivale2_term_callback
stivale2_term_callback:
bits 32
push ebp
mov ebp, esp
push ebx
push esi
push edi
; Go 64
push 0x28
push .mode64
retfd
bits 64
.mode64:
mov eax, 0x30
mov ds, ax
mov es, ax
mov ss, ax
mov rdi, [rbp + 8]
mov rsi, [rbp + 16]
mov rdx, [rbp + 24]
mov rcx, [rbp + 32]
mov rbx, rsp
mov rsp, [user_stack]
call [stivale2_term_callback_ptr]
mov rsp, rbx
; Go 32
push 0x18
push .mode32
retfq
bits 32
.mode32:
mov eax, 0x20
mov ds, ax
mov es, ax
mov ss, ax
pop edi
pop esi
pop ebx
pop ebp
ret
global stivale2_term_write_entry
stivale2_term_write_entry:
bits 64
push rbx
push rbp
push r12
@ -35,14 +82,7 @@ stivale2_term_write_entry:
mov word [user_ss], ss
push rsi
mov rcx, rsi
mov rax, MAX_TERM_BUF
cmp rcx, rax
cmovg rcx, rax
mov rsi, rdi
mov edi, [stivale2_term_buf]
rep movsb
pop rsi
push rdi
push 0x18
push .mode32
@ -53,10 +93,10 @@ bits 32
mov ds, ax
mov es, ax
mov ss, ax
push esi
push dword [stivale2_term_buf]
call term_write
add esp, 8
add esp, 16
push dword [user_cs]
push .mode64
retfd

View File

@ -10,13 +10,69 @@ user_ds: resq 1
user_es: resq 1
user_ss: resq 1
%define MAX_TERM_BUF 8192
section .text
extern term_write
extern stivale2_term_buf
extern stivale2_rt_stack
extern stivale2_term_callback_ptr
global stivale2_term_callback
stivale2_term_callback:
bits 32
push ebp
mov ebp, esp
push ebx
push esi
push edi
; Go 64
push 0x28
call .p1
.p1:
add dword [esp], .mode64 - .p1
retfd
bits 64
.mode64:
mov eax, 0x30
mov ds, ax
mov es, ax
mov ss, ax
mov rdi, [rbp + 8]
mov rsi, [rbp + 16]
mov rdx, [rbp + 24]
mov rcx, [rbp + 32]
call .get_got
.get_got:
pop rax
add rax, _GLOBAL_OFFSET_TABLE_ + $$ - .get_got wrt ..gotpc
mov rbx, rsp
mov rsp, [rax + user_stack wrt ..gotoff]
call [rax + stivale2_term_callback_ptr wrt ..gotoff]
mov rsp, rbx
; Go 32
push 0x18
call .p2
.p2:
add qword [rsp], .mode32 - .p2
retfq
bits 32
.mode32:
mov eax, 0x20
mov ds, ax
mov es, ax
mov ss, ax
pop edi
pop esi
pop ebx
pop ebp
ret
bits 64
global stivale2_term_write_entry
@ -42,21 +98,12 @@ stivale2_term_write_entry:
mov word [rbx + user_ss wrt ..gotoff], ss
push rsi
mov rcx, rsi
mov rax, MAX_TERM_BUF
cmp rcx, rax
cmovg rcx, rax
mov rsi, rdi
mov edi, [rbx + stivale2_term_buf wrt ..gotoff]
rep movsb
pop rsi
push rdi
push 0x18
call .p1
.p1:
pop rax
add rax, 8
push rax
add qword [rsp], .mode32 - .p1
retfq
bits 32
.mode32:
@ -64,16 +111,14 @@ bits 32
mov ds, ax
mov es, ax
mov ss, ax
push esi
push dword [ebx + stivale2_term_buf wrt ..gotoff]
call term_write
add esp, 8
add esp, 16
push dword [ebx + user_cs wrt ..gotoff]
call .p2
.p2:
pop eax
add eax, 6
push eax
add dword [esp], .mode64 - .p2
retfd
bits 64
.mode64: