pre-2.1.132-4..
[davej-history.git] / include / video / fbcon.h
blob5502b23811336a3911d9cbabbe319b43782c60e5
1 /*
2 * linux/drivers/video/fbcon.h -- Low level frame buffer based console driver
4 * Copyright (C) 1997 Geert Uytterhoeven
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive
8 * for more details.
9 */
11 #ifndef _VIDEO_FBCON_H
12 #define _VIDEO_FBCON_H
14 #include <linux/config.h>
15 #include <linux/console_struct.h>
18 /*
19 * `switch' for the Low Level Operations
22 struct display_switch {
23 void (*setup)(struct display *p);
24 void (*bmove)(struct display *p, int sy, int sx, int dy, int dx,
25 int height, int width);
26 /* for clear, conp may be NULL, which means use a blanking (black) color */
27 void (*clear)(struct vc_data *conp, struct display *p, int sy, int sx,
28 int height, int width);
29 void (*putc)(struct vc_data *conp, struct display *p, int c, int yy,
30 int xx);
31 void (*putcs)(struct vc_data *conp, struct display *p, const unsigned short *s,
32 int count, int yy, int xx);
33 void (*revc)(struct display *p, int xx, int yy);
34 void (*cursor)(struct display *p, int mode, int xx, int yy);
35 int (*set_font)(struct display *p, int width, int height);
36 void (*clear_margins)(struct vc_data *conp, struct display *p,
37 int bottom_only);
38 unsigned int fontwidthmask; /* 1 at (1 << (width - 1)) if width is supported */
39 };
41 extern struct display_switch fbcon_dummy;
43 #define fontheight(p) ((p)->_fontheight)
44 #define fontheightlog(p) ((p)->_fontheightlog)
46 #ifdef CONFIG_FBCON_FONTWIDTH8_ONLY
48 /* fontwidth w is supported by dispsw */
49 #define FONTWIDTH(w) (1 << ((8) - 1))
50 /* fontwidths w1-w2 inclusive are supported by dispsw */
51 #define FONTWIDTHRANGE(w1,w2) FONTWIDTH(8)
53 #define fontwidth(p) (8)
54 #define fontwidthlog(p) (0)
56 #else
58 /* fontwidth w is supported by dispsw */
59 #define FONTWIDTH(w) (1 << ((w) - 1))
60 /* fontwidths w1-w2 inclusive are supported by dispsw */
61 #define FONTWIDTHRANGE(w1,w2) (FONTWIDTH(w2+1) - FONTWIDTH(w1))
63 #define fontwidth(p) ((p)->_fontwidth)
64 #define fontwidthlog(p) ((p)->_fontwidthlog)
66 #endif
69 * Attribute Decoding
72 /* Color */
73 #define attr_fgcol(p,s) \
74 (((s) >> ((p)->fgshift)) & 0x0f)
75 #define attr_bgcol(p,s) \
76 (((s) >> ((p)->bgshift)) & 0x0f)
77 #define attr_bgcol_ec(p,conp) \
78 ((conp) ? (((conp)->vc_video_erase_char >> ((p)->bgshift)) & 0x0f) : 0)
80 /* Monochrome */
81 #define attr_bold(p,s) \
82 ((s) & 0x200)
83 #define attr_reverse(p,s) \
84 (((s) & 0x800) ^ ((p)->inverse ? 0x800 : 0))
85 #define attr_underline(p,s) \
86 ((s) & 0x400)
87 #define attr_blink(p,s) \
88 ((s) & 0x8000)
91 * Scroll Method
94 /* Internal flags */
95 #define __SCROLL_YPAN 0x001
96 #define __SCROLL_YWRAP 0x002
97 #define __SCROLL_YMOVE 0x003
98 #define __SCROLL_YREDRAW 0x004
99 #define __SCROLL_YMASK 0x00f
100 #define __SCROLL_YFIXED 0x010
101 #define __SCROLL_YNOMOVE 0x020
102 #define __SCROLL_YPANREDRAW 0x040
103 #define __SCROLL_YNOPARTIAL 0x080
105 /* Only these should be used by the drivers */
106 /* Which one should you use? If you have a fast card and slow bus,
107 then probably just 0 to indicate fbcon should choose between
108 YWRAP/YPAN+MOVE/YMOVE. On the other side, if you have a fast bus
109 and even better if your card can do fonting (1->8/32bit painting),
110 you should consider either SCROLL_YREDRAW (if your card is
111 able to do neither YPAN/YWRAP), or SCROLL_YNOMOVE.
112 The best is to test it with some real life scrolling (usually, not
113 all lines on the screen are filled completely with non-space characters,
114 and REDRAW performs much better on such lines, so don't cat a file
115 with every line covering all screen columns, it would not be the right
116 benchmark).
118 #define SCROLL_YREDRAW (__SCROLL_YFIXED|__SCROLL_YREDRAW)
119 #define SCROLL_YNOMOVE (__SCROLL_YNOMOVE|__SCROLL_YPANREDRAW)
121 /* SCROLL_YNOPARTIAL, used in combination with the above, is for video
122 cards which can not handle using panning to scroll a portion of the
123 screen without excessive flicker. Panning will only be used for
124 whole screens.
126 /* Namespace consistency */
127 #define SCROLL_YNOPARTIAL __SCROLL_YNOPARTIAL
130 extern void fbcon_redraw_bmove(struct display *, int, int, int, int, int, int);
133 /* ================================================================= */
134 /* Utility Assembler Functions */
135 /* ================================================================= */
138 #if defined(__mc68000__)
140 /* ====================================================================== */
142 /* Those of a delicate disposition might like to skip the next couple of
143 * pages.
145 * These functions are drop in replacements for memmove and
146 * memset(_, 0, _). However their five instances add at least a kilobyte
147 * to the object file. You have been warned.
149 * Not a great fan of assembler for the sake of it, but I think
150 * that these routines are at least 10 times faster than their C
151 * equivalents for large blits, and that's important to the lowest level of
152 * a graphics driver. Question is whether some scheme with the blitter
153 * would be faster. I suspect not for simple text system - not much
154 * asynchrony.
156 * Code is very simple, just gruesome expansion. Basic strategy is to
157 * increase data moved/cleared at each step to 16 bytes to reduce
158 * instruction per data move overhead. movem might be faster still
159 * For more than 15 bytes, we try to align the write direction on a
160 * longword boundary to get maximum speed. This is even more gruesome.
161 * Unaligned read/write used requires 68020+ - think this is a problem?
163 * Sorry!
167 /* ++roman: I've optimized Robert's original versions in some minor
168 * aspects, e.g. moveq instead of movel, let gcc choose the registers,
169 * use movem in some places...
170 * For other modes than 1 plane, lots of more such assembler functions
171 * were needed (e.g. the ones using movep or expanding color values).
174 /* ++andreas: more optimizations:
175 subl #65536,d0 replaced by clrw d0; subql #1,d0 for dbcc
176 addal is faster than addaw
177 movep is rather expensive compared to ordinary move's
178 some functions rewritten in C for clarity, no speed loss */
180 static __inline__ void *mymemclear_small(void *s, size_t count)
182 if (!count)
183 return(0);
185 __asm__ __volatile__(
186 "lsrl #1,%1 ; jcc 1f ; moveb %2,%0@-\n\t"
187 "1: lsrl #1,%1 ; jcc 1f ; movew %2,%0@-\n\t"
188 "1: lsrl #1,%1 ; jcc 1f ; movel %2,%0@-\n\t"
189 "1: lsrl #1,%1 ; jcc 1f ; movel %2,%0@- ; movel %2,%0@-\n\t"
190 "1: subql #1,%1 ; jcs 3f\n\t"
191 "2: moveml %2/%3/%4/%5,%0@-\n\t"
192 "dbra %1,2b\n\t"
193 "3:"
194 : "=a" (s), "=d" (count)
195 : "d" (0), "d" (0), "d" (0), "d" (0),
196 "0" ((char *)s+count), "1" (count)
199 return(0);
203 static __inline__ void *mymemclear(void *s, size_t count)
205 if (!count)
206 return(0);
208 if (count < 16) {
209 __asm__ __volatile__(
210 "lsrl #1,%1 ; jcc 1f ; clrb %0@+\n\t"
211 "1: lsrl #1,%1 ; jcc 1f ; clrw %0@+\n\t"
212 "1: lsrl #1,%1 ; jcc 1f ; clrl %0@+\n\t"
213 "1: lsrl #1,%1 ; jcc 1f ; clrl %0@+ ; clrl %0@+\n\t"
214 "1:"
215 : "=a" (s), "=d" (count)
216 : "0" (s), "1" (count)
218 } else {
219 long tmp;
220 __asm__ __volatile__(
221 "movel %1,%2\n\t"
222 "lsrl #1,%2 ; jcc 1f ; clrb %0@+ ; subqw #1,%1\n\t"
223 "lsrl #1,%2 ; jcs 2f\n\t" /* %0 increased=>bit 2 switched*/
224 "clrw %0@+ ; subqw #2,%1 ; jra 2f\n\t"
225 "1: lsrl #1,%2 ; jcc 2f\n\t"
226 "clrw %0@+ ; subqw #2,%1\n\t"
227 "2: movew %1,%2; lsrl #2,%1 ; jeq 6f\n\t"
228 "lsrl #1,%1 ; jcc 3f ; clrl %0@+\n\t"
229 "3: lsrl #1,%1 ; jcc 4f ; clrl %0@+ ; clrl %0@+\n\t"
230 "4: subql #1,%1 ; jcs 6f\n\t"
231 "5: clrl %0@+; clrl %0@+ ; clrl %0@+ ; clrl %0@+\n\t"
232 "dbra %1,5b ; clrw %1; subql #1,%1; jcc 5b\n\t"
233 "6: movew %2,%1; btst #1,%1 ; jeq 7f ; clrw %0@+\n\t"
234 "7: ; btst #0,%1 ; jeq 8f ; clrb %0@+\n\t"
235 "8:"
236 : "=a" (s), "=d" (count), "=d" (tmp)
237 : "0" (s), "1" (count)
241 return(0);
245 static __inline__ void *mymemset(void *s, size_t count)
247 if (!count)
248 return(0);
250 __asm__ __volatile__(
251 "lsrl #1,%1 ; jcc 1f ; moveb %2,%0@-\n\t"
252 "1: lsrl #1,%1 ; jcc 1f ; movew %2,%0@-\n\t"
253 "1: lsrl #1,%1 ; jcc 1f ; movel %2,%0@-\n\t"
254 "1: lsrl #1,%1 ; jcc 1f ; movel %2,%0@- ; movel %2,%0@-\n\t"
255 "1: subql #1,%1 ; jcs 3f\n\t"
256 "2: moveml %2/%3/%4/%5,%0@-\n\t"
257 "dbra %1,2b\n\t"
258 "3:"
259 : "=a" (s), "=d" (count)
260 : "d" (-1), "d" (-1), "d" (-1), "d" (-1),
261 "0" ((char *) s + count), "1" (count)
264 return(0);
268 static __inline__ void *mymemmove(void *d, const void *s, size_t count)
270 if (d < s) {
271 if (count < 16) {
272 __asm__ __volatile__(
273 "lsrl #1,%2 ; jcc 1f ; moveb %1@+,%0@+\n\t"
274 "1: lsrl #1,%2 ; jcc 1f ; movew %1@+,%0@+\n\t"
275 "1: lsrl #1,%2 ; jcc 1f ; movel %1@+,%0@+\n\t"
276 "1: lsrl #1,%2 ; jcc 1f ; movel %1@+,%0@+ ; movel %1@+,%0@+\n\t"
277 "1:"
278 : "=a" (d), "=a" (s), "=d" (count)
279 : "0" (d), "1" (s), "2" (count)
281 } else {
282 long tmp;
283 __asm__ __volatile__(
284 "movel %0,%3\n\t"
285 "lsrl #1,%3 ; jcc 1f ; moveb %1@+,%0@+ ; subqw #1,%2\n\t"
286 "lsrl #1,%3 ; jcs 2f\n\t" /* %0 increased=>bit 2 switched*/
287 "movew %1@+,%0@+ ; subqw #2,%2 ; jra 2f\n\t"
288 "1: lsrl #1,%3 ; jcc 2f\n\t"
289 "movew %1@+,%0@+ ; subqw #2,%2\n\t"
290 "2: movew %2,%-; lsrl #2,%2 ; jeq 6f\n\t"
291 "lsrl #1,%2 ; jcc 3f ; movel %1@+,%0@+\n\t"
292 "3: lsrl #1,%2 ; jcc 4f ; movel %1@+,%0@+ ; movel %1@+,%0@+\n\t"
293 "4: subql #1,%2 ; jcs 6f\n\t"
294 "5: movel %1@+,%0@+;movel %1@+,%0@+\n\t"
295 "movel %1@+,%0@+;movel %1@+,%0@+\n\t"
296 "dbra %2,5b ; clrw %2; subql #1,%2; jcc 5b\n\t"
297 "6: movew %+,%2; btst #1,%2 ; jeq 7f ; movew %1@+,%0@+\n\t"
298 "7: ; btst #0,%2 ; jeq 8f ; moveb %1@+,%0@+\n\t"
299 "8:"
300 : "=a" (d), "=a" (s), "=d" (count), "=d" (tmp)
301 : "0" (d), "1" (s), "2" (count)
304 } else {
305 if (count < 16) {
306 __asm__ __volatile__(
307 "lsrl #1,%2 ; jcc 1f ; moveb %1@-,%0@-\n\t"
308 "1: lsrl #1,%2 ; jcc 1f ; movew %1@-,%0@-\n\t"
309 "1: lsrl #1,%2 ; jcc 1f ; movel %1@-,%0@-\n\t"
310 "1: lsrl #1,%2 ; jcc 1f ; movel %1@-,%0@- ; movel %1@-,%0@-\n\t"
311 "1:"
312 : "=a" (d), "=a" (s), "=d" (count)
313 : "0" ((char *) d + count), "1" ((char *) s + count), "2" (count)
315 } else {
316 long tmp;
317 __asm__ __volatile__(
318 "movel %0,%3\n\t"
319 "lsrl #1,%3 ; jcc 1f ; moveb %1@-,%0@- ; subqw #1,%2\n\t"
320 "lsrl #1,%3 ; jcs 2f\n\t" /* %0 increased=>bit 2 switched*/
321 "movew %1@-,%0@- ; subqw #2,%2 ; jra 2f\n\t"
322 "1: lsrl #1,%3 ; jcc 2f\n\t"
323 "movew %1@-,%0@- ; subqw #2,%2\n\t"
324 "2: movew %2,%-; lsrl #2,%2 ; jeq 6f\n\t"
325 "lsrl #1,%2 ; jcc 3f ; movel %1@-,%0@-\n\t"
326 "3: lsrl #1,%2 ; jcc 4f ; movel %1@-,%0@- ; movel %1@-,%0@-\n\t"
327 "4: subql #1,%2 ; jcs 6f\n\t"
328 "5: movel %1@-,%0@-;movel %1@-,%0@-\n\t"
329 "movel %1@-,%0@-;movel %1@-,%0@-\n\t"
330 "dbra %2,5b ; clrw %2; subql #1,%2; jcc 5b\n\t"
331 "6: movew %+,%2; btst #1,%2 ; jeq 7f ; movew %1@-,%0@-\n\t"
332 "7: ; btst #0,%2 ; jeq 8f ; moveb %1@-,%0@-\n\t"
333 "8:"
334 : "=a" (d), "=a" (s), "=d" (count), "=d" (tmp)
335 : "0" ((char *) d + count), "1" ((char *) s + count), "2" (count)
340 return(0);
344 /* ++andreas: Simple and fast version of memmove, assumes size is
345 divisible by 16, suitable for moving the whole screen bitplane */
346 static __inline__ void fast_memmove(char *dst, const char *src, size_t size)
348 if (!size)
349 return;
350 if (dst < src)
351 __asm__ __volatile__
352 ("1:"
353 " moveml %0@+,%/d0/%/d1/%/a0/%/a1\n"
354 " moveml %/d0/%/d1/%/a0/%/a1,%1@\n"
355 " addql #8,%1; addql #8,%1\n"
356 " dbra %2,1b\n"
357 " clrw %2; subql #1,%2\n"
358 " jcc 1b"
359 : "=a" (src), "=a" (dst), "=d" (size)
360 : "0" (src), "1" (dst), "2" (size / 16 - 1)
361 : "d0", "d1", "a0", "a1", "memory");
362 else
363 __asm__ __volatile__
364 ("1:"
365 " subql #8,%0; subql #8,%0\n"
366 " moveml %0@,%/d0/%/d1/%/a0/%/a1\n"
367 " moveml %/d0/%/d1/%/a0/%/a1,%1@-\n"
368 " dbra %2,1b\n"
369 " clrw %2; subql #1,%2\n"
370 " jcc 1b"
371 : "=a" (src), "=a" (dst), "=d" (size)
372 : "0" (src + size), "1" (dst + size), "2" (size / 16 - 1)
373 : "d0", "d1", "a0", "a1", "memory");
376 #elif defined(CONFIG_SUN4)
378 /* You may think that I'm crazy and that I should use generic
379 routines. No, I'm not: sun4's framebuffer crashes if we std
380 into it, so we cannot use memset. */
382 static __inline__ void *sun4_memset(void *s, char val, size_t count)
384 int i;
385 for(i=0; i<count;i++)
386 ((char *) s) [i] = val;
387 return s;
390 static __inline__ void *mymemset(void *s, size_t count)
392 return sun4_memset(s, 255, count);
395 static __inline__ void *mymemclear(void *s, size_t count)
397 return sun4_memset(s, 0, count);
400 static __inline__ void *mymemclear_small(void *s, size_t count)
402 return sun4_memset(s, 0, count);
405 /* To be honest, this is slow_memmove :). But sun4 is crappy, so what we can do. */
406 static __inline__ void fast_memmove(void *d, const void *s, size_t count)
408 int i;
409 if (d<s) {
410 for (i=0; i<count; i++)
411 ((char *) d)[i] = ((char *) s)[i];
412 } else
413 for (i=0; i<count; i++)
414 ((char *) d)[count-i-1] = ((char *) s)[count-i-1];
417 static __inline__ void *mymemmove(char *dst, const char *src, size_t size)
419 fast_memmove(dst, src, size);
420 return dst;
423 #else
425 static __inline__ void *mymemclear_small(void *s, size_t count)
427 return(memset(s, 0, count));
430 static __inline__ void *mymemclear(void *s, size_t count)
432 return(memset(s, 0, count));
435 static __inline__ void *mymemset(void *s, size_t count)
437 return(memset(s, 255, count));
440 #if defined(__i386__)
442 static __inline__ void fast_memmove(void *d, const void *s, size_t count)
444 if (d < s) {
445 __asm__ __volatile__ (
446 "cld\n\t"
447 "shrl $1,%%ecx\n\t"
448 "jnc 1f\n\t"
449 "movsb\n"
450 "1:\tshrl $1,%%ecx\n\t"
451 "jnc 2f\n\t"
452 "movsw\n"
453 "2:\trep\n\t"
454 "movsl"
455 : /* no output */
456 :"c"(count),"D"((long)d),"S"((long)s)
457 :"cx","di","si","memory");
458 } else {
459 __asm__ __volatile__ (
460 "std\n\t"
461 "shrl $1,%%ecx\n\t"
462 "jnc 1f\n\t"
463 "movb 3(%%esi),%%al\n\t"
464 "movb %%al,3(%%edi)\n\t"
465 "decl %%esi\n\t"
466 "decl %%edi\n"
467 "1:\tshrl $1,%%ecx\n\t"
468 "jnc 2f\n\t"
469 "movw 2(%%esi),%%ax\n\t"
470 "movw %%ax,2(%%edi)\n\t"
471 "decl %%esi\n\t"
472 "decl %%edi\n\t"
473 "decl %%esi\n\t"
474 "decl %%edi\n"
475 "2:\trep\n\t"
476 "movsl\n\t"
477 "cld"
478 : /* no output */
479 :"c"(count),"D"(count-4+(long)d),"S"(count-4+(long)s)
480 :"ax","cx","di","si","memory");
484 static __inline__ void *mymemmove(char *dst, const char *src, size_t size)
486 fast_memmove(dst, src, size);
487 return dst;
490 #else /* !i386 */
493 * Anyone who'd like to write asm functions for other CPUs?
494 * (Why are these functions better than those from include/asm/string.h?)
497 static __inline__ void *mymemmove(void *d, const void *s, size_t count)
499 return(memmove(d, s, count));
502 static __inline__ void fast_memmove(char *dst, const char *src, size_t size)
504 memmove(dst, src, size);
507 #endif /* !i386 */
509 #endif
511 #endif /* _VIDEO_FBCON_H */