linux-old/drivers/video/fbcon-cfb4.c
<<
>>
Prefs
   1/*
   2 *  linux/drivers/video/cfb4.c -- Low level frame buffer operations for 4 bpp
   3 *                                packed pixels
   4 *
   5 *      Created 26 Dec 1997 by Michael Schmitz
   6 *      Based on the old macfb.c 4bpp code by Alan Cox
   7 *
   8 *  This file is subject to the terms and conditions of the GNU General Public
   9 *  License.  See the file COPYING in the main directory of this archive for
  10 *  more details.
  11 */
  12
  13#include <linux/module.h>
  14#include <linux/tty.h>
  15#include <linux/console.h>
  16#include <linux/string.h>
  17#include <linux/fb.h>
  18
  19#include <video/fbcon.h>
  20#include <video/fbcon-cfb4.h>
  21
  22
  23    /*
  24     *  4 bpp packed pixels
  25     */
  26
  27    /*
  28     *  IFF the font is even pixel aligned (that is to say each
  29     *  character start is a byte start in the pixel pairs). That
  30     *  avoids us having to mask bytes and means we won't be here
  31     *  all week. On a MacII that matters _lots_
  32     */
  33
  34static u16 nibbletab_cfb4[] = {
  35#if defined(__BIG_ENDIAN)
  36    0x0000,0x000f,0x00f0,0x00ff,
  37    0x0f00,0x0f0f,0x0ff0,0x0fff,
  38    0xf000,0xf00f,0xf0f0,0xf0ff,
  39    0xff00,0xff0f,0xfff0,0xffff
  40#elif defined(__LITTLE_ENDIAN)
  41    0x0000,0xf000,0x0f00,0xff00,
  42    0x00f0,0xf0f0,0x0ff0,0xfff0,
  43    0x000f,0xf00f,0x0f0f,0xff0f,
  44    0x00ff,0xf0ff,0x0fff,0xffff
  45#else
  46#error FIXME: No endianness??
  47#endif
  48
  49};
  50
  51void fbcon_cfb4_setup(struct display *p)
  52{
  53    p->next_line = p->line_length ? p->line_length : p->var.xres_virtual>>1;
  54    p->next_plane = 0;
  55}
  56
  57void fbcon_cfb4_bmove(struct display *p, int sy, int sx, int dy, int dx,
  58                      int height, int width)
  59{
  60        int bytes = p->next_line, linesize = bytes * fontheight(p), rows;
  61        u8 *src,*dst;
  62
  63        if (sx == 0 && dx == 0 && width * 4 == bytes) {
  64                fb_memmove(p->screen_base + dy * linesize,
  65                          p->screen_base + sy * linesize,
  66                          height * linesize);
  67        }
  68        else {
  69                if (dy < sy || (dy == sy && dx < sx)) {
  70                        src = p->screen_base + sy * linesize + sx * 4;
  71                        dst = p->screen_base + dy * linesize + dx * 4;
  72                        for (rows = height * fontheight(p) ; rows-- ;) {
  73                                fb_memmove(dst, src, width * 4);
  74                                src += bytes;
  75                                dst += bytes;
  76                        }
  77                }
  78                else {
  79                        src = p->screen_base + (sy+height) * linesize + sx * 4
  80                                - bytes;
  81                        dst = p->screen_base + (dy+height) * linesize + dx * 4
  82                                - bytes;
  83                        for (rows = height * fontheight(p) ; rows-- ;) {
  84                                fb_memmove(dst, src, width * 4);
  85                                src -= bytes;
  86                                dst -= bytes;
  87                        }
  88                }
  89        }
  90}
  91
  92void fbcon_cfb4_clear(struct vc_data *conp, struct display *p, int sy, int sx,
  93                      int height, int width)
  94{
  95        u8 *dest0,*dest;
  96        int bytes=p->next_line,lines=height * fontheight(p), rows, i;
  97        u32 bgx;
  98
  99/*      if(p->screen_base!=0xFDD00020)
 100                mac_boom(1);*/
 101        dest = p->screen_base + sy * fontheight(p) * bytes + sx * 4;
 102
 103        bgx=attr_bgcol_ec(p,conp);
 104        bgx |= (bgx << 4);      /* expand the colour to 32bits */
 105        bgx |= (bgx << 8);
 106        bgx |= (bgx << 16);
 107
 108        if (sx == 0 && width * 4 == bytes) {
 109                for (i = 0 ; i < lines * width ; i++) {
 110                        fb_writel (bgx, dest);
 111                        dest+=4;
 112                }
 113        } else {
 114                dest0=dest;
 115                for (rows = lines; rows-- ; dest0 += bytes) {
 116                        dest=dest0;
 117                        for (i = 0 ; i < width ; i++) {
 118                                /* memset ?? */
 119                                fb_writel (bgx, dest);
 120                                dest+=4;
 121                        }
 122                }
 123        }
 124}
 125
 126void fbcon_cfb4_putc(struct vc_data *conp, struct display *p, int c, int yy,
 127                     int xx)
 128{
 129        u8 *dest,*cdat;
 130        int bytes=p->next_line,rows;
 131        u32 eorx,fgx,bgx;
 132
 133        dest = p->screen_base + yy * fontheight(p) * bytes + xx * 4;
 134        cdat = p->fontdata + (c & p->charmask) * fontheight(p);
 135
 136        fgx=attr_fgcol(p,c);
 137        bgx=attr_bgcol(p,c);
 138        fgx |= (fgx << 4);
 139        fgx |= (fgx << 8);
 140        bgx |= (bgx << 4);
 141        bgx |= (bgx << 8);
 142        eorx = fgx ^ bgx;
 143
 144        for (rows = fontheight(p) ; rows-- ; dest += bytes) {
 145                fb_writew((nibbletab_cfb4[*cdat >> 4] & eorx) ^ bgx, dest+0);
 146                fb_writew((nibbletab_cfb4[*cdat++ & 0xf] & eorx) ^ bgx, dest+2);
 147        }
 148}
 149
 150void fbcon_cfb4_putcs(struct vc_data *conp, struct display *p, 
 151                      const unsigned short *s, int count, int yy, int xx)
 152{
 153        u8 *cdat, *dest, *dest0;
 154        u16 c;
 155        int rows,bytes=p->next_line;
 156        u32 eorx, fgx, bgx;
 157
 158        dest0 = p->screen_base + yy * fontheight(p) * bytes + xx * 4;
 159        c = scr_readw(s);
 160        fgx = attr_fgcol(p, c);
 161        bgx = attr_bgcol(p, c);
 162        fgx |= (fgx << 4);
 163        fgx |= (fgx << 8);
 164        fgx |= (fgx << 16);
 165        bgx |= (bgx << 4);
 166        bgx |= (bgx << 8);
 167        bgx |= (bgx << 16);
 168        eorx = fgx ^ bgx;
 169        while (count--) {
 170                c = scr_readw(s++) & p->charmask;
 171                cdat = p->fontdata + c * fontheight(p);
 172
 173                for (rows = fontheight(p), dest = dest0; rows-- ; dest += bytes) {
 174                        fb_writew((nibbletab_cfb4[*cdat >> 4] & eorx) ^ bgx, dest+0);
 175                        fb_writew((nibbletab_cfb4[*cdat++ & 0xf] & eorx) ^ bgx, dest+2);
 176                }
 177                dest0+=4;
 178        }
 179}
 180
 181void fbcon_cfb4_revc(struct display *p, int xx, int yy)
 182{
 183        u8 *dest;
 184        int bytes=p->next_line, rows;
 185
 186        dest = p->screen_base + yy * fontheight(p) * bytes + xx * 4;
 187        for (rows = fontheight(p) ; rows-- ; dest += bytes) {
 188                fb_writel(fb_readl(dest+0) ^ 0xffffffff, dest+0);
 189        }
 190}
 191
 192
 193    /*
 194     *  `switch' for the low level operations
 195     */
 196
 197struct display_switch fbcon_cfb4 = {
 198    setup:              fbcon_cfb4_setup,
 199    bmove:              fbcon_cfb4_bmove,
 200    clear:              fbcon_cfb4_clear,
 201    putc:               fbcon_cfb4_putc,
 202    putcs:              fbcon_cfb4_putcs,
 203    revc:               fbcon_cfb4_revc,
 204    fontwidthmask:      FONTWIDTH(8)
 205};
 206
 207
 208#ifdef MODULE
 209MODULE_LICENSE("GPL");
 210
 211int init_module(void)
 212{
 213    return 0;
 214}
 215
 216void cleanup_module(void)
 217{}
 218#endif /* MODULE */
 219
 220
 221    /*
 222     *  Visible symbols for modules
 223     */
 224
 225EXPORT_SYMBOL(fbcon_cfb4);
 226EXPORT_SYMBOL(fbcon_cfb4_setup);
 227EXPORT_SYMBOL(fbcon_cfb4_bmove);
 228EXPORT_SYMBOL(fbcon_cfb4_clear);
 229EXPORT_SYMBOL(fbcon_cfb4_putc);
 230EXPORT_SYMBOL(fbcon_cfb4_putcs);
 231EXPORT_SYMBOL(fbcon_cfb4_revc);
 232