aboutsummaryrefslogtreecommitdiffstats
path: root/com32/lib/sys/vesa
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2009-08-05 11:57:12 -0700
committerH. Peter Anvin <hpa@zytor.com>2009-08-05 11:57:12 -0700
commitca49c72894c52d770bd7c2669337b32fe83c6c2e (patch)
tree67106a08f94851b900ddb993058b42207a5028ce /com32/lib/sys/vesa
parentd97602903c76f7f65b78d8536e8b6732a2da877e (diff)
downloadsyslinux-ca49c72894c52d770bd7c2669337b32fe83c6c2e.tar.gz
syslinux-ca49c72894c52d770bd7c2669337b32fe83c6c2e.tar.xz
syslinux-ca49c72894c52d770bd7c2669337b32fe83c6c2e.zip
vesacon: infrastructure support for arbitrary resolutions
Drop the hard-coding of 640x480 resolution in preparation for being able to handle other resolutions. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'com32/lib/sys/vesa')
-rw-r--r--com32/lib/sys/vesa/background.c59
-rw-r--r--com32/lib/sys/vesa/drawtxt.c48
-rw-r--r--com32/lib/sys/vesa/initvesa.c47
-rw-r--r--com32/lib/sys/vesa/video.h23
4 files changed, 102 insertions, 75 deletions
diff --git a/com32/lib/sys/vesa/background.c b/com32/lib/sys/vesa/background.c
index 815f984c..60ff1f2b 100644
--- a/com32/lib/sys/vesa/background.c
+++ b/com32/lib/sys/vesa/background.c
@@ -44,9 +44,9 @@
aligned dwords. */
static void draw_background_line(int line, int start, int npixels)
{
- uint32_t *bgptr = &__vesacon_background[line][start];
+ uint32_t *bgptr = &__vesacon_background[line*__vesa_info.mi.h_res+start];
unsigned int bytes_per_pixel = __vesacon_bytes_per_pixel;
- size_t fbptr = line * __vesa_info.mi.logical_scan + start * bytes_per_pixel;
+ size_t fbptr = line * __vesa_info.mi.logical_scan + start*bytes_per_pixel;
__vesacon_copy_to_screen(fbptr, bgptr, npixels);
}
@@ -60,15 +60,17 @@ static void draw_background(void)
const int right_border = VIDEO_BORDER + (TEXT_PIXEL_COLS % FONT_WIDTH);
for (i = 0; i < VIDEO_BORDER; i++)
- draw_background_line(i, 0, VIDEO_X_SIZE);
+ draw_background_line(i, 0, __vesa_info.mi.h_res);
- for (i = VIDEO_BORDER; i < VIDEO_Y_SIZE - bottom_border; i++) {
+ for (i = VIDEO_BORDER; i < __vesa_info.mi.v_res - bottom_border; i++) {
draw_background_line(i, 0, VIDEO_BORDER);
- draw_background_line(i, VIDEO_X_SIZE - right_border, right_border);
+ draw_background_line(i, __vesa_info.mi.h_res - right_border,
+ right_border);
}
- for (i = VIDEO_Y_SIZE - bottom_border; i < VIDEO_Y_SIZE; i++)
- draw_background_line(i, 0, VIDEO_X_SIZE);
+ for (i = __vesa_info.mi.v_res - bottom_border;
+ i < __vesa_info.mi.v_res; i++)
+ draw_background_line(i, 0, __vesa_info.mi.h_res);
__vesacon_redraw_text();
}
@@ -82,7 +84,7 @@ static int read_png_file(FILE * fp)
png_color_16p image_background;
static const png_color_16 my_background = { 0, 0, 0, 0, 0 };
#endif
- png_bytep row_pointers[VIDEO_Y_SIZE];
+ png_bytep row_pointers[__vesa_info.mi.v_res], rp;
int passes;
int i;
int rv = -1;
@@ -98,7 +100,7 @@ static int read_png_file(FILE * fp)
png_init_io(png_ptr, fp);
png_set_sig_bytes(png_ptr, 8);
- png_set_user_limits(png_ptr, VIDEO_X_SIZE, VIDEO_Y_SIZE);
+ png_set_user_limits(png_ptr, __vesa_info.mi.h_res, __vesa_info.mi.v_res);
png_read_info(png_ptr, info_ptr);
@@ -138,8 +140,11 @@ static int read_png_file(FILE * fp)
#endif
/* Whew! Now we should get the stuff we want... */
- for (i = 0; i < (int)info_ptr->height; i++)
- row_pointers[i] = (void *)__vesacon_background[i];
+ rp = (png_bytep)__vesacon_background;
+ for (i = 0; i < (int)info_ptr->height; i++) {
+ row_pointers[i] = rp;
+ rp += __vesa_info.mi.h_res << 2;
+ }
passes = png_set_interlace_handling(png_ptr);
@@ -157,7 +162,9 @@ err:
static int jpeg_sig_cmp(uint8_t * bytes, int len)
{
(void)len;
- return (bytes[0] == 0xff && bytes[1] == 0xd8) ? 0 : -1;
+
+ /* FF D8 = start of image, FF E0 = JFIF header */
+ return memcmp(bytes, "\xff\xd8\xff\xe0", 4) ? -1 : 0;
}
static int read_jpeg_file(FILE * fp, uint8_t * header, int len)
@@ -183,12 +190,12 @@ static int read_jpeg_file(FILE * fp, uint8_t * header, int len)
goto err;
tinyjpeg_get_size(jdec, &width, &height);
- if (width > VIDEO_X_SIZE || height > VIDEO_Y_SIZE)
+ if (width > __vesa_info.mi.h_res || height > __vesa_info.mi.v_res)
goto err;
- components[0] = (void *)&__vesacon_background[0];
+ components[0] = (void *)__vesacon_background;
tinyjpeg_set_components(jdec, components, 1);
- bytes_per_row[0] = VIDEO_X_SIZE << 2;
+ bytes_per_row[0] = __vesa_info.mi.h_res << 2;
tinyjpeg_set_bytes_per_row(jdec, bytes_per_row, 1);
tinyjpeg_decode(jdec, TINYJPEG_FMT_BGRA32);
@@ -217,9 +224,11 @@ int vesacon_default_background(void)
if (__vesacon_pixel_format == PXF_NONE)
return 0; /* Not in graphics mode */
- for (y = 0, dy = -VIDEO_Y_SIZE / 2; y < VIDEO_Y_SIZE; y++, dy++) {
+ for (y = 0, dy = -__vesa_info.mi.v_res / 2;
+ y < __vesa_info.mi.v_res; y++, dy++) {
dy2 = dy * dy;
- for (x = 0, dx = -VIDEO_X_SIZE / 2; x < VIDEO_X_SIZE; x++, dx++) {
+ for (x = 0, dx = -__vesa_info.mi.h_res / 2;
+ x < __vesa_info.mi.h_res; x++, dx++) {
k = __vesacon_linear_to_srgb[500 + ((dx * dx + dy2) >> 6)];
bgptr[0] = k; /* Blue */
bgptr[1] = k; /* Green */
@@ -236,7 +245,7 @@ int vesacon_default_background(void)
int vesacon_set_background(unsigned int rgb)
{
void *bgptr = __vesacon_background;
- unsigned int count = VIDEO_X_SIZE * VIDEO_Y_SIZE;
+ unsigned int count = __vesa_info.mi.h_res * __vesa_info.mi.v_res;
if (__vesacon_pixel_format == PXF_NONE)
return 0; /* Not in graphics mode */
@@ -265,7 +274,8 @@ static inline int lss16_sig_cmp(const void *header, int len)
return 1;
return !(h->magic == LSS16_MAGIC &&
- h->xsize <= VIDEO_X_SIZE && h->ysize <= VIDEO_Y_SIZE);
+ h->xsize <= __vesa_info.mi.h_res &&
+ h->ysize <= __vesa_info.mi.v_res);
}
static int read_lss16_file(FILE * fp, const void *header, int header_len)
@@ -283,7 +293,7 @@ static int read_lss16_file(FILE * fp, const void *header, int header_len)
st_c2,
} state;
int i, x, y;
- uint32_t *bgptr = (void *)__vesacon_background;
+ uint32_t *bgptr = __vesacon_background;
/* Assume the header, 8 bytes, has already been loaded. */
if (header_len != 8)
@@ -295,7 +305,8 @@ static int read_lss16_file(FILE * fp, const void *header, int header_len)
return -1;
colors[i] = (((rgb[0] & 63) * 255 / 63) << 16) +
- (((rgb[1] & 63) * 255 / 63) << 8) + ((rgb[2] & 63) * 255 / 63);
+ (((rgb[1] & 63) * 255 / 63) << 8) +
+ ((rgb[2] & 63) * 255 / 63);
}
/* By spec, the state machine is per row */
@@ -356,12 +367,12 @@ do_run:
}
/* Zero-fill rest of row */
- i = VIDEO_X_SIZE - x;
+ i = __vesa_info.mi.h_res - x;
asm volatile ("rep; stosl":"+D" (bgptr), "+c"(i):"a"(0):"memory");
}
/* Zero-fill rest of screen */
- i = (VIDEO_Y_SIZE - y) * VIDEO_X_SIZE;
+ i = (__vesa_info.mi.v_res - y) * __vesa_info.mi.h_res;
asm volatile ("rep; stosl":"+D" (bgptr), "+c"(i):"a"(0):"memory");
return 0;
@@ -404,7 +415,7 @@ err:
int __vesacon_init_background(void)
{
- /* The BSS clearing has already cleared __vesacon_background */
+ /* __vesacon_background was cleared by calloc() */
/* The VESA BIOS has already cleared the screen */
return 0;
diff --git a/com32/lib/sys/vesa/drawtxt.c b/com32/lib/sys/vesa/drawtxt.c
index 4b46d678..92d89018 100644
--- a/com32/lib/sys/vesa/drawtxt.c
+++ b/com32/lib/sys/vesa/drawtxt.c
@@ -27,6 +27,7 @@
#include <inttypes.h>
#include <colortbl.h>
+#include <string.h>
#include "vesa.h"
#include "video.h"
#include "fill.h"
@@ -81,25 +82,20 @@ static void vesacon_update_characters(int row, int col, int nrows, int ncols)
struct vesa_char *rowptr, *rowsptr, *cptr, *csptr;
unsigned int bytes_per_pixel = __vesacon_bytes_per_pixel;
unsigned long pixel_offset;
- uint32_t row_buffer[VIDEO_X_SIZE], *rowbufptr;
+ uint32_t row_buffer[__vesa_info.mi.h_res], *rowbufptr;
size_t fbrowptr;
uint8_t sha;
- bgrowptr =
- &__vesacon_background[row * height + VIDEO_BORDER][col * width +
- VIDEO_BORDER];
-
- pixel_offset = ((row * height + VIDEO_BORDER) * VIDEO_X_SIZE) +
+ pixel_offset = ((row * height + VIDEO_BORDER) * __vesa_info.mi.h_res) +
(col * width + VIDEO_BORDER);
+ bgrowptr = &__vesacon_background[pixel_offset];
fbrowptr = (row * height + VIDEO_BORDER) * __vesa_info.mi.logical_scan +
(col * width + VIDEO_BORDER) * bytes_per_pixel;
/* Note that we keep a 1-character guard area around the real text area... */
- rowptr =
- &__vesacon_text_display[(row + 1) * (TEXT_PIXEL_COLS / FONT_WIDTH + 2) +
- (col + 1)];
- rowsptr = rowptr - ((TEXT_PIXEL_COLS / FONT_WIDTH + 2) + 1);
+ rowptr = &__vesacon_text_display[(row+1)*(__vesacon_text_cols+2)+(col+1)];
+ rowsptr = rowptr - ((__vesacon_text_cols+2)+1);
pixrow = 0;
pixsrow = height - 1;
@@ -159,7 +155,8 @@ static void vesacon_update_characters(int row, int col, int nrows, int ncols)
}
/* If this pixel is raised, use the offsetted value */
- bgval = (chxbits & 0x80) ? bgptr[VIDEO_X_SIZE + 1] : *bgptr;
+ bgval = (chxbits & 0x80)
+ ? bgptr[__vesa_info.mi.h_res + 1] : *bgptr;
bgptr++;
/* If this pixel is set, use the fg color, else the bg color */
@@ -180,15 +177,15 @@ static void vesacon_update_characters(int row, int col, int nrows, int ncols)
/* Copy to frame buffer */
__vesacon_copy_to_screen(fbrowptr, row_buffer, rowbufptr - row_buffer);
- bgrowptr += VIDEO_X_SIZE;
+ bgrowptr += __vesa_info.mi.h_res;
fbrowptr += __vesa_info.mi.logical_scan;
if (++pixrow == height) {
- rowptr += TEXT_PIXEL_COLS / FONT_WIDTH + 2;
+ rowptr += __vesacon_text_cols + 2;
pixrow = 0;
}
if (++pixsrow == height) {
- rowsptr += TEXT_PIXEL_COLS / FONT_WIDTH + 2;
+ rowsptr += __vesacon_text_cols + 2;
pixsrow = 0;
}
}
@@ -232,7 +229,7 @@ void __vesacon_erase(int x0, int y0, int x1, int y1, attr_t attr)
{
int y;
struct vesa_char *ptr = &__vesacon_text_display
- [(y0 + 1) * (TEXT_PIXEL_COLS / FONT_WIDTH + 2) + (x0 + 1)];
+ [(y0 + 1) * (__vesacon_text_cols + 2) + (x0 + 1)];
struct vesa_char fill = {
.ch = ' ',
.attr = attr,
@@ -241,7 +238,7 @@ void __vesacon_erase(int x0, int y0, int x1, int y1, attr_t attr)
for (y = y0; y <= y1; y++) {
vesacon_fill(ptr, fill, ncols);
- ptr += TEXT_PIXEL_COLS / FONT_WIDTH + 2;
+ ptr += __vesacon_text_cols + 2;
}
vesacon_touch(y0, x0, y1 - y0 + 1, ncols);
@@ -251,11 +248,11 @@ void __vesacon_erase(int x0, int y0, int x1, int y1, attr_t attr)
void __vesacon_scroll_up(int nrows, attr_t attr)
{
struct vesa_char *fromptr = &__vesacon_text_display
- [(nrows + 1) * (TEXT_PIXEL_COLS / FONT_WIDTH + 2)];
+ [(nrows + 1) * (__vesacon_text_cols + 2)];
struct vesa_char *toptr = &__vesacon_text_display
- [(TEXT_PIXEL_COLS / FONT_WIDTH + 2)];
+ [(__vesacon_text_cols + 2)];
int dword_count =
- (__vesacon_text_rows - nrows) * (TEXT_PIXEL_COLS / FONT_WIDTH + 2);
+ (__vesacon_text_rows - nrows) * (__vesacon_text_cols + 2);
struct vesa_char fill = {
.ch = ' ',
.attr = attr,
@@ -263,18 +260,18 @@ void __vesacon_scroll_up(int nrows, attr_t attr)
toptr = copy_dword(toptr, fromptr, dword_count);
- dword_count = nrows * (TEXT_PIXEL_COLS / FONT_WIDTH + 2);
+ dword_count = nrows * (__vesacon_text_cols + 2);
vesacon_fill(toptr, fill, dword_count);
- vesacon_touch(0, 0, __vesacon_text_rows, TEXT_PIXEL_COLS / FONT_WIDTH);
+ vesacon_touch(0, 0, __vesacon_text_rows, __vesacon_text_cols);
}
/* Draw one character text at a specific area of the screen */
void __vesacon_write_char(int x, int y, uint8_t ch, attr_t attr)
{
struct vesa_char *ptr = &__vesacon_text_display
- [(y + 1) * (TEXT_PIXEL_COLS / FONT_WIDTH + 2) + (x + 1)];
+ [(y + 1) * (__vesacon_text_cols + 2) + (x + 1)];
ptr->ch = ch;
ptr->attr = attr;
@@ -285,7 +282,7 @@ void __vesacon_write_char(int x, int y, uint8_t ch, attr_t attr)
void __vesacon_set_cursor(int x, int y, int visible)
{
struct vesa_char *ptr = &__vesacon_text_display
- [(y + 1) * (TEXT_PIXEL_COLS / FONT_WIDTH + 2) + (x + 1)];
+ [(y + 1) * (__vesacon_text_cols + 2) + (x + 1)];
if (cursor_pointer)
vesacon_touch(cursor_y, cursor_x, 1, 1);
@@ -309,13 +306,12 @@ void __vesacon_init_cursor(int font_height)
if (r0 < 0)
r0 = 0;
- /* cursor_pattern is assumed to be all zero */
+ memset(cursor_pattern, 0, font_height);
cursor_pattern[r0] = 0xff;
cursor_pattern[r0 + 1] = 0xff;
}
void __vesacon_redraw_text(void)
{
- vesacon_update_characters(0, 0, __vesacon_text_rows,
- TEXT_PIXEL_COLS / FONT_WIDTH);
+ vesacon_update_characters(0, 0, __vesacon_text_rows, __vesacon_text_cols);
}
diff --git a/com32/lib/sys/vesa/initvesa.c b/com32/lib/sys/vesa/initvesa.c
index 9254683b..0221fcf7 100644
--- a/com32/lib/sys/vesa/initvesa.c
+++ b/com32/lib/sys/vesa/initvesa.c
@@ -46,12 +46,14 @@ struct vesa_info __vesa_info;
struct vesa_char *__vesacon_text_display;
-int __vesacon_font_height, __vesacon_text_rows;
+int __vesacon_font_height;
+int __vesacon_text_rows;
+int __vesacon_text_cols;
enum vesa_pixel_format __vesacon_pixel_format = PXF_NONE;
unsigned int __vesacon_bytes_per_pixel;
uint8_t __vesacon_graphics_font[FONT_MAX_CHARS][FONT_MAX_HEIGHT];
-uint32_t __vesacon_background[VIDEO_Y_SIZE][VIDEO_X_SIZE];
+uint32_t *__vesacon_background, *__vesacon_shadowfb;
static void unpack_font(uint8_t * dst, uint8_t * src, int height)
{
@@ -87,7 +89,7 @@ static int vesacon_paged_mode_ok(const struct vesa_mode_info *mi)
return 0; /* Nope... */
}
-static int vesacon_set_mode(void)
+static int vesacon_set_mode(int x, int y)
{
com32sys_t rm;
uint8_t *rom_font;
@@ -96,6 +98,16 @@ static int vesacon_set_mode(void)
struct vesa_mode_info *mi;
enum vesa_pixel_format pxf, bestpxf;
+ /* Free any existing data structures */
+ if (__vesacon_background) {
+ free(__vesacon_background);
+ __vesacon_background = NULL;
+ }
+ if (__vesacon_shadowfb) {
+ free(__vesacon_shadowfb);
+ __vesacon_shadowfb = NULL;
+ }
+
/* Allocate space in the bounce buffer for these structures */
gi = &((struct vesa_info *)__com32.cs_bounce)->gi;
mi = &((struct vesa_info *)__com32.cs_bounce)->mi;
@@ -121,7 +133,7 @@ static int vesacon_set_mode(void)
/* Copy general info */
memcpy(&__vesa_info.gi, gi, sizeof *gi);
- /* Search for a 640x480 mode with a suitable color and memory model... */
+ /* Search for the proper mode with a suitable color and memory model... */
mode_ptr = GET_PTR(gi->video_mode_ptr);
bestmode = 0;
@@ -159,8 +171,8 @@ static int vesacon_set_mode(void)
if ((mi->mode_attr & 0x001b) != 0x001b)
continue;
- /* Must be 640x480 */
- if (mi->h_res != VIDEO_X_SIZE || mi->v_res != VIDEO_Y_SIZE)
+ /* Must be the chosen size */
+ if (mi->h_res != x || mi->v_res != y)
continue;
/* We don't support multibank (interlaced memory) modes */
@@ -242,9 +254,6 @@ static int vesacon_set_mode(void)
}
unpack_font((uint8_t *) __vesacon_graphics_font, rom_font,
__vesacon_font_height);
- __vesacon_text_rows =
- (VIDEO_Y_SIZE - 2 * VIDEO_BORDER) / __vesacon_font_height;
- __vesacon_init_cursor(__vesacon_font_height);
/* Now set video mode */
rm.eax.w[0] = 0x4F02; /* Set SVGA video mode */
@@ -255,6 +264,9 @@ static int vesacon_set_mode(void)
if (rm.eax.w[0] != 0x004F)
return 9; /* Failed to set mode */
+ __vesacon_background = calloc(mi->h_res*mi->v_res, 4);
+ __vesacon_shadowfb = calloc(mi->h_res*mi->v_res, 4);
+
__vesacon_init_copy_to_screen();
/* Tell syslinux we changed video mode */
@@ -266,8 +278,8 @@ static int vesacon_set_mode(void)
However, that would assume all systems that claim to handle text
output in VESA modes actually do that... */
rm.ebx.w[0] = 0x000f;
- rm.ecx.w[0] = VIDEO_X_SIZE;
- rm.edx.w[0] = VIDEO_Y_SIZE;
+ rm.ecx.w[0] = mi->h_res;
+ rm.edx.w[0] = mi->v_res;
__intcall(0x22, &rm, NULL);
__vesacon_pixel_format = bestpxf;
@@ -284,8 +296,12 @@ static int init_text_display(void)
.attr = 0,
};
- nchars = (TEXT_PIXEL_ROWS / __vesacon_font_height + 2) *
- (TEXT_PIXEL_COLS / FONT_WIDTH + 2);
+ if (__vesacon_text_display)
+ free(__vesacon_text_display);
+
+ __vesacon_text_cols = TEXT_PIXEL_COLS / FONT_WIDTH;
+ __vesacon_text_rows = TEXT_PIXEL_ROWS / __vesacon_font_height;
+ nchars = (__vesacon_text_cols+2) * (__vesacon_text_rows+2);
__vesacon_text_display = ptr = malloc(nchars * sizeof(struct vesa_char));
@@ -293,11 +309,12 @@ static int init_text_display(void)
return -1;
vesacon_fill(ptr, def_char, nchars);
+ __vesacon_init_cursor(__vesacon_font_height);
return 0;
}
-int __vesacon_init(void)
+int __vesacon_init(int x, int y)
{
int rv;
@@ -305,7 +322,7 @@ int __vesacon_init(void)
if (x86_init_fpu())
return 10;
- rv = vesacon_set_mode();
+ rv = vesacon_set_mode(x, y);
if (rv)
return rv;
diff --git a/com32/lib/sys/vesa/video.h b/com32/lib/sys/vesa/video.h
index b02b5ae7..0bd1abff 100644
--- a/com32/lib/sys/vesa/video.h
+++ b/com32/lib/sys/vesa/video.h
@@ -29,17 +29,18 @@
#define LIB_SYS_VESA_VIDEO_H
#include <colortbl.h>
+#include "vesa.h"
#define FONT_MAX_CHARS 256
#define FONT_MAX_HEIGHT 32
#define FONT_WIDTH 8
-#define VIDEO_X_SIZE 640
-#define VIDEO_Y_SIZE 480
+#define DEFAULT_VESA_X_SIZE 640
+#define DEFAULT_VESA_Y_SIZE 480
#define VIDEO_BORDER 8
-#define TEXT_PIXEL_ROWS (VIDEO_Y_SIZE-2*VIDEO_BORDER)
-#define TEXT_PIXEL_COLS (VIDEO_X_SIZE-2*VIDEO_BORDER)
+#define TEXT_PIXEL_ROWS (__vesa_info.mi.v_res - 2*VIDEO_BORDER)
+#define TEXT_PIXEL_COLS (__vesa_info.mi.h_res - 2*VIDEO_BORDER)
typedef uint16_t attr_t;
@@ -60,24 +61,26 @@ enum vesa_pixel_format {
};
extern enum vesa_pixel_format __vesacon_pixel_format;
extern unsigned int __vesacon_bytes_per_pixel;
-typedef const void *(*__vesacon_format_pixels_t) (void *, const uint32_t *,
- size_t);
+typedef const void *(*__vesacon_format_pixels_t)
+ (void *, const uint32_t *, size_t);
extern __vesacon_format_pixels_t __vesacon_format_pixels;
extern const __vesacon_format_pixels_t __vesacon_format_pixels_list[PXF_NONE];
extern struct vesa_char *__vesacon_text_display;
-extern int __vesacon_font_height, __vesacon_text_rows;
+extern int __vesacon_font_height;
+extern int __vesacon_text_rows;
+extern int __vesacon_text_cols;
extern uint8_t __vesacon_graphics_font[FONT_MAX_CHARS][FONT_MAX_HEIGHT];
-extern uint32_t __vesacon_background[VIDEO_Y_SIZE][VIDEO_X_SIZE];
-extern uint32_t __vesacon_shadowfb[VIDEO_Y_SIZE][VIDEO_X_SIZE];
+extern uint32_t *__vesacon_background;
+extern uint32_t *__vesacon_shadowfb;
extern const uint16_t __vesacon_srgb_to_linear[256];
extern const uint8_t __vesacon_linear_to_srgb[4080];
int __vesacon_init_background(void);
int vesacon_load_background(const char *);
-int __vesacon_init(void);
+int __vesacon_init(int, int);
void __vesacon_init_cursor(int);
void __vesacon_erase(int, int, int, int, attr_t);
void __vesacon_scroll_up(int, attr_t);