Treat linear framebuffer as a degenerate paged framebuffer
authorH. Peter Anvin <hpa@zytor.com>
Thu, 14 Feb 2008 05:38:37 +0000 (21:38 -0800)
committerH. Peter Anvin <hpa@zytor.com>
Thu, 14 Feb 2008 05:38:37 +0000 (21:38 -0800)
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
com32/lib/sys/vesa/drawtxt.c
com32/lib/sys/vesa/screencpy.c
com32/lib/sys/vesa/video.h

index 5794db2..941d155 100644 (file)
@@ -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);
 }
index 023c364..6e21a34 100644 (file)
@@ -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... */
index f526de5..837499e 100644 (file)
@@ -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;
 }
index 3905208..c5f2603 100644 (file)
@@ -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 */