aboutsummaryrefslogtreecommitdiffstats
path: root/com32/lib/sys/vesa/initvesa.c
diff options
context:
space:
mode:
Diffstat (limited to 'com32/lib/sys/vesa/initvesa.c')
-rw-r--r--com32/lib/sys/vesa/initvesa.c47
1 files changed, 32 insertions, 15 deletions
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;