diff options
Diffstat (limited to 'com32/lib/sys/vesa/initvesa.c')
-rw-r--r-- | com32/lib/sys/vesa/initvesa.c | 47 |
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; |