Index: kernel/genarch/src/fb/fb.c
===================================================================
--- kernel/genarch/src/fb/fb.c	(revision e71a61d2f187f60c13024e0c300fa8b4703b2c70)
+++ kernel/genarch/src/fb/fb.c	(revision 51baa8ad19af87e921ddfb1497fd4610a93ad7a9)
@@ -82,5 +82,5 @@
 #define LOGOCOLOR	0x2020b0
 
-#define RED(x, bits)	((x >> (16 + 8 - bits)) & ((1 << bits) - 1))
+#define RED(x, bits)	((x >> (8 + 8 + 8 - bits)) & ((1 << bits) - 1))
 #define GREEN(x, bits)	((x >> (8 + 8 - bits)) & ((1 << bits) - 1))
 #define BLUE(x, bits)	((x >> (8 - bits)) & ((1 << bits) - 1))
@@ -112,6 +112,6 @@
 static void bgr_byte0888(void *dst, int rgb)
 {
-	*((uint32_t *) dst) = BLUE(rgb, 8) << 16 | GREEN(rgb, 8) << 8 |	RED(rgb,
-		8);
+	*((uint32_t *) dst) = BLUE(rgb, 8) << 16 | GREEN(rgb, 8) << 8 |
+	    RED(rgb, 8);
 }
 
@@ -119,6 +119,6 @@
 {
 	int color = *(uint32_t *)(src);
-	return ((color & 0xff) << 16) | (((color >> 8) & 0xff) << 8) | ((color
-		>> 16) & 0xff);
+	return ((color & 0xff) << 16) | (((color >> 8) & 0xff) << 8) |
+	    ((color >> 16) & 0xff);
 }
 
@@ -151,6 +151,6 @@
 {
 	/* 5-bit, 5-bits, 5-bits */ 
-	*((uint16_t *) dst) = RED(rgb, 5) << 10 | GREEN(rgb, 5) << 5 | BLUE(rgb,
-		5);
+	*((uint16_t *) dst) = RED(rgb, 5) << 10 | GREEN(rgb, 5) << 5 |
+	    BLUE(rgb, 5);
 }
 
@@ -159,6 +159,6 @@
 {
 	int color = *(uint16_t *)(src);
-	return (((color >> 10) & 0x1f) << (16 + 3)) | (((color >> 5) & 0x1f) <<
-		(8 + 3)) | ((color & 0x1f) << 3);
+	return (((color >> 10) & 0x1f) << (16 + 3)) |
+	    (((color >> 5) & 0x1f) << (8 + 3)) | ((color & 0x1f) << 3);
 }
 
@@ -167,5 +167,6 @@
 {
 	/* 5-bit, 6-bits, 5-bits */ 
-	*((uint16_t *) dst) = RED(rgb, 5) << 11 | GREEN(rgb, 6) << 5 | BLUE(rgb,		5);
+	*((uint16_t *) dst) = RED(rgb, 5) << 11 | GREEN(rgb, 6) << 5 |
+	    BLUE(rgb, 5);
 }
 
@@ -174,6 +175,6 @@
 {
 	int color = *(uint16_t *)(src);
-	return (((color >> 11) & 0x1f) << (16 + 3)) | (((color >> 5) & 0x3f) <<
-		(8 + 2)) | ((color & 0x1f) << 3);
+	return (((color >> 11) & 0x1f) << (16 + 3)) |
+	    (((color >> 5) & 0x3f) << (8 + 2)) | ((color & 0x1f) << 3);
 }
 
@@ -188,6 +189,6 @@
 static void rgb_byte8(void *dst, int rgb)
 {
-	*((uint8_t *) dst) = RED(rgb, 3) << 5 | GREEN(rgb, 2) << 3 | BLUE(rgb,
-		3);
+	*((uint8_t *) dst) = RED(rgb, 3) << 5 | GREEN(rgb, 2) << 3 |
+	    BLUE(rgb, 3);
 }
 
@@ -199,6 +200,6 @@
 {
 	int color = *(uint8_t *)src;
-	return (((color >> 5) & 0x7) << (16 + 5)) | (((color >> 3) & 0x3) << (8
-		+ 6)) | ((color & 0x7) << 5);
+	return (((color >> 5) & 0x7) << (16 + 5)) |
+	    (((color >> 3) & 0x3) << (8 + 6)) | ((color & 0x7) << 5);
 }
 
@@ -232,6 +233,6 @@
 		memcpy(&fbaddress[scanline * y], blankline, xres * pixelbytes);
 		if (dbbuffer)
-			memcpy(&dbbuffer[scanline * y], blankline, xres *
-				pixelbytes);
+			memcpy(&dbbuffer[scanline * y], blankline,
+			    xres * pixelbytes);
 	}
 }
