From 4105dd749cb52ad061dc0eb04a3a821655d6c91f Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Wed, 13 Feb 2008 21:38:37 -0800 Subject: [PATCH] Treat linear framebuffer as a degenerate paged framebuffer Simplify the code by treating linear framebuffer as a degenerate case of a paged framebuffer (a single window covering all of memory, which is already in position 0 - the only possible position.) --- com32/lib/sys/vesa/background.c | 3 +- com32/lib/sys/vesa/drawtxt.c | 5 ++- com32/lib/sys/vesa/screencpy.c | 68 +++++++++++++++++++---------------------- com32/lib/sys/vesa/video.h | 2 +- 4 files changed, 35 insertions(+), 43 deletions(-) diff --git a/com32/lib/sys/vesa/background.c b/com32/lib/sys/vesa/background.c index 5794db2..941d155 100644 --- a/com32/lib/sys/vesa/background.c +++ b/com32/lib/sys/vesa/background.c @@ -53,8 +53,7 @@ static void draw_background_line(int line, int start, int npixels) { uint32_t *bgptr = &__vesacon_background[line][start]; unsigned int bytes_per_pixel = __vesacon_bytes_per_pixel; - uint8_t *fbptr = (uint8_t *)__vesa_info.mi.lfb_ptr + - line*__vesa_info.mi.logical_scan + start*bytes_per_pixel; + size_t fbptr = line*__vesa_info.mi.logical_scan + start*bytes_per_pixel; __vesacon_copy_to_screen(fbptr, bgptr, npixels); } diff --git a/com32/lib/sys/vesa/drawtxt.c b/com32/lib/sys/vesa/drawtxt.c index 023c364..6e21a34 100644 --- a/com32/lib/sys/vesa/drawtxt.c +++ b/com32/lib/sys/vesa/drawtxt.c @@ -84,7 +84,7 @@ static void vesacon_update_characters(int row, int col, int nrows, int ncols) unsigned int bytes_per_pixel = __vesacon_bytes_per_pixel; unsigned long pixel_offset; uint32_t row_buffer[VIDEO_X_SIZE], *rowbufptr; - uint8_t *fbrowptr; + size_t fbrowptr; uint8_t sha; bgrowptr = &__vesacon_background[row*height+VIDEO_BORDER][col*width+VIDEO_BORDER]; @@ -92,8 +92,7 @@ static void vesacon_update_characters(int row, int col, int nrows, int ncols) pixel_offset = ((row*height+VIDEO_BORDER)*VIDEO_X_SIZE)+ (col*width+VIDEO_BORDER); - fbrowptr = ((uint8_t *)__vesa_info.mi.lfb_ptr) + - (row*height+VIDEO_BORDER) * __vesa_info.mi.logical_scan + + 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... */ diff --git a/com32/lib/sys/vesa/screencpy.c b/com32/lib/sys/vesa/screencpy.c index f526de5..837499e 100644 --- a/com32/lib/sys/vesa/screencpy.c +++ b/com32/lib/sys/vesa/screencpy.c @@ -41,29 +41,25 @@ static struct win_info { int win_num; } wi; -static void * -memcpy_to_paged_screen(void *dst, const void *src, size_t len); - static inline int __constfunc ilog2(unsigned int x) { asm("bsrl %1,%0" : "=r" (x) : "rm" (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) { - memcpy_to_screen = memcpy; - } else { - memcpy_to_screen = memcpy_to_paged_screen; + /* Linear frame buffer */ - mi->lfb_ptr = 0; /* Zero-base this */ - wi.win_pos = -1; /* Undefined position */ + wi.win_base = (char *)mi->lfb_ptr; + wi.win_size = 0; /* 4 GB, i.e. one huge window */ + wi.win_pos = 0; /* Already positioned (only one position...) */ + } 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]) @@ -75,50 +71,48 @@ void __vesacon_init_copy_to_screen(void) 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 */ } } -void __vesacon_copy_to_screen(void *dst, const uint32_t *src, size_t npixels) +static void set_window_pos(size_t win_pos) { - size_t bytes = npixels * __vesacon_bytes_per_pixel; - char rowbuf[bytes+4]; + static com32sys_t ireg; - __vesacon_format_pixels(rowbuf, src, npixels); - memcpy_to_screen(dst, rowbuf, bytes); + ireg.eax.w[0] = 0x4F05; + ireg.ebx.b[0] = wi.win_num; + ireg.edx.w[0] = win_pos >> wi.win_gshift; + wi.win_pos = win_pos; + + __intcall(0x10, &ireg, NULL); } -static void * -memcpy_to_paged_screen(void *dst, const void *src, size_t len) +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 d = (size_t)dst; - const char *s = src; + size_t bytes = npixels * __vesacon_bytes_per_pixel; + char rowbuf[bytes+4]; + const char *s; - while (len) { - win_off = d & omask; - win_pos = d & ~omask; + __vesacon_format_pixels(rowbuf, src, npixels); + + s = rowbuf; + while (bytes) { + win_off = dst & omask; + win_pos = dst & ~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; - } + if (__unlikely(win_pos != wi.win_pos)) + set_window_pos(win_pos); - l = min(len, win_size - win_off); - memcpy(win_base + win_off, s, l); + l = min(bytes, win_size-win_off); + memcpy(win_base+win_off, s, l); - len -= l; + bytes -= l; s += l; - d += l; + dst += l; } - - return dst; } diff --git a/com32/lib/sys/vesa/video.h b/com32/lib/sys/vesa/video.h index 3905208..c5f2603 100644 --- a/com32/lib/sys/vesa/video.h +++ b/com32/lib/sys/vesa/video.h @@ -84,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 uint32_t *, size_t); +void __vesacon_copy_to_screen(size_t, const uint32_t *, size_t); void __vesacon_init_copy_to_screen(void); #endif /* LIB_SYS_VESA_VIDEO_H */ -- 2.7.4