0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/string.h>
0014 #include <linux/fb.h>
0015
0016 #include <asm/setup.h>
0017
0018 #include "atafb.h"
0019
0020 #define BPL 8
0021 #include "atafb_utils.h"
0022
0023
0024
0025
0026
0027
0028
0029
0030 void atafb_iplan2p8_copyarea(struct fb_info *info, u_long next_line,
0031 int sy, int sx, int dy, int dx,
0032 int height, int width)
0033 {
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046 u8 *src, *dst;
0047 u32 *s, *d;
0048 int w, l , i, j;
0049 u_int colsize;
0050 u_int upwards = (dy < sy) || (dy == sy && dx < sx);
0051
0052 colsize = height;
0053 if (!((sx ^ dx) & 15)) {
0054
0055
0056 if (upwards) {
0057 src = (u8 *)info->screen_base + sy * next_line + (sx & ~15) / (8 / BPL);
0058 dst = (u8 *)info->screen_base + dy * next_line + (dx & ~15) / (8 / BPL);
0059 if (sx & 15) {
0060 memmove32_col(dst, src, 0xff00ff, height, next_line - BPL * 2);
0061 src += BPL * 2;
0062 dst += BPL * 2;
0063 width -= 8;
0064 }
0065 w = width >> 4;
0066 if (w) {
0067 s = (u32 *)src;
0068 d = (u32 *)dst;
0069 w *= BPL / 2;
0070 l = next_line - w * 4;
0071 for (j = height; j > 0; j--) {
0072 for (i = w; i > 0; i--)
0073 *d++ = *s++;
0074 s = (u32 *)((u8 *)s + l);
0075 d = (u32 *)((u8 *)d + l);
0076 }
0077 }
0078 if (width & 15)
0079 memmove32_col(dst + width / (8 / BPL), src + width / (8 / BPL),
0080 0xff00ff00, height, next_line - BPL * 2);
0081 } else {
0082 src = (u8 *)info->screen_base + (sy - 1) * next_line + ((sx + width + 8) & ~15) / (8 / BPL);
0083 dst = (u8 *)info->screen_base + (dy - 1) * next_line + ((dx + width + 8) & ~15) / (8 / BPL);
0084
0085 if ((sx + width) & 15) {
0086 src -= BPL * 2;
0087 dst -= BPL * 2;
0088 memmove32_col(dst, src, 0xff00ff00, colsize, -next_line - BPL * 2);
0089 width -= 8;
0090 }
0091 w = width >> 4;
0092 if (w) {
0093 s = (u32 *)src;
0094 d = (u32 *)dst;
0095 w *= BPL / 2;
0096 l = next_line - w * 4;
0097 for (j = height; j > 0; j--) {
0098 for (i = w; i > 0; i--)
0099 *--d = *--s;
0100 s = (u32 *)((u8 *)s - l);
0101 d = (u32 *)((u8 *)d - l);
0102 }
0103 }
0104 if (sx & 15)
0105 memmove32_col(dst - (width - 16) / (8 / BPL),
0106 src - (width - 16) / (8 / BPL),
0107 0xff00ff, colsize, -next_line - BPL * 2);
0108 }
0109 } else {
0110
0111 if (upwards) {
0112 u32 *src32, *dst32;
0113 u32 pval[4], v, v1, mask;
0114 int i, j, w, f;
0115
0116 src = (u8 *)info->screen_base + sy * next_line + (sx & ~15) / (8 / BPL);
0117 dst = (u8 *)info->screen_base + dy * next_line + (dx & ~15) / (8 / BPL);
0118
0119 mask = 0xff00ff00;
0120 f = 0;
0121 w = width;
0122 if (sx & 15) {
0123 f = 1;
0124 w += 8;
0125 }
0126 if ((sx + width) & 15)
0127 f |= 2;
0128 w >>= 4;
0129 for (i = height; i; i--) {
0130 src32 = (u32 *)src;
0131 dst32 = (u32 *)dst;
0132
0133 if (f & 1) {
0134 pval[0] = (*src32++ << 8) & mask;
0135 pval[1] = (*src32++ << 8) & mask;
0136 pval[2] = (*src32++ << 8) & mask;
0137 pval[3] = (*src32++ << 8) & mask;
0138 } else {
0139 pval[0] = dst32[0] & mask;
0140 pval[1] = dst32[1] & mask;
0141 pval[2] = dst32[2] & mask;
0142 pval[3] = dst32[3] & mask;
0143 }
0144
0145 for (j = w; j > 0; j--) {
0146 v = *src32++;
0147 v1 = v & mask;
0148 *dst32++ = pval[0] | (v1 >> 8);
0149 pval[0] = (v ^ v1) << 8;
0150 v = *src32++;
0151 v1 = v & mask;
0152 *dst32++ = pval[1] | (v1 >> 8);
0153 pval[1] = (v ^ v1) << 8;
0154 v = *src32++;
0155 v1 = v & mask;
0156 *dst32++ = pval[2] | (v1 >> 8);
0157 pval[2] = (v ^ v1) << 8;
0158 v = *src32++;
0159 v1 = v & mask;
0160 *dst32++ = pval[3] | (v1 >> 8);
0161 pval[3] = (v ^ v1) << 8;
0162 }
0163
0164 if (f & 2) {
0165 dst32[0] = (dst32[0] & mask) | pval[0];
0166 dst32[1] = (dst32[1] & mask) | pval[1];
0167 dst32[2] = (dst32[2] & mask) | pval[2];
0168 dst32[3] = (dst32[3] & mask) | pval[3];
0169 }
0170
0171 src += next_line;
0172 dst += next_line;
0173 }
0174 } else {
0175 u32 *src32, *dst32;
0176 u32 pval[4], v, v1, mask;
0177 int i, j, w, f;
0178
0179 src = (u8 *)info->screen_base + (sy - 1) * next_line + ((sx + width + 8) & ~15) / (8 / BPL);
0180 dst = (u8 *)info->screen_base + (dy - 1) * next_line + ((dx + width + 8) & ~15) / (8 / BPL);
0181
0182 mask = 0xff00ff;
0183 f = 0;
0184 w = width;
0185 if ((dx + width) & 15)
0186 f = 1;
0187 if (sx & 15) {
0188 f |= 2;
0189 w += 8;
0190 }
0191 w >>= 4;
0192 for (i = height; i; i--) {
0193 src32 = (u32 *)src;
0194 dst32 = (u32 *)dst;
0195
0196 if (f & 1) {
0197 pval[0] = dst32[-1] & mask;
0198 pval[1] = dst32[-2] & mask;
0199 pval[2] = dst32[-3] & mask;
0200 pval[3] = dst32[-4] & mask;
0201 } else {
0202 pval[0] = (*--src32 >> 8) & mask;
0203 pval[1] = (*--src32 >> 8) & mask;
0204 pval[2] = (*--src32 >> 8) & mask;
0205 pval[3] = (*--src32 >> 8) & mask;
0206 }
0207
0208 for (j = w; j > 0; j--) {
0209 v = *--src32;
0210 v1 = v & mask;
0211 *--dst32 = pval[0] | (v1 << 8);
0212 pval[0] = (v ^ v1) >> 8;
0213 v = *--src32;
0214 v1 = v & mask;
0215 *--dst32 = pval[1] | (v1 << 8);
0216 pval[1] = (v ^ v1) >> 8;
0217 v = *--src32;
0218 v1 = v & mask;
0219 *--dst32 = pval[2] | (v1 << 8);
0220 pval[2] = (v ^ v1) >> 8;
0221 v = *--src32;
0222 v1 = v & mask;
0223 *--dst32 = pval[3] | (v1 << 8);
0224 pval[3] = (v ^ v1) >> 8;
0225 }
0226
0227 if (!(f & 2)) {
0228 dst32[-1] = (dst32[-1] & mask) | pval[0];
0229 dst32[-2] = (dst32[-2] & mask) | pval[1];
0230 dst32[-3] = (dst32[-3] & mask) | pval[2];
0231 dst32[-4] = (dst32[-4] & mask) | pval[3];
0232 }
0233
0234 src -= next_line;
0235 dst -= next_line;
0236 }
0237 }
0238 }
0239 }
0240
0241 void atafb_iplan2p8_fillrect(struct fb_info *info, u_long next_line, u32 color,
0242 int sy, int sx, int height, int width)
0243 {
0244 u32 *dest;
0245 int rows, i;
0246 u32 cval[4];
0247
0248 dest = (u32 *)(info->screen_base + sy * next_line + (sx & ~15) / (8 / BPL));
0249 if (sx & 15) {
0250 u8 *dest8 = (u8 *)dest + 1;
0251
0252 expand8_col2mask(color, cval);
0253
0254 for (i = height; i; i--) {
0255 fill8_col(dest8, cval);
0256 dest8 += next_line;
0257 }
0258 dest += BPL / 2;
0259 width -= 8;
0260 }
0261
0262 expand16_col2mask(color, cval);
0263 rows = width >> 4;
0264 if (rows) {
0265 u32 *d = dest;
0266 u32 off = next_line - rows * BPL * 2;
0267 for (i = height; i; i--) {
0268 d = fill16_col(d, rows, cval);
0269 d = (u32 *)((long)d + off);
0270 }
0271 dest += rows * BPL / 2;
0272 width &= 15;
0273 }
0274
0275 if (width) {
0276 u8 *dest8 = (u8 *)dest;
0277
0278 expand8_col2mask(color, cval);
0279
0280 for (i = height; i; i--) {
0281 fill8_col(dest8, cval);
0282 dest8 += next_line;
0283 }
0284 }
0285 }
0286
0287 void atafb_iplan2p8_linefill(struct fb_info *info, u_long next_line,
0288 int dy, int dx, u32 width,
0289 const u8 *data, u32 bgcolor, u32 fgcolor)
0290 {
0291 u32 *dest;
0292 const u16 *data16;
0293 int rows;
0294 u32 fgm[4], bgm[4], m;
0295
0296 dest = (u32 *)(info->screen_base + dy * next_line + (dx & ~15) / (8 / BPL));
0297 if (dx & 15) {
0298 fill8_2col((u8 *)dest + 1, fgcolor, bgcolor, *data++);
0299 dest += BPL / 2;
0300 width -= 8;
0301 }
0302
0303 if (width >= 16) {
0304 data16 = (const u16 *)data;
0305 expand16_2col2mask(fgcolor, bgcolor, fgm, bgm);
0306
0307 for (rows = width / 16; rows; rows--) {
0308 u16 d = *data16++;
0309 m = d | ((u32)d << 16);
0310 *dest++ = (m & fgm[0]) ^ bgm[0];
0311 *dest++ = (m & fgm[1]) ^ bgm[1];
0312 *dest++ = (m & fgm[2]) ^ bgm[2];
0313 *dest++ = (m & fgm[3]) ^ bgm[3];
0314 }
0315
0316 data = (const u8 *)data16;
0317 width &= 15;
0318 }
0319
0320 if (width)
0321 fill8_2col((u8 *)dest, fgcolor, bgcolor, *data);
0322 }