summaryrefslogtreecommitdiffstats
path: root/contrib/syslinux/latest/com32/lib/sys/vesa
diff options
context:
space:
mode:
authorJonathan Bauer2011-04-15 19:27:42 +0200
committerJonathan Bauer2011-04-15 19:27:42 +0200
commit1d7eb8c79b17fc9b2f9e93c215d574c8a6563441 (patch)
tree6bf557bcfef5371cfacbd88c54f4f15a90ac1ffc /contrib/syslinux/latest/com32/lib/sys/vesa
parentfix? (diff)
downloadusb-boot-stick-1d7eb8c79b17fc9b2f9e93c215d574c8a6563441.tar.gz
usb-boot-stick-1d7eb8c79b17fc9b2f9e93c215d574c8a6563441.tar.xz
usb-boot-stick-1d7eb8c79b17fc9b2f9e93c215d574c8a6563441.zip
fix :)
Diffstat (limited to 'contrib/syslinux/latest/com32/lib/sys/vesa')
-rw-r--r--contrib/syslinux/latest/com32/lib/sys/vesa/alphatbl.pl53
-rw-r--r--contrib/syslinux/latest/com32/lib/sys/vesa/background.c456
-rw-r--r--contrib/syslinux/latest/com32/lib/sys/vesa/debug.h36
-rw-r--r--contrib/syslinux/latest/com32/lib/sys/vesa/drawtxt.c317
-rw-r--r--contrib/syslinux/latest/com32/lib/sys/vesa/fill.h63
-rw-r--r--contrib/syslinux/latest/com32/lib/sys/vesa/fmtpixel.c101
-rw-r--r--contrib/syslinux/latest/com32/lib/sys/vesa/i915resolution.c795
-rw-r--r--contrib/syslinux/latest/com32/lib/sys/vesa/initvesa.c357
-rw-r--r--contrib/syslinux/latest/com32/lib/sys/vesa/screencpy.c117
-rw-r--r--contrib/syslinux/latest/com32/lib/sys/vesa/vesa.h114
-rw-r--r--contrib/syslinux/latest/com32/lib/sys/vesa/video.h97
11 files changed, 2506 insertions, 0 deletions
diff --git a/contrib/syslinux/latest/com32/lib/sys/vesa/alphatbl.pl b/contrib/syslinux/latest/com32/lib/sys/vesa/alphatbl.pl
new file mode 100644
index 0000000..d70c76e
--- /dev/null
+++ b/contrib/syslinux/latest/com32/lib/sys/vesa/alphatbl.pl
@@ -0,0 +1,53 @@
+#!/usr/bin/perl
+#
+# Produce gamma-correction tables for alpha blending, assuming sRGB space.
+#
+
+sub srgb_to_linear($)
+{
+ my($s) = @_;
+
+ if ($s <= 10) {
+ return $s/(255*12.92);
+ } else {
+ return (($s+14.025)/269.025)**2.4;
+ }
+}
+
+sub linear_to_srgb($)
+{
+ my($l) = @_;
+ my $s;
+
+ if ($l <= 0.00304) {
+ $s = 12.92*$l;
+ } else {
+ $s = 1.055*$l**(1.0/2.4) - 0.055;
+ }
+
+ return int($s*255+0.5);
+}
+
+# Header
+print "#include <inttypes.h>\n\n";
+
+#
+# Table 1: convert 8-bit sRGB values to 16-bit linear values
+#
+
+print "const uint16_t __vesacon_srgb_to_linear[256] = {\n";
+for ($i = 0; $i <= 255; $i++) {
+ printf "\t%5d,\n", int(srgb_to_linear($i)*65535+0.5);
+}
+print "};\n\n";
+
+#
+# Table 2: convert linear values in the range [0, 65535*255],
+# shifted right by 12 bits, to sRGB
+#
+
+print "const uint8_t __vesacon_linear_to_srgb[4080] = {\n";
+for ($i = 0; $i <= 4079; $i++) {
+ printf "\t%3d,\n", linear_to_srgb(($i+0.5)/4079.937744);
+}
+print "};\n\n";
diff --git a/contrib/syslinux/latest/com32/lib/sys/vesa/background.c b/contrib/syslinux/latest/com32/lib/sys/vesa/background.c
new file mode 100644
index 0000000..9357746
--- /dev/null
+++ b/contrib/syslinux/latest/com32/lib/sys/vesa/background.c
@@ -0,0 +1,456 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2006-2008 H. Peter Anvin - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <stdio.h>
+#include <png.h>
+#include <tinyjpeg.h>
+#include <com32.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <minmax.h>
+#include <stdbool.h>
+#include <ilog2.h>
+#include <syslinux/loadfile.h>
+#include "vesa.h"
+#include "video.h"
+
+/*** FIX: This really should be alpha-blended with color index 0 ***/
+
+/* For best performance, "start" should be a multiple of 4, to assure
+ aligned dwords. */
+static void draw_background_line(int line, int start, int npixels)
+{
+ 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;
+
+ __vesacon_copy_to_screen(fbptr, bgptr, npixels);
+}
+
+/* This draws the border, then redraws the text area */
+static void draw_background(void)
+{
+ int i;
+ const int bottom_border = VIDEO_BORDER +
+ (TEXT_PIXEL_ROWS % __vesacon_font_height);
+ const int right_border = VIDEO_BORDER + (TEXT_PIXEL_COLS % FONT_WIDTH);
+
+ for (i = 0; i < VIDEO_BORDER; i++)
+ draw_background_line(i, 0, __vesa_info.mi.h_res);
+
+ for (i = VIDEO_BORDER; i < __vesa_info.mi.v_res - bottom_border; i++) {
+ draw_background_line(i, 0, VIDEO_BORDER);
+ draw_background_line(i, __vesa_info.mi.h_res - right_border,
+ right_border);
+ }
+
+ 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();
+}
+
+/*
+ * Tile an image in the UL corner across the entire screen
+ */
+static void tile_image(int width, int height)
+{
+ int xsize = __vesa_info.mi.h_res;
+ int ysize = __vesa_info.mi.v_res;
+ int x, y, yr;
+ int xl, yl;
+ uint32_t *sp, *dp, *drp, *dtp;
+
+ drp = __vesacon_background;
+ for (y = 0 ; y < ysize ; y += height) {
+ yl = min(height, ysize-y);
+ dtp = drp;
+ for (x = 0 ; x < xsize ; x += width) {
+ xl = min(width, xsize-x);
+ if (x || y) {
+ sp = __vesacon_background;
+ dp = dtp;
+ for (yr = 0 ; yr < yl ; yr++) {
+ memcpy(dp, sp, xl*sizeof(uint32_t));
+ dp += xsize;
+ sp += xsize;
+ }
+ }
+ dtp += xl;
+ }
+ drp += xsize*height;
+ }
+}
+
+static int read_png_file(FILE * fp)
+{
+ png_structp png_ptr = NULL;
+ png_infop info_ptr = NULL;
+#if 0
+ png_color_16p image_background;
+ static const png_color_16 my_background = { 0, 0, 0, 0, 0 };
+#endif
+ png_bytep row_pointers[__vesa_info.mi.v_res], rp;
+ int i;
+ int rv = -1;
+
+ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ info_ptr = png_create_info_struct(png_ptr);
+
+ if (!png_ptr || !info_ptr || setjmp(png_jmpbuf(png_ptr)))
+ goto err;
+
+ png_init_io(png_ptr, fp);
+ png_set_sig_bytes(png_ptr, 8);
+
+ png_set_user_limits(png_ptr, __vesa_info.mi.h_res, __vesa_info.mi.v_res);
+
+ png_read_info(png_ptr, info_ptr);
+
+ /* Set the appropriate set of transformations. We need to end up
+ with 32-bit BGRA format, no more, no less. */
+
+ /* Expand to RGB first... */
+ if (info_ptr->color_type & PNG_COLOR_MASK_PALETTE)
+ png_set_palette_to_rgb(png_ptr);
+ else if (!(info_ptr->color_type & PNG_COLOR_MASK_COLOR))
+ png_set_gray_to_rgb(png_ptr);
+
+ /* Add alpha channel, if need be */
+ if (!(png_ptr->color_type & PNG_COLOR_MASK_ALPHA)) {
+ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
+ png_set_tRNS_to_alpha(png_ptr);
+ else
+ png_set_add_alpha(png_ptr, ~0, PNG_FILLER_AFTER);
+ }
+
+ /* Adjust the byte order, if necessary */
+ png_set_bgr(png_ptr);
+
+ /* Make sure we end up with 8-bit data */
+ if (info_ptr->bit_depth == 16)
+ png_set_strip_16(png_ptr);
+ else if (info_ptr->bit_depth < 8)
+ png_set_packing(png_ptr);
+
+#if 0
+ if (png_get_bKGD(png_ptr, info_ptr, &image_background))
+ png_set_background(png_ptr, image_background,
+ PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
+ else
+ png_set_background(png_ptr, &my_background,
+ PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
+#endif
+
+ /* Whew! Now we should get the stuff we want... */
+ 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;
+ }
+
+ png_read_image(png_ptr, row_pointers);
+
+ tile_image(info_ptr->width, info_ptr->height);
+
+ rv = 0;
+
+err:
+ if (png_ptr)
+ png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
+ return rv;
+}
+
+static int jpeg_sig_cmp(uint8_t * bytes, int len)
+{
+ (void)len;
+
+ return (bytes[0] == 0xff && bytes[1] == 0xd8) ? 0 : -1;
+}
+
+static int read_jpeg_file(FILE * fp, uint8_t * header, int len)
+{
+ struct jdec_private *jdec = NULL;
+ void *jpeg_file = NULL;
+ size_t length_of_file;
+ unsigned int width, height;
+ int rv = -1;
+ unsigned char *components[1];
+ unsigned int bytes_per_row[1];
+
+ rv = floadfile(fp, &jpeg_file, &length_of_file, header, len);
+ fclose(fp);
+ if (rv)
+ goto err;
+
+ jdec = tinyjpeg_init();
+ if (!jdec)
+ goto err;
+
+ if (tinyjpeg_parse_header(jdec, jpeg_file, length_of_file) < 0)
+ goto err;
+
+ tinyjpeg_get_size(jdec, &width, &height);
+ if (width > __vesa_info.mi.h_res || height > __vesa_info.mi.v_res)
+ goto err;
+
+ components[0] = (void *)__vesacon_background;
+ tinyjpeg_set_components(jdec, components, 1);
+ 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);
+ tile_image(width, height);
+
+ rv = 0;
+
+err:
+ /* Don't use tinyjpeg_free() here, since we didn't allow tinyjpeg
+ to allocate the frame buffer */
+ if (jdec)
+ free(jdec);
+
+ if (jpeg_file)
+ free(jpeg_file);
+
+ return rv;
+}
+
+/* Simple grey Gaussian hole, enough to look interesting */
+int vesacon_default_background(void)
+{
+ int x, y, dx, dy, dy2;
+ int z;
+ unsigned int shft;
+ uint8_t *bgptr = (uint8_t *)__vesacon_background;
+ uint8_t k;
+
+ if (__vesacon_pixel_format == PXF_NONE)
+ return 0; /* Not in graphics mode */
+
+ z = max(__vesa_info.mi.v_res, __vesa_info.mi.h_res) >> 1;
+ z = ((z*z) >> 11) - 1;
+ shft = ilog2(z) + 1;
+
+ for (y = 0, dy = -(__vesa_info.mi.v_res >> 1);
+ y < __vesa_info.mi.v_res; y++, dy++) {
+ dy2 = dy * dy;
+ for (x = 0, dx = -(__vesa_info.mi.h_res >> 1);
+ x < __vesa_info.mi.h_res; x++, dx++) {
+ k = __vesacon_linear_to_srgb[500 + ((dx*dx + dy2) >> shft)];
+ bgptr[0] = k; /* Blue */
+ bgptr[1] = k; /* Green */
+ bgptr[2] = k; /* Red */
+ bgptr += 4; /* Dummy alpha */
+ }
+ }
+
+ draw_background();
+ return 0;
+}
+
+/* Set the background to a single flat color */
+int vesacon_set_background(unsigned int rgb)
+{
+ void *bgptr = __vesacon_background;
+ 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 */
+
+ asm volatile ("rep; stosl":"+D" (bgptr), "+c"(count)
+ :"a"(rgb)
+ :"memory");
+
+ draw_background();
+ return 0;
+}
+
+struct lss16_header {
+ uint32_t magic;
+ uint16_t xsize;
+ uint16_t ysize;
+};
+
+#define LSS16_MAGIC 0x1413f33d
+
+static inline int lss16_sig_cmp(const void *header, int len)
+{
+ const struct lss16_header *h = header;
+
+ if (len != 8)
+ return 1;
+
+ return !(h->magic == LSS16_MAGIC &&
+ 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)
+{
+ const struct lss16_header *h = header;
+ uint32_t colors[16], color;
+ bool has_nybble;
+ uint8_t byte;
+ int count;
+ int nybble, prev;
+ enum state {
+ st_start,
+ st_c0,
+ st_c1,
+ st_c2,
+ } state;
+ int i, x, y;
+ uint32_t *bgptr = __vesacon_background;
+
+ /* Assume the header, 8 bytes, has already been loaded. */
+ if (header_len != 8)
+ return -1;
+
+ for (i = 0; i < 16; i++) {
+ uint8_t rgb[3];
+ if (fread(rgb, 1, 3, fp) != 3)
+ return -1;
+
+ colors[i] = (((rgb[0] & 63) * 255 / 63) << 16) +
+ (((rgb[1] & 63) * 255 / 63) << 8) +
+ ((rgb[2] & 63) * 255 / 63);
+ }
+
+ /* By spec, the state machine is per row */
+ for (y = 0; y < h->ysize; y++) {
+ state = st_start;
+ has_nybble = false;
+ color = colors[prev = 0]; /* By specification */
+ count = 0;
+
+ x = 0;
+ while (x < h->xsize) {
+ if (!has_nybble) {
+ if (fread(&byte, 1, 1, fp) != 1)
+ return -1;
+ nybble = byte & 0xf;
+ has_nybble = true;
+ } else {
+ nybble = byte >> 4;
+ has_nybble = false;
+ }
+
+ switch (state) {
+ case st_start:
+ if (nybble != prev) {
+ *bgptr++ = color = colors[prev = nybble];
+ x++;
+ } else {
+ state = st_c0;
+ }
+ break;
+
+ case st_c0:
+ if (nybble == 0) {
+ state = st_c1;
+ } else {
+ count = nybble;
+ goto do_run;
+ }
+ break;
+
+ case st_c1:
+ count = nybble + 16;
+ state = st_c2;
+ break;
+
+ case st_c2:
+ count += nybble << 4;
+ goto do_run;
+
+do_run:
+ count = min(count, h->xsize - x);
+ x += count;
+ asm volatile ("rep; stosl":"+D" (bgptr),
+ "+c"(count):"a"(color));
+ state = st_start;
+ break;
+ }
+ }
+
+ /* Zero-fill rest of row */
+ i = __vesa_info.mi.h_res - x;
+ asm volatile ("rep; stosl":"+D" (bgptr), "+c"(i):"a"(0):"memory");
+ }
+
+ /* Zero-fill rest of screen */
+ 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;
+}
+
+int vesacon_load_background(const char *filename)
+{
+ FILE *fp = NULL;
+ uint8_t header[8];
+ int rv = 1;
+
+ if (__vesacon_pixel_format == PXF_NONE)
+ return 0; /* Not in graphics mode */
+
+ fp = fopen(filename, "r");
+
+ if (!fp)
+ goto err;
+
+ if (fread(header, 1, 8, fp) != 8)
+ goto err;
+
+ if (!png_sig_cmp(header, 0, 8)) {
+ rv = read_png_file(fp);
+ } else if (!jpeg_sig_cmp(header, 8)) {
+ rv = read_jpeg_file(fp, header, 8);
+ } else if (!lss16_sig_cmp(header, 8)) {
+ rv = read_lss16_file(fp, header, 8);
+ }
+
+ /* This actually displays the stuff */
+ draw_background();
+
+err:
+ if (fp)
+ fclose(fp);
+
+ return rv;
+}
+
+int __vesacon_init_background(void)
+{
+ /* __vesacon_background was cleared by calloc() */
+
+ /* The VESA BIOS has already cleared the screen */
+ return 0;
+}
diff --git a/contrib/syslinux/latest/com32/lib/sys/vesa/debug.h b/contrib/syslinux/latest/com32/lib/sys/vesa/debug.h
new file mode 100644
index 0000000..86d085f
--- /dev/null
+++ b/contrib/syslinux/latest/com32/lib/sys/vesa/debug.h
@@ -0,0 +1,36 @@
+#ifndef LIB_SYS_VESA_DEBUG_H
+#define LIB_SYS_VESA_DEBUG_H
+
+#if 0
+
+#include <stdio.h>
+#include <unistd.h>
+
+ssize_t __serial_write(void *fp, const void *buf, size_t count);
+
+static void debug(const char *str, ...)
+{
+ va_list va;
+ char buf[65536];
+ size_t len;
+
+ va_start(va, str);
+ len = vsnprintf(buf, sizeof buf, str, va);
+ va_end(va);
+
+ if (len >= sizeof buf)
+ len = sizeof buf - 1;
+
+ __serial_write(NULL, buf, len);
+}
+
+#else
+
+static inline void debug(const char *str, ...)
+{
+ (void)str;
+}
+
+#endif
+
+#endif /* LIB_SYS_VESA_DEBUG_H */
diff --git a/contrib/syslinux/latest/com32/lib/sys/vesa/drawtxt.c b/contrib/syslinux/latest/com32/lib/sys/vesa/drawtxt.c
new file mode 100644
index 0000000..85a9e97
--- /dev/null
+++ b/contrib/syslinux/latest/com32/lib/sys/vesa/drawtxt.c
@@ -0,0 +1,317 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2006-2008 H. Peter Anvin - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <inttypes.h>
+#include <colortbl.h>
+#include <string.h>
+#include "vesa.h"
+#include "video.h"
+#include "fill.h"
+
+/*
+ * Visible cursor information
+ */
+static uint8_t cursor_pattern[FONT_MAX_HEIGHT];
+static struct vesa_char *cursor_pointer = NULL;
+static int cursor_x, cursor_y;
+
+static inline void *copy_dword(void *dst, void *src, size_t dword_count)
+{
+ asm volatile ("rep; movsl":"+D" (dst), "+S"(src), "+c"(dword_count));
+ return dst; /* Updated destination pointer */
+}
+
+static inline __attribute__ ((always_inline))
+uint8_t alpha_val(uint8_t fg, uint8_t bg, uint8_t alpha)
+{
+ unsigned int tmp;
+
+ tmp = __vesacon_srgb_to_linear[fg] * alpha;
+ tmp += __vesacon_srgb_to_linear[bg] * (255 - alpha);
+
+ return __vesacon_linear_to_srgb[tmp >> 12];
+}
+
+static uint32_t alpha_pixel(uint32_t fg, uint32_t bg)
+{
+ uint8_t alpha = fg >> 24;
+ uint8_t fg_r = fg >> 16;
+ uint8_t fg_g = fg >> 8;
+ uint8_t fg_b = fg;
+ uint8_t bg_r = bg >> 16;
+ uint8_t bg_g = bg >> 8;
+ uint8_t bg_b = bg;
+
+ return
+ (alpha_val(fg_r, bg_r, alpha) << 16) |
+ (alpha_val(fg_g, bg_g, alpha) << 8) | (alpha_val(fg_b, bg_b, alpha));
+}
+
+static void vesacon_update_characters(int row, int col, int nrows, int ncols)
+{
+ const int height = __vesacon_font_height;
+ const int width = FONT_WIDTH;
+ uint32_t *bgrowptr, *bgptr, bgval, fgval;
+ uint32_t fgcolor = 0, bgcolor = 0, color;
+ uint8_t chbits = 0, chxbits = 0, chsbits = 0;
+ int i, j, jx, pixrow, pixsrow;
+ struct vesa_char *rowptr, *rowsptr, *cptr, *csptr;
+ unsigned int bytes_per_pixel = __vesacon_bytes_per_pixel;
+ unsigned long pixel_offset;
+ uint32_t row_buffer[__vesa_info.mi.h_res], *rowbufptr;
+ size_t fbrowptr;
+ uint8_t sha;
+
+ 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)*(__vesacon_text_cols+2)+(col+1)];
+ rowsptr = rowptr - ((__vesacon_text_cols+2)+1);
+ pixrow = 0;
+ pixsrow = height - 1;
+
+ for (i = height * nrows; i >= 0; i--) {
+ bgptr = bgrowptr;
+ rowbufptr = row_buffer;
+
+ cptr = rowptr;
+ csptr = rowsptr;
+
+ chsbits = __vesacon_graphics_font[csptr->ch][pixsrow];
+ if (__unlikely(csptr == cursor_pointer))
+ chsbits |= cursor_pattern[pixsrow];
+ sha = console_color_table[csptr->attr].shadow;
+ chsbits &= (sha & 0x02) ? 0xff : 0x00;
+ chsbits ^= (sha & 0x01) ? 0xff : 0x00;
+ chsbits <<= (width - 2);
+ csptr++;
+
+ /* Draw two pixels beyond the end of the line. One for the shadow,
+ and one to make sure we have a whole dword of data for the copy
+ operation at the end. Note that this code depends on the fact that
+ all characters begin on dword boundaries in the frame buffer. */
+
+ for (jx = 1, j = width * ncols + 1; j >= 0; j--) {
+ chbits <<= 1;
+ chsbits <<= 1;
+ chxbits <<= 1;
+
+ switch (jx) {
+ case 1:
+ chbits = __vesacon_graphics_font[cptr->ch][pixrow];
+ if (__unlikely(cptr == cursor_pointer))
+ chbits |= cursor_pattern[pixrow];
+ sha = console_color_table[cptr->attr].shadow;
+ chxbits = chbits;
+ chxbits &= (sha & 0x02) ? 0xff : 0x00;
+ chxbits ^= (sha & 0x01) ? 0xff : 0x00;
+ fgcolor = console_color_table[cptr->attr].argb_fg;
+ bgcolor = console_color_table[cptr->attr].argb_bg;
+ cptr++;
+ jx--;
+ break;
+ case 0:
+ chsbits = __vesacon_graphics_font[csptr->ch][pixsrow];
+ if (__unlikely(csptr == cursor_pointer))
+ chsbits |= cursor_pattern[pixsrow];
+ sha = console_color_table[csptr->attr].shadow;
+ chsbits &= (sha & 0x02) ? 0xff : 0x00;
+ chsbits ^= (sha & 0x01) ? 0xff : 0x00;
+ csptr++;
+ jx = width - 1;
+ break;
+ default:
+ jx--;
+ break;
+ }
+
+ /* If this pixel is raised, use the offsetted value */
+ 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 */
+ fgval = (chbits & 0x80) ? fgcolor : bgcolor;
+
+ /* Produce the combined color pixel value */
+ color = alpha_pixel(fgval, bgval);
+
+ /* Apply the shadow (75% shadow) */
+ if ((chsbits & ~chxbits) & 0x80) {
+ color >>= 2;
+ color &= 0x3f3f3f;
+ }
+
+ *rowbufptr++ = color;
+ }
+
+ /* Copy to frame buffer */
+ __vesacon_copy_to_screen(fbrowptr, row_buffer, rowbufptr - row_buffer);
+
+ bgrowptr += __vesa_info.mi.h_res;
+ fbrowptr += __vesa_info.mi.logical_scan;
+
+ if (++pixrow == height) {
+ rowptr += __vesacon_text_cols + 2;
+ pixrow = 0;
+ }
+ if (++pixsrow == height) {
+ rowsptr += __vesacon_text_cols + 2;
+ pixsrow = 0;
+ }
+ }
+}
+
+/* Bounding box for changed text. The (x1, y1) coordinates are +1! */
+static unsigned int upd_x0 = -1U, upd_x1, upd_y0 = -1U, upd_y1;
+
+/* Update the range already touched by various variables */
+void __vesacon_doit(void)
+{
+ if (upd_x1 > upd_x0 && upd_y1 > upd_y0) {
+ vesacon_update_characters(upd_y0, upd_x0, upd_y1 - upd_y0,
+ upd_x1 - upd_x0);
+ upd_x0 = upd_y0 = -1U;
+ upd_x1 = upd_y1 = 0;
+ }
+}
+
+/* Mark a range for update; note argument sequence is the same as
+ vesacon_update_characters() */
+static inline void vesacon_touch(int row, int col, int rows, int cols)
+{
+ unsigned int y0 = row;
+ unsigned int x0 = col;
+ unsigned int y1 = y0 + rows;
+ unsigned int x1 = x0 + cols;
+
+ if (y0 < upd_y0)
+ upd_y0 = y0;
+ if (y1 > upd_y1)
+ upd_y1 = y1;
+ if (x0 < upd_x0)
+ upd_x0 = x0;
+ if (x1 > upd_x1)
+ upd_x1 = x1;
+}
+
+/* Erase a region of the screen */
+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) * (__vesacon_text_cols + 2) + (x0 + 1)];
+ struct vesa_char fill = {
+ .ch = ' ',
+ .attr = attr,
+ };
+ int ncols = x1 - x0 + 1;
+
+ for (y = y0; y <= y1; y++) {
+ vesacon_fill(ptr, fill, ncols);
+ ptr += __vesacon_text_cols + 2;
+ }
+
+ vesacon_touch(y0, x0, y1 - y0 + 1, ncols);
+}
+
+/* Scroll the screen up */
+void __vesacon_scroll_up(int nrows, attr_t attr)
+{
+ struct vesa_char *fromptr = &__vesacon_text_display
+ [(nrows + 1) * (__vesacon_text_cols + 2)];
+ struct vesa_char *toptr = &__vesacon_text_display
+ [(__vesacon_text_cols + 2)];
+ int dword_count =
+ (__vesacon_text_rows - nrows) * (__vesacon_text_cols + 2);
+ struct vesa_char fill = {
+ .ch = ' ',
+ .attr = attr,
+ };
+
+ toptr = copy_dword(toptr, fromptr, dword_count);
+
+ dword_count = nrows * (__vesacon_text_cols + 2);
+
+ vesacon_fill(toptr, fill, dword_count);
+
+ 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) * (__vesacon_text_cols + 2) + (x + 1)];
+
+ ptr->ch = ch;
+ ptr->attr = attr;
+
+ vesacon_touch(y, x, 1, 1);
+}
+
+void __vesacon_set_cursor(int x, int y, bool visible)
+{
+ struct vesa_char *ptr = &__vesacon_text_display
+ [(y + 1) * (__vesacon_text_cols + 2) + (x + 1)];
+
+ if (cursor_pointer)
+ vesacon_touch(cursor_y, cursor_x, 1, 1);
+
+ if (!visible) {
+ /* Invisible cursor */
+ cursor_pointer = NULL;
+ } else {
+ cursor_pointer = ptr;
+ vesacon_touch(y, x, 1, 1);
+ }
+
+ cursor_x = x;
+ cursor_y = y;
+}
+
+void __vesacon_init_cursor(int font_height)
+{
+ int r0 = font_height - (font_height < 10 ? 2 : 3);
+
+ if (r0 < 0)
+ r0 = 0;
+
+ 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, __vesacon_text_cols);
+}
diff --git a/contrib/syslinux/latest/com32/lib/sys/vesa/fill.h b/contrib/syslinux/latest/com32/lib/sys/vesa/fill.h
new file mode 100644
index 0000000..5a43c72
--- /dev/null
+++ b/contrib/syslinux/latest/com32/lib/sys/vesa/fill.h
@@ -0,0 +1,63 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2006-2008 H. Peter Anvin - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef LIB_SYS_VESA_FILL_H
+#define LIB_SYS_VESA_FILL_H
+
+#include "video.h"
+
+/* Fill a number of characters. */
+static inline struct vesa_char *vesacon_fill(struct vesa_char *ptr,
+ struct vesa_char fill,
+ unsigned int count)
+{
+ switch (sizeof(struct vesa_char)) {
+ case 1:
+ asm volatile ("rep; stosb":"+D" (ptr), "+c"(count)
+ :"a"(fill)
+ :"memory");
+ break;
+ case 2:
+ asm volatile ("rep; stosw":"+D" (ptr), "+c"(count)
+ :"a"(fill)
+ :"memory");
+ break;
+ case 4:
+ asm volatile ("rep; stosl":"+D" (ptr), "+c"(count)
+ :"a"(fill)
+ :"memory");
+ break;
+ default:
+ while (count--)
+ *ptr++ = fill;
+ break;
+ }
+
+ return ptr;
+}
+
+#endif /* LIB_SYS_VESA_FILL_H */
diff --git a/contrib/syslinux/latest/com32/lib/sys/vesa/fmtpixel.c b/contrib/syslinux/latest/com32/lib/sys/vesa/fmtpixel.c
new file mode 100644
index 0000000..381fc21
--- /dev/null
+++ b/contrib/syslinux/latest/com32/lib/sys/vesa/fmtpixel.c
@@ -0,0 +1,101 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2006-2008 H. Peter Anvin - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * fmtpixel.c
+ *
+ * Functions to format a single pixel
+ */
+
+#include <inttypes.h>
+#include "video.h"
+
+/*
+ * Format a sequence of pixels. The first argument is the line buffer;
+ * we can use it to write up to 4 bytes past the end of the last pixel.
+ * Return the place we should be copying from, this is usually the
+ * buffer address, but doesn't *have* to be.
+ */
+
+static const void *format_pxf_bgra32(void *ptr, const uint32_t * p, size_t n)
+{
+ (void)ptr;
+ (void)n;
+ return p; /* No conversion needed! */
+}
+
+static const void *format_pxf_bgr24(void *ptr, const uint32_t * p, size_t n)
+{
+ char *q = ptr;
+
+ while (n--) {
+ *(uint32_t *) q = *p++;
+ q += 3;
+ }
+ return ptr;
+}
+
+static const void *format_pxf_le_rgb16_565(void *ptr, const uint32_t * p,
+ size_t n)
+{
+ uint32_t bgra;
+ uint16_t *q = ptr;
+
+ while (n--) {
+ bgra = *p++;
+ *q++ =
+ ((bgra >> 3) & 0x1f) +
+ ((bgra >> (2 + 8 - 5)) & (0x3f << 5)) +
+ ((bgra >> (3 + 16 - 11)) & (0x1f << 11));
+ }
+ return ptr;
+}
+
+static const void *format_pxf_le_rgb15_555(void *ptr, const uint32_t * p,
+ size_t n)
+{
+ uint32_t bgra;
+ uint16_t *q = ptr;
+
+ while (n--) {
+ bgra = *p++;
+ *q++ =
+ ((bgra >> 3) & 0x1f) +
+ ((bgra >> (2 + 8 - 5)) & (0x1f << 5)) +
+ ((bgra >> (3 + 16 - 10)) & (0x1f << 10));
+ }
+ return ptr;
+}
+
+__vesacon_format_pixels_t __vesacon_format_pixels;
+
+const __vesacon_format_pixels_t __vesacon_format_pixels_list[PXF_NONE] = {
+ [PXF_BGRA32] = format_pxf_bgra32,
+ [PXF_BGR24] = format_pxf_bgr24,
+ [PXF_LE_RGB16_565] = format_pxf_le_rgb16_565,
+ [PXF_LE_RGB15_555] = format_pxf_le_rgb15_555,
+};
diff --git a/contrib/syslinux/latest/com32/lib/sys/vesa/i915resolution.c b/contrib/syslinux/latest/com32/lib/sys/vesa/i915resolution.c
new file mode 100644
index 0000000..6ebb04d
--- /dev/null
+++ b/contrib/syslinux/latest/com32/lib/sys/vesa/i915resolution.c
@@ -0,0 +1,795 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2010 Intel Corporation; author: H. Peter Anvin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * Based on:
+ *
+ * 915 resolution by steve tomljenovic
+ *
+ * This was tested only on Sony VGN-FS550. Use at your own risk
+ *
+ * This code is based on the techniques used in :
+ *
+ * - 855patch. Many thanks to Christian Zietz (czietz gmx net)
+ * for demonstrating how to shadow the VBIOS into system RAM
+ * and then modify it.
+ *
+ * - 1280patch by Andrew Tipton (andrewtipton null li).
+ *
+ * - 855resolution by Alain Poirier
+ *
+ * This source code is into the public domain.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#define __USE_GNU
+#include <string.h>
+#include <sys/io.h>
+#include <sys/cpu.h>
+#include <sys/pci.h>
+#include <unistd.h>
+#include <assert.h>
+#include <stdbool.h>
+#include "video.h"
+#include "debug.h"
+
+#define VBIOS_START 0xc0000
+#define VBIOS_SIZE 0x10000
+
+#define MODE_TABLE_OFFSET_845G 617
+
+#define VERSION "0.5.3"
+
+#define ATI_SIGNATURE1 "ATI MOBILITY RADEON"
+#define ATI_SIGNATURE2 "ATI Technologies Inc"
+#define NVIDIA_SIGNATURE "NVIDIA Corp"
+#define INTEL_SIGNATURE "Intel Corp"
+
+typedef unsigned char * address;
+
+typedef enum {
+ CT_UNKWN, CT_830, CT_845G, CT_855GM, CT_865G, CT_915G, CT_915GM,
+ CT_945G, CT_945GM, CT_946GZ, CT_G965, CT_Q965, CT_945GME,
+ CHIPSET_TYPES
+} chipset_type;
+
+typedef enum {
+ BT_UNKWN, BT_1, BT_2, BT_3
+} bios_type;
+
+static int freqs[] = { 60, 75, 85 };
+
+typedef struct {
+ uint8_t mode;
+ uint8_t bits_per_pixel;
+ uint16_t resolution;
+ uint8_t unknown;
+} __attribute__((packed)) vbios_mode;
+
+typedef struct {
+ uint16_t clock; /* Clock frequency in 10 kHz */
+ uint8_t x1;
+ uint8_t x_total;
+ uint8_t x2;
+ uint8_t y1;
+ uint8_t y_total;
+ uint8_t y2;
+} __attribute__((packed)) vbios_resolution_type1;
+
+typedef struct {
+ uint32_t clock;
+
+ uint16_t x1;
+ uint16_t htotal;
+ uint16_t x2;
+ uint16_t hblank;
+ uint16_t hsyncstart;
+ uint16_t hsyncend;
+
+ uint16_t y1;
+ uint16_t vtotal;
+ uint16_t y2;
+ uint16_t vblank;
+ uint16_t vsyncstart;
+ uint16_t vsyncend;
+} __attribute__((packed)) vbios_modeline_type2;
+
+typedef struct {
+ uint8_t xchars;
+ uint8_t ychars;
+ uint8_t unknown[4];
+
+ vbios_modeline_type2 modelines[];
+} __attribute__((packed)) vbios_resolution_type2;
+
+typedef struct {
+ uint32_t clock;
+
+ uint16_t x1;
+ uint16_t htotal;
+ uint16_t x2;
+ uint16_t hblank;
+ uint16_t hsyncstart;
+ uint16_t hsyncend;
+
+ uint16_t y1;
+ uint16_t vtotal;
+ uint16_t y2;
+ uint16_t vblank;
+ uint16_t vsyncstart;
+ uint16_t vsyncend;
+
+ uint16_t timing_h;
+ uint16_t timing_v;
+
+ uint8_t unknown[6];
+} __attribute__((packed)) vbios_modeline_type3;
+
+typedef struct {
+ unsigned char unknown[6];
+
+ vbios_modeline_type3 modelines[];
+} __attribute__((packed)) vbios_resolution_type3;
+
+
+typedef struct {
+ unsigned int chipset_id;
+ chipset_type chipset;
+ bios_type bios;
+
+ address bios_ptr;
+
+ vbios_mode * mode_table;
+ unsigned int mode_table_size;
+
+ uint8_t b1, b2;
+
+ bool unlocked;
+} vbios_map;
+
+#if 0 /* Debugging hacks */
+static void good_marker(int x)
+{
+ ((uint16_t *)0xb8000)[x] = 0x2f30 - ((x & 0xf0) << 4) + (x & 0x0f);
+}
+
+static void bad_marker(int x)
+{
+ ((uint16_t *)0xb8000)[x] = 0x4f30 - ((x & 0xf0) << 4) + (x & 0x0f);
+}
+
+static void status(const char *fmt, ...)
+{
+ va_list ap;
+ char msg[81], *p;
+ int i;
+ uint16_t *q;
+
+ memset(msg, 0, sizeof msg);
+ va_start(ap, fmt);
+ vsnprintf(msg, sizeof msg, fmt, ap);
+ va_end(ap);
+ p = msg;
+ q = (uint16_t *)0xb8000 + 80;
+ for (i = 0; i < 80; i++)
+ *q++ = *p++ + 0x1f00;
+}
+#else
+static inline void good_marker(int x) { (void)x; }
+static inline void bad_marker(int x) { (void)x; }
+static inline void status(const char *fmt, ...) { (void)fmt; }
+#endif
+
+static unsigned int get_chipset_id(void) {
+ return pci_readl(0x80000000);
+}
+
+static chipset_type get_chipset(unsigned int id) {
+ chipset_type type;
+
+ switch (id) {
+ case 0x35758086:
+ type = CT_830;
+ break;
+
+ case 0x25608086:
+ type = CT_845G;
+ break;
+
+ case 0x35808086:
+ type = CT_855GM;
+ break;
+
+ case 0x25708086:
+ type = CT_865G;
+ break;
+
+ case 0x25808086:
+ type = CT_915G;
+ break;
+
+ case 0x25908086:
+ type = CT_915GM;
+ break;
+
+ case 0x27708086:
+ type = CT_945G;
+ break;
+
+ case 0x27a08086:
+ type = CT_945GM;
+ break;
+
+ case 0x29708086:
+ type = CT_946GZ;
+ break;
+
+ case 0x29a08086:
+ type = CT_G965;
+ break;
+
+ case 0x29908086:
+ type = CT_Q965;
+ break;
+
+ case 0x27ac8086:
+ type = CT_945GME;
+ break;
+
+ default:
+ type = CT_UNKWN;
+ break;
+ }
+
+ return type;
+}
+
+
+static vbios_resolution_type1 * map_type1_resolution(vbios_map * map,
+ uint16_t res)
+{
+ vbios_resolution_type1 * ptr = ((vbios_resolution_type1*)(map->bios_ptr + res));
+ return ptr;
+}
+
+static vbios_resolution_type2 * map_type2_resolution(vbios_map * map,
+ uint16_t res)
+{
+ vbios_resolution_type2 * ptr = ((vbios_resolution_type2*)(map->bios_ptr + res));
+ return ptr;
+}
+
+static vbios_resolution_type3 * map_type3_resolution(vbios_map * map,
+ uint16_t res)
+{
+ vbios_resolution_type3 * ptr = ((vbios_resolution_type3*)(map->bios_ptr + res));
+ return ptr;
+}
+
+
+static bool detect_bios_type(vbios_map * map, int entry_size)
+{
+ unsigned int i;
+ uint16_t r1, r2;
+
+ r1 = r2 = 32000;
+
+ for (i = 0; i < map->mode_table_size; i++) {
+ if (map->mode_table[i].resolution <= r1) {
+ r1 = map->mode_table[i].resolution;
+ } else if (map->mode_table[i].resolution <= r2) {
+ r2 = map->mode_table[i].resolution;
+ }
+ }
+
+ return ((r2-r1-6) % entry_size) == 0;
+}
+
+static inline void close_vbios(vbios_map *map)
+{
+ (void)map;
+}
+
+static vbios_map * open_vbios(void)
+{
+ static vbios_map _map;
+ vbios_map * const map = &_map;
+
+ memset(&_map, 0, sizeof _map);
+
+ /*
+ * Determine chipset
+ */
+ map->chipset_id = get_chipset_id();
+ good_marker(0x10);
+ map->chipset = get_chipset(map->chipset_id);
+ good_marker(0x11);
+
+ /*
+ * Map the video bios to memory
+ */
+ map->bios_ptr = (void *)VBIOS_START;
+
+ /*
+ * check if we have ATI Radeon
+ */
+
+ if (memmem(map->bios_ptr, VBIOS_SIZE, ATI_SIGNATURE1, strlen(ATI_SIGNATURE1)) ||
+ memmem(map->bios_ptr, VBIOS_SIZE, ATI_SIGNATURE2, strlen(ATI_SIGNATURE2)) ) {
+ debug("ATI chipset detected. 915resolution only works with Intel 800/900 series graphic chipsets.\r\n");
+ return NULL;
+ }
+
+ /*
+ * check if we have NVIDIA
+ */
+
+ if (memmem(map->bios_ptr, VBIOS_SIZE, NVIDIA_SIGNATURE, strlen(NVIDIA_SIGNATURE))) {
+ debug("NVIDIA chipset detected. 915resolution only works with Intel 800/900 series graphic chipsets.\r\n");
+ return NULL;
+ }
+
+ /*
+ * check if we have Intel
+ */
+
+ if (map->chipset == CT_UNKWN && memmem(map->bios_ptr, VBIOS_SIZE, INTEL_SIGNATURE, strlen(INTEL_SIGNATURE))) {
+ debug("Intel chipset detected. However, 915resolution was unable to determine the chipset type.\r\n");
+
+ debug("Chipset Id: %x\r\n", map->chipset_id);
+
+ debug("Please report this problem to stomljen@yahoo.com\r\n");
+
+ close_vbios(map);
+ return NULL;
+ }
+
+ /*
+ * check for others
+ */
+
+ if (map->chipset == CT_UNKWN) {
+ debug("Unknown chipset type and unrecognized bios.\r\n");
+ debug("915resolution only works with Intel 800/900 series graphic chipsets.\r\n");
+
+ debug("Chipset Id: %x\r\n", map->chipset_id);
+ close_vbios(map);
+ return NULL;
+ }
+
+ /*
+ * Figure out where the mode table is
+ */
+ good_marker(0x12);
+
+ {
+ address p = map->bios_ptr + 16;
+ address limit = map->bios_ptr + VBIOS_SIZE - (3 * sizeof(vbios_mode));
+
+ while (p < limit && map->mode_table == 0) {
+ vbios_mode * mode_ptr = (vbios_mode *) p;
+
+ if (((mode_ptr[0].mode & 0xf0) == 0x30) && ((mode_ptr[1].mode & 0xf0) == 0x30) &&
+ ((mode_ptr[2].mode & 0xf0) == 0x30) && ((mode_ptr[3].mode & 0xf0) == 0x30)) {
+
+ map->mode_table = mode_ptr;
+ }
+
+ p++;
+ }
+
+ if (map->mode_table == 0) {
+ debug("Unable to locate the mode table.\r\n");
+ close_vbios(map);
+ return NULL;
+ }
+ }
+ good_marker(0x13);
+
+ /*
+ * Determine size of mode table
+ */
+
+ {
+ vbios_mode * mode_ptr = map->mode_table;
+
+ while (mode_ptr->mode != 0xff) {
+ map->mode_table_size++;
+ mode_ptr++;
+ }
+ }
+ good_marker(0x14);
+ status("mode_table_size = %d", map->mode_table_size);
+
+ /*
+ * Figure out what type of bios we have
+ * order of detection is important
+ */
+
+ if (detect_bios_type(map, sizeof(vbios_modeline_type3))) {
+ map->bios = BT_3;
+ }
+ else if (detect_bios_type(map, sizeof(vbios_modeline_type2))) {
+ map->bios = BT_2;
+ }
+ else if (detect_bios_type(map, sizeof(vbios_resolution_type1))) {
+ map->bios = BT_1;
+ }
+ else {
+ debug("Unable to determine bios type.\r\n");
+ debug("Mode Table Offset: $C0000 + $%x\r\n", ((unsigned int)map->mode_table) - ((unsigned int)map->bios_ptr));
+ debug("Mode Table Entries: %u\r\n", map->mode_table_size);
+ bad_marker(0x15);
+ return NULL;
+ }
+ good_marker(0x15);
+
+ return map;
+}
+
+static void unlock_vbios(vbios_map * map)
+{
+ assert(!map->unlocked);
+
+ map->unlocked = true;
+
+ switch (map->chipset) {
+ case CT_UNKWN:
+ case CHIPSET_TYPES: /* Shut up gcc */
+ break;
+ case CT_830:
+ case CT_855GM:
+ map->b1 = pci_readb(0x8000005a);
+ pci_writeb(0x33, 0x8000005a);
+ break;
+ case CT_845G:
+ case CT_865G:
+ case CT_915G:
+ case CT_915GM:
+ case CT_945G:
+ case CT_945GM:
+ case CT_945GME:
+ case CT_946GZ:
+ case CT_G965:
+ case CT_Q965:
+ map->b1 = pci_readb(0x80000091);
+ map->b2 = pci_readb(0x80000092);
+ pci_writeb(0x33, 0x80000091);
+ pci_writeb(0x33, 0x80000092);
+ break;
+ }
+
+#if DEBUG
+ {
+ unsigned int t = inl(0xcfc);
+ debug("unlock PAM: (0x%08x)\r\n", t);
+ }
+#endif
+}
+
+static void relock_vbios(vbios_map * map)
+{
+ assert(map->unlocked);
+ map->unlocked = false;
+
+ switch (map->chipset) {
+ case CT_UNKWN:
+ case CHIPSET_TYPES: /* Shut up gcc */
+ break;
+ case CT_830:
+ case CT_855GM:
+ pci_writeb(map->b1, 0x8000005a);
+ break;
+ case CT_845G:
+ case CT_865G:
+ case CT_915G:
+ case CT_915GM:
+ case CT_945G:
+ case CT_945GM:
+ case CT_945GME:
+ case CT_946GZ:
+ case CT_G965:
+ case CT_Q965:
+ pci_writeb(map->b1, 0x80000091);
+ pci_writeb(map->b2, 0x80000092);
+ break;
+ }
+
+#if DEBUG
+ {
+ unsigned int t = inl(0xcfc);
+ debug("relock PAM: (0x%08x)\r\n", t);
+ }
+#endif
+}
+
+#if 0
+static void list_modes(vbios_map *map, unsigned int raw)
+{
+ unsigned int i, x, y;
+
+ for (i=0; i < map->mode_table_size; i++) {
+ switch(map->bios) {
+ case BT_1:
+ {
+ vbios_resolution_type1 * res = map_type1_resolution(map, map->mode_table[i].resolution);
+
+ x = ((((unsigned int) res->x2) & 0xf0) << 4) | res->x1;
+ y = ((((unsigned int) res->y2) & 0xf0) << 4) | res->y1;
+
+ if (x != 0 && y != 0) {
+ debug("Mode %02x : %dx%d, %d bits/pixel\r\n", map->mode_table[i].mode, x, y, map->mode_table[i].bits_per_pixel);
+ }
+
+ if (raw)
+ {
+ debug("Mode %02x (raw) :\r\n\t%02x %02x\r\n\t%02x\r\n\t%02x\r\n\t%02x\r\n\t%02x\r\n\t%02x\r\n\t%02x\r\n", map->mode_table[i].mode, res->unknow1[0],res->unknow1[1], res->x1,res->x_total,res->x2,res->y1,res->y_total,res->y2);
+ }
+
+ }
+ break;
+ case BT_2:
+ {
+ vbios_resolution_type2 * res = map_type2_resolution(map, map->mode_table[i].resolution);
+
+ x = res->modelines[0].x1+1;
+ y = res->modelines[0].y1+1;
+
+ if (x != 0 && y != 0) {
+ debug("Mode %02x : %dx%d, %d bits/pixel\r\n", map->mode_table[i].mode, x, y, map->mode_table[i].bits_per_pixel);
+ }
+ }
+ break;
+ case BT_3:
+ {
+ vbios_resolution_type3 * res = map_type3_resolution(map, map->mode_table[i].resolution);
+
+ x = res->modelines[0].x1+1;
+ y = res->modelines[0].y1+1;
+
+ if (x != 0 && y != 0) {
+ debug("Mode %02x : %dx%d, %d bits/pixel\r\n", map->mode_table[i].mode, x, y, map->mode_table[i].bits_per_pixel);
+ }
+ }
+ break;
+ case BT_UNKWN:
+ break;
+ }
+ }
+}
+#endif
+
+static void gtf_timings(int x, int y, int freq, uint32_t *clock,
+ uint16_t *hsyncstart, uint16_t *hsyncend, uint16_t *hblank,
+ uint16_t *vsyncstart, uint16_t *vsyncend, uint16_t *vblank)
+{
+ int hbl, vbl, vfreq;
+
+ vbl = y + (y+1)/(20000.0/(11*freq) - 1) + 1.5;
+ vfreq = vbl * freq;
+ hbl = 16 * (int)(x * (30.0 - 300000.0 / vfreq) /
+ (70.0 + 300000.0 / vfreq) / 16.0 + 0.5);
+
+ *vsyncstart = y;
+ *vsyncend = y + 3;
+ *vblank = vbl - 1;
+ *hsyncstart = x + hbl / 2 - (x + hbl + 50) / 100 * 8 - 1;
+ *hsyncend = x + hbl / 2 - 1;
+ *hblank = x + hbl - 1;
+ *clock = (x + hbl) * vfreq / 1000;
+}
+
+static int set_mode(vbios_map * map, unsigned int mode,
+ unsigned int x, unsigned int y, unsigned int bp,
+ unsigned int htotal, unsigned int vtotal)
+{
+ int xprev, yprev;
+ unsigned int i, j;
+ int rv = -1;
+
+ for (i=0; i < map->mode_table_size; i++) {
+ if (map->mode_table[i].mode == mode) {
+ switch(map->bios) {
+ case BT_1:
+ {
+ vbios_resolution_type1 * res = map_type1_resolution(map, map->mode_table[i].resolution);
+ uint32_t clock;
+ uint16_t hsyncstart, hsyncend, hblank;
+ uint16_t vsyncstart, vsyncend, vblank;
+
+ if (bp) {
+ map->mode_table[i].bits_per_pixel = bp;
+ }
+
+ gtf_timings(x, y, freqs[0], &clock,
+ &hsyncstart, &hsyncend, &hblank,
+ &vsyncstart, &vsyncend, &vblank);
+
+ status("x = %d, y = %d, clock = %lu, h = %d %d %d, v = %d %d %d\n",
+ x, y, clock,
+ hsyncstart, hsyncend, hblank,
+ vsyncstart, vsyncend, vblank);
+
+ htotal = htotal ? htotal : (unsigned int)hblank+1;
+ vtotal = vtotal ? vtotal : (unsigned int)vblank+1;
+
+ res->clock = clock/10; /* Units appear to be 10 kHz */
+ res->x2 = (((htotal-x) >> 8) & 0x0f) | ((x >> 4) & 0xf0);
+ res->x1 = (x & 0xff);
+
+ res->y2 = (((vtotal-y) >> 8) & 0x0f) | ((y >> 4) & 0xf0);
+ res->y1 = (y & 0xff);
+ if (htotal)
+ res->x_total = ((htotal-x) & 0xff);
+
+ if (vtotal)
+ res->y_total = ((vtotal-y) & 0xff);
+
+ rv = 0;
+ }
+ break;
+ case BT_2:
+ {
+ vbios_resolution_type2 * res = map_type2_resolution(map, map->mode_table[i].resolution);
+
+ res->xchars = x / 8;
+ res->ychars = y / 16 - 1;
+ xprev = res->modelines[0].x1;
+ yprev = res->modelines[0].y1;
+
+ for(j=0; j < 3; j++) {
+ vbios_modeline_type2 * modeline = &res->modelines[j];
+
+ if (modeline->x1 == xprev && modeline->y1 == yprev) {
+ modeline->x1 = modeline->x2 = x-1;
+ modeline->y1 = modeline->y2 = y-1;
+
+ gtf_timings(x, y, freqs[j], &modeline->clock,
+ &modeline->hsyncstart, &modeline->hsyncend,
+ &modeline->hblank, &modeline->vsyncstart,
+ &modeline->vsyncend, &modeline->vblank);
+
+ if (htotal)
+ modeline->htotal = htotal;
+ else
+ modeline->htotal = modeline->hblank;
+
+ if (vtotal)
+ modeline->vtotal = vtotal;
+ else
+ modeline->vtotal = modeline->vblank;
+ }
+ }
+
+ rv = 0;
+ }
+ break;
+ case BT_3:
+ {
+ vbios_resolution_type3 * res = map_type3_resolution(map, map->mode_table[i].resolution);
+
+ xprev = res->modelines[0].x1;
+ yprev = res->modelines[0].y1;
+
+ for (j=0; j < 3; j++) {
+ vbios_modeline_type3 * modeline = &res->modelines[j];
+
+ if (modeline->x1 == xprev && modeline->y1 == yprev) {
+ modeline->x1 = modeline->x2 = x-1;
+ modeline->y1 = modeline->y2 = y-1;
+
+ gtf_timings(x, y, freqs[j], &modeline->clock,
+ &modeline->hsyncstart, &modeline->hsyncend,
+ &modeline->hblank, &modeline->vsyncstart,
+ &modeline->vsyncend, &modeline->vblank);
+ if (htotal)
+ modeline->htotal = htotal;
+ else
+ modeline->htotal = modeline->hblank;
+ if (vtotal)
+ modeline->vtotal = vtotal;
+ else
+ modeline->vtotal = modeline->vblank;
+
+ modeline->timing_h = y-1;
+ modeline->timing_v = x-1;
+ }
+ }
+
+ rv = 0;
+ }
+ break;
+ case BT_UNKWN:
+ break;
+ }
+ }
+ }
+
+ return rv;
+}
+
+static inline void display_map_info(vbios_map * map) {
+#ifdef DEBUG
+ static const char * bios_type_names[] =
+ {"UNKNOWN", "TYPE 1", "TYPE 2", "TYPE 3"};
+ static const char * chipset_type_names[] = {
+ "UNKNOWN", "830", "845G", "855GM", "865G", "915G", "915GM", "945G",
+ "945GM", "946GZ", "G965", "Q965", "945GME"
+ };
+
+ debug("Chipset: %s\r\n", chipset_type_names[map->chipset]);
+ debug("BIOS: %s\r\n", bios_type_names[map->bios]);
+
+ debug("Mode Table Offset: $C0000 + $%x\r\n",
+ ((unsigned int)map->mode_table) - ((unsigned int)map->bios_ptr));
+ debug("Mode Table Entries: %u\r\n", map->mode_table_size);
+#endif
+ (void)map;
+}
+
+int __vesacon_i915resolution(int x, int y)
+{
+ vbios_map * map;
+ unsigned int mode = 0x52; /* 800x600x32 mode in known BIOSes */
+ unsigned int bp = 32; /* 32 bits per pixel */
+ int rv = 0;
+
+ good_marker(0);
+
+ map = open_vbios();
+ if (!map)
+ return -1;
+
+ good_marker(1);
+
+ display_map_info(map);
+
+ debug("\r\n");
+
+ if (mode && x && y) {
+ good_marker(2);
+ cli();
+ good_marker(3);
+ unlock_vbios(map);
+ good_marker(4);
+ rv = set_mode(map, mode, x, y, bp, 0, 0);
+ if (rv)
+ bad_marker(5);
+ else
+ good_marker(5);
+ relock_vbios(map);
+ good_marker(6);
+ sti();
+
+ debug("Patch mode %02x to resolution %dx%d complete\r\n", mode, x, y);
+ }
+ close_vbios(map);
+
+ return rv;
+}
diff --git a/contrib/syslinux/latest/com32/lib/sys/vesa/initvesa.c b/contrib/syslinux/latest/com32/lib/sys/vesa/initvesa.c
new file mode 100644
index 0000000..9a1ae38
--- /dev/null
+++ b/contrib/syslinux/latest/com32/lib/sys/vesa/initvesa.c
@@ -0,0 +1,357 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 1999-2008 H. Peter Anvin - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * initvesa.c
+ *
+ * Query the VESA BIOS and select a 640x480x32 mode with local mapping
+ * support, if one exists.
+ */
+
+#include <inttypes.h>
+#include <com32.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/fpu.h>
+#include <syslinux/video.h>
+#include "vesa.h"
+#include "video.h"
+#include "fill.h"
+#include "debug.h"
+
+struct vesa_info __vesa_info;
+
+struct vesa_char *__vesacon_text_display;
+
+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, *__vesacon_shadowfb;
+
+static void unpack_font(uint8_t * dst, uint8_t * src, int height)
+{
+ int i;
+
+ for (i = 0; i < FONT_MAX_CHARS; i++) {
+ memcpy(dst, src, height);
+ memset(dst + height, 0, FONT_MAX_HEIGHT - height);
+
+ dst += FONT_MAX_HEIGHT;
+ src += height;
+ }
+}
+
+static int __constfunc is_power_of_2(unsigned int x)
+{
+ return x && !(x & (x - 1));
+}
+
+static int vesacon_paged_mode_ok(const struct vesa_mode_info *mi)
+{
+ int i;
+
+ if (!is_power_of_2(mi->win_size) ||
+ !is_power_of_2(mi->win_grain) || mi->win_grain > mi->win_size)
+ return 0; /* Impossible... */
+
+ for (i = 0; i < 2; i++) {
+ if ((mi->win_attr[i] & 0x05) == 0x05 && mi->win_seg[i])
+ return 1; /* Usable window */
+ }
+
+ return 0; /* Nope... */
+}
+
+static int vesacon_set_mode(int x, int y)
+{
+ com32sys_t rm;
+ uint8_t *rom_font;
+ uint16_t mode, bestmode, *mode_ptr;
+ struct vesa_info *vi;
+ struct vesa_general_info *gi;
+ struct vesa_mode_info *mi;
+ enum vesa_pixel_format pxf, bestpxf;
+ int err = 0;
+
+ debug("Hello, World!\r\n");
+
+ /* 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 */
+ vi = lzalloc(sizeof *vi);
+ if (!vi) {
+ err = 10; /* Out of memory */
+ goto exit;
+ }
+ gi = &vi->gi;
+ mi = &vi->mi;
+
+ memset(&rm, 0, sizeof rm);
+
+ gi->signature = VBE2_MAGIC; /* Get VBE2 extended data */
+ rm.eax.w[0] = 0x4F00; /* Get SVGA general information */
+ rm.edi.w[0] = OFFS(gi);
+ rm.es = SEG(gi);
+ __intcall(0x10, &rm, &rm);
+
+ if (rm.eax.w[0] != 0x004F) {
+ err = 1; /* Function call failed */
+ goto exit;
+ }
+ if (gi->signature != VESA_MAGIC) {
+ err = 2; /* No magic */
+ goto exit;
+ }
+ if (gi->version < 0x0102) {
+ err = 3; /* VESA 1.2+ required */
+ goto exit;
+ }
+
+ /* Copy general info */
+ memcpy(&__vesa_info.gi, gi, sizeof *gi);
+
+ /* Search for the proper mode with a suitable color and memory model... */
+
+ mode_ptr = GET_PTR(gi->video_mode_ptr);
+ bestmode = 0;
+ bestpxf = PXF_NONE;
+
+ while ((mode = *mode_ptr++) != 0xFFFF) {
+ mode &= 0x1FF; /* The rest are attributes of sorts */
+
+ debug("Found mode: 0x%04x\r\n", mode);
+
+ memset(mi, 0, sizeof *mi);
+ rm.eax.w[0] = 0x4F01; /* Get SVGA mode information */
+ rm.ecx.w[0] = mode;
+ rm.edi.w[0] = OFFS(mi);
+ rm.es = SEG(mi);
+ __intcall(0x10, &rm, &rm);
+
+ /* Must be a supported mode */
+ if (rm.eax.w[0] != 0x004f)
+ continue;
+
+ debug
+ ("mode_attr 0x%04x, h_res = %4d, v_res = %4d, bpp = %2d, layout = %d (%d,%d,%d)\r\n",
+ mi->mode_attr, mi->h_res, mi->v_res, mi->bpp, mi->memory_layout,
+ mi->rpos, mi->gpos, mi->bpos);
+
+ /* Must be an LFB color graphics mode supported by the hardware.
+
+ The bits tested are:
+ 4 - graphics mode
+ 3 - color mode
+ 1 - mode information available (mandatory in VBE 1.2+)
+ 0 - mode supported by hardware
+ */
+ if ((mi->mode_attr & 0x001b) != 0x001b)
+ continue;
+
+ /* Must be the chosen size */
+ if (mi->h_res != x || mi->v_res != y)
+ continue;
+
+ /* We don't support multibank (interlaced memory) modes */
+ /*
+ * Note: The Bochs VESA BIOS (vbe.c 1.58 2006/08/19) violates the
+ * specification which states that banks == 1 for unbanked modes;
+ * fortunately it does report bank_size == 0 for those.
+ */
+ if (mi->banks > 1 && mi->bank_size) {
+ debug("bad: banks = %d, banksize = %d, pages = %d\r\n",
+ mi->banks, mi->bank_size, mi->image_pages);
+ continue;
+ }
+
+ /* Must be either a flat-framebuffer mode, or be an acceptable
+ paged mode */
+ if (!(mi->mode_attr & 0x0080) && !vesacon_paged_mode_ok(mi)) {
+ debug("bad: invalid paged mode\r\n");
+ continue;
+ }
+
+ /* Must either be a packed-pixel mode or a direct color mode
+ (depending on VESA version ); must be a supported pixel format */
+ pxf = PXF_NONE; /* Not usable */
+
+ if (mi->bpp == 32 &&
+ (mi->memory_layout == 4 ||
+ (mi->memory_layout == 6 && mi->rpos == 16 && mi->gpos == 8 &&
+ mi->bpos == 0)))
+ pxf = PXF_BGRA32;
+ else if (mi->bpp == 24 &&
+ (mi->memory_layout == 4 ||
+ (mi->memory_layout == 6 && mi->rpos == 16 && mi->gpos == 8 &&
+ mi->bpos == 0)))
+ pxf = PXF_BGR24;
+ else if (mi->bpp == 16 &&
+ (mi->memory_layout == 4 ||
+ (mi->memory_layout == 6 && mi->rpos == 11 && mi->gpos == 5 &&
+ mi->bpos == 0)))
+ pxf = PXF_LE_RGB16_565;
+ else if (mi->bpp == 15 &&
+ (mi->memory_layout == 4 ||
+ (mi->memory_layout == 6 && mi->rpos == 10 && mi->gpos == 5 &&
+ mi->bpos == 0)))
+ pxf = PXF_LE_RGB15_555;
+
+ if (pxf < bestpxf) {
+ debug("Best mode so far, pxf = %d\r\n", pxf);
+
+ /* Best mode so far... */
+ bestmode = mode;
+ bestpxf = pxf;
+
+ /* Copy mode info */
+ memcpy(&__vesa_info.mi, mi, sizeof *mi);
+ }
+ }
+
+ if (bestpxf == PXF_NONE) {
+ err = 4; /* No mode found */
+ goto exit;
+ }
+
+ mi = &__vesa_info.mi;
+ mode = bestmode;
+ __vesacon_bytes_per_pixel = (mi->bpp + 7) >> 3;
+ __vesacon_format_pixels = __vesacon_format_pixels_list[bestpxf];
+
+ /* Download the SYSLINUX- or BIOS-provided font */
+ __vesacon_font_height = syslinux_font_query(&rom_font);
+ if (!__vesacon_font_height) {
+ /* Get BIOS 8x16 font */
+
+ rm.eax.w[0] = 0x1130; /* Get Font Information */
+ rm.ebx.w[0] = 0x0600; /* Get 8x16 ROM font */
+ __intcall(0x10, &rm, &rm);
+ rom_font = MK_PTR(rm.es, rm.ebp.w[0]);
+ __vesacon_font_height = 16;
+ }
+ unpack_font((uint8_t *) __vesacon_graphics_font, rom_font,
+ __vesacon_font_height);
+
+ /* Now set video mode */
+ rm.eax.w[0] = 0x4F02; /* Set SVGA video mode */
+ if (mi->mode_attr & 0x0080)
+ mode |= 0x4000; /* Request linear framebuffer if supported */
+ rm.ebx.w[0] = mode;
+ __intcall(0x10, &rm, &rm);
+ if (rm.eax.w[0] != 0x004F) {
+ err = 9; /* Failed to set mode */
+ goto exit;
+ }
+
+ __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 */
+ /* In theory this should be:
+
+ flags = (mi->mode_attr & 4) ? 0x0007 : 0x000f;
+
+ However, that would assume all systems that claim to handle text
+ output in VESA modes actually do that... */
+ syslinux_report_video_mode(0x000f, mi->h_res, mi->v_res);
+
+ __vesacon_pixel_format = bestpxf;
+
+exit:
+ if (vi)
+ lfree(vi);
+
+ return err;
+}
+
+static int init_text_display(void)
+{
+ size_t nchars;
+ struct vesa_char *ptr;
+ struct vesa_char def_char = {
+ .ch = ' ',
+ .attr = 0,
+ };
+
+ 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));
+
+ if (!ptr)
+ return -1;
+
+ vesacon_fill(ptr, def_char, nchars);
+ __vesacon_init_cursor(__vesacon_font_height);
+
+ return 0;
+}
+
+int __vesacon_init(int x, int y)
+{
+ int rv;
+
+ /* We need the FPU for graphics, at least libpng et al will need it... */
+ if (x86_init_fpu())
+ return 10;
+
+ rv = vesacon_set_mode(x, y);
+ if (rv) {
+ /* Try to see if we can just patch the BIOS... */
+ if (__vesacon_i915resolution(x, y))
+ return rv;
+ if (vesacon_set_mode(x, y))
+ return rv;
+ }
+
+ init_text_display();
+
+ debug("Mode set, now drawing at %#p\r\n", __vesa_info.mi.lfb_ptr);
+
+ __vesacon_init_background();
+
+ debug("Ready!\r\n");
+ return 0;
+}
diff --git a/contrib/syslinux/latest/com32/lib/sys/vesa/screencpy.c b/contrib/syslinux/latest/com32/lib/sys/vesa/screencpy.c
new file mode 100644
index 0000000..32dce9e
--- /dev/null
+++ b/contrib/syslinux/latest/com32/lib/sys/vesa/screencpy.c
@@ -0,0 +1,117 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2008 H. Peter Anvin - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <inttypes.h>
+#include <minmax.h>
+#include <klibc/compiler.h>
+#include <string.h>
+#include <com32.h>
+#include <ilog2.h>
+#include "vesa.h"
+#include "video.h"
+
+static struct win_info {
+ char *win_base;
+ size_t win_pos;
+ size_t win_size;
+ int win_gshift;
+ int win_num;
+} wi;
+
+void __vesacon_init_copy_to_screen(void)
+{
+ struct vesa_mode_info *const mi = &__vesa_info.mi;
+ int winn;
+
+ if (mi->mode_attr & 0x0080) {
+ /* Linear frame buffer */
+
+ wi.win_base = (char *)mi->lfb_ptr;
+ wi.win_size = 1 << 31; /* 2 GB, i.e. one huge window */
+ wi.win_pos = 0; /* Already positioned (only one position...) */
+ wi.win_num = -1; /* Not a window */
+ } else {
+ /* Paged frame buffer */
+
+ /* We have already tested that *one* of these is usable */
+ if ((mi->win_attr[0] & 0x05) == 0x05 && mi->win_seg[0])
+ winn = 0;
+ else
+ winn = 1;
+
+ wi.win_num = winn;
+ wi.win_base = (char *)(mi->win_seg[winn] << 4);
+ wi.win_size = mi->win_size << 10;
+ wi.win_gshift = ilog2(mi->win_grain) + 10;
+ wi.win_pos = -1; /* Undefined position */
+ }
+}
+
+static void set_window_pos(size_t win_pos)
+{
+ static com32sys_t ireg;
+
+ wi.win_pos = win_pos;
+
+ if (wi.win_num < 0)
+ return; /* This should never happen... */
+
+ ireg.eax.w[0] = 0x4F05;
+ ireg.ebx.b[0] = wi.win_num;
+ ireg.edx.w[0] = win_pos >> wi.win_gshift;
+
+ __intcall(0x10, &ireg, NULL);
+}
+
+void __vesacon_copy_to_screen(size_t dst, const uint32_t * src, size_t npixels)
+{
+ size_t win_pos, win_off;
+ size_t win_size = wi.win_size;
+ size_t omask = win_size - 1;
+ char *win_base = wi.win_base;
+ size_t l;
+ size_t bytes = npixels * __vesacon_bytes_per_pixel;
+ char rowbuf[bytes + 4] __aligned(4);
+ const char *s;
+
+ s = (const char *)__vesacon_format_pixels(rowbuf, src, npixels);
+
+ while (bytes) {
+ win_off = dst & omask;
+ win_pos = dst & ~omask;
+
+ if (__unlikely(win_pos != wi.win_pos))
+ set_window_pos(win_pos);
+
+ l = min(bytes, win_size - win_off);
+ memcpy(win_base + win_off, s, l);
+
+ bytes -= l;
+ s += l;
+ dst += l;
+ }
+}
diff --git a/contrib/syslinux/latest/com32/lib/sys/vesa/vesa.h b/contrib/syslinux/latest/com32/lib/sys/vesa/vesa.h
new file mode 100644
index 0000000..3926c32
--- /dev/null
+++ b/contrib/syslinux/latest/com32/lib/sys/vesa/vesa.h
@@ -0,0 +1,114 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 1999-2008 H. Peter Anvin - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef LIB_SYS_VESA_H
+#define LIB_SYS_VESA_H
+
+#include <inttypes.h>
+#include <com32.h>
+
+/* VESA General Information table */
+struct vesa_general_info {
+ uint32_t signature; /* Magic number = "VESA" */
+ uint16_t version;
+ far_ptr_t vendor_string;
+ uint8_t capabilities[4];
+ far_ptr_t video_mode_ptr;
+ uint16_t total_memory;
+
+ uint16_t oem_software_rev;
+ far_ptr_t oem_vendor_name_ptr;
+ far_ptr_t oem_product_name_ptr;
+ far_ptr_t oem_product_rev_ptr;
+
+ uint8_t reserved[222];
+ uint8_t oem_data[256];
+} __attribute__ ((packed));
+
+#define VESA_MAGIC ('V' + ('E' << 8) + ('S' << 16) + ('A' << 24))
+#define VBE2_MAGIC ('V' + ('B' << 8) + ('E' << 16) + ('2' << 24))
+
+struct vesa_mode_info {
+ uint16_t mode_attr;
+ uint8_t win_attr[2];
+ uint16_t win_grain;
+ uint16_t win_size;
+ uint16_t win_seg[2];
+ far_ptr_t win_scheme;
+ uint16_t logical_scan;
+
+ uint16_t h_res;
+ uint16_t v_res;
+ uint8_t char_width;
+ uint8_t char_height;
+ uint8_t memory_planes;
+ uint8_t bpp;
+ uint8_t banks;
+ uint8_t memory_layout;
+ uint8_t bank_size;
+ uint8_t image_pages;
+ uint8_t page_function;
+
+ uint8_t rmask;
+ uint8_t rpos;
+ uint8_t gmask;
+ uint8_t gpos;
+ uint8_t bmask;
+ uint8_t bpos;
+ uint8_t resv_mask;
+ uint8_t resv_pos;
+ uint8_t dcm_info;
+
+ uint8_t *lfb_ptr; /* Linear frame buffer address */
+ uint8_t *offscreen_ptr; /* Offscreen memory address */
+ uint16_t offscreen_size;
+
+ uint8_t reserved[206];
+} __attribute__ ((packed));
+
+struct vesa_info {
+ struct vesa_general_info gi;
+ struct vesa_mode_info mi;
+};
+
+extern struct vesa_info __vesa_info;
+
+#if 0
+static inline void vesa_debug(uint32_t color, int pos)
+{
+ uint32_t *stp = (uint32_t *) __vesa_info.mi.lfb_ptr;
+ stp[pos * 3] = color;
+}
+#else
+static inline void vesa_debug(uint32_t color, int pos)
+{
+ (void)color;
+ (void)pos;
+}
+#endif
+
+#endif /* LIB_SYS_VESA_H */
diff --git a/contrib/syslinux/latest/com32/lib/sys/vesa/video.h b/contrib/syslinux/latest/com32/lib/sys/vesa/video.h
new file mode 100644
index 0000000..d14494b
--- /dev/null
+++ b/contrib/syslinux/latest/com32/lib/sys/vesa/video.h
@@ -0,0 +1,97 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2006-2008 H. Peter Anvin - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef LIB_SYS_VESA_VIDEO_H
+#define LIB_SYS_VESA_VIDEO_H
+
+#include <stdbool.h>
+#include <colortbl.h>
+#include "vesa.h"
+
+#define FONT_MAX_CHARS 256
+#define FONT_MAX_HEIGHT 32
+#define FONT_WIDTH 8
+
+#define DEFAULT_VESA_X_SIZE 640
+#define DEFAULT_VESA_Y_SIZE 480
+
+#define VIDEO_BORDER 8
+#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;
+
+struct vesa_char {
+ uint8_t ch; /* Character */
+ uint8_t _filler; /* Currently unused */
+ attr_t attr; /* Color table index */
+};
+
+/* Pixel formats in order of decreasing preference; PXF_NONE should be last */
+/* BGR24 is preferred over BGRA32 since the I/O overhead is smaller. */
+enum vesa_pixel_format {
+ PXF_BGR24, /* 24-bit BGR */
+ PXF_BGRA32, /* 32-bit BGRA */
+ PXF_LE_RGB16_565, /* 16-bit littleendian 5:6:5 RGB */
+ PXF_LE_RGB15_555, /* 15-bit littleendian 5:5:5 RGB */
+ PXF_NONE
+};
+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);
+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;
+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;
+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(int, int);
+void __vesacon_init_cursor(int);
+void __vesacon_erase(int, int, int, int, attr_t);
+void __vesacon_scroll_up(int, attr_t);
+void __vesacon_write_char(int, int, uint8_t, attr_t);
+void __vesacon_redraw_text(void);
+void __vesacon_doit(void);
+void __vesacon_set_cursor(int, int, bool);
+void __vesacon_copy_to_screen(size_t, const uint32_t *, size_t);
+void __vesacon_init_copy_to_screen(void);
+
+int __vesacon_i915resolution(int x, int y);
+
+#endif /* LIB_SYS_VESA_VIDEO_H */