diff options
Diffstat (limited to 'com32')
-rw-r--r-- | com32/lib/sys/vesa/background.c | 42 | ||||
-rw-r--r-- | com32/lib/sys/vesa/drawtxt.c | 33 | ||||
-rw-r--r-- | com32/lib/sys/vesa/fmtpixel.h | 6 | ||||
-rw-r--r-- | com32/lib/sys/vesa/initvesa.c | 21 | ||||
-rw-r--r-- | com32/lib/sys/vesa/video.h | 3 |
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); |