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 2
0021 #include "atafb_utils.h"
0022
0023 void atafb_iplan2p2_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 } else {
0129 pval[0] = dst32[0] & mask;
0130 }
0131
0132 for (j = w; j > 0; j--) {
0133 v = *src32++;
0134 v1 = v & mask;
0135 *dst32++ = pval[0] | (v1 >> 8);
0136 pval[0] = (v ^ v1) << 8;
0137 }
0138
0139 if (f & 2) {
0140 dst32[0] = (dst32[0] & mask) | pval[0];
0141 }
0142
0143 src += next_line;
0144 dst += next_line;
0145 }
0146 } else {
0147 u32 *src32, *dst32;
0148 u32 pval[4], v, v1, mask;
0149 int i, j, w, f;
0150
0151 src = (u8 *)info->screen_base + (sy - 1) * next_line + ((sx + width + 8) & ~15) / (8 / BPL);
0152 dst = (u8 *)info->screen_base + (dy - 1) * next_line + ((dx + width + 8) & ~15) / (8 / BPL);
0153
0154 mask = 0xff00ff;
0155 f = 0;
0156 w = width;
0157 if ((dx + width) & 15)
0158 f = 1;
0159 if (sx & 15) {
0160 f |= 2;
0161 w += 8;
0162 }
0163 w >>= 4;
0164 for (i = height; i; i--) {
0165 src32 = (u32 *)src;
0166 dst32 = (u32 *)dst;
0167
0168 if (f & 1) {
0169 pval[0] = dst32[-1] & mask;
0170 } else {
0171 pval[0] = (*--src32 >> 8) & mask;
0172 }
0173
0174 for (j = w; j > 0; j--) {
0175 v = *--src32;
0176 v1 = v & mask;
0177 *--dst32 = pval[0] | (v1 << 8);
0178 pval[0] = (v ^ v1) >> 8;
0179 }
0180
0181 if (!(f & 2)) {
0182 dst32[-1] = (dst32[-1] & mask) | pval[0];
0183 }
0184
0185 src -= next_line;
0186 dst -= next_line;
0187 }
0188 }
0189 }
0190 }
0191
0192 void atafb_iplan2p2_fillrect(struct fb_info *info, u_long next_line, u32 color,
0193 int sy, int sx, int height, int width)
0194 {
0195 u32 *dest;
0196 int rows, i;
0197 u32 cval[4];
0198
0199 dest = (u32 *)(info->screen_base + sy * next_line + (sx & ~15) / (8 / BPL));
0200 if (sx & 15) {
0201 u8 *dest8 = (u8 *)dest + 1;
0202
0203 expand8_col2mask(color, cval);
0204
0205 for (i = height; i; i--) {
0206 fill8_col(dest8, cval);
0207 dest8 += next_line;
0208 }
0209 dest += BPL / 2;
0210 width -= 8;
0211 }
0212
0213 expand16_col2mask(color, cval);
0214 rows = width >> 4;
0215 if (rows) {
0216 u32 *d = dest;
0217 u32 off = next_line - rows * BPL * 2;
0218 for (i = height; i; i--) {
0219 d = fill16_col(d, rows, cval);
0220 d = (u32 *)((long)d + off);
0221 }
0222 dest += rows * BPL / 2;
0223 width &= 15;
0224 }
0225
0226 if (width) {
0227 u8 *dest8 = (u8 *)dest;
0228
0229 expand8_col2mask(color, cval);
0230
0231 for (i = height; i; i--) {
0232 fill8_col(dest8, cval);
0233 dest8 += next_line;
0234 }
0235 }
0236 }
0237
0238 void atafb_iplan2p2_linefill(struct fb_info *info, u_long next_line,
0239 int dy, int dx, u32 width,
0240 const u8 *data, u32 bgcolor, u32 fgcolor)
0241 {
0242 u32 *dest;
0243 const u16 *data16;
0244 int rows;
0245 u32 fgm[4], bgm[4], m;
0246
0247 dest = (u32 *)(info->screen_base + dy * next_line + (dx & ~15) / (8 / BPL));
0248 if (dx & 15) {
0249 fill8_2col((u8 *)dest + 1, fgcolor, bgcolor, *data++);
0250 dest += BPL / 2;
0251 width -= 8;
0252 }
0253
0254 if (width >= 16) {
0255 data16 = (const u16 *)data;
0256 expand16_2col2mask(fgcolor, bgcolor, fgm, bgm);
0257
0258 for (rows = width / 16; rows; rows--) {
0259 u16 d = *data16++;
0260 m = d | ((u32)d << 16);
0261 *dest++ = (m & fgm[0]) ^ bgm[0];
0262 }
0263
0264 data = (const u8 *)data16;
0265 width &= 15;
0266 }
0267
0268 if (width)
0269 fill8_2col((u8 *)dest, fgcolor, bgcolor, *data);
0270 }