mirror of
https://github.com/limine-bootloader/limine
synced 2025-03-18 07:22:53 +03:00
term: Mass backport changes done in Vinix upstream
This commit is contained in:
parent
993a602afb
commit
c7a46830f6
@ -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 \
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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) ({ \
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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),
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
Loading…
x
Reference in New Issue
Block a user