diff -Naur linux-2.5.61-fbdev/drivers/video/console/fbcon.c linux-2.5.61/drivers/video/console/fbcon.c --- linux-2.5.61-fbdev/drivers/video/console/fbcon.c 2003-02-22 02:34:26.000000000 +0000 +++ linux-2.5.61/drivers/video/console/fbcon.c 2003-02-22 03:16:45.000000000 +0000 @@ -332,16 +332,22 @@ } #define FB_PIXMAPSIZE 8192 +/* + * FIXME: Break up this function, it's becoming too long... + */ void accel_putcs(struct vc_data *vc, struct display *p, const unsigned short *s, int count, int yy, int xx) { + static u8 pixmap[FB_PIXMAPSIZE]; + struct fb_image image; struct fb_info *info = p->fb_info; unsigned short charmask = p->charmask; unsigned int width = ((vc->vc_font.width + 7)/8); unsigned int cellsize = vc->vc_font.height * width; - struct fb_image image; + unsigned int pitch, cnt, i, j, k; + unsigned int maxcnt = FB_PIXMAPSIZE/cellsize; + u8 *src, *dst, *dst0; u16 c = scr_readw(s); - static u8 pixmap[FB_PIXMAPSIZE]; image.fg_color = attr_fgcol(p, c); image.bg_color = attr_bgcol(p, c); @@ -349,13 +355,9 @@ image.dy = yy * vc->vc_font.height; image.height = vc->vc_font.height; image.depth = 0; + image.data = pixmap; if (!(vc->vc_font.width & 7)) { - unsigned int pitch, cnt, i, j, k; - unsigned int maxcnt = FB_PIXMAPSIZE/cellsize; - char *src, *dst, *dst0; - - image.data = pixmap; while (count) { if (count > maxcnt) cnt = k = maxcnt; @@ -381,14 +383,48 @@ image.dx += cnt * vc->vc_font.width; count -= cnt; } + } else { - image.width = vc->vc_font.width; - while (count--) { - image.data = p->fontdata + - (scr_readw(s++) & charmask) * cellsize; + unsigned int shift_low = 0, mod = vc->vc_font.width % 8; + unsigned int shift_high = 8; + unsigned idx = vc->vc_font.width/8; + u8 mask; + + while (count) { + if (count > maxcnt) + cnt = k = maxcnt; + else + cnt = k = count; + + dst0 = pixmap; + image.width = vc->vc_font.width * cnt; + pitch = (image.width + 7)/8; + while (k--) { + src = p->fontdata + (scr_readw(s++)&charmask)* + cellsize; + dst = dst0; + mask = (u8) (0xfff << shift_high); + for (i = image.height; i--; ) { + for (j = 0; j < idx; j++) { + dst[j] &= mask; + dst[j] |= *src >> shift_low; + dst[j+1] = *src << shift_high; + src++; + } + dst[idx] &= mask; + dst[idx] |= *src++ >> shift_low; + dst += pitch; + } + shift_low += mod; + shift_low &= 7; + shift_high = 8 - shift_low; + dst0 += (shift_low) ? width - 1 : width; + } + info->fbops->fb_imageblit(info, &image); - image.dx += vc->vc_font.width; - } + image.dx += cnt * vc->vc_font.width; + count -= cnt; + } } } diff -Naur linux-2.5.61-fbdev/drivers/video/fbmem.c linux-2.5.61/drivers/video/fbmem.c --- linux-2.5.61-fbdev/drivers/video/fbmem.c 2003-02-22 02:34:26.000000000 +0000 +++ linux-2.5.61/drivers/video/fbmem.c 2003-02-22 02:42:06.000000000 +0000 @@ -363,14 +363,14 @@ static int ofonly __initdata = 0; #endif +#ifdef CONFIG_LOGO +#include + static inline unsigned safe_shift(unsigned d, int n) { return n < 0 ? d >> -n : d << n; } -#ifdef CONFIG_FB_LOGO -#include - static void __init fb_set_logocmap(struct fb_info *info, const struct linux_logo *logo) {