2 * linux/drivers/video/afb.c -- Low level frame buffer operations for
5 * Created 5 Apr 1997 by Geert Uytterhoeven
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file COPYING in the main directory of this archive for
12 #include <linux/module.h>
13 #include <linux/tty.h>
14 #include <linux/console.h>
15 #include <linux/string.h>
18 #include <video/fbcon.h>
19 #include <video/fbcon-afb.h>
23 * Bitplanes à la Amiga
26 static u8 expand_table[1024] = {
28 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
29 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
30 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
31 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
32 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
33 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
34 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
35 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
36 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
37 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
38 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
39 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
40 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
41 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
42 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
43 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
44 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
45 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
46 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
47 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
48 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
49 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
50 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
51 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
52 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
53 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
54 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
55 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
56 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
57 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
59 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
61 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
62 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
63 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
64 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
65 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
66 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
67 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
68 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
69 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
70 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
71 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
72 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
73 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
74 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
75 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
76 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
77 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
78 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
79 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
80 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
81 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
82 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
83 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
84 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
85 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
86 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
87 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
88 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
89 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
90 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
91 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
92 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
94 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
95 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
96 0xef, 0xee, 0xed, 0xec, 0xeb, 0xea, 0xe9, 0xe8,
97 0xe7, 0xe6, 0xe5, 0xe4, 0xe3, 0xe2, 0xe1, 0xe0,
98 0xdf, 0xde, 0xdd, 0xdc, 0xdb, 0xda, 0xd9, 0xd8,
99 0xd7, 0xd6, 0xd5, 0xd4, 0xd3, 0xd2, 0xd1, 0xd0,
100 0xcf, 0xce, 0xcd, 0xcc, 0xcb, 0xca, 0xc9, 0xc8,
101 0xc7, 0xc6, 0xc5, 0xc4, 0xc3, 0xc2, 0xc1, 0xc0,
102 0xbf, 0xbe, 0xbd, 0xbc, 0xbb, 0xba, 0xb9, 0xb8,
103 0xb7, 0xb6, 0xb5, 0xb4, 0xb3, 0xb2, 0xb1, 0xb0,
104 0xaf, 0xae, 0xad, 0xac, 0xab, 0xaa, 0xa9, 0xa8,
105 0xa7, 0xa6, 0xa5, 0xa4, 0xa3, 0xa2, 0xa1, 0xa0,
106 0x9f, 0x9e, 0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98,
107 0x97, 0x96, 0x95, 0x94, 0x93, 0x92, 0x91, 0x90,
108 0x8f, 0x8e, 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88,
109 0x87, 0x86, 0x85, 0x84, 0x83, 0x82, 0x81, 0x80,
110 0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0x7a, 0x79, 0x78,
111 0x77, 0x76, 0x75, 0x74, 0x73, 0x72, 0x71, 0x70,
112 0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x69, 0x68,
113 0x67, 0x66, 0x65, 0x64, 0x63, 0x62, 0x61, 0x60,
114 0x5f, 0x5e, 0x5d, 0x5c, 0x5b, 0x5a, 0x59, 0x58,
115 0x57, 0x56, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50,
116 0x4f, 0x4e, 0x4d, 0x4c, 0x4b, 0x4a, 0x49, 0x48,
117 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, 0x40,
118 0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38,
119 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30,
120 0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28,
121 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20,
122 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18,
123 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
124 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
125 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
127 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
128 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
129 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
130 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
131 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
132 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
133 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
134 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
135 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
136 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
137 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
138 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
139 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
140 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
141 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
142 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
143 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
144 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
145 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
146 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
147 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
148 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
149 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
150 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
151 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
152 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
153 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
154 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
155 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
156 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
157 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
158 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
161 void fbcon_afb_setup(struct display *p)
164 p->next_line = p->line_length;
166 p->next_line = p->var.xres_virtual>>3;
167 p->next_plane = p->var.yres_virtual*p->next_line;
170 void fbcon_afb_bmove(struct display *p, int sy, int sx, int dy, int dx,
171 int height, int width)
173 u8 *src, *dest, *src0, *dest0;
176 if (sx == 0 && dx == 0 && width == p->next_line) {
177 src = p->screen_base+sy*fontheight(p)*width;
178 dest = p->screen_base+dy*fontheight(p)*width;
179 i = p->var.bits_per_pixel;
181 fb_memmove(dest, src, height*fontheight(p)*width);
182 src += p->next_plane;
183 dest += p->next_plane;
185 } else if (dy <= sy) {
186 src0 = p->screen_base+sy*fontheight(p)*p->next_line+sx;
187 dest0 = p->screen_base+dy*fontheight(p)*p->next_line+dx;
188 i = p->var.bits_per_pixel;
192 j = height*fontheight(p);
194 fb_memmove(dest, src, width);
196 dest += p->next_line;
198 src0 += p->next_plane;
199 dest0 += p->next_plane;
202 src0 = p->screen_base+(sy+height)*fontheight(p)*p->next_line+sx;
203 dest0 = p->screen_base+(dy+height)*fontheight(p)*p->next_line+dx;
204 i = p->var.bits_per_pixel;
208 j = height*fontheight(p);
211 dest -= p->next_line;
212 fb_memmove(dest, src, width);
214 src0 += p->next_plane;
215 dest0 += p->next_plane;
220 void fbcon_afb_clear(struct vc_data *conp, struct display *p, int sy, int sx,
221 int height, int width)
227 dest0 = p->screen_base+sy*fontheight(p)*p->next_line+sx;
229 bg = attr_bgcol_ec(p,conp);
230 i = p->var.bits_per_pixel;
233 j = height*fontheight(p);
236 fb_memset255(dest, width);
238 fb_memclear(dest, width);
239 dest += p->next_line;
242 dest0 += p->next_plane;
246 void fbcon_afb_putc(struct vc_data *conp, struct display *p, int c, int yy,
249 u8 *dest, *dest0, *cdat, *cdat0, *expand;
253 dest0 = p->screen_base+yy*fontheight(p)*p->next_line+xx;
254 cdat0 = p->fontdata+(c&p->charmask)*fontheight(p);
255 fg = attr_fgcol(p,c);
256 bg = attr_bgcol(p,c);
258 i = p->var.bits_per_pixel;
262 expand = expand_table;
269 *dest = expand[*cdat++];
270 dest += p->next_line;
274 dest0 += p->next_plane;
279 * I've split the console character loop in two parts
280 * (cfr. fbcon_putcs_ilbm())
283 void fbcon_afb_putcs(struct vc_data *conp, struct display *p,
284 const unsigned short *s, int count, int yy, int xx)
286 u8 *dest, *dest0, *dest1, *expand;
287 u8 *cdat1, *cdat2, *cdat3, *cdat4, *cdat10, *cdat20, *cdat30, *cdat40;
290 int fg0, bg0, fg, bg;
292 dest0 = p->screen_base+yy*fontheight(p)*p->next_line+xx;
294 fg0 = attr_fgcol(p, c1);
295 bg0 = attr_bgcol(p, c1);
298 if (xx&3 || count < 3) { /* Slow version */
299 c1 = scr_readw(s++) & p->charmask;
303 cdat10 = p->fontdata+c1*fontheight(p);
307 i = p->var.bits_per_pixel;
311 expand = expand_table;
318 *dest = expand[*cdat1++];
319 dest += p->next_line;
323 dest1 += p->next_plane;
325 } else { /* Fast version */
326 c1 = scr_readw(&s[0]) & p->charmask;
327 c2 = scr_readw(&s[1]) & p->charmask;
328 c3 = scr_readw(&s[2]) & p->charmask;
329 c4 = scr_readw(&s[3]) & p->charmask;
332 cdat10 = p->fontdata+c1*fontheight(p);
333 cdat20 = p->fontdata+c2*fontheight(p);
334 cdat30 = p->fontdata+c3*fontheight(p);
335 cdat40 = p->fontdata+c4*fontheight(p);
339 i = p->var.bits_per_pixel;
346 expand = expand_table;
353 #if defined(__BIG_ENDIAN)
354 *(u32 *)dest = expand[*cdat1++]<<24 |
355 expand[*cdat2++]<<16 |
356 expand[*cdat3++]<<8 |
358 #elif defined(__LITTLE_ENDIAN)
359 *(u32 *)dest = expand[*cdat1++] |
360 expand[*cdat2++]<<8 |
361 expand[*cdat3++]<<16 |
362 expand[*cdat4++]<<24;
364 #error FIXME: No endianness??
366 dest += p->next_line;
370 dest1 += p->next_plane;
379 void fbcon_afb_revc(struct display *p, int xx, int yy)
385 dest0 = p->screen_base+yy*fontheight(p)*p->next_line+xx;
386 mask = p->fgcol ^ p->bgcol;
389 * This should really obey the individual character's
390 * background and foreground colors instead of simply
394 i = p->var.bits_per_pixel;
401 dest += p->next_line;
405 dest0 += p->next_plane;
411 * `switch' for the low level operations
414 struct display_switch fbcon_afb = {
415 setup: fbcon_afb_setup,
416 bmove: fbcon_afb_bmove,
417 clear: fbcon_afb_clear,
418 putc: fbcon_afb_putc,
419 putcs: fbcon_afb_putcs,
420 revc: fbcon_afb_revc,
421 fontwidthmask: FONTWIDTH(8)
426 MODULE_LICENSE("GPL");
428 int init_module(void)
433 void cleanup_module(void)
439 * Visible symbols for modules
442 EXPORT_SYMBOL(fbcon_afb);
443 EXPORT_SYMBOL(fbcon_afb_setup);
444 EXPORT_SYMBOL(fbcon_afb_bmove);
445 EXPORT_SYMBOL(fbcon_afb_clear);
446 EXPORT_SYMBOL(fbcon_afb_putc);
447 EXPORT_SYMBOL(fbcon_afb_putcs);
448 EXPORT_SYMBOL(fbcon_afb_revc);