2 * linux/drivers/video/fbcon-mac.c -- Low level frame buffer operations for
3 * x bpp packed pixels, font width != 8
5 * Created 26 Dec 1997 by Michael Schmitz
6 * Based on the old macfb.c 6x11 code by Randy Thelen
8 * This driver is significantly slower than the 8bit font drivers
9 * and would probably benefit from splitting into drivers for each depth.
11 * This file is subject to the terms and conditions of the GNU General Public
12 * License. See the file COPYING in the main directory of this archive for
15 #include <linux/module.h>
16 #include <linux/tty.h>
17 #include <linux/console.h>
18 #include <linux/string.h>
20 #include <linux/delay.h>
22 #include <video/fbcon.h>
23 #include <video/fbcon-mac.h>
27 * variable bpp packed pixels
30 static void plot_pixel_mac(struct display
*p
, int bw
, int pixel_x
,
32 static int get_pixel_mac(struct display
*p
, int pixel_x
, int pixel_y
);
34 void fbcon_mac_setup(struct display
*p
)
37 p
->next_line
= p
->line_length
;
39 p
->next_line
= p
->var
.xres_virtual
>>3;
47 #define PIXEL_BLACK_MAC 0
48 #define PIXEL_WHITE_MAC 1
49 #define PIXEL_INVERT_MAC 2
51 void fbcon_mac_bmove(struct display
*p
, int sy
, int sx
, int dy
, int dx
,
52 int height
, int width
)
57 int dl
,dr
,dt
,db
,dw
,dlo
;
60 src
= (u8
*) (p
->screen_base
+ sy
* fontheight(p
) * p
->next_line
);
61 dest
= (u8
*) (p
->screen_base
+ dy
* fontheight(p
) * p
->next_line
);
63 if( sx
== 0 && width
== p
->conp
->vc_cols
) {
64 s
= height
* fontheight(p
) * p
->next_line
;
65 mymemmove(dest
, src
, s
);
69 l
= sx
* fontwidth(p
);
70 r
= l
+ width
* fontwidth(p
);
71 t
= sy
* fontheight(p
);
72 b
= t
+ height
* fontheight(p
);
74 dl
= dx
* fontwidth(p
);
75 dr
= dl
+ width
* fontwidth(p
);
76 dt
= dy
* fontheight(p
);
77 db
= dt
+ height
* fontheight(p
);
79 /* w is the # pixels between two long-aligned points, left and right */
80 w
= (r
&~31) - ((l
+31)&~31);
81 dw
= (dr
&~31) - ((dl
+31)&~31);
82 /* lo is the # pixels between the left edge and a long-aligned left pixel */
83 lo
= ((l
+31)&~31) - l
;
84 dlo
= ((dl
+31)&~31) - dl
;
86 /* if dx != sx then, logic has to align the left and right edges for fast moves */
89 dlo
= ((dl
+7)&~7) - dl
;
90 w
= (r
&~7) - ((l
+7)&~7);
91 dw
= (dr
&~7) - ((dl
+7)&~7);
93 unsigned char err_str
[128];
94 unsigned short err_buf
[256];
95 unsigned long cnt
, len
;
96 sprintf( err_str
, "ERROR: Shift algorithm: sx=%d,sy=%d,dx=%d,dy=%d,w=%d,h=%d,bpp=%d",
97 sx
,sy
,dx
,dy
,width
,height
,p
->var
.bits_per_pixel
);
98 len
= strlen(err_str
);
99 for (cnt
= 0; cnt
< len
; cnt
++)
100 err_buf
[cnt
] = 0x700 | err_str
[cnt
];
101 fbcon_mac_putcs(p
->conp
, p
, err_buf
, len
, 0, 0);
102 /* pause for the user */
103 for(cnt
= 0; cnt
< 50000; cnt
++)
110 switch (p
->var
.bits_per_pixel
) {
146 src
+= height
* fontheight(p
);
147 dest
+= height
* fontheight(p
);
154 for (i
= t
; i
< b
; i
++) {
157 for (; j
& 31 && j
< r
; j
++)
158 plot_pixel_mac(p
, get_pixel_mac(p
, j
+(dx
-sx
), i
+(dy
-sy
)), j
, i
);
161 mymemmove(dest
, src
, s
);
163 dest
+= p
->next_line
;
166 dest
-= p
->next_line
;
173 plot_pixel_mac(p
, get_pixel_mac(p
, j
+(dx
-sx
), i
+(dy
-sy
)), j
, i
);
189 void fbcon_mac_clear(struct vc_data
*conp
, struct display
*p
, int sy
, int sx
,
190 int height
, int width
)
198 inverse
= conp
? attr_reverse(p
,conp
->vc_attr
) : 0;
199 pixel
= inverse
? PIXEL_WHITE_MAC
: PIXEL_BLACK_MAC
;
200 dest
= (u8
*) (p
->screen_base
+ sy
* fontheight(p
) * p
->next_line
);
202 if( sx
== 0 && width
== p
->conp
->vc_cols
) {
203 s
= height
* fontheight(p
) * p
->next_line
;
210 l
= sx
* fontwidth(p
);
211 r
= l
+ width
* fontwidth(p
);
212 t
= sy
* fontheight(p
);
213 b
= t
+ height
* fontheight(p
);
214 /* w is the # pixels between two long-aligned points, left and right */
215 w
= (r
&~31) - ((l
+31)&~31);
216 /* lo is the # pixels between the left edge and a long-aligned left pixel */
217 lo
= ((l
+31)&~31) - l
;
219 switch (p
->var
.bits_per_pixel
) {
246 for (i
= t
; i
< b
; i
++) {
249 for (; j
& 31 && j
< r
; j
++)
250 plot_pixel_mac(p
, pixel
, j
, i
);
253 if (PIXEL_WHITE_MAC
== pixel
)
257 dest
+= p
->next_line
;
262 plot_pixel_mac(p
, pixel
, j
, i
);
267 void fbcon_mac_putc(struct vc_data
*conp
, struct display
*p
, int c
, int yy
,
271 u_int rows
, bold
, ch_reverse
, ch_underline
;
275 cdat
= p
->fontdata
+(c
&p
->charmask
)*fontheight(p
);
276 bold
= attr_bold(p
,c
);
277 ch_reverse
= attr_reverse(p
,c
);
278 ch_underline
= attr_underline(p
,c
);
280 for (rows
= 0; rows
< fontheight(p
); rows
++) {
282 if (!conp
->vc_can_do_color
) {
283 if (ch_underline
&& rows
== (fontheight(p
)-2))
290 for (j
= 0; j
< fontwidth(p
); j
++) {
291 plot_pixel_mac(p
, (d
& 0x80) >> 7, (xx
*fontwidth(p
)) + j
, (yy
*fontheight(p
)) + rows
);
298 void fbcon_mac_putcs(struct vc_data
*conp
, struct display
*p
,
299 const unsigned short *s
, int count
, int yy
, int xx
)
305 fbcon_mac_putc(conp
, p
, c
, yy
, xx
++);
310 void fbcon_mac_revc(struct display
*p
, int xx
, int yy
)
314 for (rows
= 0; rows
< fontheight(p
); rows
++) {
315 for (j
= 0; j
< fontwidth(p
); j
++) {
316 plot_pixel_mac (p
, PIXEL_INVERT_MAC
, (xx
*fontwidth(p
))+j
, (yy
*fontheight(p
))+rows
);
328 static void plot_pixel_mac(struct display
*p
, int bw
, int pixel_x
, int pixel_y
)
334 if (pixel_x
< 0 || pixel_y
< 0 || pixel_x
>= 832 || pixel_y
>= 624) {
336 printk ("ERROR: pixel_x == %d, pixel_y == %d", pixel_x
, pixel_y
);
337 for(cnt
= 0; cnt
< 100000; cnt
++)
342 switch (p
->var
.bits_per_pixel
) {
344 dest
= (u8
*) ((pixel_x
>> 3) + p
->screen_base
+ pixel_y
* p
->next_line
);
345 bit
= 0x80 >> (pixel_x
& 7);
347 case PIXEL_BLACK_MAC
:
350 case PIXEL_WHITE_MAC
:
353 case PIXEL_INVERT_MAC
:
357 printk( "ERROR: Unknown pixel value in plot_pixel_mac\n");
362 dest
= (u8
*) ((pixel_x
>> 2) + p
->screen_base
+ pixel_y
* p
->next_line
);
363 bit
= 0xC0 >> ((pixel_x
& 3) << 1);
365 case PIXEL_BLACK_MAC
:
368 case PIXEL_WHITE_MAC
:
371 case PIXEL_INVERT_MAC
:
375 printk( "ERROR: Unknown pixel value in plot_pixel_mac\n");
380 dest
= (u8
*) ((pixel_x
/ 2) + p
->screen_base
+ pixel_y
* p
->next_line
);
381 bit
= 0xF0 >> ((pixel_x
& 1) << 2);
383 case PIXEL_BLACK_MAC
:
386 case PIXEL_WHITE_MAC
:
389 case PIXEL_INVERT_MAC
:
393 printk( "ERROR: Unknown pixel value in plot_pixel_mac\n");
398 dest
= (u8
*) (pixel_x
+ p
->screen_base
+ pixel_y
* p
->next_line
);
401 case PIXEL_BLACK_MAC
:
404 case PIXEL_WHITE_MAC
:
407 case PIXEL_INVERT_MAC
:
411 printk( "ERROR: Unknown pixel value in plot_pixel_mac\n");
416 dest16
= (u16
*) ((pixel_x
*2) + p
->screen_base
+ pixel_y
* p
->next_line
);
419 case PIXEL_BLACK_MAC
:
422 case PIXEL_WHITE_MAC
:
425 case PIXEL_INVERT_MAC
:
429 printk( "ERROR: Unknown pixel value in plot_pixel_mac\n");
434 dest32
= (u32
*) ((pixel_x
*4) + p
->screen_base
+ pixel_y
* p
->next_line
);
437 case PIXEL_BLACK_MAC
:
440 case PIXEL_WHITE_MAC
:
443 case PIXEL_INVERT_MAC
:
447 printk( "ERROR: Unknown pixel value in plot_pixel_mac\n");
453 static int get_pixel_mac(struct display
*p
, int pixel_x
, int pixel_y
)
460 switch (p
->var
.bits_per_pixel
) {
462 dest
= (u8
*) ((pixel_x
/ 8) + p
->screen_base
+ pixel_y
* p
->next_line
);
463 bit
= 0x80 >> (pixel_x
& 7);
467 dest
= (u8
*) ((pixel_x
/ 4) + p
->screen_base
+ pixel_y
* p
->next_line
);
468 bit
= 0xC0 >> (pixel_x
& 3);
472 dest
= (u8
*) ((pixel_x
/ 2) + p
->screen_base
+ pixel_y
* p
->next_line
);
473 bit
= 0xF0 >> (pixel_x
& 1);
477 dest
= (u8
*) (pixel_x
+ p
->screen_base
+ pixel_y
* p
->next_line
);
481 dest16
= (u16
*) ((pixel_x
*2) + p
->screen_base
+ pixel_y
* p
->next_line
);
482 pixel
= *dest16
? 1 : 0;
485 dest32
= (u32
*) ((pixel_x
*4) + p
->screen_base
+ pixel_y
* p
->next_line
);
486 pixel
= *dest32
? 1 : 0;
490 return pixel
? PIXEL_BLACK_MAC
: PIXEL_WHITE_MAC
;
495 * `switch' for the low level operations
498 struct display_switch fbcon_mac
= {
499 fbcon_mac_setup
, fbcon_mac_bmove
, fbcon_mac_clear
, fbcon_mac_putc
,
500 fbcon_mac_putcs
, fbcon_mac_revc
, NULL
, NULL
, NULL
, FONTWIDTHRANGE(1,8)
505 int init_module(void)
510 void cleanup_module(void)
516 * Visible symbols for modules
519 EXPORT_SYMBOL(fbcon_mac
);
520 EXPORT_SYMBOL(fbcon_mac_setup
);
521 EXPORT_SYMBOL(fbcon_mac_bmove
);
522 EXPORT_SYMBOL(fbcon_mac_clear
);
523 EXPORT_SYMBOL(fbcon_mac_putc
);
524 EXPORT_SYMBOL(fbcon_mac_putcs
);
525 EXPORT_SYMBOL(fbcon_mac_revc
);