@@ -244,20 +245,64 @@
 		count_t first;
 		
+		/* Clear the last row */
 		memcpy(&dbbuffer[dboffset * scanline], blankline, ROW_BYTES);
 		
 		dboffset = (dboffset + FONT_SCANLINES) % yres;
 		first = yres - dboffset;
-
-		memcpy(fbaddress, &dbbuffer[scanline * dboffset], first *
-			scanline);
-		memcpy(&fbaddress[first * scanline], dbbuffer, dboffset *
-			scanline);
+		
+		/* Move all rows one row up */
+		if (xres * pixelbytes == scanline) {
+			memcpy(fbaddress, &dbbuffer[dboffset * scanline],
+			    first * scanline);
+			memcpy(&fbaddress[first * scanline], dbbuffer,
+			    dboffset * scanline);
+		} else {
+			/*
+			 * When the scanline is bigger than number of bytes
+			 * in the X-resolution, chances are that the
+			 * frame buffer memory past the X-resolution is special
+			 * in some way. For example, the SUNW,ffb framebuffer
+			 * wraps this area around the beginning of the same
+			 * line. To avoid troubles, copy only memory as
+			 * specified by the resolution.
+			 */
+			int i;
+
+			for (i = 0; i < first; i++)
+				memcpy(&fbaddress[i * scanline],
+				    &dbbuffer[(dboffset + i) * scanline],
+				    xres * pixelbytes);
+			for (i = 0; i < dboffset; i++)
+				memcpy(&fbaddress[(first + i) * scanline],
+				    &dbbuffer[i * scanline], xres * pixelbytes);
+		}
 	} else {
 		uint8_t *lastline = &fbaddress[(rows - 1) * ROW_BYTES];
 		
-		memcpy((void *) fbaddress, (void *) &fbaddress[ROW_BYTES],
-			scanline * yres - ROW_BYTES);
-		/* Clear last row */
-		memcpy((void *) lastline, (void *) blankline, ROW_BYTES);
+		if (xres * pixelbytes == scanline) {
+			/* Move all rows one row up */
+			memcpy((void *) fbaddress,
+			    (void *) &fbaddress[ROW_BYTES],
+			    scanline * yres - ROW_BYTES);
+			/* Clear the last row */
+			memcpy((void *) lastline, (void *) blankline,
+			    ROW_BYTES);
+		} else {
+			/*
+			 * See the comment in the dbbuffer case.
+			 */
+			int i;
+
+			/* Move all rows one row up */
+			for (i = 0; i < yres - FONT_SCANLINES; i++)
+				memcpy(&fbaddress[i * scanline],
+				    &fbaddress[(i + FONT_SCANLINES) * scanline],
+				    xres * pixelbytes);
+			/* Clear the last row */
+			for (i = 0; i < FONT_SCANLINES; i++)
+				memcpy(&lastline[i * scanline],
+				    &blankline[i * scanline],
+				    xres * pixelbytes);
+		}
 	}
 }
@@ -291,6 +336,6 @@
 
 	for (y = 0; y < FONT_SCANLINES; y++)
-		draw_glyph_line(fb_font[glyph * FONT_SCANLINES + y], col *
-			COL_WIDTH, row * FONT_SCANLINES + y);
+		draw_glyph_line(fb_font[glyph * FONT_SCANLINES + y],
+		    col * COL_WIDTH, row * FONT_SCANLINES + y);
 }
 
@@ -303,6 +348,6 @@
 	for (x = 0; x < COL_WIDTH; x++)
 		for (y = 0; y < FONT_SCANLINES; y++)
-			invert_pixel(col * COL_WIDTH + x, row * FONT_SCANLINES +
-				y);
+			invert_pixel(col * COL_WIDTH + x,
+			    row * FONT_SCANLINES + y);
 }
 
@@ -328,5 +373,5 @@
 			if (byte & 1)
 				putpixel(startx + x, starty + y,
-					COLOR(LOGOCOLOR));
+				    COLOR(LOGOCOLOR));
 		}
 }
@@ -401,5 +446,5 @@
  */
 void fb_init(uintptr_t addr, unsigned int x, unsigned int y, unsigned int scan,
-	unsigned int visual)
+    unsigned int visual)
 {
 	switch (visual) {
@@ -468,6 +513,6 @@
 	sysinfo_set_item_val("fb.visual", NULL, visual);
 	sysinfo_set_item_val("fb.address.physical", NULL, addr);
-	sysinfo_set_item_val("fb.address.color", NULL, PAGE_COLOR((uintptr_t)
-		fbaddress));
+	sysinfo_set_item_val("fb.address.color", NULL,
+	    PAGE_COLOR((uintptr_t) fbaddress));
 	sysinfo_set_item_val("fb.invert-colors", NULL, invert_colors);
 
