00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #if DEPTH == 8
00026 #define BPP 1
00027 #define PIXEL_TYPE uint8_t
00028 #elif DEPTH == 15 || DEPTH == 16
00029 #define BPP 2
00030 #define PIXEL_TYPE uint16_t
00031 #elif DEPTH == 32
00032 #define BPP 4
00033 #define PIXEL_TYPE uint32_t
00034 #else
00035 #error unsupport depth
00036 #endif
00037
00038 #ifdef BGR_FORMAT
00039 #define PIXEL_NAME glue(DEPTH, bgr)
00040 #else
00041 #define PIXEL_NAME DEPTH
00042 #endif
00043
00044 #if DEPTH != 15 && !defined(BGR_FORMAT)
00045
00046 static inline void glue(vga_draw_glyph_line_, DEPTH)(uint8_t *d,
00047 uint32_t font_data,
00048 uint32_t xorcol,
00049 uint32_t bgcol)
00050 {
00051 #if BPP == 1
00052 ((uint32_t *)d)[0] = (dmask16[(font_data >> 4)] & xorcol) ^ bgcol;
00053 ((uint32_t *)d)[1] = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol;
00054 #elif BPP == 2
00055 ((uint32_t *)d)[0] = (dmask4[(font_data >> 6)] & xorcol) ^ bgcol;
00056 ((uint32_t *)d)[1] = (dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol;
00057 ((uint32_t *)d)[2] = (dmask4[(font_data >> 2) & 3] & xorcol) ^ bgcol;
00058 ((uint32_t *)d)[3] = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol;
00059 #else
00060 ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol;
00061 ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol;
00062 ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol;
00063 ((uint32_t *)d)[3] = (-((font_data >> 4) & 1) & xorcol) ^ bgcol;
00064 ((uint32_t *)d)[4] = (-((font_data >> 3) & 1) & xorcol) ^ bgcol;
00065 ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol;
00066 ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol;
00067 ((uint32_t *)d)[7] = (-((font_data >> 0) & 1) & xorcol) ^ bgcol;
00068 #endif
00069 }
00070
00071 static void glue(vga_draw_glyph8_, DEPTH)(uint8_t *d, int linesize,
00072 const uint8_t *font_ptr, int h,
00073 uint32_t fgcol, uint32_t bgcol)
00074 {
00075 uint32_t font_data, xorcol;
00076
00077 xorcol = bgcol ^ fgcol;
00078 do {
00079 font_data = font_ptr[0];
00080 glue(vga_draw_glyph_line_, DEPTH)(d, font_data, xorcol, bgcol);
00081 font_ptr += 4;
00082 d += linesize;
00083 } while (--h);
00084 }
00085
00086 static void glue(vga_draw_glyph16_, DEPTH)(uint8_t *d, int linesize,
00087 const uint8_t *font_ptr, int h,
00088 uint32_t fgcol, uint32_t bgcol)
00089 {
00090 uint32_t font_data, xorcol;
00091
00092 xorcol = bgcol ^ fgcol;
00093 do {
00094 font_data = font_ptr[0];
00095 glue(vga_draw_glyph_line_, DEPTH)(d,
00096 expand4to8[font_data >> 4],
00097 xorcol, bgcol);
00098 glue(vga_draw_glyph_line_, DEPTH)(d + 8 * BPP,
00099 expand4to8[font_data & 0x0f],
00100 xorcol, bgcol);
00101 font_ptr += 4;
00102 d += linesize;
00103 } while (--h);
00104 }
00105
00106 static void glue(vga_draw_glyph9_, DEPTH)(uint8_t *d, int linesize,
00107 const uint8_t *font_ptr, int h,
00108 uint32_t fgcol, uint32_t bgcol, int dup9)
00109 {
00110 uint32_t font_data, xorcol, v;
00111
00112 xorcol = bgcol ^ fgcol;
00113 do {
00114 font_data = font_ptr[0];
00115 #if BPP == 1
00116 cpu_to_32wu((uint32_t *)d, (dmask16[(font_data >> 4)] & xorcol) ^ bgcol);
00117 v = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol;
00118 cpu_to_32wu(((uint32_t *)d)+1, v);
00119 if (dup9)
00120 ((uint8_t *)d)[8] = v >> (24 * (1 - BIG));
00121 else
00122 ((uint8_t *)d)[8] = bgcol;
00123
00124 #elif BPP == 2
00125 cpu_to_32wu(((uint32_t *)d)+0, (dmask4[(font_data >> 6)] & xorcol) ^ bgcol);
00126 cpu_to_32wu(((uint32_t *)d)+1, (dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol);
00127 cpu_to_32wu(((uint32_t *)d)+2, (dmask4[(font_data >> 2) & 3] & xorcol) ^ bgcol);
00128 v = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol;
00129 cpu_to_32wu(((uint32_t *)d)+3, v);
00130 if (dup9)
00131 ((uint16_t *)d)[8] = v >> (16 * (1 - BIG));
00132 else
00133 ((uint16_t *)d)[8] = bgcol;
00134 #else
00135 ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol;
00136 ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol;
00137 ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol;
00138 ((uint32_t *)d)[3] = (-((font_data >> 4) & 1) & xorcol) ^ bgcol;
00139 ((uint32_t *)d)[4] = (-((font_data >> 3) & 1) & xorcol) ^ bgcol;
00140 ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol;
00141 ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol;
00142 v = (-((font_data >> 0) & 1) & xorcol) ^ bgcol;
00143 ((uint32_t *)d)[7] = v;
00144 if (dup9)
00145 ((uint32_t *)d)[8] = v;
00146 else
00147 ((uint32_t *)d)[8] = bgcol;
00148 #endif
00149 font_ptr += 4;
00150 d += linesize;
00151 } while (--h);
00152 }
00153
00154
00155
00156
00157 static void glue(vga_draw_line2_, DEPTH)(VGAState *s1, uint8_t *d,
00158 const uint8_t *s, int width)
00159 {
00160 uint32_t plane_mask, *palette, data, v;
00161 int x;
00162
00163 palette = s1->last_palette;
00164 plane_mask = mask16[s1->ar[0x12] & 0xf];
00165 width >>= 3;
00166 for(x = 0; x < width; x++) {
00167 data = ((uint32_t *)s)[0];
00168 data &= plane_mask;
00169 v = expand2[GET_PLANE(data, 0)];
00170 v |= expand2[GET_PLANE(data, 2)] << 2;
00171 ((PIXEL_TYPE *)d)[0] = palette[v >> 12];
00172 ((PIXEL_TYPE *)d)[1] = palette[(v >> 8) & 0xf];
00173 ((PIXEL_TYPE *)d)[2] = palette[(v >> 4) & 0xf];
00174 ((PIXEL_TYPE *)d)[3] = palette[(v >> 0) & 0xf];
00175
00176 v = expand2[GET_PLANE(data, 1)];
00177 v |= expand2[GET_PLANE(data, 3)] << 2;
00178 ((PIXEL_TYPE *)d)[4] = palette[v >> 12];
00179 ((PIXEL_TYPE *)d)[5] = palette[(v >> 8) & 0xf];
00180 ((PIXEL_TYPE *)d)[6] = palette[(v >> 4) & 0xf];
00181 ((PIXEL_TYPE *)d)[7] = palette[(v >> 0) & 0xf];
00182 d += BPP * 8;
00183 s += 4;
00184 }
00185 }
00186
00187 #if BPP == 1
00188 #define PUT_PIXEL2(d, n, v) ((uint16_t *)d)[(n)] = (v)
00189 #elif BPP == 2
00190 #define PUT_PIXEL2(d, n, v) ((uint32_t *)d)[(n)] = (v)
00191 #else
00192 #define PUT_PIXEL2(d, n, v) \
00193 ((uint32_t *)d)[2*(n)] = ((uint32_t *)d)[2*(n)+1] = (v)
00194 #endif
00195
00196
00197
00198
00199 static void glue(vga_draw_line2d2_, DEPTH)(VGAState *s1, uint8_t *d,
00200 const uint8_t *s, int width)
00201 {
00202 uint32_t plane_mask, *palette, data, v;
00203 int x;
00204
00205 palette = s1->last_palette;
00206 plane_mask = mask16[s1->ar[0x12] & 0xf];
00207 width >>= 3;
00208 for(x = 0; x < width; x++) {
00209 data = ((uint32_t *)s)[0];
00210 data &= plane_mask;
00211 v = expand2[GET_PLANE(data, 0)];
00212 v |= expand2[GET_PLANE(data, 2)] << 2;
00213 PUT_PIXEL2(d, 0, palette[v >> 12]);
00214 PUT_PIXEL2(d, 1, palette[(v >> 8) & 0xf]);
00215 PUT_PIXEL2(d, 2, palette[(v >> 4) & 0xf]);
00216 PUT_PIXEL2(d, 3, palette[(v >> 0) & 0xf]);
00217
00218 v = expand2[GET_PLANE(data, 1)];
00219 v |= expand2[GET_PLANE(data, 3)] << 2;
00220 PUT_PIXEL2(d, 4, palette[v >> 12]);
00221 PUT_PIXEL2(d, 5, palette[(v >> 8) & 0xf]);
00222 PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
00223 PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
00224 d += BPP * 16;
00225 s += 4;
00226 }
00227 }
00228
00229
00230
00231
00232 static void glue(vga_draw_line4_, DEPTH)(VGAState *s1, uint8_t *d,
00233 const uint8_t *s, int width)
00234 {
00235 uint32_t plane_mask, data, v, *palette;
00236 int x;
00237
00238 palette = s1->last_palette;
00239 plane_mask = mask16[s1->ar[0x12] & 0xf];
00240 width >>= 3;
00241 for(x = 0; x < width; x++) {
00242 data = ((uint32_t *)s)[0];
00243 data &= plane_mask;
00244 v = expand4[GET_PLANE(data, 0)];
00245 v |= expand4[GET_PLANE(data, 1)] << 1;
00246 v |= expand4[GET_PLANE(data, 2)] << 2;
00247 v |= expand4[GET_PLANE(data, 3)] << 3;
00248 ((PIXEL_TYPE *)d)[0] = palette[v >> 28];
00249 ((PIXEL_TYPE *)d)[1] = palette[(v >> 24) & 0xf];
00250 ((PIXEL_TYPE *)d)[2] = palette[(v >> 20) & 0xf];
00251 ((PIXEL_TYPE *)d)[3] = palette[(v >> 16) & 0xf];
00252 ((PIXEL_TYPE *)d)[4] = palette[(v >> 12) & 0xf];
00253 ((PIXEL_TYPE *)d)[5] = palette[(v >> 8) & 0xf];
00254 ((PIXEL_TYPE *)d)[6] = palette[(v >> 4) & 0xf];
00255 ((PIXEL_TYPE *)d)[7] = palette[(v >> 0) & 0xf];
00256 d += BPP * 8;
00257 s += 4;
00258 }
00259 }
00260
00261
00262
00263
00264 static void glue(vga_draw_line4d2_, DEPTH)(VGAState *s1, uint8_t *d,
00265 const uint8_t *s, int width)
00266 {
00267 uint32_t plane_mask, data, v, *palette;
00268 int x;
00269
00270 palette = s1->last_palette;
00271 plane_mask = mask16[s1->ar[0x12] & 0xf];
00272 width >>= 3;
00273 for(x = 0; x < width; x++) {
00274 data = ((uint32_t *)s)[0];
00275 data &= plane_mask;
00276 v = expand4[GET_PLANE(data, 0)];
00277 v |= expand4[GET_PLANE(data, 1)] << 1;
00278 v |= expand4[GET_PLANE(data, 2)] << 2;
00279 v |= expand4[GET_PLANE(data, 3)] << 3;
00280 PUT_PIXEL2(d, 0, palette[v >> 28]);
00281 PUT_PIXEL2(d, 1, palette[(v >> 24) & 0xf]);
00282 PUT_PIXEL2(d, 2, palette[(v >> 20) & 0xf]);
00283 PUT_PIXEL2(d, 3, palette[(v >> 16) & 0xf]);
00284 PUT_PIXEL2(d, 4, palette[(v >> 12) & 0xf]);
00285 PUT_PIXEL2(d, 5, palette[(v >> 8) & 0xf]);
00286 PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
00287 PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
00288 d += BPP * 16;
00289 s += 4;
00290 }
00291 }
00292
00293
00294
00295
00296
00297
00298 static void glue(vga_draw_line8d2_, DEPTH)(VGAState *s1, uint8_t *d,
00299 const uint8_t *s, int width)
00300 {
00301 uint32_t *palette;
00302 int x;
00303
00304 palette = s1->last_palette;
00305 width >>= 3;
00306 for(x = 0; x < width; x++) {
00307 PUT_PIXEL2(d, 0, palette[s[0]]);
00308 PUT_PIXEL2(d, 1, palette[s[1]]);
00309 PUT_PIXEL2(d, 2, palette[s[2]]);
00310 PUT_PIXEL2(d, 3, palette[s[3]]);
00311 d += BPP * 8;
00312 s += 4;
00313 }
00314 }
00315
00316
00317
00318
00319
00320
00321 static void glue(vga_draw_line8_, DEPTH)(VGAState *s1, uint8_t *d,
00322 const uint8_t *s, int width)
00323 {
00324 uint32_t *palette;
00325 int x;
00326
00327 palette = s1->last_palette;
00328 width >>= 3;
00329 for(x = 0; x < width; x++) {
00330 ((PIXEL_TYPE *)d)[0] = palette[s[0]];
00331 ((PIXEL_TYPE *)d)[1] = palette[s[1]];
00332 ((PIXEL_TYPE *)d)[2] = palette[s[2]];
00333 ((PIXEL_TYPE *)d)[3] = palette[s[3]];
00334 ((PIXEL_TYPE *)d)[4] = palette[s[4]];
00335 ((PIXEL_TYPE *)d)[5] = palette[s[5]];
00336 ((PIXEL_TYPE *)d)[6] = palette[s[6]];
00337 ((PIXEL_TYPE *)d)[7] = palette[s[7]];
00338 d += BPP * 8;
00339 s += 8;
00340 }
00341 }
00342
00343 void glue(vga_draw_cursor_line_, DEPTH)(uint8_t *d1,
00344 const uint8_t *src1,
00345 int poffset, int w,
00346 unsigned int color0,
00347 unsigned int color1,
00348 unsigned int color_xor)
00349 {
00350 const uint8_t *plane0, *plane1;
00351 int x, b0, b1;
00352 uint8_t *d;
00353
00354 d = d1;
00355 plane0 = src1;
00356 plane1 = src1 + poffset;
00357 for(x = 0; x < w; x++) {
00358 b0 = (plane0[x >> 3] >> (7 - (x & 7))) & 1;
00359 b1 = (plane1[x >> 3] >> (7 - (x & 7))) & 1;
00360 #if DEPTH == 8
00361 switch(b0 | (b1 << 1)) {
00362 case 0:
00363 break;
00364 case 1:
00365 d[0] ^= color_xor;
00366 break;
00367 case 2:
00368 d[0] = color0;
00369 break;
00370 case 3:
00371 d[0] = color1;
00372 break;
00373 }
00374 #elif DEPTH == 16
00375 switch(b0 | (b1 << 1)) {
00376 case 0:
00377 break;
00378 case 1:
00379 ((uint16_t *)d)[0] ^= color_xor;
00380 break;
00381 case 2:
00382 ((uint16_t *)d)[0] = color0;
00383 break;
00384 case 3:
00385 ((uint16_t *)d)[0] = color1;
00386 break;
00387 }
00388 #elif DEPTH == 32
00389 switch(b0 | (b1 << 1)) {
00390 case 0:
00391 break;
00392 case 1:
00393 ((uint32_t *)d)[0] ^= color_xor;
00394 break;
00395 case 2:
00396 ((uint32_t *)d)[0] = color0;
00397 break;
00398 case 3:
00399 ((uint32_t *)d)[0] = color1;
00400 break;
00401 }
00402 #else
00403 #error unsupported depth
00404 #endif
00405 d += BPP;
00406 }
00407 }
00408
00409 #endif
00410
00411
00412
00413
00414
00415
00416
00417 static void glue(vga_draw_line15_, PIXEL_NAME)(VGAState *s1, uint8_t *d,
00418 const uint8_t *s, int width)
00419 {
00420 #if DEPTH == 15 && defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
00421 memcpy(d, s, width * 2);
00422 #else
00423 int w;
00424 uint32_t v, r, g, b;
00425
00426 w = width;
00427 do {
00428 v = lduw_raw((void *)s);
00429 r = (v >> 7) & 0xf8;
00430 g = (v >> 2) & 0xf8;
00431 b = (v << 3) & 0xf8;
00432 ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
00433 s += 2;
00434 d += BPP;
00435 } while (--w != 0);
00436 #endif
00437 }
00438
00439
00440
00441
00442 static void glue(vga_draw_line16_, PIXEL_NAME)(VGAState *s1, uint8_t *d,
00443 const uint8_t *s, int width)
00444 {
00445 #if DEPTH == 16 && defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
00446 memcpy(d, s, width * 2);
00447 #else
00448 int w;
00449 uint32_t v, r, g, b;
00450
00451 w = width;
00452 do {
00453 v = lduw_raw((void *)s);
00454 r = (v >> 8) & 0xf8;
00455 g = (v >> 3) & 0xfc;
00456 b = (v << 3) & 0xf8;
00457 ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
00458 s += 2;
00459 d += BPP;
00460 } while (--w != 0);
00461 #endif
00462 }
00463
00464
00465
00466
00467 static void glue(vga_draw_line24_, PIXEL_NAME)(VGAState *s1, uint8_t *d,
00468 const uint8_t *s, int width)
00469 {
00470 int w;
00471 uint32_t r, g, b;
00472
00473 w = width;
00474 do {
00475 #if defined(TARGET_WORDS_BIGENDIAN)
00476 r = s[0];
00477 g = s[1];
00478 b = s[2];
00479 #else
00480 b = s[0];
00481 g = s[1];
00482 r = s[2];
00483 #endif
00484 ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
00485 s += 3;
00486 d += BPP;
00487 } while (--w != 0);
00488 }
00489
00490
00491
00492
00493 static void glue(vga_draw_line32_, PIXEL_NAME)(VGAState *s1, uint8_t *d,
00494 const uint8_t *s, int width)
00495 {
00496 #if DEPTH == 32 && defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN) && !defined(BGR_FORMAT)
00497 memcpy(d, s, width * 4);
00498 #else
00499 int w;
00500 uint32_t r, g, b;
00501
00502 w = width;
00503 do {
00504 #if defined(TARGET_WORDS_BIGENDIAN)
00505 r = s[1];
00506 g = s[2];
00507 b = s[3];
00508 #else
00509 b = s[0];
00510 g = s[1];
00511 r = s[2];
00512 #endif
00513 ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
00514 s += 4;
00515 d += BPP;
00516 } while (--w != 0);
00517 #endif
00518 }
00519
00520 #undef PUT_PIXEL2
00521 #undef DEPTH
00522 #undef BPP
00523 #undef PIXEL_TYPE
00524 #undef PIXEL_NAME
00525 #undef BGR_FORMAT