diff options
-rw-r--r-- | com32/lib/Makefile | 2 | ||||
-rw-r--r-- | com32/lib/sys/vesa/background.c | 9 | ||||
-rw-r--r-- | com32/lib/sys/vesa/drawtxt.c | 10 | ||||
-rw-r--r-- | com32/lib/sys/vesa/fmtpixel.c (renamed from com32/lib/sys/vesa/fmtpixel.h) | 95 | ||||
-rw-r--r-- | com32/lib/sys/vesa/initvesa.c | 1 | ||||
-rw-r--r-- | com32/lib/sys/vesa/screencpy.c | 29 | ||||
-rw-r--r-- | com32/lib/sys/vesa/video.h | 9 |
7 files changed, 85 insertions, 70 deletions
diff --git a/com32/lib/Makefile b/com32/lib/Makefile index cd0cebd9..cb330242 100644 --- a/com32/lib/Makefile +++ b/com32/lib/Makefile @@ -43,7 +43,7 @@ LIBOBJS = \ \ sys/vesacon_write.o sys/vesaserial_write.o \ sys/vesa/initvesa.o sys/vesa/drawtxt.o sys/vesa/background.o \ - sys/vesa/alphatbl.o sys/vesa/screencpy.o \ + sys/vesa/alphatbl.o sys/vesa/screencpy.o sys/vesa/fmtpixel.o \ \ pci/cfgtype.o pci/scan.o \ pci/readb.o pci/readw.o pci/readl.o pci/readbios.o \ diff --git a/com32/lib/sys/vesa/background.c b/com32/lib/sys/vesa/background.c index d7a0d019..5794db2e 100644 --- a/com32/lib/sys/vesa/background.c +++ b/com32/lib/sys/vesa/background.c @@ -35,7 +35,6 @@ #include <minmax.h> #include "vesa.h" #include "video.h" -#include "fmtpixel.h" static size_t filesize(FILE *fp) { @@ -52,18 +51,12 @@ static size_t filesize(FILE *fp) 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*__vesa_info.mi.logical_scan + start*bytes_per_pixel; - lbp = line_buf; - while (npixels--) - lbp = format_pixel(lbp, *bgptr++, pixel_format); - - __vesacon_copy_to_screen(fbptr, line_buf, lbp-line_buf); + __vesacon_copy_to_screen(fbptr, bgptr, npixels); } /* This draws the border, then redraws the text area */ diff --git a/com32/lib/sys/vesa/drawtxt.c b/com32/lib/sys/vesa/drawtxt.c index 9e222ecc..023c3646 100644 --- a/com32/lib/sys/vesa/drawtxt.c +++ b/com32/lib/sys/vesa/drawtxt.c @@ -29,7 +29,6 @@ #include <colortbl.h> #include "vesa.h" #include "video.h" -#include "fmtpixel.h" #include "fill.h" /* @@ -84,7 +83,7 @@ static void vesacon_update_characters(int row, int col, int nrows, int ncols) struct vesa_char *rowptr, *rowsptr, *cptr, *csptr; unsigned int bytes_per_pixel = __vesacon_bytes_per_pixel; unsigned long pixel_offset; - uint8_t row_buffer[VIDEO_X_SIZE*4], *rowbufptr; + uint32_t row_buffer[VIDEO_X_SIZE], *rowbufptr; uint8_t *fbrowptr; uint8_t sha; @@ -174,14 +173,11 @@ static void vesacon_update_characters(int row, int col, int nrows, int ncols) color &= 0x3f3f3f; } - rowbufptr = format_pixel(rowbufptr, color, __vesacon_pixel_format); + *rowbufptr++ = color; } /* Copy to frame buffer */ - /* Note that the dword_count is rounded down, not up. That's because - the row_buffer includes a spillover pixel. */ - __vesacon_copy_to_screen(fbrowptr, row_buffer, - (rowbufptr-row_buffer) & ~3); + __vesacon_copy_to_screen(fbrowptr, row_buffer, rowbufptr-row_buffer); bgrowptr += VIDEO_X_SIZE; fbrowptr += __vesa_info.mi.logical_scan; diff --git a/com32/lib/sys/vesa/fmtpixel.h b/com32/lib/sys/vesa/fmtpixel.c index dcde0109..74c79ef1 100644 --- a/com32/lib/sys/vesa/fmtpixel.h +++ b/com32/lib/sys/vesa/fmtpixel.c @@ -26,63 +26,76 @@ * ----------------------------------------------------------------------- */ /* - * fmtpixel.h + * fmtpixel.c * - * Inline function to format a single pixel + * Functions to format a single pixel */ -#ifndef LIB_SYS_VESA_FMTPIXEL_H -#define LIB_SYS_VESA_FMTPIXEL_H - #include <inttypes.h> #include "video.h" /* Format a pixel and return the advanced pointer. THIS FUNCTION IS ALLOWED TO WRITE BEYOND THE END OF THE PIXEL. */ -static inline __attribute__((always_inline)) - void *format_pixel(void *ptr, uint32_t bgra, enum vesa_pixel_format fmt) +static inline uint32_t *copy_dword(uint32_t *dst, const uint32_t *src, + size_t dword_count) { - switch (fmt) { - case PXF_BGRA32: - *(uint32_t *)ptr = bgra; - ptr = (uint32_t *)ptr + 1; - break; - - case PXF_BGR24: - *(uint32_t *)ptr = bgra; - ptr = (uint8_t *)ptr + 3; - break; + asm volatile("cld; rep; movsl" + : "+D" (dst), "+S" (src), "+c" (dword_count)); + return dst; /* Updated destination pointer */ +} - case PXF_LE_RGB16_565: - { - uint16_t pxv = - ((bgra >> 3) & 0x1f) + - ((bgra >> (2+8-5)) & (0x3f << 5)) + - ((bgra >> (3+16-11)) & (0x1f << 11)); +static void *format_pxf_bgra32(void *ptr, const uint32_t *p, size_t n) +{ + return copy_dword(ptr, p, n); +} - *(uint16_t *)ptr = pxv; - ptr = (uint16_t *)ptr + 1; - } - break; +static void *format_pxf_bgr24(void *ptr, const uint32_t *p, size_t n) +{ + char *q = ptr; - case PXF_LE_RGB15_555: - { - uint16_t pxv = - ((bgra >> 3) & 0x1f) + - ((bgra >> (2+8-5)) & (0x1f << 5)) + - ((bgra >> (3+16-10)) & (0x1f << 10)); + while (n--) { + *(uint32_t *)q = *p++; + q += 3; + } + return q; +} - *(uint16_t *)ptr = pxv; - ptr = (uint16_t *)ptr + 1; - } - break; +static void *format_pxf_le_rgb16_565(void *ptr, const uint32_t *p, size_t n) +{ + uint32_t bgra; + uint16_t *q = ptr; - case PXF_NONE: /* Shuts up gcc */ - break; + while (n--) { + bgra = *p++; + *q++ = + ((bgra >> 3) & 0x1f) + + ((bgra >> (2+8-5)) & (0x3f << 5)) + + ((bgra >> (3+16-11)) & (0x1f << 11)); } + return q; +} - return ptr; +static 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 q; } -#endif /* LIB_SYS_VESA_FMTPIXEL_H */ +__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/com32/lib/sys/vesa/initvesa.c b/com32/lib/sys/vesa/initvesa.c index d5aa9ba7..b5aba989 100644 --- a/com32/lib/sys/vesa/initvesa.c +++ b/com32/lib/sys/vesa/initvesa.c @@ -236,6 +236,7 @@ static int vesacon_set_mode(void) 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 */ rm.eax.w[0] = 0x0018; /* Query custom font */ diff --git a/com32/lib/sys/vesa/screencpy.c b/com32/lib/sys/vesa/screencpy.c index a8be4306..f526de5a 100644 --- a/com32/lib/sys/vesa/screencpy.c +++ b/com32/lib/sys/vesa/screencpy.c @@ -42,7 +42,7 @@ static struct win_info { } wi; static void * -vesacon_copy_to_paged_screen(void *dst, const void *src, size_t len); +memcpy_to_paged_screen(void *dst, const void *src, size_t len); static inline int __constfunc ilog2(unsigned int x) { @@ -50,15 +50,17 @@ static inline int __constfunc ilog2(unsigned int x) return x; } +static void * (*memcpy_to_screen)(void *, const void *, size_t); + void __vesacon_init_copy_to_screen(void) { struct vesa_mode_info * const mi = &__vesa_info.mi; int winn; if (mi->mode_attr & 0x0080) { - __vesacon_copy_to_screen = memcpy; /* Really easy... */ + memcpy_to_screen = memcpy; } else { - __vesacon_copy_to_screen = vesacon_copy_to_paged_screen; + memcpy_to_screen = memcpy_to_paged_screen; mi->lfb_ptr = 0; /* Zero-base this */ wi.win_pos = -1; /* Undefined position */ @@ -76,8 +78,17 @@ void __vesacon_init_copy_to_screen(void) } } +void __vesacon_copy_to_screen(void *dst, const uint32_t *src, size_t npixels) +{ + size_t bytes = npixels * __vesacon_bytes_per_pixel; + char rowbuf[bytes+4]; + + __vesacon_format_pixels(rowbuf, src, npixels); + memcpy_to_screen(dst, rowbuf, bytes); +} + static void * -vesacon_copy_to_paged_screen(void *dst, const void *src, size_t len) +memcpy_to_paged_screen(void *dst, const void *src, size_t len) { size_t win_pos, win_off; size_t win_size = wi.win_size; @@ -86,18 +97,16 @@ vesacon_copy_to_paged_screen(void *dst, const void *src, size_t len) size_t l; size_t d = (size_t)dst; const char *s = src; - com32sys_t ireg; - - memset(&ireg, 0, sizeof ireg); - ireg.eax.w[0] = 0x4F05; /* VBE Window Control */ - /* BH = 0 -> Set memory window */ - ireg.ebx.b[0] = wi.win_num; while (len) { win_off = d & omask; win_pos = d & ~omask; if (win_pos != wi.win_pos) { + com32sys_t ireg; + memset(&ireg, 0, sizeof ireg); + 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); wi.win_pos = win_pos; diff --git a/com32/lib/sys/vesa/video.h b/com32/lib/sys/vesa/video.h index 699d4e9a..39052087 100644 --- a/com32/lib/sys/vesa/video.h +++ b/com32/lib/sys/vesa/video.h @@ -58,12 +58,15 @@ enum vesa_pixel_format { 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 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, __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]; @@ -81,7 +84,7 @@ 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, int); -void * (*__vesacon_copy_to_screen)(void *, const void *, size_t); +void __vesacon_copy_to_screen(void *, const uint32_t *, size_t); void __vesacon_init_copy_to_screen(void); #endif /* LIB_SYS_VESA_VIDEO_H */ |