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