aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2006-09-14 14:17:31 -0700
committerH. Peter Anvin <hpa@zytor.com>2006-09-14 14:17:31 -0700
commita5147010cc5f56bfa218654768988d6b50ba4174 (patch)
treebffe5ffacd2906521a7822e8347ccdf79fdbb109
parent95f2a1f57721a15dc1ef26024577321938834451 (diff)
downloadsyslinux-a5147010cc5f56bfa218654768988d6b50ba4174.tar.gz
Properly support 16, 24 and 32-bit modes; now working properly.syslinux-3.30-pre6
-rw-r--r--com32/lib/sys/vesa/background.c42
-rw-r--r--com32/lib/sys/vesa/drawtxt.c33
-rw-r--r--com32/lib/sys/vesa/fmtpixel.h6
-rw-r--r--com32/lib/sys/vesa/initvesa.c21
-rw-r--r--com32/lib/sys/vesa/video.h3
5 files changed, 79 insertions, 26 deletions
diff --git a/com32/lib/sys/vesa/background.c b/com32/lib/sys/vesa/background.c
index a599d059..2e5b108f 100644
--- a/com32/lib/sys/vesa/background.c
+++ b/com32/lib/sys/vesa/background.c
@@ -35,6 +35,7 @@
#include <minmax.h>
#include "vesa.h"
#include "video.h"
+#include "fmtpixel.h"
static size_t filesize(FILE *fp)
{
@@ -45,11 +46,46 @@ static size_t filesize(FILE *fp)
return st.st_size;
}
-/* FIX THIS: we need to redraw any text on the screen... */
+/*** 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)
+{
+ uint8_t line_buf[VIDEO_X_SIZE*4], *lbp;
+ uint32_t *bgptr = &__vesacon_background[line][start];
+ unsigned int bytes_per_pixel = __vesacon_bytes_per_pixel;
+ enum vesa_pixel_format pixel_format = __vesacon_pixel_format;
+ uint8_t *fbptr = (uint8_t *)__vesa_info.mi.lfb_ptr +
+ (line*VIDEO_X_SIZE+start)*bytes_per_pixel;
+
+ lbp = line_buf;
+ while (npixels--)
+ lbp = format_pixel(lbp, *bgptr++, pixel_format);
+
+ memcpy(fbptr, line_buf, lbp-line_buf);
+}
+
+/* This draws the border, then redraws the text area */
static void draw_background(void)
{
- memcpy(__vesa_info.mi.lfb_ptr, __vesacon_background,
- sizeof __vesacon_background);
+ 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, VIDEO_X_SIZE);
+
+ for (i = VIDEO_BORDER; i < VIDEO_Y_SIZE-bottom_border; i++) {
+ draw_background_line(i, 0, VIDEO_BORDER);
+ draw_background_line(i, VIDEO_X_SIZE-right_border, right_border);
+ }
+
+ for (i = VIDEO_Y_SIZE-bottom_border; i < VIDEO_Y_SIZE; i++)
+ draw_background_line(i, 0, VIDEO_X_SIZE);
+
+ __vesacon_redraw_text();
}
static int read_png_file(FILE *fp)
diff --git a/com32/lib/sys/vesa/drawtxt.c b/com32/lib/sys/vesa/drawtxt.c
index 08b0e914..794ebe00 100644
--- a/com32/lib/sys/vesa/drawtxt.c
+++ b/com32/lib/sys/vesa/drawtxt.c
@@ -38,6 +38,13 @@ 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("cld; rep; movsl"
+ : "+D" (dst), "+S" (src), "+c" (dword_count));
+ return dst; /* Updated destination pointer */
+}
+
/*
* Linear alpha blending. Useless for anything that's actually
* depends on color accuracy (because of gamma), but it's fine for
@@ -78,7 +85,8 @@ static void vesacon_update_characters(int row, int col, int nrows, int ncols)
uint8_t chbits = 0, chxbits = 0, chsbits = 0;
int i, j, pixrow, pixsrow;
struct vesa_char *rowptr, *rowsptr, *cptr, *csptr;
- unsigned long pixel_offset, bytes_per_pixel, bytes_per_row;
+ unsigned int bytes_per_pixel = __vesacon_bytes_per_pixel;
+ unsigned long pixel_offset, bytes_per_row;
uint8_t row_buffer[VIDEO_X_SIZE*4], *rowbufptr;
uint8_t *fbrowptr;
@@ -180,17 +188,9 @@ static void vesacon_update_characters(int row, int col, int nrows, int ncols)
}
/* Copy to frame buffer */
- {
- void *fb_ptr = fbrowptr;
- void *rb_ptr = row_buffer;
- unsigned int dword_count = (rowbufptr-row_buffer) >> 2;
-
- /* Note that the dword_count is rounded down, not up. That's because
- the row_buffer includes a spillover pixel. */
-
- asm volatile("cld; rep; movsl"
- : "+D" (fb_ptr), "+S" (rb_ptr), "+c" (dword_count));
- }
+ /* Note that the dword_count is rounded down, not up. That's because
+ the row_buffer includes a spillover pixel. */
+ copy_dword(fbrowptr, row_buffer, (rowbufptr-row_buffer) >> 2);
bgrowptr += VIDEO_X_SIZE;
fbrowptr += bytes_per_row;
@@ -286,8 +286,7 @@ void __vesacon_scroll_up(int nrows, uint8_t attr, int rev)
.sha = rev,
};
- asm volatile("cld ; rep ; movsl"
- : "+D" (toptr), "+S" (fromptr), "+c" (dword_count));
+ toptr = copy_dword(toptr, fromptr, dword_count);
dword_count = nrows*(TEXT_PIXEL_COLS/FONT_WIDTH+2);
@@ -341,3 +340,9 @@ void __vesacon_init_cursor(int 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);
+}
diff --git a/com32/lib/sys/vesa/fmtpixel.h b/com32/lib/sys/vesa/fmtpixel.h
index 1d9d5520..b1d9fa50 100644
--- a/com32/lib/sys/vesa/fmtpixel.h
+++ b/com32/lib/sys/vesa/fmtpixel.h
@@ -40,8 +40,8 @@
/* Format a pixel and return the advanced pointer.
THIS FUNCTION IS ALLOWED TO WRITE BEYOND THE END OF THE PIXEL. */
-static inline void *format_pixel(void *ptr, uint32_t bgra,
- enum vesa_pixel_format fmt)
+static inline __attribute__((always_inline))
+ void *format_pixel(void *ptr, uint32_t bgra, enum vesa_pixel_format fmt)
{
switch (fmt) {
case PXF_BGRA32:
@@ -59,7 +59,7 @@ static inline void *format_pixel(void *ptr, uint32_t bgra,
uint16_t pxv =
((bgra >> 3) & 0x1f) +
((bgra >> (2+8-5)) & (0x3f << 5)) +
- (bgra >> (3+16-11));
+ ((bgra >> (3+16-11)) & (0x1f << 11));
*(uint16_t *)ptr = pxv;
ptr = (uint16_t *)ptr + 1;
diff --git a/com32/lib/sys/vesa/initvesa.c b/com32/lib/sys/vesa/initvesa.c
index ebef3044..8acbe996 100644
--- a/com32/lib/sys/vesa/initvesa.c
+++ b/com32/lib/sys/vesa/initvesa.c
@@ -48,6 +48,7 @@ struct vesa_char *__vesacon_text_display;
int __vesacon_font_height, __vesacon_text_rows;
enum vesa_pixel_format __vesacon_pixel_format;
+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];
@@ -118,6 +119,9 @@ static int vesacon_set_mode(void)
return 3; /* VESA 2.0 not supported */
}
+ /* Copy general info */
+ memcpy(&__vesa_info.gi, gi, sizeof *gi);
+
/* Search for a 640x480 32-bit linear frame buffer mode */
mode_ptr = GET_PTR(gi->video_mode_ptr);
bestmode = 0;
@@ -150,6 +154,8 @@ static int vesacon_set_mode(void)
/* Must either be a packed-pixel mode or a direct color mode
(depending on VESA version ) */
+ pxf = PXF_NONE; /* Not usable */
+
if (mi->bpp == 32 &&
(mi->memory_layout == 4 ||
(mi->memory_layout == 6 && mi->rpos == 16 && mi->gpos == 8 &&
@@ -165,19 +171,27 @@ static int vesacon_set_mode(void)
(mi->memory_layout == 6 && mi->rpos == 11 && mi->gpos == 5 &&
mi->bpos == 0)))
pxf = PXF_LE_RGB16_565;
- else
- pxf = PXF_NONE; /* Not a usable mode for us */
if (pxf < bestpxf) {
+ debug("Best mode so far, pxf = %d\n", pxf);
+
/* Best mode so far... */
bestmode = mode;
bestpxf = pxf;
+
+ /* Copy mode info */
+ memcpy(&__vesa_info.mi, mi, sizeof *mi);
}
}
if (bestpxf == PXF_NONE)
return 4; /* No mode found */
+ mi = &__vesa_info.mi;
+ mode = bestmode;
+ __vesacon_pixel_format = bestpxf;
+ __vesacon_bytes_per_pixel = mi->bpp >> 3;
+
/* Download the SYSLINUX- or BIOS-provided font */
rm.eax.w[0] = 0x0018; /* Query custom font */
__intcall(0x22, &rm, &rm);
@@ -216,9 +230,6 @@ static int vesacon_set_mode(void)
rm.edx.w[0] = VIDEO_Y_SIZE;
__intcall(0x22, &rm, NULL);
- /* Copy established state out of the bounce buffer */
- memcpy(&__vesa_info, __com32.cs_bounce, sizeof __vesa_info);
-
return 0;
}
diff --git a/com32/lib/sys/vesa/video.h b/com32/lib/sys/vesa/video.h
index ab3c765a..13449d87 100644
--- a/com32/lib/sys/vesa/video.h
+++ b/com32/lib/sys/vesa/video.h
@@ -64,6 +64,7 @@ extern struct vesa_char *__vesacon_text_display;
extern int __vesacon_font_height, __vesacon_text_rows;
extern enum vesa_pixel_format __vesacon_pixel_format;
+extern unsigned int __vesacon_bytes_per_pixel;
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];
@@ -76,8 +77,8 @@ int __vesacon_init(void);
void __vesacon_init_cursor(int);
void __vesacon_erase(int, int, int, int, uint8_t, int);
void __vesacon_scroll_up(int, uint8_t, int);
-void __vesacon_write_at(int, int, const char *, uint8_t, int);
void __vesacon_write_char(int, int, uint8_t, uint8_t, int);
+void __vesacon_redraw_text(void);
void __vesacon_doit(void);
void __vesacon_set_cursor(int, int, int);