diff options
author | H. Peter Anvin <hpa@zytor.com> | 2008-02-13 21:38:37 -0800 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2008-02-13 21:38:37 -0800 |
commit | 4105dd749cb52ad061dc0eb04a3a821655d6c91f (patch) | |
tree | 828818fa58dbf9d22d58c45a687249f7c6706e9d /com32/lib/sys/vesa/screencpy.c | |
parent | bc1081b746cc3a224470567990364bf62162b405 (diff) | |
download | syslinux-4105dd749cb52ad061dc0eb04a3a821655d6c91f.tar.gz syslinux-4105dd749cb52ad061dc0eb04a3a821655d6c91f.tar.xz syslinux-4105dd749cb52ad061dc0eb04a3a821655d6c91f.zip |
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.)
Diffstat (limited to 'com32/lib/sys/vesa/screencpy.c')
-rw-r--r-- | com32/lib/sys/vesa/screencpy.c | 68 |
1 files changed, 31 insertions, 37 deletions
diff --git a/com32/lib/sys/vesa/screencpy.c b/com32/lib/sys/vesa/screencpy.c index f526de5a..837499e2 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; } |