This source file includes following definitions.
- CURSOR_UNDRAWN
- fbcon_startup
- fbcon_init
- fbcon_deinit
- fbcon_changevar
- fbcon_setup
- mymemclear_small
- mymemclear
- mymemset
- mymemmove
- fast_memmove
- memclear_4p_col
- memset_even_4p
- memmove_4p_col
- expand4l
- expand4dl
- dup4l
- memclear_8p_col
- memset_even_8p
- memmove_8p_col
- expand8dl
- memclear_2p_col
- memset_even_2p
- memmove_2p_col
- expand2w
- expand2l
- dup2w
- real_y
- fbcon_clear
- fbcon_putc
- fbcon_putcs
- fbcon_cursor
- fbcon_vbl_handler
- fbcon_scroll
- fbcon_bmove
- fbcon_bmove_rec
- fbcon_switch
- fbcon_blank
- bmove_mono
- clear_mono
- putc_mono
- putcs_mono
- rev_char_mono
- bmove_ilbm
- clear_ilbm
- putc_ilbm
- putcs_ilbm
- rev_char_ilbm
- bmove_plan
- clear_plan
- putc_plan
- putcs_plan
- rev_char_plan
- bmove_2_plane
- clear_2_plane
- putc_2_plane
- putcs_2_plane
- rev_char_2_plane
- bmove_4_plane
- clear_4_plane
- putc_4_plane
- putcs_4_plane
- rev_char_4_plane
- bmove_8_plane
- clear_8_plane
- putc_8_plane
- putcs_8_plane
- rev_char_8_plane
- bmove_8_packed
- clear_8_packed
- putc_8_packed
- putcs_8_packed
- rev_char_8_packed
- bmove_16_packed
- clear_16_packed
- putc_16_packed
- putcs_16_packed
- rev_char_16_packed
- bmove_cyber
- clear_cyber
- putc_cyber
- putcs_cyber
- rev_char_cyber
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 #include <linux/types.h>
43 #include <linux/fs.h>
44 #include <linux/kernel.h>
45 #include <linux/tty.h>
46 #include <linux/console.h>
47 #include <linux/string.h>
48 #include <linux/config.h>
49 #include <linux/kd.h>
50
51 #include <asm/bootinfo.h>
52 #include <asm/irq.h>
53 #ifdef CONFIG_AMIGA
54 #include <asm/amigahw.h>
55 #include <asm/amigaints.h>
56 #endif
57 #ifdef CONFIG_ATARI
58 #include <asm/atariints.h>
59 #endif
60 #ifdef CONFIG_FB_CYBER
61 #include "../amiga/s3blit.h"
62 #endif
63 #include <linux/fb.h>
64 #include <asm/font.h>
65 #include <asm/machdep.h>
66
67 #include <asm/system.h>
68
69 #include "../../../drivers/char/vt_kern.h"
70
71
72
73
74 extern int console_blanked;
75
76
77
78
79
80
81
82
83
84 #undef CONFIG_FBCON_MONO
85 #undef CONFIG_FBCON_ILBM
86 #undef CONFIG_FBCON_PLANES
87 #undef CONFIG_FBCON_2PLANE
88 #undef CONFIG_FBCON_4PLANE
89 #undef CONFIG_FBCON_8PLANE
90 #undef CONFIG_FBCON_8PACKED
91 #undef CONFIG_FBCON_16PACKED
92 #undef CONFIG_FBCON_24PACKED
93 #undef CONFIG_FBCON_32PACKED
94 #undef CONFIG_FBCON_CYBER
95
96
97
98
99 #define CONFIG_FBCON_MONO
100
101
102
103 #ifdef CONFIG_AMIGA
104 #ifndef CONFIG_FBCON_ILBM
105 #define CONFIG_FBCON_ILBM
106 #endif
107 #ifndef CONFIG_FBCON_PLANES
108 #define CONFIG_FBCON_PLANES
109 #endif
110
111
112
113 #ifdef CONFIG_FB_CYBER
114 #ifndef CONFIG_FBCON_CYBER
115 #define CONFIG_FBCON_CYBER
116 #endif
117 #endif
118
119 #endif
120
121
122
123 #ifdef CONFIG_ATARI
124 #ifndef CONFIG_FBCON_2PLANE
125 #define CONFIG_FBCON_2PLANE
126 #endif
127 #ifndef CONFIG_FBCON_4PLANE
128 #define CONFIG_FBCON_4PLANE
129 #endif
130 #ifndef CONFIG_FBCON_8PLANE
131 #define CONFIG_FBCON_8PLANE
132 #endif
133 #ifndef CONFIG_FBCON_8PACKED
134 #define CONFIG_FBCON_8PACKED
135 #endif
136 #ifndef CONFIG_FBCON_16PACKED
137 #define CONFIG_FBCON_16PACKED
138 #endif
139 #endif
140
141
142
143
144 #if defined(CONFIG_FBCON_2PLANE) || defined(CONFIG_FBCON_4PLANE) || \
145 defined(CONFIG_FBCON_8PLANE)
146 #define CONFIG_FBCON_IPLAN2
147 #else
148 #undef CONFIG_FBCON_IPLAN2
149 #endif
150
151 #if defined(CONFIG_FBCON_CYBER) || defined(CONFIG_FBCON_8PACKED) || \
152 defined(CONFIG_FBCON_16PACKED) || defined(CONFIG_FBCON_24PACKED) || \
153 defined(CONFIG_FBCON_32PACKED)
154 #define CONFIG_FBCON_PACKED
155 #else
156 #undef CONFIG_FBCON_PACKED
157 #endif
158
159
160 struct fb_info *fb_info;
161 struct display *disp;
162
163
164
165
166
167 static int cursor_drawn = 0;
168
169 #define CURSOR_DRAW_DELAY (2)
170
171
172 #define AMIGA_CURSOR_BLINK_RATE (20)
173 #define ATARI_CURSOR_BLINK_RATE (42)
174
175 static int vbl_cursor_cnt = 0;
176 static int cursor_on = 0;
177 static int cursor_blink_rate;
178
179 static __inline__ int CURSOR_UNDRAWN(void)
180 {
181 int cursor_was_drawn;
182 vbl_cursor_cnt = 0;
183 cursor_was_drawn = cursor_drawn;
184 cursor_drawn = 0;
185 return(cursor_was_drawn);
186 }
187
188
189
190
191
192
193 #define attr_fgcol(p,conp) \
194 (((conp)->vc_attr >> ((p)->inverse ? 4 : 0)) & 0x0f)
195 #define attr_bgcol(p,conp) \
196 (((conp)->vc_attr >> ((p)->inverse ? 0 : 4)) & 0x0f)
197 #define attr_bgcol_ec(p,conp) \
198 (((conp)->vc_video_erase_char >> ((p)->inverse ? 8 : 12)) & 0x0f)
199
200
201 #define attr_bold(p,conp) \
202 (((conp)->vc_attr & 3) == 2)
203 #define attr_reverse(p,conp) \
204 (((conp)->vc_attr & 8) ^ ((p)->inverse ? 8 : 0))
205 #define attr_underline(p,conp) \
206 (((conp)->vc_attr) & 4)
207
208
209
210
211
212
213 #define SCROLL_YWRAP (0)
214 #define SCROLL_YPAN (1)
215 #define SCROLL_YMOVE (2)
216
217 #define divides(a, b) ((!(a) || (b)%(a)) ? 0 : 1)
218
219
220
221
222
223
224 static u_long fbcon_startup(u_long kmem_start, char **display_desc);
225 static void fbcon_init(struct vc_data *conp);
226 static int fbcon_deinit(struct vc_data *conp);
227 static int fbcon_changevar(int con);
228 static int fbcon_clear(struct vc_data *conp, int sy, int sx, int height,
229 int width);
230 static int fbcon_putc(struct vc_data *conp, int c, int y, int x);
231 static int fbcon_putcs(struct vc_data *conp, const char *s, int count, int y,
232 int x);
233 static int fbcon_cursor(struct vc_data *conp, int mode);
234 static int fbcon_scroll(struct vc_data *conp, int t, int b, int dir, int count);
235 static int fbcon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
236 int height, int width);
237 static int fbcon_switch(struct vc_data *conp);
238 static int fbcon_blank(int blank);
239
240
241
242
243
244
245 static void fbcon_setup(int con, int setcol, int cls);
246 static __inline__ void *mymemclear_small(void *s, size_t count);
247 static __inline__ void *mymemclear(void *s, size_t count);
248 static __inline__ void *mymemset(void *s, size_t count);
249 static __inline__ void *mymemmove(void *d, void *s, size_t count);
250 static __inline__ void fast_memmove(char *dst, char *src, size_t size);
251 static __inline__ void memclear_4p_col(void *d, size_t h, u_long val, int bpr);
252 static __inline__ void memset_even_4p(void *d, size_t count, u_long val1,
253 u_long val2);
254 static __inline__ void memmove_4p_col(void *d, void *s, int h, int bpr);
255 static __inline__ u_long expand4l(u_char c);
256 static __inline__ void expand4dl(u_char c, u_long *ret1, u_long *ret2);
257 static __inline__ u_long dup4l(u_char c);
258 static __inline__ void memclear_8p_col(void *d, size_t h, u_long val1,
259 u_long val2, int bpr);
260 static __inline__ void memset_even_8p(void *d, size_t count, u_long val1,
261 u_long val2, u_long val3, u_long val4);
262 static __inline__ void memmove_8p_col(void *d, void *s, int h, int bpr);
263 static __inline__ void expand8dl(u_char c, u_long *ret1, u_long *ret2);
264 static __inline__ void memclear_2p_col(void *d, size_t h, u_short val, int bpr);
265 static __inline__ void memset_even_2p(void *d, size_t count, u_long val);
266 static __inline__ void memmove_2p_col(void *d, void *s, int h, int bpr);
267 static __inline__ u_short expand2w(u_char c);
268 static __inline__ u_long expand2l(u_char c);
269 static __inline__ u_short dup2w(u_char c);
270 static __inline__ int real_y(struct display *p, int y);
271 static void fbcon_vbl_handler(int irq, struct pt_regs *fp, void *dummy);
272 static void fbcon_bmove_rec(struct display *p, int sy, int sx, int dy, int dx,
273 int height, int width, u_int y_break);
274
275
276
277
278
279
280 #ifdef CONFIG_FBCON_MONO
281 static void bmove_mono(struct display *p, int sy, int sx, int dy, int dx,
282 int height, int width);
283 static void clear_mono(struct vc_data *conp, struct display *p, int sy, int sx,
284 int height, int width);
285 static void putc_mono(struct vc_data *conp, struct display *p, int c, int y,
286 int x);
287 static void putcs_mono(struct vc_data *conp, struct display *p, const char *s,
288 int count, int y, int x);
289 static void rev_char_mono(struct display *p, int x, int y);
290 #endif
291
292
293
294
295
296
297 #ifdef CONFIG_FBCON_ILBM
298 static void bmove_ilbm(struct display *p, int sy, int sx, int dy, int dx,
299 int height, int width);
300 static void clear_ilbm(struct vc_data *conp, struct display *p, int sy, int sx,
301 int height, int width);
302 static void putc_ilbm(struct vc_data *conp, struct display *p, int c, int y,
303 int x);
304 static void putcs_ilbm(struct vc_data *conp, struct display *p, const char *s,
305 int count, int y, int x);
306 static void rev_char_ilbm(struct display *p, int x, int y);
307 #endif
308
309
310
311
312
313
314 #ifdef CONFIG_FBCON_PLANES
315 static void bmove_plan(struct display *p, int sy, int sx, int dy, int dx,
316 int height, int width);
317 static void clear_plan(struct vc_data *conp, struct display *p, int sy, int sx,
318 int height, int width);
319 static void putc_plan(struct vc_data *conp, struct display *p, int c, int y,
320 int x);
321 static void putcs_plan(struct vc_data *conp, struct display *p, const char *s,
322 int count, int y, int x);
323 static void rev_char_plan(struct display *p, int x, int y);
324 #endif
325
326
327
328
329
330
331 #ifdef CONFIG_FBCON_2PLANE
332 static void bmove_2_plane(struct display *p, int sy, int sx, int dy, int dx,
333 int height, int width);
334 static void clear_2_plane(struct vc_data *conp, struct display *p, int sy,
335 int sx, int height, int width);
336 static void putc_2_plane(struct vc_data *conp, struct display *p, int c, int y,
337 int x);
338 static void putcs_2_plane(struct vc_data *conp, struct display *p,
339 const char *s, int count, int y, int x);
340 static void rev_char_2_plane(struct display *display, int x, int y);
341 #endif
342
343
344
345
346
347
348 #ifdef CONFIG_FBCON_4PLANE
349 static void bmove_4_plane(struct display *p, int sy, int sx, int dy, int dx,
350 int height, int width);
351 static void clear_4_plane(struct vc_data *conp, struct display *p, int sy,
352 int sx, int height, int width);
353 static void putc_4_plane(struct vc_data *conp, struct display *p, int c, int y,
354 int x);
355 static void putcs_4_plane(struct vc_data *conp, struct display *p,
356 const char *s, int count, int y, int x);
357 static void rev_char_4_plane(struct display *p, int x, int y);
358 #endif
359
360
361
362
363
364
365 #ifdef CONFIG_FBCON_8PLANE
366 static void bmove_8_plane(struct display *p, int sy, int sx, int dy, int dx,
367 int height, int width);
368 static void clear_8_plane(struct vc_data *conp, struct display *p, int sy,
369 int sx, int height, int width);
370 static void putc_8_plane(struct vc_data *conp, struct display *p, int c, int y,
371 int x);
372 static void putcs_8_plane(struct vc_data *conp, struct display *p,
373 const char *s, int count, int y, int x);
374 static void rev_char_8_plane(struct display *display, int x, int y);
375 #endif
376
377
378
379
380
381
382 #ifdef CONFIG_FBCON_8PACKED
383 static void bmove_8_packed(struct display *p, int sy, int sx, int dy, int dx,
384 int height, int width);
385 static void clear_8_packed(struct vc_data *conp, struct display *p, int sy,
386 int sx, int height, int width);
387 static void putc_8_packed(struct vc_data *conp, struct display *p, int c, int y,
388 int x);
389 static void putcs_8_packed(struct vc_data *conp, struct display *p,
390 const char *s, int count, int y, int x);
391 static void rev_char_8_packed(struct display *p, int x, int y);
392 #endif
393
394
395
396
397
398
399 #ifdef CONFIG_FBCON_16PACKED
400 static void bmove_16_packed(struct display *p, int sy, int sx, int dy, int dx,
401 int height, int width);
402 static void clear_16_packed(struct vc_data *conp, struct display *p, int sy,
403 int sx, int height, int width);
404 static void putc_16_packed(struct vc_data *conp, struct display *p, int c,
405 int y, int x);
406 static void putcs_16_packed(struct vc_data *conp, struct display *p,
407 const char *s, int count, int y, int x);
408 static void rev_char_16_packed(struct display *p, int x, int y);
409 #endif */ CONFIG_FBCON_8PACKED */
410
411
412
413
414
415
416 #ifdef CONFIG_FBCON_CYBER
417 static void bmove_cyber(struct display *p, int sy, int sx, int dy, int dx,
418 int height, int width);
419 static void clear_cyber(struct vc_data *conp, struct display *p, int sy, int sx,
420 int height, int width);
421 static void putc_cyber(struct vc_data *conp, struct display *p, int c, int y,
422 int x);
423 static void putcs_cyber(struct vc_data *conp, struct display *p, const char *s,
424 int count, int y, int x);
425 static void rev_char_cyber(struct display *p, int x, int y);
426
427 extern void Cyber_WaitQueue(u_short fifo);
428 extern void Cyber_WaitBlit(void);
429 extern void Cyber_BitBLT(u_short curx, u_short cury, u_short destx,
430 u_short desty, u_short width, u_short height,
431 u_short mode);
432 extern void Cyber_RectFill(u_short x, u_short y, u_short width, u_short height,
433 u_short mode, u_short color);
434 extern void Cyber_MoveCursor(u_short x, u_short y);
435 #endif
436
437
438
439
440
441
442 struct display_switch {
443 void (*bmove)(struct display *p, int sy, int sx, int dy, int dx, int height,
444 int width);
445 void (*clear)(struct vc_data *conp, struct display *p, int sy, int sx,
446 int height, int width);
447 void (*putc)(struct vc_data *conp, struct display *p, int c, int y, int x);
448 void (*putcs)(struct vc_data *conp, struct display *p, const char *s,
449 int count, int y, int x);
450 void (*rev_char)(struct display *p, int x, int y);
451 };
452
453
454 #ifdef CONFIG_FBCON_MONO
455 struct display_switch dispsw_mono = {
456 bmove_mono, clear_mono, putc_mono, putcs_mono, rev_char_mono
457 };
458 #endif
459
460 #ifdef CONFIG_FBCON_ILBM
461 struct display_switch dispsw_ilbm = {
462 bmove_ilbm, clear_ilbm, putc_ilbm, putcs_ilbm, rev_char_ilbm
463 };
464 #endif
465
466 #ifdef CONFIG_FBCON_PLANES
467 struct display_switch dispsw_plan = {
468 bmove_plan, clear_plan, putc_plan, putcs_plan, rev_char_plan
469 };
470 #endif
471
472 #ifdef CONFIG_FBCON_2PLANE
473 struct display_switch dispsw_2_plane = {
474 bmove_2_plane, clear_2_plane, putc_2_plane, putcs_2_plane, rev_char_2_plane
475 };
476 #endif
477
478 #ifdef CONFIG_FBCON_4PLANE
479 struct display_switch dispsw_4_plane = {
480 bmove_4_plane, clear_4_plane, putc_4_plane, putcs_4_plane, rev_char_4_plane
481 };
482 #endif
483
484 #ifdef CONFIG_FBCON_8PLANE
485 struct display_switch dispsw_8_plane = {
486 bmove_8_plane, clear_8_plane, putc_8_plane, putcs_8_plane, rev_char_8_plane
487 };
488 #endif
489
490 #ifdef CONFIG_FBCON_8PACKED
491 struct display_switch dispsw_8_packed = {
492 bmove_8_packed, clear_8_packed, putc_8_packed, putcs_8_packed, rev_char_8_packed
493 };
494 #endif
495
496 #ifdef CONFIG_FBCON_16PACKED
497 struct display_switch dispsw_16_packed = {
498 bmove_16_packed, clear_16_packed, putc_16_packed, putcs_16_packed,
499 rev_char_16_packed
500 };
501 #endif
502
503 #ifdef CONFIG_FBCON_CYBER
504 struct display_switch dispsw_cyber = {
505 bmove_cyber, clear_cyber, putc_cyber, putcs_cyber, rev_char_cyber
506 };
507 #endif
508
509
510 static u_long fbcon_startup(u_long kmem_start, char **display_desc)
511 {
512 int irqres = 0;
513
514 fb_info = mach_fb_init(&kmem_start);
515 disp = fb_info->disp;
516 *display_desc = fb_info->modename;
517 fb_info->changevar = &fbcon_changevar;
518
519 #ifdef CONFIG_AMIGA
520 if (MACH_IS_AMIGA) {
521 cursor_blink_rate = AMIGA_CURSOR_BLINK_RATE;
522 irqres = add_isr(IRQ_AMIGA_VERTB, fbcon_vbl_handler, 0, NULL,
523 "console/cursor");
524 }
525 #endif
526 #ifdef CONFIG_ATARI
527 if (MACH_IS_ATARI) {
528 cursor_blink_rate = ATARI_CURSOR_BLINK_RATE;
529 irqres = add_isr(IRQ_AUTO_4, fbcon_vbl_handler, IRQ_TYPE_PRIO, NULL,
530 "console/cursor");
531 }
532 #endif
533
534 if (!irqres)
535 panic("fbcon_startup: Couldn't add vblank interrupt");
536
537 return(kmem_start);
538 }
539
540
541 static void fbcon_init(struct vc_data *conp)
542 {
543 int unit = conp->vc_num;
544
545 if (unit)
546 disp[unit] = disp[0];
547 disp[unit].conp = conp;
548 fbcon_setup(unit, 1, 0);
549 }
550
551
552 static int fbcon_deinit(struct vc_data *conp)
553 {
554 disp[conp->vc_num].conp = 0;
555 return(0);
556 }
557
558
559 static int fbcon_changevar(int con)
560 {
561 fbcon_setup(con, 1, 1);
562 return(0);
563 }
564
565
566 static void fbcon_setup(int con, int setcol, int cls)
567 {
568 struct display *p = &disp[con];
569 struct vc_data *conp = p->conp;
570
571 p->var.xoffset = p->var.yoffset = p->yscroll = 0;
572
573 if (!fb_info->fontname[0] ||
574 !findsoftfont(fb_info->fontname, &p->fontwidth, &p->fontheight,
575 &p->fontdata) || p->fontwidth != 8)
576 getdefaultfont(p->var.xres, p->var.yres, NULL, &p->fontwidth,
577 &p->fontheight, &p->fontdata);
578 if (p->fontwidth != 8)
579 panic("fbcon_setup: No support for fontwidth != 8");
580
581 if (divides(p->ywrapstep, p->fontheight))
582 p->scrollmode = SCROLL_YWRAP;
583 else if (divides(p->ypanstep, p->fontheight) &&
584 p->var.yres_virtual >= p->var.yres+p->fontheight)
585 p->scrollmode = SCROLL_YPAN;
586 else
587 p->scrollmode = SCROLL_YMOVE;
588
589 conp->vc_cols = p->var.xres/p->fontwidth;
590 conp->vc_rows = p->var.yres/p->fontheight;
591 conp->vc_can_do_color = p->var.bits_per_pixel != 1;
592
593 #ifdef CONFIG_FBCON_MONO
594 if (p->var.bits_per_pixel == 1) {
595 p->next_line = p->var.xres_virtual>>3;
596 p->next_plane = 0;
597 p->dispsw = &dispsw_mono;
598 } else
599 #endif
600 #ifdef CONFIG_FBCON_IPLAN2
601 if (p->type == FB_TYPE_INTERLEAVED_PLANES && p->type_aux == 2) {
602 p->next_line = p->var.xres_virtual*p->var.bits_per_pixel>>3;
603 p->next_plane = 0;
604 #ifdef CONFIG_FBCON_2PLANE
605 if (p->var.bits_per_pixel == 2)
606 p->dispsw = &dispsw_2_plane;
607 else
608 #endif
609 #ifdef CONFIG_FBCON_4PLANE
610 if (p->var.bits_per_pixel == 4)
611 p->dispsw = &dispsw_4_plane;
612 else
613 #endif
614 #ifdef CONFIG_FBCON_8PLANE
615 if (p->var.bits_per_pixel == 8)
616 p->dispsw = &dispsw_8_plane;
617 else
618 #endif
619 goto fail;
620 } else
621 #endif
622 #ifdef CONFIG_FBCON_ILBM
623 if (p->type == FB_TYPE_INTERLEAVED_PLANES && p->type_aux != 2) {
624 p->next_line = p->type_aux;
625 p->next_plane = p->type_aux/p->var.bits_per_pixel;
626 p->dispsw = &dispsw_ilbm;
627 } else
628 #endif
629 #ifdef CONFIG_FBCON_PLANES
630 if (p->type == FB_TYPE_PLANES) {
631 p->next_line = p->var.xres_virtual>>3;
632 p->next_plane = p->var.yres_virtual*p->next_line;
633 p->dispsw = &dispsw_plan;
634 } else
635 #endif
636 #ifdef CONFIG_FBCON_PACKED
637 if (p->type == FB_TYPE_PACKED_PIXELS) {
638 p->next_line = p->var.xres_virtual*p->var.bits_per_pixel>>3;
639 p->next_plane = 0;
640 #ifdef CONFIG_FBCON_CYBER
641 if (p->var.accel == FB_ACCEL_CYBERVISION)
642 p->dispsw = &dispsw_cyber;
643 else
644 #endif
645 #ifdef CONFIG_FBCON_8PACKED
646 if (p->var.bits_per_pixel == 8)
647 p->dispsw = &dispsw_8_packed;
648 else
649 #endif
650 #ifdef CONFIG_FBCON_16PACKED
651 if (p->var.bits_per_pixel == 16)
652 p->dispsw = &dispsw_16_packed;
653 else
654 #endif
655 #ifdef CONFIG_FBCON_24PACKED
656 if (p->var.bits_per_pixel == 24)
657 p->dispsw = &dispsw_24_packed;
658 else
659 #endif
660 #ifdef CONFIG_FBCON_32PACKED
661 if (p->var.bits_per_pixel == 32)
662 p->dispsw = &dispsw_32_packed;
663 else
664 #endif
665 goto fail;
666 } else
667 #endif
668 {
669 fail:
670 #ifdef CONFIG_FBCON_MONO
671 printk("fbcon_setup: type %d (aux %d) not supported, trying mono\n",
672 p->type, p->type_aux);
673 p->next_line = (p->var.xres_virtual)>>3;
674 p->next_plane = 0;
675 p->var.bits_per_pixel = 1;
676 p->dispsw = &dispsw_mono;
677 #else
678 panic("fbcon_setup: no default driver");
679 #endif
680 }
681
682 if (setcol) {
683 p->fgcol = p->var.bits_per_pixel > 2 ? 7 : (1<<p->var.bits_per_pixel)-1;
684 p->bgcol = 0;
685 }
686
687 if (cls)
688 vc_resize_con(conp->vc_rows, conp->vc_cols, con);
689 }
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737 static __inline__ void *mymemclear_small(void *s, size_t count)
738 {
739 if (!count)
740 return(0);
741
742 __asm__ __volatile__(
743 "lsrl #1,%1 ; jcc 1f ; moveb %2,%0@-\n\t"
744 "1: lsrl #1,%1 ; jcc 1f ; movew %2,%0@-\n\t"
745 "1: lsrl #1,%1 ; jcc 1f ; movel %2,%0@-\n\t"
746 "1: lsrl #1,%1 ; jcc 1f ; movel %2,%0@- ; movel %2,%0@-\n\t"
747 "1: subql #1,%1 ; jcs 3f\n\t"
748 "2: moveml %2/%3/%4/%5,%0@-\n\t"
749 "dbra %1,2b\n\t"
750 "3:"
751 : "=a" (s), "=d" (count)
752 : "d" (0), "d" (0), "d" (0), "d" (0),
753 "0" ((char *)s+count), "1" (count)
754 );
755
756 return(0);
757 }
758
759
760 static __inline__ void *mymemclear(void *s, size_t count)
761 {
762 if (!count)
763 return(0);
764
765 if (count < 16) {
766 __asm__ __volatile__(
767 "lsrl #1,%1 ; jcc 1f ; clrb %0@+\n\t"
768 "1: lsrl #1,%1 ; jcc 1f ; clrw %0@+\n\t"
769 "1: lsrl #1,%1 ; jcc 1f ; clrl %0@+\n\t"
770 "1: lsrl #1,%1 ; jcc 1f ; clrl %0@+ ; clrl %0@+\n\t"
771 "1:"
772 : "=a" (s), "=d" (count)
773 : "0" (s), "1" (count)
774 );
775 } else {
776 long tmp;
777 __asm__ __volatile__(
778 "movel %1,%2\n\t"
779 "lsrl #1,%2 ; jcc 1f ; clrb %0@+ ; subqw #1,%1\n\t"
780 "lsrl #1,%2 ; jcs 2f\n\t"
781 "clrw %0@+ ; subqw #2,%1 ; jra 2f\n\t"
782 "1: lsrl #1,%2 ; jcc 2f\n\t"
783 "clrw %0@+ ; subqw #2,%1\n\t"
784 "2: movew %1,%2; lsrl #2,%1 ; jeq 6f\n\t"
785 "lsrl #1,%1 ; jcc 3f ; clrl %0@+\n\t"
786 "3: lsrl #1,%1 ; jcc 4f ; clrl %0@+ ; clrl %0@+\n\t"
787 "4: subql #1,%1 ; jcs 6f\n\t"
788 "5: clrl %0@+; clrl %0@+ ; clrl %0@+ ; clrl %0@+\n\t"
789 "dbra %1,5b ; clrw %1; subql #1,%1; jcc 5b\n\t"
790 "6: movew %2,%1; btst #1,%1 ; jeq 7f ; clrw %0@+\n\t"
791 "7: ; btst #0,%1 ; jeq 8f ; clrb %0@+\n\t"
792 "8:"
793 : "=a" (s), "=d" (count), "=d" (tmp)
794 : "0" (s), "1" (count)
795 );
796 }
797
798 return(0);
799 }
800
801
802 static __inline__ void *mymemset(void *s, size_t count)
803 {
804 if (!count)
805 return(0);
806
807 __asm__ __volatile__(
808 "lsrl #1,%1 ; jcc 1f ; moveb %2,%0@-\n\t"
809 "1: lsrl #1,%1 ; jcc 1f ; movew %2,%0@-\n\t"
810 "1: lsrl #1,%1 ; jcc 1f ; movel %2,%0@-\n\t"
811 "1: lsrl #1,%1 ; jcc 1f ; movel %2,%0@- ; movel %2,%0@-\n\t"
812 "1: subql #1,%1 ; jcs 3f\n\t"
813 "2: moveml %2/%3/%4/%5,%0@-\n\t"
814 "dbra %1,2b\n\t"
815 "3:"
816 : "=a" (s), "=d" (count)
817 : "d" (-1), "d" (-1), "d" (-1), "d" (-1),
818 "0" ((char *) s + count), "1" (count)
819 );
820
821 return(0);
822 }
823
824
825 static __inline__ void *mymemmove(void *d, void *s, size_t count)
826 {
827 if (d < s) {
828 if (count < 16) {
829 __asm__ __volatile__(
830 "lsrl #1,%2 ; jcc 1f ; moveb %1@+,%0@+\n\t"
831 "1: lsrl #1,%2 ; jcc 1f ; movew %1@+,%0@+\n\t"
832 "1: lsrl #1,%2 ; jcc 1f ; movel %1@+,%0@+\n\t"
833 "1: lsrl #1,%2 ; jcc 1f ; movel %1@+,%0@+ ; movel %1@+,%0@+\n\t"
834 "1:"
835 : "=a" (d), "=a" (s), "=d" (count)
836 : "0" (d), "1" (s), "2" (count)
837 );
838 } else {
839 long tmp;
840 __asm__ __volatile__(
841 "movel %0,%3\n\t"
842 "lsrl #1,%3 ; jcc 1f ; moveb %1@+,%0@+ ; subqw #1,%2\n\t"
843 "lsrl #1,%3 ; jcs 2f\n\t"
844 "movew %1@+,%0@+ ; subqw #2,%2 ; jra 2f\n\t"
845 "1: lsrl #1,%3 ; jcc 2f\n\t"
846 "movew %1@+,%0@+ ; subqw #2,%2\n\t"
847 "2: movew %2,%-; lsrl #2,%2 ; jeq 6f\n\t"
848 "lsrl #1,%2 ; jcc 3f ; movel %1@+,%0@+\n\t"
849 "3: lsrl #1,%2 ; jcc 4f ; movel %1@+,%0@+ ; movel %1@+,%0@+\n\t"
850 "4: subql #1,%2 ; jcs 6f\n\t"
851 "5: movel %1@+,%0@+;movel %1@+,%0@+\n\t"
852 "movel %1@+,%0@+;movel %1@+,%0@+\n\t"
853 "dbra %2,5b ; clrw %2; subql #1,%2; jcc 5b\n\t"
854 "6: movew %+,%2; btst #1,%2 ; jeq 7f ; movew %1@+,%0@+\n\t"
855 "7: ; btst #0,%2 ; jeq 8f ; moveb %1@+,%0@+\n\t"
856 "8:"
857 : "=a" (d), "=a" (s), "=d" (count), "=d" (tmp)
858 : "0" (d), "1" (s), "2" (count)
859 );
860 }
861 } else {
862 if (count < 16) {
863 __asm__ __volatile__(
864 "lsrl #1,%2 ; jcc 1f ; moveb %1@-,%0@-\n\t"
865 "1: lsrl #1,%2 ; jcc 1f ; movew %1@-,%0@-\n\t"
866 "1: lsrl #1,%2 ; jcc 1f ; movel %1@-,%0@-\n\t"
867 "1: lsrl #1,%2 ; jcc 1f ; movel %1@-,%0@- ; movel %1@-,%0@-\n\t"
868 "1:"
869 : "=a" (d), "=a" (s), "=d" (count)
870 : "0" ((char *) d + count), "1" ((char *) s + count), "2" (count)
871 );
872 } else {
873 long tmp;
874 __asm__ __volatile__(
875 "movel %0,%3\n\t"
876 "lsrl #1,%3 ; jcc 1f ; moveb %1@-,%0@- ; subqw #1,%2\n\t"
877 "lsrl #1,%3 ; jcs 2f\n\t"
878 "movew %1@-,%0@- ; subqw #2,%2 ; jra 2f\n\t"
879 "1: lsrl #1,%3 ; jcc 2f\n\t"
880 "movew %1@-,%0@- ; subqw #2,%2\n\t"
881 "2: movew %2,%-; lsrl #2,%2 ; jeq 6f\n\t"
882 "lsrl #1,%2 ; jcc 3f ; movel %1@-,%0@-\n\t"
883 "3: lsrl #1,%2 ; jcc 4f ; movel %1@-,%0@- ; movel %1@-,%0@-\n\t"
884 "4: subql #1,%2 ; jcs 6f\n\t"
885 "5: movel %1@-,%0@-;movel %1@-,%0@-\n\t"
886 "movel %1@-,%0@-;movel %1@-,%0@-\n\t"
887 "dbra %2,5b ; clrw %2; subql #1,%2; jcc 5b\n\t"
888 "6: movew %+,%2; btst #1,%2 ; jeq 7f ; movew %1@-,%0@-\n\t"
889 "7: ; btst #0,%2 ; jeq 8f ; moveb %1@-,%0@-\n\t"
890 "8:"
891 : "=a" (d), "=a" (s), "=d" (count), "=d" (tmp)
892 : "0" ((char *) d + count), "1" ((char *) s + count), "2" (count)
893 );
894 }
895 }
896
897 return(0);
898 }
899
900
901
902
903 static __inline__ void fast_memmove(char *dst, char *src, size_t size)
904 {
905 if (!size)
906 return;
907 if (dst < src)
908 __asm__ __volatile__
909 ("1:"
910 " moveml %0@+,%/d0/%/d1/%/a0/%/a1\n"
911 " moveml %/d0/%/d1/%/a0/%/a1,%1@\n"
912 " addql #8,%1; addql #8,%1\n"
913 " dbra %2,1b\n"
914 " clrw %2; subql #1,%2\n"
915 " jcc 1b"
916 : "=a" (src), "=a" (dst), "=d" (size)
917 : "0" (src), "1" (dst), "2" (size / 16 - 1)
918 : "d0", "d1", "a0", "a1", "memory");
919 else
920 __asm__ __volatile__
921 ("1:"
922 " subql #8,%0; subql #8,%0\n"
923 " moveml %0@,%/d0/%/d1/%/a0/%/a1\n"
924 " moveml %/d0/%/d1/%/a0/%/a1,%1@-\n"
925 " dbra %2,1b\n"
926 " clrw %2; subql #1,%2\n"
927 " jcc 1b"
928 : "=a" (src), "=a" (dst), "=d" (size)
929 : "0" (src + size), "1" (dst + size), "2" (size / 16 - 1)
930 : "d0", "d1", "a0", "a1", "memory");
931 }
932
933
934
935
936
937
938
939
940
941
942
943
944
945 static __inline__ void memclear_4p_col(void *d, size_t h, u_long val, int bpr)
946 {
947 __asm__ __volatile__
948 ("1: movepl %4,%0@(0)\n\t"
949 "addal %5,%0\n\t"
950 "dbra %1,1b"
951 : "=a" (d), "=d" (h)
952 : "0" (d), "1" (h - 1), "d" (val), "r" (bpr)
953 );
954 }
955
956
957
958
959
960
961
962
963
964
965
966
967 static __inline__ void memset_even_4p(void *d, size_t count, u_long val1,
968 u_long val2)
969 {
970 u_long *dd = d;
971
972 count /= 8;
973 while (count--)
974 {
975 *dd++ = val1;
976 *dd++ = val2;
977 }
978 }
979
980
981
982 static __inline__ void memmove_4p_col (void *d, void *s, int h, int bpr)
983 {
984 u_char *dd = d, *ss = s;
985
986 while (h--)
987 {
988 dd[0] = ss[0];
989 dd[2] = ss[2];
990 dd[4] = ss[4];
991 dd[6] = ss[6];
992 dd += bpr;
993 ss += bpr;
994 }
995 }
996
997
998
999
1000 static __inline__ u_long expand4l(u_char c)
1001 {
1002 u_long rv;
1003
1004 __asm__ __volatile__
1005 ("lsrb #1,%2\n\t"
1006 "scs %0\n\t"
1007 "lsll #8,%0\n\t"
1008 "lsrb #1,%2\n\t"
1009 "scs %0\n\t"
1010 "lsll #8,%0\n\t"
1011 "lsrb #1,%2\n\t"
1012 "scs %0\n\t"
1013 "lsll #8,%0\n\t"
1014 "lsrb #1,%2\n\t"
1015 "scs %0\n\t"
1016 : "=&d" (rv), "=d" (c)
1017 : "1" (c)
1018 );
1019 return(rv);
1020 }
1021
1022
1023
1024
1025
1026 static __inline__ void expand4dl(u_char c, u_long *ret1, u_long *ret2)
1027 {
1028 u_long rv1, rv2;
1029
1030 __asm__ __volatile__
1031 ("lsrb #1,%3\n\t"
1032 "scs %0\n\t"
1033 "extw %0\n\t"
1034 "swap %0\n\t"
1035 "lsrb #1,%3\n\t"
1036 "scs %0\n\t"
1037 "extw %0\n\t"
1038 "lsrb #1,%3\n\t"
1039 "scs %1\n\t"
1040 "extw %1\n\t"
1041 "swap %1\n\t"
1042 "lsrb #1,%3\n\t"
1043 "scs %1\n\t"
1044 "extw %1"
1045 : "=&d" (rv1), "=&d" (rv2), "=d" (c)
1046 : "2" (c)
1047 );
1048 *ret1 = rv1;
1049 *ret2 = rv2;
1050 }
1051
1052
1053
1054
1055 static __inline__ u_long dup4l(u_char c)
1056 {
1057 ushort tmp;
1058 ulong rv;
1059
1060 __asm__ __volatile__
1061 ("moveb %2,%0\n\t"
1062 "lslw #8,%0\n\t"
1063 "moveb %2,%0\n\t"
1064 "movew %0,%1\n\t"
1065 "swap %0\n\t"
1066 "movew %1,%0"
1067 : "=&d" (rv), "=d" (tmp)
1068 : "d" (c)
1069 );
1070
1071 return(rv);
1072 }
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090 static __inline__ void memclear_8p_col(void *d, size_t h, u_long val1,
1091 u_long val2, int bpr)
1092 {
1093 __asm__ __volatile__
1094 ("1: movepl %4,%0@(0)\n\t"
1095 "movepl %5,%0@(8)\n\t"
1096 "addal %6,%0\n\t"
1097 "dbra %1,1b"
1098 : "=a" (d), "=d" (h)
1099 : "0" (d), "1" (h - 1), "d" (val1), "d" (val2), "r" (bpr)
1100 );
1101 }
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118 static __inline__ void memset_even_8p(void *d, size_t count, u_long val1,
1119 u_long val2, u_long val3, u_long val4)
1120 {
1121 u_long *dd = d;
1122
1123 count /= 16;
1124 while (count--)
1125 {
1126 *dd++ = val1;
1127 *dd++ = val2;
1128 *dd++ = val3;
1129 *dd++ = val4;
1130 }
1131 }
1132
1133
1134
1135 static __inline__ void memmove_8p_col (void *d, void *s, int h, int bpr)
1136 {
1137 u_char *dd = d, *ss = s;
1138
1139 while (h--)
1140 {
1141 dd[0] = ss[0];
1142 dd[2] = ss[2];
1143 dd[4] = ss[4];
1144 dd[6] = ss[6];
1145 dd[8] = ss[8];
1146 dd[10] = ss[10];
1147 dd[12] = ss[12];
1148 dd[14] = ss[14];
1149 dd += bpr;
1150 ss += bpr;
1151 }
1152 }
1153
1154
1155
1156
1157
1158
1159 static __inline__ void expand8dl(u_char c, u_long *ret1, u_long *ret2)
1160 {
1161 u_long rv1, rv2;
1162
1163 __asm__ __volatile__
1164 ("lsrb #1,%3\n\t"
1165 "scs %0\n\t"
1166 "lsll #8,%0\n\t"
1167 "lsrb #1,%3\n\t"
1168 "scs %0\n\t"
1169 "lsll #8,%0\n\t"
1170 "lsrb #1,%3\n\t"
1171 "scs %0\n\t"
1172 "lsll #8,%0\n\t"
1173 "lsrb #1,%3\n\t"
1174 "scs %0\n\t"
1175 "lsrb #1,%3\n\t"
1176 "scs %1\n\t"
1177 "lsll #8,%1\n\t"
1178 "lsrb #1,%3\n\t"
1179 "scs %1\n\t"
1180 "lsll #8,%1\n\t"
1181 "lsrb #1,%3\n\t"
1182 "scs %1\n\t"
1183 "lsll #8,%1\n\t"
1184 "lsrb #1,%3\n\t"
1185 "scs %1"
1186 : "=&d" (rv1), "=&d" (rv2),"=d" (c)
1187 : "2" (c)
1188 );
1189
1190 *ret1 = rv1;
1191 *ret2 = rv2;
1192 }
1193
1194
1195
1196
1197
1198
1199 #define expand8ql(c, rv1, rv2, rv3, rv4) \
1200 do { u_char tmp = c; \
1201 __asm__ __volatile__ \
1202 ("lsrb #1,%5\n\t" \
1203 "scs %0\n\t" \
1204 "extw %0\n\t" \
1205 "swap %0\n\t" \
1206 "lsrb #1,%5\n\t" \
1207 "scs %0\n\t" \
1208 "extw %0\n\t" \
1209 "lsrb #1,%5\n\t" \
1210 "scs %1\n\t" \
1211 "extw %1\n\t" \
1212 "swap %1\n\t" \
1213 "lsrb #1,%5\n\t" \
1214 "scs %1\n\t" \
1215 "extw %1\n\t" \
1216 "lsrb #1,%5\n\t" \
1217 "scs %2\n\t" \
1218 "extw %2\n\t" \
1219 "swap %2\n\t" \
1220 "lsrb #1,%5\n\t" \
1221 "scs %2\n\t" \
1222 "extw %2\n\t" \
1223 "lsrb #1,%5\n\t" \
1224 "scs %3\n\t" \
1225 "extw %3\n\t" \
1226 "swap %3\n\t" \
1227 "lsrb #1,%5\n\t" \
1228 "scs %3\n\t" \
1229 "extw %3" \
1230 : "=&d" (rv1), "=&d" (rv2), "=&d" (rv3), \
1231 "=&d" (rv4), "=d" (tmp) \
1232 : "4" (tmp) \
1233 ); \
1234 } while (0)
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246 static __inline__ void memclear_2p_col(void *d, size_t h, u_short val, int bpr)
1247 {
1248 __asm__ __volatile__
1249 ("1: movepw %4,%0@(0)\n\t"
1250 "addal %5,%0\n\t"
1251 "dbra %1,1b"
1252 : "=a" (d), "=d" (h)
1253 : "0" (d), "1" (h - 1), "d" (val), "r" (bpr)
1254 );
1255 }
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266 static __inline__ void memset_even_2p(void *d, size_t count, u_long val)
1267 {
1268 u_long *dd = d;
1269
1270 count /= 4;
1271 while (count--)
1272 *dd++ = val;
1273 }
1274
1275
1276
1277 static __inline__ void memmove_2p_col (void *d, void *s, int h, int bpr)
1278 {
1279 u_char *dd = d, *ss = s;
1280
1281 while (h--)
1282 {
1283 dd[0] = ss[0];
1284 dd[2] = ss[2];
1285 dd += bpr;
1286 ss += bpr;
1287 }
1288 }
1289
1290
1291
1292
1293 static __inline__ u_short expand2w(u_char c)
1294 {
1295 u_short rv;
1296
1297 __asm__ __volatile__
1298 ("lsrb #1,%2\n\t"
1299 "scs %0\n\t"
1300 "lsll #8,%0\n\t"
1301 "lsrb #1,%2\n\t"
1302 "scs %0\n\t"
1303 : "=&d" (rv), "=d" (c)
1304 : "1" (c)
1305 );
1306 return(rv);
1307 }
1308
1309
1310
1311
1312
1313 static __inline__ u_long expand2l(u_char c)
1314 {
1315 u_long rv;
1316
1317 __asm__ __volatile__
1318 ("lsrb #1,%2\n\t"
1319 "scs %0\n\t"
1320 "extw %0\n\t"
1321 "swap %0\n\t"
1322 "lsrb #1,%2\n\t"
1323 "scs %0\n\t"
1324 "extw %0\n\t"
1325 : "=&d" (rv), "=d" (c)
1326 : "1" (c)
1327 );
1328
1329 return rv;
1330 }
1331
1332
1333
1334
1335 static __inline__ u_short dup2w(u_char c)
1336 {
1337 ushort rv;
1338
1339 __asm__ __volatile__
1340 ( "moveb %1,%0\n\t"
1341 "lslw #8,%0\n\t"
1342 "moveb %1,%0\n\t"
1343 : "=&d" (rv)
1344 : "d" (c)
1345 );
1346
1347 return( rv );
1348 }
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376 static __inline__ int real_y(struct display *p, int y)
1377 {
1378 int rows = p->conp->vc_rows;
1379
1380 y += p->yscroll;
1381 return(y < rows || p->scrollmode != SCROLL_YWRAP ? y : y-rows);
1382 }
1383
1384
1385 static int fbcon_clear(struct vc_data *conp, int sy, int sx, int height,
1386 int width)
1387 {
1388 int unit = conp->vc_num;
1389 struct display *p = &disp[unit];
1390 u_int y_break;
1391
1392 if (!p->can_soft_blank && console_blanked)
1393 return(0);
1394
1395 if ((sy <= p->cursor_y) && (p->cursor_y < sy+height) &&
1396 (sx <= p->cursor_x) && (p->cursor_x < sx+width))
1397 CURSOR_UNDRAWN();
1398
1399
1400
1401 y_break = conp->vc_rows-p->yscroll;
1402 if (sy < y_break && sy+height-1 >= y_break) {
1403 u_int b = y_break-sy;
1404 p->dispsw->clear(conp, p, real_y(p, sy), sx, b, width);
1405 p->dispsw->clear(conp, p, real_y(p, sy+b), sx, height-b, width);
1406 } else
1407 p->dispsw->clear(conp, p, real_y(p, sy), sx, height, width);
1408
1409 return(0);
1410 }
1411
1412
1413 static int fbcon_putc(struct vc_data *conp, int c, int y, int x)
1414 {
1415 int unit = conp->vc_num;
1416 struct display *p = &disp[unit];
1417
1418 if (!p->can_soft_blank && console_blanked)
1419 return(0);
1420
1421 if ((p->cursor_x == x) && (p->cursor_y == y))
1422 CURSOR_UNDRAWN();
1423
1424 p->dispsw->putc(conp, p, c, real_y(p, y), x);
1425
1426 return(0);
1427 }
1428
1429
1430 static int fbcon_putcs(struct vc_data *conp, const char *s, int count, int y,
1431 int x)
1432 {
1433 int unit = conp->vc_num;
1434 struct display *p = &disp[unit];
1435
1436 if (!p->can_soft_blank && console_blanked)
1437 return(0);
1438
1439 if ((p->cursor_y == y) && (x <= p->cursor_x) && (p->cursor_x < x+count))
1440 CURSOR_UNDRAWN();
1441
1442 p->dispsw->putcs(conp, p, s, count, real_y(p, y), x);
1443
1444 return(0);
1445 }
1446
1447
1448 static int fbcon_cursor(struct vc_data *conp, int mode)
1449 {
1450 int unit = conp->vc_num;
1451 struct display *p = &disp[unit];
1452
1453 if (CURSOR_UNDRAWN ())
1454 p->dispsw->rev_char(p, p->cursor_x, real_y(p, p->cursor_y));
1455 p->cursor_x = conp->vc_x;
1456 p->cursor_y = conp->vc_y;
1457
1458 switch (mode) {
1459 case CM_ERASE:
1460 cursor_on = 0;
1461 break;
1462
1463 case CM_MOVE:
1464 case CM_DRAW:
1465 vbl_cursor_cnt = CURSOR_DRAW_DELAY;
1466 cursor_on = 1;
1467 break;
1468 }
1469
1470 return(0);
1471 }
1472
1473
1474 static void fbcon_vbl_handler(int irq, struct pt_regs *fp, void *dummy)
1475 {
1476 struct display *p;
1477
1478 if (!cursor_on)
1479 return;
1480
1481 if (vbl_cursor_cnt && --vbl_cursor_cnt == 0) {
1482
1483
1484
1485 p = &disp[fg_console];
1486 p->dispsw->rev_char(p, p->cursor_x, real_y(p, p->cursor_y));
1487 cursor_drawn ^= 1;
1488 vbl_cursor_cnt = cursor_blink_rate;
1489 }
1490 }
1491
1492
1493 static int fbcon_scroll(struct vc_data *conp, int t, int b, int dir, int count)
1494 {
1495 int unit = conp->vc_num;
1496 struct display *p = &disp[unit];
1497
1498 if (!p->can_soft_blank && console_blanked)
1499 return(0);
1500
1501 fbcon_cursor(conp, CM_ERASE);
1502
1503
1504
1505
1506
1507 switch (dir) {
1508 case SM_UP:
1509 if (t == 0 && b == conp->vc_rows &&
1510 vt_cons[unit]->vc_mode == KD_TEXT) {
1511 if (count > conp->vc_rows)
1512 count = conp->vc_rows;
1513 switch (p->scrollmode) {
1514 case SCROLL_YWRAP:
1515 p->yscroll += count;
1516 if (p->yscroll >= conp->vc_rows)
1517 p->yscroll -= conp->vc_rows;
1518 p->var.xoffset = 0;
1519 p->var.yoffset = p->yscroll*p->fontheight;
1520 p->var.vmode |= FB_VMODE_YWRAP;
1521 fb_info->updatevar(unit);
1522 break;
1523
1524 case SCROLL_YPAN:
1525 p->yscroll += count;
1526 if (p->yscroll*p->fontheight+p->var.yres >
1527 p->var.yres_virtual) {
1528 p->dispsw->bmove(p, p->yscroll, 0, 0, 0, b-count,
1529 conp->vc_cols);
1530 p->yscroll = 0;
1531 }
1532 p->var.xoffset = 0;
1533 p->var.yoffset = p->yscroll*p->fontheight;
1534 p->var.vmode &= ~FB_VMODE_YWRAP;
1535 fb_info->updatevar(unit);
1536 break;
1537
1538 case SCROLL_YMOVE:
1539 p->dispsw->bmove(p, count, 0, 0, 0, b-count, conp->vc_cols);
1540 break;
1541 }
1542 } else
1543 fbcon_bmove(conp, t+count, 0, t, 0, b-t-count, conp->vc_cols);
1544 fbcon_clear(conp, b-count, 0, count, conp->vc_cols);
1545 break;
1546
1547 case SM_DOWN:
1548 if (t == 0 && b == conp->vc_rows &&
1549 vt_cons[unit]->vc_mode == KD_TEXT) {
1550 if (count > conp->vc_rows)
1551 count = conp->vc_rows;
1552 switch (p->scrollmode) {
1553 case SCROLL_YWRAP:
1554 p->yscroll -= count;
1555 if (p->yscroll < 0)
1556 p->yscroll += conp->vc_rows;
1557 p->var.xoffset = 0;
1558 p->var.yoffset = p->yscroll*p->fontheight;
1559 p->var.vmode |= FB_VMODE_YWRAP;
1560 fb_info->updatevar(unit);
1561 break;
1562
1563 case SCROLL_YPAN:
1564 p->yscroll -= count;
1565 if (p->yscroll < 0) {
1566 p->yscroll = (p->var.yres_virtual-p->var.yres)/
1567 p->fontheight;
1568 p->dispsw->bmove(p, 0, 0, p->yscroll+count, 0, b-count,
1569 conp->vc_cols);
1570 }
1571 p->var.xoffset = 0;
1572 p->var.yoffset = p->yscroll*p->fontheight;
1573 p->var.vmode &= ~FB_VMODE_YWRAP;
1574 fb_info->updatevar(unit);
1575 break;
1576
1577 case SCROLL_YMOVE:
1578 p->dispsw->bmove(p, 0, 0, count, 0, b-count, conp->vc_cols);
1579 break;
1580 }
1581 } else
1582 fbcon_bmove(conp, t, 0, t+count, 0, b-t-count, conp->vc_cols);
1583
1584
1585
1586
1587
1588 fbcon_clear(conp, t, 0, count, conp->vc_cols);
1589 break;
1590
1591 case SM_LEFT:
1592 fbcon_bmove(conp, 0, t+count, 0, t, conp->vc_rows, b-t-count);
1593 fbcon_clear(conp, 0, b-count, conp->vc_rows, count);
1594 break;
1595
1596 case SM_RIGHT:
1597 fbcon_bmove(conp, 0, t, 0, t+count, conp->vc_rows, b-t-count);
1598 fbcon_clear(conp, 0, t, conp->vc_rows, count);
1599 break;
1600 }
1601
1602 return(0);
1603 }
1604
1605
1606 static int fbcon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
1607 int height, int width)
1608 {
1609 int unit = conp->vc_num;
1610 struct display *p = &disp[unit];
1611
1612 if (!p->can_soft_blank && console_blanked)
1613 return(0);
1614
1615 if (((sy <= p->cursor_y) && (p->cursor_y < sy+height) &&
1616 (sx <= p->cursor_x) && (p->cursor_x < sx+width)) ||
1617 ((dy <= p->cursor_y) && (p->cursor_y < dy+height) &&
1618 (dx <= p->cursor_x) && (p->cursor_x < dx+width)))
1619 fbcon_cursor(conp, CM_ERASE);
1620
1621
1622
1623
1624
1625
1626
1627
1628 fbcon_bmove_rec(p, sy, sx, dy, dx, height, width, conp->vc_rows-p->yscroll);
1629
1630 return(0);
1631 }
1632
1633
1634 static void fbcon_bmove_rec(struct display *p, int sy, int sx, int dy, int dx,
1635 int height, int width, u_int y_break)
1636 {
1637 u_int b;
1638
1639 if (sy < y_break && sy+height > y_break) {
1640 b = y_break-sy;
1641 if (dy < sy) {
1642 fbcon_bmove_rec(p, sy, sx, dy, dx, b, width, y_break);
1643 fbcon_bmove_rec(p, sy+b, sx, dy+b, dx, height-b, width, y_break);
1644 } else {
1645 fbcon_bmove_rec(p, sy+b, sx, dy+b, dx, height-b, width, y_break);
1646 fbcon_bmove_rec(p, sy, sx, dy, dx, b, width, y_break);
1647 }
1648 return;
1649 }
1650
1651 if (dy < y_break && dy+height > y_break) {
1652 b = y_break-dy;
1653 if (dy < sy) {
1654 fbcon_bmove_rec(p, sy, sx, dy, dx, b, width, y_break);
1655 fbcon_bmove_rec(p, sy+b, sx, dy+b, dx, height-b, width, y_break);
1656 } else {
1657 fbcon_bmove_rec(p, sy+b, sx, dy+b, dx, height-b, width, y_break);
1658 fbcon_bmove_rec(p, sy, sx, dy, dx, b, width, y_break);
1659 }
1660 return;
1661 }
1662 p->dispsw->bmove(p, real_y(p, sy), sx, real_y(p, dy), dx, height, width);
1663 }
1664
1665
1666 static int fbcon_switch(struct vc_data *conp)
1667 {
1668 if (fb_info && fb_info->switch_con)
1669 (*fb_info->switch_con)(conp->vc_num);
1670 return(0);
1671 }
1672
1673
1674 static int fbcon_blank(int blank)
1675 {
1676 struct display *p = &disp[fg_console];
1677
1678 fbcon_cursor(p->conp, blank ? CM_ERASE : CM_DRAW);
1679
1680 if (!p->can_soft_blank)
1681 if (blank) {
1682 if (p->visual == FB_VISUAL_MONO01)
1683 mymemset(p->screen_base, p->var.xres_virtual*p->var.yres_virtual*
1684 p->var.bits_per_pixel>>3);
1685 else
1686 mymemclear(p->screen_base, p->var.xres_virtual*p->var.yres_virtual*
1687 p->var.bits_per_pixel>>3);
1688 return(0);
1689 } else {
1690
1691 return(1);
1692 }
1693 (*fb_info->blank)(blank);
1694 return(0);
1695 }
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713 #ifdef CONFIG_FBCON_MONO
1714
1715
1716
1717
1718
1719 static void bmove_mono(struct display *p, int sy, int sx, int dy, int dx,
1720 int height, int width)
1721 {
1722 u_char *src, *dest;
1723 u_int rows;
1724
1725 if (sx == 0 && sy == 0 && width == p->next_line) {
1726 src = p->screen_base;
1727 dest = p->screen_base+dy*p->fontheight*width;
1728 mymemmove(dest, src, height*p->fontheight*width);
1729 } else if (dy <= sy) {
1730 src = p->screen_base+sy*p->fontheight*p->next_line+sx;
1731 dest = p->screen_base+dy*p->fontheight*p->next_line+dx;
1732 for (rows = height*p->fontheight; rows--;) {
1733 mymemmove(dest, src, width);
1734 src += p->next_line;
1735 dest += p->next_line;
1736 }
1737 } else {
1738 src = p->screen_base+((sy+height)*p->fontheight-1)*p->next_line+sx;
1739 dest = p->screen_base+((dy+height)*p->fontheight-1)*p->next_line+dx;
1740 for (rows = height*p->fontheight; rows--;) {
1741 mymemmove(dest, src, width);
1742 src -= p->next_line;
1743 dest -= p->next_line;
1744 }
1745 }
1746 }
1747
1748
1749 static void clear_mono(struct vc_data *conp, struct display *p, int sy, int sx,
1750 int height, int width)
1751 {
1752 u_char *dest;
1753 u_int rows;
1754
1755 dest = p->screen_base+sy*p->fontheight*p->next_line+sx;
1756
1757 if (sx == 0 && width == p->next_line)
1758 if (attr_reverse(p,conp))
1759 mymemset(dest, height*p->fontheight*width);
1760 else
1761 mymemclear(dest, height*p->fontheight*width);
1762 else
1763 for (rows = height*p->fontheight; rows--; dest += p->next_line)
1764 if (attr_reverse(p,conp))
1765 mymemset(dest, width);
1766 else
1767 mymemclear_small(dest, width);
1768 }
1769
1770
1771 static void putc_mono(struct vc_data *conp, struct display *p, int c, int y,
1772 int x)
1773 {
1774 u_char *dest, *cdat;
1775 u_int rows, bold, reverse, underline;
1776 u_char d;
1777
1778 c &= 0xff;
1779
1780 dest = p->screen_base+y*p->fontheight*p->next_line+x;
1781 cdat = p->fontdata+c*p->fontheight;
1782 bold = attr_bold(p,conp);
1783 reverse = attr_reverse(p,conp);
1784 underline = attr_underline(p,conp);
1785
1786 for (rows = p->fontheight; rows--; dest += p->next_line) {
1787 d = *cdat++;
1788 if (underline && !rows)
1789 d = 0xff;
1790 else if (bold)
1791 d |= d>>1;
1792 if (reverse)
1793 d = ~d;
1794 *dest = d;
1795 }
1796 }
1797
1798
1799 static void putcs_mono(struct vc_data *conp, struct display *p, const char *s,
1800 int count, int y, int x)
1801 {
1802 u_char *dest, *dest0, *cdat;
1803 u_int rows, bold, reverse, underline;
1804 u_char c, d;
1805
1806 dest0 = p->screen_base+y*p->fontheight*p->next_line+x;
1807 bold = attr_bold(p,conp);
1808 reverse = attr_reverse(p,conp);
1809 underline = attr_underline(p,conp);
1810
1811 while (count--) {
1812 c = *s++;
1813 dest = dest0++;
1814 cdat = p->fontdata+c*p->fontheight;
1815 for (rows = p->fontheight; rows--; dest += p->next_line) {
1816 d = *cdat++;
1817 if (underline && !rows)
1818 d = 0xff;
1819 else if (bold)
1820 d |= d>>1;
1821 if (reverse)
1822 d = ~d;
1823 *dest = d;
1824 }
1825 }
1826 }
1827
1828
1829 static void rev_char_mono(struct display *p, int x, int y)
1830 {
1831 u_char *dest;
1832 u_int rows;
1833
1834 dest = p->screen_base+y*p->fontheight*p->next_line+x;
1835 for (rows = p->fontheight; rows--; dest += p->next_line)
1836 *dest = ~*dest;
1837 }
1838
1839 #endif
1840
1841
1842
1843
1844 #ifdef CONFIG_FBCON_ILBM
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857 static void bmove_ilbm(struct display *p, int sy, int sx, int dy, int dx,
1858 int height, int width)
1859 {
1860 if (sx == 0 && sy == 0 && width == p->next_plane)
1861 mymemmove(p->screen_base+dy*p->fontheight*p->next_line, p->screen_base,
1862 height*p->fontheight*p->next_line);
1863 else {
1864 u_char *src, *dest;
1865 u_int i;
1866
1867 if (dy <= sy) {
1868 src = p->screen_base+sy*p->fontheight*p->next_line+sx;
1869 dest = p->screen_base+dy*p->fontheight*p->next_line+dx;
1870 for (i = p->var.bits_per_pixel*height*p->fontheight; i--;) {
1871 mymemmove(dest, src, width);
1872 src += p->next_plane;
1873 dest += p->next_plane;
1874 }
1875 } else {
1876 src = p->screen_base+(sy+height)*p->fontheight*p->next_line+sx;
1877 dest = p->screen_base+(dy+height)*p->fontheight*p->next_line+dx;
1878 for (i = p->var.bits_per_pixel*height*p->fontheight; i--;) {
1879 src -= p->next_plane;
1880 dest -= p->next_plane;
1881 mymemmove(dest, src, width);
1882 }
1883 }
1884 }
1885 }
1886
1887
1888 static void clear_ilbm(struct vc_data *conp, struct display *p, int sy, int sx,
1889 int height, int width)
1890 {
1891 u_char *dest;
1892 u_int i, rows;
1893 int bg, bg0;
1894
1895 dest = p->screen_base+sy*p->fontheight*p->next_line+sx;
1896
1897 bg0 = attr_bgcol_ec(p,conp);
1898 for (rows = height*p->fontheight; rows--;) {
1899 bg = bg0;
1900 for (i = p->var.bits_per_pixel; i--; dest += p->next_plane) {
1901 if (bg & 1)
1902 mymemset(dest, width);
1903 else
1904 mymemclear(dest, width);
1905 bg >>= 1;
1906 }
1907 }
1908 }
1909
1910
1911 static void putc_ilbm(struct vc_data *conp, struct display *p, int c, int y,
1912 int x)
1913 {
1914 u_char *dest, *cdat;
1915 u_int rows, i;
1916 u_char d;
1917 int fg0, bg0, fg, bg;
1918
1919 c &= 0xff;
1920
1921 dest = p->screen_base+y*p->fontheight*p->next_line+x;
1922 cdat = p->fontdata+c*p->fontheight;
1923 fg0 = attr_fgcol(p,conp);
1924 bg0 = attr_bgcol(p,conp);
1925
1926 for (rows = p->fontheight; rows--;) {
1927 d = *cdat++;
1928 fg = fg0;
1929 bg = bg0;
1930 for (i = p->var.bits_per_pixel; i--; dest += p->next_plane) {
1931 if (bg & 1)
1932 if (fg & 1)
1933 *dest = 0xff;
1934 else
1935 *dest = ~d;
1936 else
1937 if (fg & 1)
1938 *dest = d;
1939 else
1940 *dest = 0x00;
1941 bg >>= 1;
1942 fg >>= 1;
1943 }
1944 }
1945 }
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963 static void putcs_ilbm(struct vc_data *conp, struct display *p, const char *s,
1964 int count, int y, int x)
1965 {
1966 u_char *dest0, *dest, *cdat1, *cdat2, *cdat3, *cdat4;
1967 u_int rows, i;
1968 u_char c1, c2, c3, c4;
1969 u_long d;
1970 int fg0, bg0, fg, bg;
1971
1972 dest0 = p->screen_base+y*p->fontheight*p->next_line+x;
1973 fg0 = attr_fgcol(p,conp);
1974 bg0 = attr_bgcol(p,conp);
1975
1976 while (count--)
1977 if (x&3 || count < 3) {
1978 c1 = *s++;
1979 dest = dest0++;
1980 x++;
1981
1982 cdat1 = p->fontdata+c1*p->fontheight;
1983 for (rows = p->fontheight; rows--;) {
1984 d = *cdat1++;
1985 fg = fg0;
1986 bg = bg0;
1987 for (i = p->var.bits_per_pixel; i--; dest += p->next_plane) {
1988 if (bg & 1)
1989 if (fg & 1)
1990 *dest = 0xff;
1991 else
1992 *dest = ~d;
1993 else
1994 if (fg & 1)
1995 *dest = d;
1996 else
1997 *dest = 0x00;
1998 bg >>= 1;
1999 fg >>= 1;
2000 }
2001 }
2002 } else {
2003 c1 = s[0];
2004 c2 = s[1];
2005 c3 = s[2];
2006 c4 = s[3];
2007
2008 dest = dest0;
2009 cdat1 = p->fontdata+c1*p->fontheight;
2010 cdat2 = p->fontdata+c2*p->fontheight;
2011 cdat3 = p->fontdata+c3*p->fontheight;
2012 cdat4 = p->fontdata+c4*p->fontheight;
2013 for (rows = p->fontheight; rows--;) {
2014 d = *cdat1++<<24 | *cdat2++<<16 | *cdat3++<<8 | *cdat4++;
2015 fg = fg0;
2016 bg = bg0;
2017 for (i = p->var.bits_per_pixel; i--; dest += p->next_plane) {
2018 if (bg & 1)
2019 if (fg & 1)
2020 *(u_long *)dest = 0xffffffff;
2021 else
2022 *(u_long *)dest = ~d;
2023 else
2024 if (fg & 1)
2025 *(u_long *)dest = d;
2026 else
2027 *(u_long *)dest = 0x00000000;
2028 bg >>= 1;
2029 fg >>= 1;
2030 }
2031 }
2032 s += 4;
2033 dest0 += 4;
2034 x += 4;
2035 count -= 3;
2036 }
2037 }
2038
2039
2040 static void rev_char_ilbm(struct display *p, int x, int y)
2041 {
2042 u_char *dest, *dest0;
2043 u_int rows, i;
2044 int mask;
2045
2046 dest0 = p->screen_base+y*p->fontheight*p->next_line+x;
2047 mask = p->fgcol ^ p->bgcol;
2048
2049
2050
2051
2052
2053
2054
2055 for (i = p->var.bits_per_pixel; i--; dest0 += p->next_plane) {
2056 if (mask & 1) {
2057 dest = dest0;
2058 for (rows = p->fontheight; rows--; dest += p->next_line)
2059 *dest = ~*dest;
2060 }
2061 mask >>= 1;
2062 }
2063 }
2064
2065 #endif
2066
2067
2068
2069
2070 #ifdef CONFIG_FBCON_PLANES
2071
2072
2073
2074
2075
2076 static void bmove_plan(struct display *p, int sy, int sx, int dy, int dx,
2077 int height, int width)
2078 {
2079 u_char *src, *dest, *src0, *dest0;
2080 u_int i, rows;
2081
2082 if (sx == 0 && sy == 0 && width == p->next_line) {
2083 src = p->screen_base;
2084 dest = p->screen_base+dy*p->fontheight*width;
2085 for (i = p->var.bits_per_pixel; i--;) {
2086 mymemmove(dest, src, height*p->fontheight*width);
2087 src += p->next_plane;
2088 dest += p->next_plane;
2089 }
2090 } else if (dy <= sy) {
2091 src0 = p->screen_base+sy*p->fontheight*p->next_line+sx;
2092 dest0 = p->screen_base+dy*p->fontheight*p->next_line+dx;
2093 for (i = p->var.bits_per_pixel; i--;) {
2094 src = src0;
2095 dest = dest0;
2096 for (rows = height*p->fontheight; rows--;) {
2097 mymemmove(dest, src, width);
2098 src += p->next_line;
2099 dest += p->next_line;
2100 }
2101 src0 += p->next_plane;
2102 dest0 += p->next_plane;
2103 }
2104 } else {
2105 src0 = p->screen_base+(sy+height)*p->fontheight*p->next_line+sx;
2106 dest0 = p->screen_base+(dy+height)*p->fontheight*p->next_line+dx;
2107 for (i = p->var.bits_per_pixel; i--;) {
2108 src = src0;
2109 dest = dest0;
2110 for (rows = height*p->fontheight; rows--;) {
2111 src -= p->next_line;
2112 dest -= p->next_line;
2113 mymemmove(dest, src, width);
2114 }
2115 src0 += p->next_plane;
2116 dest0 += p->next_plane;
2117 }
2118 }
2119 }
2120
2121
2122 static void clear_plan(struct vc_data *conp, struct display *p, int sy, int sx,
2123 int height, int width)
2124 {
2125 u_char *dest, *dest0;
2126 u_int i, rows;
2127 int bg;
2128
2129 dest0 = p->screen_base+sy*p->fontheight*p->next_line+sx;
2130
2131 bg = attr_bgcol_ec(p,conp);
2132 for (i = p->var.bits_per_pixel; i--; dest0 += p->next_plane) {
2133 dest = dest0;
2134 for (rows = height*p->fontheight; rows--; dest += p->next_line)
2135 if (bg & 1)
2136 mymemset(dest, width);
2137 else
2138 mymemclear(dest, width);
2139 bg >>= 1;
2140 }
2141 }
2142
2143
2144 static void putc_plan(struct vc_data *conp, struct display *p, int c, int y,
2145 int x)
2146 {
2147 u_char *dest, *dest0, *cdat, *cdat0;
2148 u_int rows, i;
2149 u_char d;
2150 int fg, bg;
2151
2152 c &= 0xff;
2153
2154 dest0 = p->screen_base+y*p->fontheight*p->next_line+x;
2155 cdat0 = p->fontdata+c*p->fontheight;
2156 fg = attr_fgcol(p,conp);
2157 bg = attr_bgcol(p,conp);
2158
2159 for (i = p->var.bits_per_pixel; i--; dest0 += p->next_plane) {
2160 dest = dest0;
2161 cdat = cdat0;
2162 for (rows = p->fontheight; rows--; dest += p->next_line) {
2163 d = *cdat++;
2164 if (bg & 1)
2165 if (fg & 1)
2166 *dest = 0xff;
2167 else
2168 *dest = ~d;
2169 else
2170 if (fg & 1)
2171 *dest = d;
2172 else
2173 *dest = 0x00;
2174 }
2175 bg >>= 1;
2176 fg >>= 1;
2177 }
2178 }
2179
2180
2181
2182
2183
2184
2185
2186 static void putcs_plan(struct vc_data *conp, struct display *p, const char *s,
2187 int count, int y, int x)
2188 {
2189 u_char *dest, *dest0, *dest1;
2190 u_char *cdat1, *cdat2, *cdat3, *cdat4, *cdat10, *cdat20, *cdat30, *cdat40;
2191 u_int rows, i;
2192 u_char c1, c2, c3, c4;
2193 u_long d;
2194 int fg0, bg0, fg, bg;
2195
2196 dest0 = p->screen_base+y*p->fontheight*p->next_line+x;
2197 fg0 = attr_fgcol(p,conp);
2198 bg0 = attr_bgcol(p,conp);
2199
2200 while (count--)
2201 if (x&3 || count < 3) {
2202 c1 = *s++;
2203 dest1 = dest0++;
2204 x++;
2205
2206 cdat10 = p->fontdata+c1*p->fontheight;
2207 fg = fg0;
2208 bg = bg0;
2209
2210 for (i = p->var.bits_per_pixel; i--; dest1 += p->next_plane) {
2211 dest = dest1;
2212 cdat1 = cdat10;
2213 for (rows = p->fontheight; rows--; dest += p->next_line) {
2214 d = *cdat1++;
2215 if (bg & 1)
2216 if (fg & 1)
2217 *dest = 0xff;
2218 else
2219 *dest = ~d;
2220 else
2221 if (fg & 1)
2222 *dest = d;
2223 else
2224 *dest = 0x00;
2225 }
2226 bg >>= 1;
2227 fg >>= 1;
2228 }
2229 } else {
2230 c1 = s[0];
2231 c2 = s[1];
2232 c3 = s[2];
2233 c4 = s[3];
2234
2235 dest1 = dest0;
2236 cdat10 = p->fontdata+c1*p->fontheight;
2237 cdat20 = p->fontdata+c2*p->fontheight;
2238 cdat30 = p->fontdata+c3*p->fontheight;
2239 cdat40 = p->fontdata+c4*p->fontheight;
2240 fg = fg0;
2241 bg = bg0;
2242
2243 for (i = p->var.bits_per_pixel; i--; dest1 += p->next_plane) {
2244 dest = dest1;
2245 cdat1 = cdat10;
2246 cdat2 = cdat20;
2247 cdat3 = cdat30;
2248 cdat4 = cdat40;
2249 for (rows = p->fontheight; rows--; dest += p->next_line) {
2250 d = *cdat1++<<24 | *cdat2++<<16 | *cdat3++<<8 | *cdat4++;
2251 if (bg & 1)
2252 if (fg & 1)
2253 *(u_long *)dest = 0xffffffff;
2254 else
2255 *(u_long *)dest = ~d;
2256 else
2257 if (fg & 1)
2258 *(u_long *)dest = d;
2259 else
2260 *(u_long *)dest = 0x00000000;
2261 }
2262 bg >>= 1;
2263 fg >>= 1;
2264 }
2265 s += 4;
2266 dest0 += 4;
2267 x += 4;
2268 count -= 3;
2269 }
2270 }
2271
2272
2273 static void rev_char_plan(struct display *p, int x, int y)
2274 {
2275 u_char *dest, *dest0;
2276 u_int rows, i;
2277 int mask;
2278
2279 dest0 = p->screen_base+y*p->fontheight*p->next_line+x;
2280 mask = p->fgcol ^ p->bgcol;
2281
2282
2283
2284
2285
2286
2287
2288 for (i = p->var.bits_per_pixel; i--; dest0 += p->next_plane) {
2289 if (mask & 1) {
2290 dest = dest0;
2291 for (rows = p->fontheight; rows--; dest += p->next_line)
2292 *dest = ~*dest;
2293 }
2294 mask >>= 1;
2295 }
2296 }
2297
2298 #endif
2299
2300
2301
2302
2303 #ifdef CONFIG_FBCON_2PLANE
2304
2305
2306
2307
2308
2309
2310
2311 #define INC_2P(p) do { if (!((long)(++(p)) & 1)) (p) += 2; } while(0)
2312 #define DEC_2P(p) do { if ((long)(--(p)) & 1) (p) -= 2; } while(0)
2313
2314
2315
2316
2317
2318
2319 #define COLOR_2P(c) (((c & 7) >= 3 && (c & 7) != 4) | (c & 8) >> 2)
2320
2321
2322 static void bmove_2_plane(struct display *p, int sy, int sx, int dy, int dx,
2323 int height, int width)
2324 {
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337 if (sx == 0 && dx == 0 && width == p->next_line/2) {
2338
2339
2340
2341 mymemmove(p->screen_base + dy * p->next_line * p->fontheight,
2342 p->screen_base + sy * p->next_line * p->fontheight,
2343 p->next_line * height * p->fontheight);
2344 } else {
2345 int rows, cols;
2346 u_char *src;
2347 u_char *dst;
2348 int bytes = p->next_line;
2349 int linesize = bytes * p->fontheight;
2350 u_int colsize = height * p->fontheight;
2351 u_int upwards = (dy < sy) || (dy == sy && dx < sx);
2352
2353 if ((sx & 1) == (dx & 1)) {
2354
2355
2356 if (upwards) {
2357
2358 src = p->screen_base + sy * linesize + (sx>>1)*4 + (sx & 1);
2359 dst = p->screen_base + dy * linesize + (dx>>1)*4 + (dx & 1);
2360
2361 if (sx & 1) {
2362 memmove_2p_col(dst, src, colsize, bytes);
2363 src += 3;
2364 dst += 3;
2365 --width;
2366 }
2367
2368 if (width > 1) {
2369 for(rows = colsize; rows > 0; --rows) {
2370 mymemmove(dst, src, (width>>1)*4);
2371 src += bytes;
2372 dst += bytes;
2373 }
2374 }
2375
2376 if (width & 1) {
2377 src -= colsize * bytes;
2378 dst -= colsize * bytes;
2379 memmove_2p_col(dst + (width>>1)*4, src + (width>>1)*4,
2380 colsize, bytes);
2381 }
2382 }
2383 else {
2384
2385 if (!((sx+width-1) & 1)) {
2386 src = p->screen_base + sy * linesize + ((sx+width-1)>>1)*4;
2387 dst = p->screen_base + dy * linesize + ((dx+width-1)>>1)*4;
2388 memmove_2p_col(dst, src, colsize, bytes);
2389 --width;
2390 }
2391
2392 src = p->screen_base + sy * linesize + (sx>>1)*4 + (sx & 1);
2393 dst = p->screen_base + dy * linesize + (dx>>1)*4 + (dx & 1);
2394
2395 if (width > 1) {
2396 src += colsize * bytes + (sx & 1)*3;
2397 dst += colsize * bytes + (sx & 1)*3;
2398 for(rows = colsize; rows > 0; --rows) {
2399 src -= bytes;
2400 dst -= bytes;
2401 mymemmove(dst, src, (width>>1)*4);
2402 }
2403 }
2404
2405 if (width & 1) {
2406 memmove_2p_col(dst-3, src-3, colsize, bytes);
2407 }
2408
2409 }
2410 }
2411 else {
2412
2413
2414 if (upwards) {
2415 src = p->screen_base + sy * linesize + (sx>>1)*4 + (sx & 1);
2416 dst = p->screen_base + dy * linesize + (dx>>1)*4 + (dx & 1);
2417 for(cols = width; cols > 0; --cols) {
2418 memmove_2p_col(dst, src, colsize, bytes);
2419 INC_2P(src);
2420 INC_2P(dst);
2421 }
2422 }
2423 else {
2424 sx += width-1;
2425 dx += width-1;
2426 src = p->screen_base + sy * linesize + (sx>>1)*4 + (sx & 1);
2427 dst = p->screen_base + dy * linesize + (dx>>1)*4 + (dx & 1);
2428 for(cols = width; cols > 0; --cols) {
2429 memmove_2p_col(dst, src, colsize, bytes);
2430 DEC_2P(src);
2431 DEC_2P(dst);
2432 }
2433 }
2434 }
2435
2436
2437 }
2438 }
2439
2440
2441 static void clear_2_plane(struct vc_data *conp, struct display *p, int sy,
2442 int sx, int height, int width)
2443 {
2444 ulong offset;
2445 u_char *start;
2446 int rows;
2447 int bytes = p->next_line;
2448 int lines = height * p->fontheight;
2449 ulong size;
2450 u_long cval;
2451 u_short pcval;
2452
2453 cval = expand2l (COLOR_2P (attr_bgcol_ec(p,conp)));
2454
2455 if (sx == 0 && width == bytes/2) {
2456
2457 offset = sy * bytes * p->fontheight;
2458 size = lines * bytes;
2459 memset_even_2p(p->screen_base+offset, size, cval);
2460
2461 } else {
2462
2463 offset = (sy * bytes * p->fontheight) + (sx>>1)*4 + (sx & 1);
2464 start = p->screen_base + offset;
2465 pcval = expand2w(COLOR_2P(attr_bgcol_ec(p,conp)));
2466
2467
2468
2469
2470
2471
2472
2473
2474 if (sx & 1) {
2475 memclear_2p_col(start, lines, pcval, bytes);
2476 start += 3;
2477 width--;
2478 }
2479
2480 if (width & 1) {
2481 memclear_2p_col(start + (width>>1)*4, lines, pcval, bytes);
2482 width--;
2483 }
2484
2485 if (width) {
2486 for(rows = lines; rows-- ; start += bytes)
2487 memset_even_2p(start, width*2, cval);
2488 }
2489 }
2490 }
2491
2492
2493 static void putc_2_plane(struct vc_data *conp, struct display *p, int c, int y,
2494 int x)
2495 {
2496 u_char *dest;
2497 u_char *cdat;
2498 int rows;
2499 int bytes = p->next_line;
2500 ulong eorx, fgx, bgx, fdx;
2501
2502 c &= 0xff;
2503
2504 dest = p->screen_base + y * p->fontheight * bytes + (x>>1)*4 + (x & 1);
2505 cdat = p->fontdata + (c * p->fontheight);
2506
2507 fgx = expand2w(COLOR_2P(attr_fgcol(p,conp)));
2508 bgx = expand2w(COLOR_2P(attr_bgcol(p,conp)));
2509 eorx = fgx ^ bgx;
2510
2511 for(rows = p->fontheight ; rows-- ; dest += bytes) {
2512 fdx = dup2w(*cdat++);
2513 __asm__ __volatile__ ("movepw %1,%0@(0)" :
2514 : "a" (dest), "d" ((fdx & eorx) ^ bgx));
2515 }
2516 }
2517
2518
2519 static void putcs_2_plane(struct vc_data *conp, struct display *p,
2520 const char *s, int count, int y, int x)
2521 {
2522 u_char *dest, *dest0;
2523 u_char *cdat, c;
2524 int rows;
2525 int bytes;
2526 ulong eorx, fgx, bgx, fdx;
2527
2528 bytes = p->next_line;
2529 dest0 = p->screen_base + y * p->fontheight * bytes + (x>>1)*4 + (x & 1);
2530 fgx = expand2w(COLOR_2P(attr_fgcol(p,conp)));
2531 bgx = expand2w(COLOR_2P(attr_bgcol(p,conp)));
2532 eorx = fgx ^ bgx;
2533
2534 while (count--) {
2535
2536 c = *s++;
2537 cdat = p->fontdata + (c * p->fontheight);
2538
2539 for(rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) {
2540 fdx = dup2w(*cdat++);
2541 __asm__ __volatile__ ("movepw %1,%0@(0)" :
2542 : "a" (dest), "d" ((fdx & eorx) ^ bgx));
2543 }
2544 INC_2P(dest0);
2545 }
2546 }
2547
2548
2549 static void rev_char_2_plane(struct display *p, int x, int y)
2550 {
2551 u_char *dest;
2552 int j;
2553 int bytes;
2554
2555 dest = p->screen_base + y * p->fontheight * p->next_line + (x>>1)*4 + (x & 1);
2556 j = p->fontheight;
2557 bytes = p->next_line;
2558 while (j--)
2559 {
2560
2561
2562
2563
2564 dest[0] = ~dest[0];
2565 dest[2] = ~dest[2];
2566 dest += bytes;
2567 }
2568 }
2569 #endif
2570
2571
2572
2573
2574 #ifdef CONFIG_FBCON_4PLANE
2575
2576
2577
2578
2579
2580
2581
2582 #define INC_4P(p) do { if (!((long)(++(p)) & 1)) (p) += 6; } while(0)
2583 #define DEC_4P(p) do { if ((long)(--(p)) & 1) (p) -= 6; } while(0)
2584
2585
2586 static void bmove_4_plane(struct display *p, int sy, int sx, int dy, int dx,
2587 int height, int width)
2588 {
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601 if (sx == 0 && dx == 0 && width == p->next_line/4) {
2602
2603
2604
2605 mymemmove(p->screen_base + dy * p->next_line * p->fontheight,
2606 p->screen_base + sy * p->next_line * p->fontheight,
2607 p->next_line * height * p->fontheight);
2608 } else {
2609 int rows, cols;
2610 u_char *src;
2611 u_char *dst;
2612 int bytes = p->next_line;
2613 int linesize = bytes * p->fontheight;
2614 u_int colsize = height * p->fontheight;
2615 u_int upwards = (dy < sy) || (dy == sy && dx < sx);
2616
2617 if ((sx & 1) == (dx & 1)) {
2618
2619
2620 if (upwards) {
2621
2622 src = p->screen_base + sy * linesize + (sx>>1)*8 + (sx & 1);
2623 dst = p->screen_base + dy * linesize + (dx>>1)*8 + (dx & 1);
2624
2625 if (sx & 1) {
2626 memmove_4p_col(dst, src, colsize, bytes);
2627 src += 7;
2628 dst += 7;
2629 --width;
2630 }
2631
2632 if (width > 1) {
2633 for(rows = colsize; rows > 0; --rows) {
2634 mymemmove(dst, src, (width>>1)*8);
2635 src += bytes;
2636 dst += bytes;
2637 }
2638 }
2639
2640 if (width & 1) {
2641 src -= colsize * bytes;
2642 dst -= colsize * bytes;
2643 memmove_4p_col(dst + (width>>1)*8, src + (width>>1)*8,
2644 colsize, bytes);
2645 }
2646 }
2647 else {
2648
2649 if (!((sx+width-1) & 1)) {
2650 src = p->screen_base + sy * linesize + ((sx+width-1)>>1)*8;
2651 dst = p->screen_base + dy * linesize + ((dx+width-1)>>1)*8;
2652 memmove_4p_col(dst, src, colsize, bytes);
2653 --width;
2654 }
2655
2656 src = p->screen_base + sy * linesize + (sx>>1)*8 + (sx & 1);
2657 dst = p->screen_base + dy * linesize + (dx>>1)*8 + (dx & 1);
2658
2659 if (width > 1) {
2660 src += colsize * bytes + (sx & 1)*7;
2661 dst += colsize * bytes + (sx & 1)*7;
2662 for(rows = colsize; rows > 0; --rows) {
2663 src -= bytes;
2664 dst -= bytes;
2665 mymemmove(dst, src, (width>>1)*8);
2666 }
2667 }
2668
2669 if (width & 1) {
2670 memmove_4p_col(dst-7, src-7, colsize, bytes);
2671 }
2672
2673 }
2674 }
2675 else {
2676
2677
2678 if (upwards) {
2679 src = p->screen_base + sy * linesize + (sx>>1)*8 + (sx & 1);
2680 dst = p->screen_base + dy * linesize + (dx>>1)*8 + (dx & 1);
2681 for(cols = width; cols > 0; --cols) {
2682 memmove_4p_col(dst, src, colsize, bytes);
2683 INC_4P(src);
2684 INC_4P(dst);
2685 }
2686 }
2687 else {
2688 sx += width-1;
2689 dx += width-1;
2690 src = p->screen_base + sy * linesize + (sx>>1)*8 + (sx & 1);
2691 dst = p->screen_base + dy * linesize + (dx>>1)*8 + (dx & 1);
2692 for(cols = width; cols > 0; --cols) {
2693 memmove_4p_col(dst, src, colsize, bytes);
2694 DEC_4P(src);
2695 DEC_4P(dst);
2696 }
2697 }
2698 }
2699
2700
2701 }
2702 }
2703
2704
2705 static void clear_4_plane(struct vc_data *conp, struct display *p, int sy,
2706 int sx, int height, int width)
2707 {
2708 ulong offset;
2709 u_char *start;
2710 int rows;
2711 int bytes = p->next_line;
2712 int lines = height * p->fontheight;
2713 ulong size;
2714 u_long cval1, cval2, pcval;
2715
2716 expand4dl(attr_bgcol_ec(p,conp), &cval1, &cval2);
2717
2718 if (sx == 0 && width == bytes/4) {
2719
2720 offset = sy * bytes * p->fontheight;
2721 size = lines * bytes;
2722 memset_even_4p(p->screen_base+offset, size, cval1, cval2);
2723
2724 } else {
2725
2726 offset = (sy * bytes * p->fontheight) + (sx>>1)*8 + (sx & 1);
2727 start = p->screen_base + offset;
2728 pcval = expand4l(attr_bgcol_ec(p,conp));
2729
2730
2731
2732
2733
2734
2735
2736
2737 if (sx & 1) {
2738 memclear_4p_col(start, lines, pcval, bytes);
2739 start += 7;
2740 width--;
2741 }
2742
2743 if (width & 1) {
2744 memclear_4p_col(start + (width>>1)*8, lines, pcval, bytes);
2745 width--;
2746 }
2747
2748 if (width) {
2749 for(rows = lines; rows-- ; start += bytes)
2750 memset_even_4p(start, width*4, cval1, cval2);
2751 }
2752 }
2753 }
2754
2755
2756 static void putc_4_plane(struct vc_data *conp, struct display *p, int c, int y,
2757 int x)
2758 {
2759 u_char *dest;
2760 u_char *cdat;
2761 int rows;
2762 int bytes = p->next_line;
2763 ulong eorx, fgx, bgx, fdx;
2764
2765 c &= 0xff;
2766
2767 dest = p->screen_base + y * p->fontheight * bytes + (x>>1)*8 + (x & 1);
2768 cdat = p->fontdata + (c * p->fontheight);
2769
2770 fgx = expand4l(attr_fgcol(p,conp));
2771 bgx = expand4l(attr_bgcol(p,conp));
2772 eorx = fgx ^ bgx;
2773
2774 for(rows = p->fontheight ; rows-- ; dest += bytes) {
2775 fdx = dup4l(*cdat++);
2776 __asm__ __volatile__ ("movepl %1,%0@(0)" :
2777 : "a" (dest), "d" ((fdx & eorx) ^ bgx));
2778 }
2779 }
2780
2781
2782 static void putcs_4_plane(struct vc_data *conp, struct display *p,
2783 const char *s, int count, int y, int x)
2784 {
2785 u_char *dest, *dest0;
2786 u_char *cdat, c;
2787 int rows;
2788 int bytes;
2789 ulong eorx, fgx, bgx, fdx;
2790
2791 bytes = p->next_line;
2792 dest0 = p->screen_base + y * p->fontheight * bytes + (x>>1)*8 + (x & 1);
2793 fgx = expand4l(attr_fgcol(p,conp));
2794 bgx = expand4l(attr_bgcol(p,conp));
2795 eorx = fgx ^ bgx;
2796
2797 while (count--) {
2798
2799
2800
2801
2802
2803
2804
2805
2806 c = *s++;
2807 cdat = p->fontdata + (c * p->fontheight);
2808
2809 for(rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) {
2810 fdx = dup4l(*cdat++);
2811 __asm__ __volatile__ ("movepl %1,%0@(0)" :
2812 : "a" (dest), "d" ((fdx & eorx) ^ bgx));
2813 }
2814 INC_4P(dest0);
2815 }
2816 }
2817
2818
2819 static void rev_char_4_plane(struct display *p, int x, int y)
2820 {
2821 u_char *dest;
2822 int j;
2823 int bytes;
2824
2825 dest = p->screen_base + y * p->fontheight * p->next_line + (x>>1)*8 + (x & 1);
2826 j = p->fontheight;
2827 bytes = p->next_line;
2828
2829 while (j--)
2830 {
2831
2832
2833
2834
2835 dest[0] = ~dest[0];
2836 dest[2] = ~dest[2];
2837 dest[4] = ~dest[4];
2838 dest[6] = ~dest[6];
2839 dest += bytes;
2840 }
2841 }
2842 #endif
2843
2844
2845
2846
2847 #ifdef CONFIG_FBCON_8PLANE
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861 #define INC_8P(p) do { if (!((long)(++(p)) & 1)) (p) += 14; } while(0)
2862 #define DEC_8P(p) do { if ((long)(--(p)) & 1) (p) -= 14; } while(0)
2863
2864
2865 static void bmove_8_plane(struct display *p, int sy, int sx, int dy, int dx,
2866 int height, int width)
2867 {
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880 if (sx == 0 && dx == 0 && width == p->next_line/8) {
2881
2882
2883
2884 fast_memmove (p->screen_base + dy * p->next_line * p->fontheight,
2885 p->screen_base + sy * p->next_line * p->fontheight,
2886 p->next_line * height * p->fontheight);
2887 } else {
2888 int rows, cols;
2889 u_char *src;
2890 u_char *dst;
2891 int bytes = p->next_line;
2892 int linesize = bytes * p->fontheight;
2893 u_int colsize = height * p->fontheight;
2894 u_int upwards = (dy < sy) || (dy == sy && dx < sx);
2895
2896 if ((sx & 1) == (dx & 1)) {
2897
2898
2899 if (upwards) {
2900
2901 src = p->screen_base + sy * linesize + (sx>>1)*16 + (sx & 1);
2902 dst = p->screen_base + dy * linesize + (dx>>1)*16 + (dx & 1);
2903
2904 if (sx & 1) {
2905 memmove_8p_col(dst, src, colsize, bytes);
2906 src += 15;
2907 dst += 15;
2908 --width;
2909 }
2910
2911 if (width > 1) {
2912 for(rows = colsize; rows > 0; --rows) {
2913 fast_memmove (dst, src, (width >> 1) * 16);
2914 src += bytes;
2915 dst += bytes;
2916 }
2917 }
2918
2919 if (width & 1) {
2920 src -= colsize * bytes;
2921 dst -= colsize * bytes;
2922 memmove_8p_col(dst + (width>>1)*16, src + (width>>1)*16,
2923 colsize, bytes);
2924 }
2925 }
2926 else {
2927
2928 if (!((sx+width-1) & 1)) {
2929 src = p->screen_base + sy * linesize + ((sx+width-1)>>1)*16;
2930 dst = p->screen_base + dy * linesize + ((dx+width-1)>>1)*16;
2931 memmove_8p_col(dst, src, colsize, bytes);
2932 --width;
2933 }
2934
2935 src = p->screen_base + sy * linesize + (sx>>1)*16 + (sx & 1);
2936 dst = p->screen_base + dy * linesize + (dx>>1)*16 + (dx & 1);
2937
2938 if (width > 1) {
2939 src += colsize * bytes + (sx & 1)*15;
2940 dst += colsize * bytes + (sx & 1)*15;
2941 for(rows = colsize; rows > 0; --rows) {
2942 src -= bytes;
2943 dst -= bytes;
2944 fast_memmove (dst, src, (width>>1)*16);
2945 }
2946 }
2947
2948 if (width & 1) {
2949 memmove_8p_col(dst-15, src-15, colsize, bytes);
2950 }
2951
2952 }
2953 }
2954 else {
2955
2956
2957 if (upwards) {
2958 src = p->screen_base + sy * linesize + (sx>>1)*16 + (sx & 1);
2959 dst = p->screen_base + dy * linesize + (dx>>1)*16 + (dx & 1);
2960 for(cols = width; cols > 0; --cols) {
2961 memmove_8p_col(dst, src, colsize, bytes);
2962 INC_8P(src);
2963 INC_8P(dst);
2964 }
2965 }
2966 else {
2967 sx += width-1;
2968 dx += width-1;
2969 src = p->screen_base + sy * linesize + (sx>>1)*16 + (sx & 1);
2970 dst = p->screen_base + dy * linesize + (dx>>1)*16 + (dx & 1);
2971 for(cols = width; cols > 0; --cols) {
2972 memmove_8p_col(dst, src, colsize, bytes);
2973 DEC_8P(src);
2974 DEC_8P(dst);
2975 }
2976 }
2977 }
2978
2979
2980 }
2981 }
2982
2983
2984 static void clear_8_plane(struct vc_data *conp, struct display *p, int sy,
2985 int sx, int height, int width)
2986 {
2987 ulong offset;
2988 u_char *start;
2989 int rows;
2990 int bytes = p->next_line;
2991 int lines = height * p->fontheight;
2992 ulong size;
2993 u_long cval1, cval2, cval3, cval4, pcval1, pcval2;
2994
2995 expand8ql(attr_bgcol_ec(p,conp), cval1, cval2, cval3, cval4);
2996
2997 if (sx == 0 && width == bytes/8) {
2998
2999 offset = sy * bytes * p->fontheight;
3000 size = lines * bytes;
3001 memset_even_8p(p->screen_base+offset, size, cval1, cval2, cval3, cval4);
3002
3003 } else {
3004
3005 offset = (sy * bytes * p->fontheight) + (sx>>1)*16 + (sx & 1);
3006 start = p->screen_base + offset;
3007 expand8dl(attr_bgcol_ec(p,conp), &pcval1, &pcval2);
3008
3009
3010
3011
3012
3013
3014
3015
3016 if (sx & 1) {
3017 memclear_8p_col(start, lines, pcval1, pcval2, bytes);
3018 start += 7;
3019 width--;
3020 }
3021
3022 if (width & 1) {
3023 memclear_8p_col(start + (width>>1)*16, lines, pcval1,
3024 pcval2, bytes);
3025 width--;
3026 }
3027
3028 if (width) {
3029 for(rows = lines; rows-- ; start += bytes)
3030 memset_even_8p(start, width*8, cval1, cval2, cval3, cval4);
3031 }
3032 }
3033 }
3034
3035
3036 static void putc_8_plane(struct vc_data *conp, struct display *p, int c, int y,
3037 int x)
3038 {
3039 u_char *dest;
3040 u_char *cdat;
3041 int rows;
3042 int bytes = p->next_line;
3043 ulong eorx1, eorx2, fgx1, fgx2, bgx1, bgx2, fdx;
3044
3045 c &= 0xff;
3046
3047 dest = p->screen_base + y * p->fontheight * bytes + (x>>1)*16 + (x & 1);
3048 cdat = p->fontdata + (c * p->fontheight);
3049
3050 expand8dl(attr_fgcol(p,conp), &fgx1, &fgx2);
3051 expand8dl(attr_bgcol(p,conp), &bgx1, &bgx2);
3052 eorx1 = fgx1 ^ bgx1; eorx2 = fgx2 ^ bgx2;
3053
3054 for(rows = p->fontheight ; rows-- ; dest += bytes) {
3055 fdx = dup4l(*cdat++);
3056 __asm__ __volatile__
3057 ("movepl %1,%0@(0)\n\t"
3058 "movepl %2,%0@(8)"
3059 :
3060 : "a" (dest), "d" ((fdx & eorx1) ^ bgx1),
3061 "d" ((fdx & eorx2) ^ bgx2)
3062 );
3063 }
3064 }
3065
3066
3067 static void putcs_8_plane(struct vc_data *conp, struct display *p,
3068 const char *s, int count, int y, int x)
3069 {
3070 u_char *dest, *dest0;
3071 u_char *cdat, c;
3072 int rows;
3073 int bytes;
3074 ulong eorx1, eorx2, fgx1, fgx2, bgx1, bgx2, fdx;
3075
3076 bytes = p->next_line;
3077 dest0 = p->screen_base + y * p->fontheight * bytes + (x>>1)*16 + (x & 1);
3078
3079 expand8dl(attr_fgcol(p,conp), &fgx1, &fgx2);
3080 expand8dl(attr_bgcol(p,conp), &bgx1, &bgx2);
3081 eorx1 = fgx1 ^ bgx1; eorx2 = fgx2 ^ bgx2;
3082
3083 while (count--) {
3084
3085
3086
3087
3088
3089
3090
3091
3092 c = *s++;
3093 cdat = p->fontdata + (c * p->fontheight);
3094
3095 for(rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) {
3096 fdx = dup4l(*cdat++);
3097 __asm__ __volatile__
3098 ("movepl %1,%0@(0)\n\t"
3099 "movepl %2,%0@(8)"
3100 :
3101 : "a" (dest), "d" ((fdx & eorx1) ^ bgx1),
3102 "d" ((fdx & eorx2) ^ bgx2)
3103 );
3104 }
3105 INC_8P(dest0);
3106 }
3107 }
3108
3109
3110 static void rev_char_8_plane(struct display *p, int x, int y)
3111 {
3112 u_char *dest;
3113 int j;
3114 int bytes;
3115
3116 dest = p->screen_base + y * p->fontheight * p->next_line + (x>>1)*16 + (x & 1);
3117 j = p->fontheight;
3118 bytes = p->next_line;
3119
3120 while (j--)
3121 {
3122
3123
3124
3125
3126
3127
3128 dest[0] = ~dest[0];
3129 dest[2] = ~dest[2];
3130 dest[4] = ~dest[4];
3131 dest[6] = ~dest[6];
3132 dest += bytes;
3133 }
3134 }
3135 #endif
3136
3137
3138
3139
3140 #ifdef CONFIG_FBCON_8PACKED
3141
3142
3143
3144
3145
3146 static u_long nibbletab_8_packed[]={
3147 0x00000000,0x000000ff,0x0000ff00,0x0000ffff,
3148 0x00ff0000,0x00ff00ff,0x00ffff00,0x00ffffff,
3149 0xff000000,0xff0000ff,0xff00ff00,0xff00ffff,
3150 0xffff0000,0xffff00ff,0xffffff00,0xffffffff};
3151
3152 static void bmove_8_packed(struct display *p, int sy, int sx, int dy, int dx,
3153 int height, int width)
3154 {
3155 int bytes = p->next_line, linesize = bytes * p->fontheight, rows;
3156 u_char *src,*dst;
3157
3158 if (sx == 0 && dx == 0 && width * 8 == bytes) {
3159 mymemmove(p->screen_base + dy * linesize,
3160 p->screen_base + sy * linesize,
3161 height * linesize);
3162 }
3163 else {
3164 if (dy < sy || (dy == sy && dx < sx)) {
3165 src = p->screen_base + sy * linesize + sx * 8;
3166 dst = p->screen_base + dy * linesize + dx * 8;
3167 for (rows = height * p->fontheight ; rows-- ;) {
3168 mymemmove(dst, src, width * 8);
3169 src += bytes;
3170 dst += bytes;
3171 }
3172 }
3173 else {
3174 src = p->screen_base + (sy+height) * linesize + sx * 8
3175 - bytes;
3176 dst = p->screen_base + (dy+height) * linesize + dx * 8
3177 - bytes;
3178 for (rows = height * p->fontheight ; rows-- ;) {
3179 mymemmove(dst, src, width * 8);
3180 src -= bytes;
3181 dst -= bytes;
3182 }
3183 }
3184 }
3185 }
3186
3187
3188 static void clear_8_packed(struct vc_data *conp, struct display *p, int sy,
3189 int sx, int height, int width)
3190 {
3191 u_char *dest0,*dest;
3192 int bytes=p->next_line,lines=height * p->fontheight, rows, i;
3193 u_long bgx;
3194
3195 dest = p->screen_base + sy * p->fontheight * bytes + sx * 8;
3196
3197 bgx=attr_bgcol_ec(p,conp);
3198 bgx |= (bgx << 8);
3199 bgx |= (bgx << 16);
3200
3201 if (sx == 0 && width * 8 == bytes) {
3202 for (i = 0 ; i < lines * width ; i++) {
3203 ((u_long *)dest)[0]=bgx;
3204 ((u_long *)dest)[1]=bgx;
3205 dest+=8;
3206 }
3207 } else {
3208 dest0=dest;
3209 for (rows = lines; rows-- ; dest0 += bytes) {
3210 dest=dest0;
3211 for (i = 0 ; i < width ; i++) {
3212 ((u_long *)dest)[0]=bgx;
3213 ((u_long *)dest)[1]=bgx;
3214 dest+=8;
3215 }
3216 }
3217 }
3218 }
3219
3220
3221 static void putc_8_packed(struct vc_data *conp, struct display *p, int c, int y,
3222 int x)
3223 {
3224 u_char *dest,*cdat;
3225 int bytes=p->next_line,rows;
3226 ulong eorx,fgx,bgx;
3227
3228 c &= 0xff;
3229
3230 dest = p->screen_base + y * p->fontheight * bytes + x * 8;
3231 cdat = p->fontdata + c * p->fontheight;
3232
3233 fgx=attr_fgcol(p,conp);
3234 bgx=attr_bgcol(p,conp);
3235 fgx |= (fgx << 8);
3236 fgx |= (fgx << 16);
3237 bgx |= (bgx << 8);
3238 bgx |= (bgx << 16);
3239 eorx = fgx ^ bgx;
3240
3241 for (rows = p->fontheight ; rows-- ; dest += bytes) {
3242 ((u_long *)dest)[0]=
3243 (nibbletab_8_packed[*cdat >> 4] & eorx) ^ bgx;
3244 ((u_long *)dest)[1]=
3245 (nibbletab_8_packed[*cdat++ & 0xf] & eorx) ^ bgx;
3246 }
3247 }
3248
3249
3250 static void putcs_8_packed(struct vc_data *conp, struct display *p,
3251 const char *s, int count, int y, int x)
3252 {
3253 u_char *cdat, c, *dest, *dest0;
3254 int rows,bytes=p->next_line;
3255 u_long eorx, fgx, bgx;
3256
3257 dest0 = p->screen_base + y * p->fontheight * bytes + x * 8;
3258 fgx=attr_fgcol(p,conp);
3259 bgx=attr_bgcol(p,conp);
3260 fgx |= (fgx << 8);
3261 fgx |= (fgx << 16);
3262 bgx |= (bgx << 8);
3263 bgx |= (bgx << 16);
3264 eorx = fgx ^ bgx;
3265 while (count--) {
3266 c = *s++;
3267 cdat = p->fontdata + c * p->fontheight;
3268
3269 for (rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) {
3270 ((u_long *)dest)[0]=
3271 (nibbletab_8_packed[*cdat >> 4] & eorx) ^ bgx;
3272 ((u_long *)dest)[1]=
3273 (nibbletab_8_packed[*cdat++ & 0xf] & eorx) ^ bgx;
3274 }
3275 dest0+=8;
3276 }
3277 }
3278
3279
3280 static void rev_char_8_packed(struct display *p, int x, int y)
3281 {
3282 u_char *dest;
3283 int bytes=p->next_line, rows;
3284
3285 dest = p->screen_base + y * p->fontheight * bytes + x * 8;
3286 for (rows = p->fontheight ; rows-- ; dest += bytes) {
3287 ((u_long *)dest)[0] ^= 0x0f0f0f0f;
3288 ((u_long *)dest)[1] ^= 0x0f0f0f0f;
3289 }
3290 }
3291
3292 #endif
3293
3294
3295
3296
3297 #ifdef CONFIG_FBCON_16PACKED
3298
3299
3300
3301
3302
3303 u_short packed16_cmap[16];
3304
3305 static u_long tab_16_packed[]={
3306 0x00000000,0x0000ffff,0xffff0000,0xffffffff};
3307
3308 static void bmove_16_packed(struct display *p, int sy, int sx, int dy, int dx,
3309 int height, int width)
3310 {
3311 int bytes = p->next_line, linesize = bytes * p->fontheight, rows;
3312 u_char *src,*dst;
3313
3314 if (sx == 0 && dx == 0 && width * 16 == bytes) {
3315 mymemmove(p->screen_base + dy * linesize,
3316 p->screen_base + sy * linesize,
3317 height * linesize);
3318 }
3319 else {
3320 if (dy < sy || (dy == sy && dx < sx)) {
3321 src = p->screen_base + sy * linesize + sx * 16;
3322 dst = p->screen_base + dy * linesize + dx * 16;
3323 for (rows = height * p->fontheight ; rows-- ;) {
3324 mymemmove(dst, src, width * 16);
3325 src += bytes;
3326 dst += bytes;
3327 }
3328 }
3329 else {
3330 src = p->screen_base + (sy+height) * linesize + sx * 16
3331 - bytes;
3332 dst = p->screen_base + (dy+height) * linesize + dx * 16
3333 - bytes;
3334 for (rows = height * p->fontheight ; rows-- ;) {
3335 mymemmove(dst, src, width * 16);
3336 src -= bytes;
3337 dst -= bytes;
3338 }
3339 }
3340 }
3341 }
3342
3343
3344 static void clear_16_packed(struct vc_data *conp, struct display *p, int sy,
3345 int sx, int height, int width)
3346 {
3347 u_char *dest0,*dest;
3348 int bytes=p->next_line,lines=height * p->fontheight, rows, i;
3349 u_long bgx;
3350
3351 dest = p->screen_base + sy * p->fontheight * bytes + sx * 16;
3352
3353 bgx = attr_bgcol_ec(p,conp);
3354 bgx = packed16_cmap[bgx];
3355 bgx |= (bgx << 16);
3356
3357 if (sx == 0 && width * 16 == bytes) {
3358 for (i = 0 ; i < lines * width ; i++) {
3359 ((u_long *)dest)[0]=bgx;
3360 ((u_long *)dest)[1]=bgx;
3361 ((u_long *)dest)[2]=bgx;
3362 ((u_long *)dest)[3]=bgx;
3363 dest+=16;
3364 }
3365 } else {
3366 dest0=dest;
3367 for (rows = lines; rows-- ; dest0 += bytes) {
3368 dest=dest0;
3369 for (i = 0 ; i < width ; i++) {
3370 ((u_long *)dest)[0]=bgx;
3371 ((u_long *)dest)[1]=bgx;
3372 ((u_long *)dest)[2]=bgx;
3373 ((u_long *)dest)[3]=bgx;
3374 dest+=16;
3375 }
3376 }
3377 }
3378 }
3379
3380
3381 static void putc_16_packed(struct vc_data *conp, struct display *p, int c,
3382 int y, int x)
3383 {
3384 u_char *dest,*cdat;
3385 int bytes=p->next_line,rows;
3386 ulong eorx,fgx,bgx;
3387
3388 c &= 0xff;
3389
3390 dest = p->screen_base + y * p->fontheight * bytes + x * 16;
3391 cdat = p->fontdata + c * p->fontheight;
3392
3393 fgx = attr_fgcol(p,conp);
3394 fgx = packed16_cmap[fgx];
3395 bgx = attr_bgcol(p,conp);
3396 bgx = packed16_cmap[bgx];
3397 fgx |= (fgx << 16);
3398 bgx |= (bgx << 16);
3399 eorx = fgx ^ bgx;
3400
3401 for (rows = p->fontheight ; rows-- ; dest += bytes) {
3402 ((u_long *)dest)[0]=
3403 (tab_16_packed[*cdat >> 6] & eorx) ^ bgx;
3404 ((u_long *)dest)[1]=
3405 (tab_16_packed[*cdat >> 4 & 0x3] & eorx) ^ bgx;
3406 ((u_long *)dest)[2]=
3407 (tab_16_packed[*cdat >> 2 & 0x3] & eorx) ^ bgx;
3408 ((u_long *)dest)[3]=
3409 (tab_16_packed[*cdat++ & 0x3] & eorx) ^ bgx;
3410 }
3411 }
3412
3413
3414
3415 static void putcs_16_packed(struct vc_data *conp, struct display *p,
3416 const char *s, int count, int y, int x)
3417 {
3418 u_char *cdat, c, *dest, *dest0;
3419 int rows,bytes=p->next_line;
3420 u_long eorx, fgx, bgx;
3421
3422 dest0 = p->screen_base + y * p->fontheight * bytes + x * 16;
3423 fgx = attr_fgcol(p,conp);
3424 fgx = packed16_cmap[fgx];
3425 bgx = attr_bgcol(p,conp);
3426 bgx = packed16_cmap[bgx];
3427 fgx |= (fgx << 16);
3428 bgx |= (bgx << 16);
3429 eorx = fgx ^ bgx;
3430 while (count--) {
3431 c = *s++;
3432 cdat = p->fontdata + c * p->fontheight;
3433
3434 for (rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) {
3435 ((u_long *)dest)[0]=
3436 (tab_16_packed[*cdat >> 6] & eorx) ^ bgx;
3437 ((u_long *)dest)[1]=
3438 (tab_16_packed[*cdat >> 4 & 0x3] & eorx) ^ bgx;
3439 ((u_long *)dest)[2]=
3440 (tab_16_packed[*cdat >> 2 & 0x3] & eorx) ^ bgx;
3441 ((u_long *)dest)[3]=
3442 (tab_16_packed[*cdat++ & 0x3] & eorx) ^ bgx;
3443 }
3444 dest0+=16;
3445 }
3446 }
3447
3448
3449 static void rev_char_16_packed(struct display *p, int x, int y)
3450 {
3451 u_char *dest;
3452 int bytes=p->next_line, rows;
3453
3454 dest = p->screen_base + y * p->fontheight * bytes + x * 16;
3455 for (rows = p->fontheight ; rows-- ; dest += bytes) {
3456 ((u_long *)dest)[0] ^= 0xffffffff;
3457 ((u_long *)dest)[1] ^= 0xffffffff;
3458 ((u_long *)dest)[2] ^= 0xffffffff;
3459 ((u_long *)dest)[3] ^= 0xffffffff;
3460 }
3461 }
3462
3463 #endif
3464
3465
3466
3467
3468 #ifdef CONFIG_FBCON_CYBER
3469
3470
3471
3472
3473
3474 static void bmove_cyber(struct display *p, int sy, int sx, int dy, int dx,
3475 int height, int width)
3476 {
3477 sx *= 8; dx *= 8; width *= 8;
3478 Cyber_BitBLT((u_short)sx, (u_short)(sy*p->fontheight), (u_short)dx,
3479 (u_short)(dy*p->fontheight), (u_short)width,
3480 (u_short)(height*p->fontheight), (u_short)S3_NEW);
3481 }
3482
3483
3484 static void clear_cyber(struct vc_data *conp, struct display *p, int sy, int sx,
3485 int height, int width)
3486 {
3487 u_char bg;
3488
3489 sx *= 8; width *= 8;
3490 bg = attr_bgcol_ec(p,conp);
3491 Cyber_RectFill((u_short)sx, (u_short)(sy*p->fontheight), (u_short)width,
3492 (u_short)(height*p->fontheight), (u_short)S3_NEW,
3493 (u_short)bg);
3494 }
3495
3496
3497 static void putc_cyber(struct vc_data *conp, struct display *p, int c, int y,
3498 int x)
3499 {
3500 u_char *dest, *cdat;
3501 u_long tmp;
3502 u_int rows, reverse, underline;
3503 u_char d;
3504 u_char fg, bg;
3505
3506 c &= 0xff;
3507
3508 dest = p->screen_base+y*p->fontheight*p->next_line+8*x;
3509 cdat = p->fontdata+(c*p->fontheight);
3510 fg = disp->fgcol;
3511 bg = disp->bgcol;
3512 reverse = conp->vc_reverse;
3513 underline = conp->vc_underline;
3514
3515 Cyber_WaitBlit();
3516 for (rows = p->fontheight; rows--; dest += p->next_line) {
3517 d = *cdat++;
3518
3519 if (underline && !rows)
3520 d = 0xff;
3521 if (reverse)
3522 d = ~d;
3523
3524 tmp = ((d & 0x80) ? fg : bg) << 24;
3525 tmp |= ((d & 0x40) ? fg : bg) << 16;
3526 tmp |= ((d & 0x20) ? fg : bg) << 8;
3527 tmp |= ((d & 0x10) ? fg : bg);
3528 *((u_long*) dest) = tmp;
3529 tmp = ((d & 0x8) ? fg : bg) << 24;
3530 tmp |= ((d & 0x4) ? fg : bg) << 16;
3531 tmp |= ((d & 0x2) ? fg : bg) << 8;
3532 tmp |= ((d & 0x1) ? fg : bg);
3533 *((u_long*) dest + 1) = tmp;
3534 }
3535 }
3536
3537
3538 static void putcs_cyber(struct vc_data *conp, struct display *p, const char *s,
3539 int count, int y, int x)
3540 {
3541 u_char *dest, *dest0, *cdat;
3542 u_long tmp;
3543 u_int rows, reverse, underline;
3544 u_char c, d;
3545 u_char fg, bg;
3546
3547 dest0 = p->screen_base+y*p->fontheight*p->next_line+8*x;
3548 fg = disp->fgcol;
3549 bg = disp->bgcol;
3550 reverse = conp->vc_reverse;
3551 underline = conp->vc_underline;
3552
3553 Cyber_WaitBlit();
3554 while (count--) {
3555 c = *s++;
3556 dest = dest0;
3557 dest0 += 8;
3558 cdat = p->fontdata+(c*p->fontheight);
3559 for (rows = p->fontheight; rows--; dest += p->next_line) {
3560 d = *cdat++;
3561
3562 if (underline && !rows)
3563 d = 0xff;
3564 if (reverse)
3565 d = ~d;
3566
3567 tmp = ((d & 0x80) ? fg : bg) << 24;
3568 tmp |= ((d & 0x40) ? fg : bg) << 16;
3569 tmp |= ((d & 0x20) ? fg : bg) << 8;
3570 tmp |= ((d & 0x10) ? fg : bg);
3571 *((u_long*) dest) = tmp;
3572 tmp = ((d & 0x8) ? fg : bg) << 24;
3573 tmp |= ((d & 0x4) ? fg : bg) << 16;
3574 tmp |= ((d & 0x2) ? fg : bg) << 8;
3575 tmp |= ((d & 0x1) ? fg : bg);
3576 *((u_long*) dest + 1) = tmp;
3577 }
3578 }
3579 }
3580
3581
3582 static void rev_char_cyber(struct display *p, int x, int y)
3583 {
3584 u_char *dest;
3585 u_int rows;
3586 u_char fg, bg;
3587
3588 fg = disp->fgcol;
3589 bg = disp->bgcol;
3590
3591 dest = p->screen_base+y*p->fontheight*p->next_line+8*x;
3592 Cyber_WaitBlit();
3593 for (rows = p->fontheight; rows--; dest += p->next_line) {
3594 *dest = (*dest == fg) ? bg : fg;
3595 *(dest+1) = (*(dest + 1) == fg) ? bg : fg;
3596 *(dest+2) = (*(dest + 2) == fg) ? bg : fg;
3597 *(dest+3) = (*(dest + 3) == fg) ? bg : fg;
3598 *(dest+4) = (*(dest + 4) == fg) ? bg : fg;
3599 *(dest+5) = (*(dest + 5) == fg) ? bg : fg;
3600 *(dest+6) = (*(dest + 6) == fg) ? bg : fg;
3601 *(dest+7) = (*(dest + 7) == fg) ? bg : fg;
3602 }
3603 }
3604
3605 #endif
3606
3607
3608
3609
3610
3611
3612
3613
3614 struct consw fb_con = {
3615 fbcon_startup, fbcon_init, fbcon_deinit, fbcon_clear, fbcon_putc,
3616 fbcon_putcs, fbcon_cursor, fbcon_scroll, fbcon_bmove, fbcon_switch,
3617 fbcon_blank
3618 };