linux-old/drivers/video/fbcon-cfb2.c
<<
>>
Prefs
   1/*
   2 *  linux/drivers/video/cfb2.c -- Low level frame buffer operations for 2 bpp
   3 *                                packed pixels
   4 *
   5 *      Created 26 Dec 1997 by Michael Schmitz
   6 *      Based on cfb4.c
   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-cfb2.h>
  21
  22
  23    /*
  24     *  2 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 u_char nibbletab_cfb2[]={
  35#if defined(__BIG_ENDIAN)
  36        0x00,0x03,0x0c,0x0f,
  37        0x30,0x33,0x3c,0x3f,
  38        0xc0,0xc3,0xcc,0xcf,
  39        0xf0,0xf3,0xfc,0xff
  40#elif defined(__LITTLE_ENDIAN)
  41        0x00,0xc0,0x30,0xf0,
  42        0x0c,0xcc,0x3c,0xfc,
  43        0x03,0xc3,0x33,0xf3,
  44        0x0f,0xcf,0x3f,0xff
  45#else
  46#error FIXME: No endianness??
  47#endif
  48};
  49 
  50
  51void fbcon_cfb2_setup(struct display *p)
  52{
  53    p->next_line = p->line_length ? p->line_length : p->var.xres_virtual>>2;
  54    p->next_plane = 0;
  55}
  56
  57void fbcon_cfb2_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 * 2 == 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 * 2;
  71                        dst = p->screen_base + dy * linesize + dx * 2;
  72                        for (rows = height * fontheight(p) ; rows-- ;) {
  73                                fb_memmove(dst, src, width * 2);
  74                                src += bytes;
  75                                dst += bytes;
  76                        }
  77                }
  78                else {
  79                        src = p->screen_base + (sy+height) * linesize + sx * 2
  80                                - bytes;
  81                        dst = p->screen_base + (dy+height) * linesize + dx * 2
  82                                - bytes;
  83                        for (rows = height * fontheight(p) ; rows-- ;) {
  84                                fb_memmove(dst, src, width * 2);
  85                                src -= bytes;
  86                                dst -= bytes;
  87                        }
  88                }
  89        }
  90}
  91
  92void fbcon_cfb2_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        dest = p->screen_base + sy * fontheight(p) * bytes + sx * 2;
 100
 101        bgx=attr_bgcol_ec(p,conp);
 102        bgx |= (bgx << 2);      /* expand the colour to 16 bits */
 103        bgx |= (bgx << 4);
 104        bgx |= (bgx << 8);
 105
 106        if (sx == 0 && width * 2 == bytes) {
 107                for (i = 0 ; i < lines * width ; i++) {
 108                        fb_writew (bgx, dest);
 109                        dest+=2;
 110                }
 111        } else {
 112                dest0=dest;
 113                for (rows = lines; rows-- ; dest0 += bytes) {
 114                        dest=dest0;
 115                        for (i = 0 ; i < width ; i++) {
 116                                /* memset ?? */
 117                                fb_writew (bgx, dest);
 118                                dest+=2;
 119                        }
 120                }
 121        }
 122}
 123
 124void fbcon_cfb2_putc(struct vc_data *conp, struct display *p, int c, int yy,
 125                     int xx)
 126{
 127        u8 *dest,*cdat;
 128        int bytes=p->next_line,rows;
 129        u32 eorx,fgx,bgx;
 130
 131        dest = p->screen_base + yy * fontheight(p) * bytes + xx * 2;
 132        cdat = p->fontdata + (c & p->charmask) * fontheight(p);
 133
 134        fgx=3;/*attr_fgcol(p,c);*/
 135        bgx=attr_bgcol(p,c);
 136        fgx |= (fgx << 2);      /* expand color to 8 bits */
 137        fgx |= (fgx << 4);
 138        bgx |= (bgx << 2);
 139        bgx |= (bgx << 4);
 140        eorx = fgx ^ bgx;
 141
 142        for (rows = fontheight(p) ; rows-- ; dest += bytes) {
 143                fb_writeb((nibbletab_cfb2[*cdat >> 4] & eorx) ^ bgx, dest+0);
 144                fb_writeb((nibbletab_cfb2[*cdat++ & 0xf] & eorx) ^ bgx, dest+1);
 145        }
 146}
 147
 148void fbcon_cfb2_putcs(struct vc_data *conp, struct display *p, const unsigned short *s,
 149                      int count, int yy, int xx)
 150{
 151        u8 *cdat, *dest, *dest0;
 152        u16 c;
 153        int rows,bytes=p->next_line;
 154        u32 eorx, fgx, bgx;
 155
 156        dest0 = p->screen_base + yy * fontheight(p) * bytes + xx * 2;
 157        c = scr_readw(s);
 158        fgx = 3/*attr_fgcol(p, c)*/;
 159        bgx = attr_bgcol(p, c);
 160        fgx |= (fgx << 2);
 161        fgx |= (fgx << 4);
 162        bgx |= (bgx << 2);
 163        bgx |= (bgx << 4);
 164        eorx = fgx ^ bgx;
 165        while (count--) {
 166                c = scr_readw(s++) & p->charmask;
 167                cdat = p->fontdata + c * fontheight(p);
 168
 169                for (rows = fontheight(p), dest = dest0; rows-- ; dest += bytes) {
 170                        fb_writeb((nibbletab_cfb2[*cdat >> 4] & eorx) ^ bgx, dest+0);
 171                        fb_writeb((nibbletab_cfb2[*cdat++ & 0xf] & eorx) ^ bgx, dest+1);
 172                }
 173                dest0+=2;
 174        }
 175}
 176
 177void fbcon_cfb2_revc(struct display *p, int xx, int yy)
 178{
 179        u8 *dest;
 180        int bytes=p->next_line, rows;
 181
 182        dest = p->screen_base + yy * fontheight(p) * bytes + xx * 2;
 183        for (rows = fontheight(p) ; rows-- ; dest += bytes) {
 184                fb_writew(fb_readw(dest) ^ 0xffff, dest);
 185        }
 186}
 187
 188
 189    /*
 190     *  `switch' for the low level operations
 191     */
 192
 193struct display_switch fbcon_cfb2 = {
 194    setup:              fbcon_cfb2_setup,
 195    bmove:              fbcon_cfb2_bmove,
 196    clear:              fbcon_cfb2_clear,
 197    putc:               fbcon_cfb2_putc,
 198    putcs:              fbcon_cfb2_putcs,
 199    revc:               fbcon_cfb2_revc,
 200    fontwidthmask:      FONTWIDTH(8)
 201};
 202
 203
 204#ifdef MODULE
 205MODULE_LICENSE("GPL");
 206
 207int init_module(void)
 208{
 209    return 0;
 210}
 211
 212void cleanup_module(void)
 213{}
 214#endif /* MODULE */
 215
 216
 217    /*
 218     *  Visible symbols for modules
 219     */
 220
 221EXPORT_SYMBOL(fbcon_cfb2);
 222EXPORT_SYMBOL(fbcon_cfb2_setup);
 223EXPORT_SYMBOL(fbcon_cfb2_bmove);
 224EXPORT_SYMBOL(fbcon_cfb2_clear);
 225EXPORT_SYMBOL(fbcon_cfb2_putc);
 226EXPORT_SYMBOL(fbcon_cfb2_putcs);
 227EXPORT_SYMBOL(fbcon_cfb2_revc);
 228