2 * linux/drivers/video/iplan2p8.c -- Low level frame buffer operations for
3 * interleaved bitplanes à la Atari (8
4 * planes, 2 bytes interleave)
6 * Created 5 Apr 1997 by Geert Uytterhoeven
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file COPYING in the main directory of this archive for
13 #include <linux/module.h>
14 #include <linux/string.h>
17 #include <asm/setup.h>
22 #include "atafb_utils.h"
25 /* Copies a 8 plane column from 's', height 'h', to 'd'. */
27 /* This expands a 8 bit color into two longs for two movepl (8 plane)
31 void atafb_iplan2p8_copyarea(struct fb_info
*info
, u_long next_line
,
32 int sy
, int sx
, int dy
, int dx
,
33 int height
, int width
)
35 /* bmove() has to distinguish two major cases: If both, source and
36 * destination, start at even addresses or both are at odd
37 * addresses, just the first odd and last even column (if present)
38 * require special treatment (memmove_col()). The rest between
39 * then can be copied by normal operations, because all adjacent
40 * bytes are affected and are to be stored in the same order.
41 * The pathological case is when the move should go from an odd
42 * address to an even or vice versa. Since the bytes in the plane
43 * words must be assembled in new order, it seems wisest to make
44 * all movements by memmove_col().
51 u_int upwards
= (dy
< sy
) || (dy
== sy
&& dx
< sx
);
54 if (!((sx
^ dx
) & 15)) {
55 /* odd->odd or even->even */
58 src
= (u8
*)info
->screen_base
+ sy
* next_line
+ (sx
& ~15) / (8 / BPL
);
59 dst
= (u8
*)info
->screen_base
+ dy
* next_line
+ (dx
& ~15) / (8 / BPL
);
61 memmove32_col(dst
, src
, 0xff00ff, height
, next_line
- BPL
* 2);
71 l
= next_line
- w
* 4;
72 for (j
= height
; j
> 0; j
--) {
73 for (i
= w
; i
> 0; i
--)
75 s
= (u32
*)((u8
*)s
+ l
);
76 d
= (u32
*)((u8
*)d
+ l
);
80 memmove32_col(dst
+ width
/ (8 / BPL
), src
+ width
/ (8 / BPL
),
81 0xff00ff00, height
, next_line
- BPL
* 2);
83 src
= (u8
*)info
->screen_base
+ (sy
- 1) * next_line
+ ((sx
+ width
+ 8) & ~15) / (8 / BPL
);
84 dst
= (u8
*)info
->screen_base
+ (dy
- 1) * next_line
+ ((dx
+ width
+ 8) & ~15) / (8 / BPL
);
86 if ((sx
+ width
) & 15) {
89 memmove32_col(dst
, src
, 0xff00ff00, colsize
, -next_line
- BPL
* 2);
97 l
= next_line
- w
* 4;
98 for (j
= height
; j
> 0; j
--) {
99 for (i
= w
; i
> 0; i
--)
101 s
= (u32
*)((u8
*)s
- l
);
102 d
= (u32
*)((u8
*)d
- l
);
106 memmove32_col(dst
- (width
- 16) / (8 / BPL
),
107 src
- (width
- 16) / (8 / BPL
),
108 0xff00ff, colsize
, -next_line
- BPL
* 2);
111 /* odd->even or even->odd */
114 u32 pval
[4], v
, v1
, mask
;
117 src
= (u8
*)info
->screen_base
+ sy
* next_line
+ (sx
& ~15) / (8 / BPL
);
118 dst
= (u8
*)info
->screen_base
+ dy
* next_line
+ (dx
& ~15) / (8 / BPL
);
127 if ((sx
+ width
) & 15)
130 for (i
= height
; i
; i
--) {
135 pval
[0] = (*src32
++ << 8) & mask
;
136 pval
[1] = (*src32
++ << 8) & mask
;
137 pval
[2] = (*src32
++ << 8) & mask
;
138 pval
[3] = (*src32
++ << 8) & mask
;
140 pval
[0] = dst32
[0] & mask
;
141 pval
[1] = dst32
[1] & mask
;
142 pval
[2] = dst32
[2] & mask
;
143 pval
[3] = dst32
[3] & mask
;
146 for (j
= w
; j
> 0; j
--) {
149 *dst32
++ = pval
[0] | (v1
>> 8);
150 pval
[0] = (v
^ v1
) << 8;
153 *dst32
++ = pval
[1] | (v1
>> 8);
154 pval
[1] = (v
^ v1
) << 8;
157 *dst32
++ = pval
[2] | (v1
>> 8);
158 pval
[2] = (v
^ v1
) << 8;
161 *dst32
++ = pval
[3] | (v1
>> 8);
162 pval
[3] = (v
^ v1
) << 8;
166 dst32
[0] = (dst32
[0] & mask
) | pval
[0];
167 dst32
[1] = (dst32
[1] & mask
) | pval
[1];
168 dst32
[2] = (dst32
[2] & mask
) | pval
[2];
169 dst32
[3] = (dst32
[3] & mask
) | pval
[3];
177 u32 pval
[4], v
, v1
, mask
;
180 src
= (u8
*)info
->screen_base
+ (sy
- 1) * next_line
+ ((sx
+ width
+ 8) & ~15) / (8 / BPL
);
181 dst
= (u8
*)info
->screen_base
+ (dy
- 1) * next_line
+ ((dx
+ width
+ 8) & ~15) / (8 / BPL
);
186 if ((dx
+ width
) & 15)
193 for (i
= height
; i
; i
--) {
198 pval
[0] = dst32
[-1] & mask
;
199 pval
[1] = dst32
[-2] & mask
;
200 pval
[2] = dst32
[-3] & mask
;
201 pval
[3] = dst32
[-4] & mask
;
203 pval
[0] = (*--src32
>> 8) & mask
;
204 pval
[1] = (*--src32
>> 8) & mask
;
205 pval
[2] = (*--src32
>> 8) & mask
;
206 pval
[3] = (*--src32
>> 8) & mask
;
209 for (j
= w
; j
> 0; j
--) {
212 *--dst32
= pval
[0] | (v1
<< 8);
213 pval
[0] = (v
^ v1
) >> 8;
216 *--dst32
= pval
[1] | (v1
<< 8);
217 pval
[1] = (v
^ v1
) >> 8;
220 *--dst32
= pval
[2] | (v1
<< 8);
221 pval
[2] = (v
^ v1
) >> 8;
224 *--dst32
= pval
[3] | (v1
<< 8);
225 pval
[3] = (v
^ v1
) >> 8;
229 dst32
[-1] = (dst32
[-1] & mask
) | pval
[0];
230 dst32
[-2] = (dst32
[-2] & mask
) | pval
[1];
231 dst32
[-3] = (dst32
[-3] & mask
) | pval
[2];
232 dst32
[-4] = (dst32
[-4] & mask
) | pval
[3];
242 void atafb_iplan2p8_fillrect(struct fb_info
*info
, u_long next_line
, u32 color
,
243 int sy
, int sx
, int height
, int width
)
249 dest
= (u32
*)(info
->screen_base
+ sy
* next_line
+ (sx
& ~15) / (8 / BPL
));
251 u8
*dest8
= (u8
*)dest
+ 1;
253 expand8_col2mask(color
, cval
);
255 for (i
= height
; i
; i
--) {
256 fill8_col(dest8
, cval
);
263 expand16_col2mask(color
, cval
);
267 u32 off
= next_line
- rows
* BPL
* 2;
268 for (i
= height
; i
; i
--) {
269 d
= fill16_col(d
, rows
, cval
);
270 d
= (u32
*)((long)d
+ off
);
272 dest
+= rows
* BPL
/ 2;
277 u8
*dest8
= (u8
*)dest
;
279 expand8_col2mask(color
, cval
);
281 for (i
= height
; i
; i
--) {
282 fill8_col(dest8
, cval
);
288 void atafb_iplan2p8_linefill(struct fb_info
*info
, u_long next_line
,
289 int dy
, int dx
, u32 width
,
290 const u8
*data
, u32 bgcolor
, u32 fgcolor
)
295 u32 fgm
[4], bgm
[4], m
;
297 dest
= (u32
*)(info
->screen_base
+ dy
* next_line
+ (dx
& ~15) / (8 / BPL
));
299 fill8_2col((u8
*)dest
+ 1, fgcolor
, bgcolor
, *data
++);
305 data16
= (const u16
*)data
;
306 expand16_2col2mask(fgcolor
, bgcolor
, fgm
, bgm
);
308 for (rows
= width
/ 16; rows
; rows
--) {
310 m
= d
| ((u32
)d
<< 16);
311 *dest
++ = (m
& fgm
[0]) ^ bgm
[0];
312 *dest
++ = (m
& fgm
[1]) ^ bgm
[1];
313 *dest
++ = (m
& fgm
[2]) ^ bgm
[2];
314 *dest
++ = (m
& fgm
[3]) ^ bgm
[3];
317 data
= (const u8
*)data16
;
322 fill8_2col((u8
*)dest
, fgcolor
, bgcolor
, *data
);
326 MODULE_LICENSE("GPL");
328 int init_module(void)
333 void cleanup_module(void)
340 * Visible symbols for modules
343 EXPORT_SYMBOL(atafb_iplan2p8_copyarea
);
344 EXPORT_SYMBOL(atafb_iplan2p8_fillrect
);
345 EXPORT_SYMBOL(atafb_iplan2p8_linefill
);