VirtualBox

source: vbox/trunk/src/VBox/Devices/Graphics/DevVGATmpl.h@ 5999

Last change on this file since 5999 was 5999, checked in by vboxsync, 17 years ago

The Giant CDDL Dual-License Header Change.

  • Property svn:eol-style set to native
File size: 16.5 KB
Line 
1/** @file
2 *
3 * VBox VGA/VESA device
4 */
5
6/*
7 * Copyright (C) 2006-2007 innotek GmbH
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 * --------------------------------------------------------------------
17 *
18 * This code is based on:
19 *
20 * QEMU VGA Emulator templates
21 *
22 * Copyright (c) 2003 Fabrice Bellard
23 *
24 * Permission is hereby granted, free of charge, to any person obtaining a copy
25 * of this software and associated documentation files (the "Software"), to deal
26 * in the Software without restriction, including without limitation the rights
27 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
28 * copies of the Software, and to permit persons to whom the Software is
29 * furnished to do so, subject to the following conditions:
30 *
31 * The above copyright notice and this permission notice shall be included in
32 * all copies or substantial portions of the Software.
33 *
34 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
35 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
36 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
37 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
38 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
39 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
40 * THE SOFTWARE.
41 */
42
43#if DEPTH == 8
44#define BPP 1
45#define PIXEL_TYPE uint8_t
46#elif DEPTH == 15 || DEPTH == 16
47#define BPP 2
48#define PIXEL_TYPE uint16_t
49#elif DEPTH == 32
50#define BPP 4
51#define PIXEL_TYPE uint32_t
52#else
53#error unsupport depth
54#endif
55
56#if DEPTH != 15
57
58static inline void glue(vga_draw_glyph_line_, DEPTH)(uint8_t *d,
59 uint32_t font_data,
60 uint32_t xorcol,
61 uint32_t bgcol)
62{
63#if BPP == 1
64 ((uint32_t *)d)[0] = (dmask16[(font_data >> 4)] & xorcol) ^ bgcol;
65 ((uint32_t *)d)[1] = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol;
66#elif BPP == 2
67 ((uint32_t *)d)[0] = (dmask4[(font_data >> 6)] & xorcol) ^ bgcol;
68 ((uint32_t *)d)[1] = (dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol;
69 ((uint32_t *)d)[2] = (dmask4[(font_data >> 2) & 3] & xorcol) ^ bgcol;
70 ((uint32_t *)d)[3] = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol;
71#else
72 ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol;
73 ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol;
74 ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol;
75 ((uint32_t *)d)[3] = (-((font_data >> 4) & 1) & xorcol) ^ bgcol;
76 ((uint32_t *)d)[4] = (-((font_data >> 3) & 1) & xorcol) ^ bgcol;
77 ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol;
78 ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol;
79 ((uint32_t *)d)[7] = (-((font_data >> 0) & 1) & xorcol) ^ bgcol;
80#endif
81}
82
83static void glue(vga_draw_glyph8_, DEPTH)(uint8_t *d, int linesize,
84 const uint8_t *font_ptr, int h,
85 uint32_t fgcol, uint32_t bgcol)
86{
87 uint32_t font_data, xorcol;
88
89 xorcol = bgcol ^ fgcol;
90 do {
91 font_data = font_ptr[0];
92 glue(vga_draw_glyph_line_, DEPTH)(d, font_data, xorcol, bgcol);
93 font_ptr += 4;
94 d += linesize;
95 } while (--h);
96}
97
98static void glue(vga_draw_glyph16_, DEPTH)(uint8_t *d, int linesize,
99 const uint8_t *font_ptr, int h,
100 uint32_t fgcol, uint32_t bgcol)
101{
102 uint32_t font_data, xorcol;
103
104 xorcol = bgcol ^ fgcol;
105 do {
106 font_data = font_ptr[0];
107 glue(vga_draw_glyph_line_, DEPTH)(d,
108 expand4to8[font_data >> 4],
109 xorcol, bgcol);
110 glue(vga_draw_glyph_line_, DEPTH)(d + 8 * BPP,
111 expand4to8[font_data & 0x0f],
112 xorcol, bgcol);
113 font_ptr += 4;
114 d += linesize;
115 } while (--h);
116}
117
118static void glue(vga_draw_glyph9_, DEPTH)(uint8_t *d, int linesize,
119 const uint8_t *font_ptr, int h,
120 uint32_t fgcol, uint32_t bgcol, int dup9)
121{
122 uint32_t font_data, xorcol, v;
123
124 xorcol = bgcol ^ fgcol;
125 do {
126 font_data = font_ptr[0];
127#if BPP == 1
128 cpu_to_32wu((uint32_t *)d, (dmask16[(font_data >> 4)] & xorcol) ^ bgcol);
129 v = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol;
130 cpu_to_32wu(((uint32_t *)d)+1, v);
131 if (dup9)
132 ((uint8_t *)d)[8] = v >> (24 * (1 - BIG));
133 else
134 ((uint8_t *)d)[8] = bgcol;
135
136#elif BPP == 2
137 cpu_to_32wu(((uint32_t *)d)+0, (dmask4[(font_data >> 6)] & xorcol) ^ bgcol);
138 cpu_to_32wu(((uint32_t *)d)+1, (dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol);
139 cpu_to_32wu(((uint32_t *)d)+2, (dmask4[(font_data >> 2) & 3] & xorcol) ^ bgcol);
140 v = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol;
141 cpu_to_32wu(((uint32_t *)d)+3, v);
142 if (dup9)
143 ((uint16_t *)d)[8] = v >> (16 * (1 - BIG));
144 else
145 ((uint16_t *)d)[8] = bgcol;
146#else
147 ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol;
148 ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol;
149 ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol;
150 ((uint32_t *)d)[3] = (-((font_data >> 4) & 1) & xorcol) ^ bgcol;
151 ((uint32_t *)d)[4] = (-((font_data >> 3) & 1) & xorcol) ^ bgcol;
152 ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol;
153 ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol;
154 v = (-((font_data >> 0) & 1) & xorcol) ^ bgcol;
155 ((uint32_t *)d)[7] = v;
156 if (dup9)
157 ((uint32_t *)d)[8] = v;
158 else
159 ((uint32_t *)d)[8] = bgcol;
160#endif
161 font_ptr += 4;
162 d += linesize;
163 } while (--h);
164}
165
166/*
167 * 4 color mode
168 */
169static void glue(vga_draw_line2_, DEPTH)(VGAState *s1, uint8_t *d,
170 const uint8_t *s, int width)
171{
172 uint32_t plane_mask, *palette, data, v, src_inc, dwb_mode;
173 int x;
174
175 palette = s1->last_palette;
176 plane_mask = mask16[s1->ar[0x12] & 0xf];
177 dwb_mode = (s1->cr[0x14] & 0x40) ? 2 : (s1->cr[0x17] & 0x40) ? 0 : 1;
178 src_inc = 4 << dwb_mode;
179 width >>= 3;
180 for(x = 0; x < width; x++) {
181 data = ((uint32_t *)s)[0];
182 data &= plane_mask;
183 v = expand2[GET_PLANE(data, 0)];
184 v |= expand2[GET_PLANE(data, 2)] << 2;
185 ((PIXEL_TYPE *)d)[0] = palette[v >> 12];
186 ((PIXEL_TYPE *)d)[1] = palette[(v >> 8) & 0xf];
187 ((PIXEL_TYPE *)d)[2] = palette[(v >> 4) & 0xf];
188 ((PIXEL_TYPE *)d)[3] = palette[(v >> 0) & 0xf];
189
190 v = expand2[GET_PLANE(data, 1)];
191 v |= expand2[GET_PLANE(data, 3)] << 2;
192 ((PIXEL_TYPE *)d)[4] = palette[v >> 12];
193 ((PIXEL_TYPE *)d)[5] = palette[(v >> 8) & 0xf];
194 ((PIXEL_TYPE *)d)[6] = palette[(v >> 4) & 0xf];
195 ((PIXEL_TYPE *)d)[7] = palette[(v >> 0) & 0xf];
196 d += BPP * 8;
197 s += src_inc;
198 }
199}
200
201#if BPP == 1
202#define PUT_PIXEL2(d, n, v) ((uint16_t *)d)[(n)] = (v)
203#elif BPP == 2
204#define PUT_PIXEL2(d, n, v) ((uint32_t *)d)[(n)] = (v)
205#else
206#define PUT_PIXEL2(d, n, v) \
207((uint32_t *)d)[2*(n)] = ((uint32_t *)d)[2*(n)+1] = (v)
208#endif
209
210/*
211 * 4 color mode, dup2 horizontal
212 */
213static void glue(vga_draw_line2d2_, DEPTH)(VGAState *s1, uint8_t *d,
214 const uint8_t *s, int width)
215{
216 uint32_t plane_mask, *palette, data, v, src_inc, dwb_mode;
217 int x;
218
219 palette = s1->last_palette;
220 plane_mask = mask16[s1->ar[0x12] & 0xf];
221 dwb_mode = (s1->cr[0x14] & 0x40) ? 2 : (s1->cr[0x17] & 0x40) ? 0 : 1;
222 src_inc = 4 << dwb_mode;
223 width >>= 3;
224 for(x = 0; x < width; x++) {
225 data = ((uint32_t *)s)[0];
226 data &= plane_mask;
227 v = expand2[GET_PLANE(data, 0)];
228 v |= expand2[GET_PLANE(data, 2)] << 2;
229 PUT_PIXEL2(d, 0, palette[v >> 12]);
230 PUT_PIXEL2(d, 1, palette[(v >> 8) & 0xf]);
231 PUT_PIXEL2(d, 2, palette[(v >> 4) & 0xf]);
232 PUT_PIXEL2(d, 3, palette[(v >> 0) & 0xf]);
233
234 v = expand2[GET_PLANE(data, 1)];
235 v |= expand2[GET_PLANE(data, 3)] << 2;
236 PUT_PIXEL2(d, 4, palette[v >> 12]);
237 PUT_PIXEL2(d, 5, palette[(v >> 8) & 0xf]);
238 PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
239 PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
240 d += BPP * 16;
241 s += src_inc;
242 }
243}
244
245/*
246 * 16 color mode
247 */
248static void glue(vga_draw_line4_, DEPTH)(VGAState *s1, uint8_t *d,
249 const uint8_t *s, int width)
250{
251 uint32_t plane_mask, data, v, *palette;
252 int x;
253
254 palette = s1->last_palette;
255 plane_mask = mask16[s1->ar[0x12] & 0xf];
256 width >>= 3;
257 for(x = 0; x < width; x++) {
258 data = ((uint32_t *)s)[0];
259 data &= plane_mask;
260 v = expand4[GET_PLANE(data, 0)];
261 v |= expand4[GET_PLANE(data, 1)] << 1;
262 v |= expand4[GET_PLANE(data, 2)] << 2;
263 v |= expand4[GET_PLANE(data, 3)] << 3;
264 ((PIXEL_TYPE *)d)[0] = palette[v >> 28];
265 ((PIXEL_TYPE *)d)[1] = palette[(v >> 24) & 0xf];
266 ((PIXEL_TYPE *)d)[2] = palette[(v >> 20) & 0xf];
267 ((PIXEL_TYPE *)d)[3] = palette[(v >> 16) & 0xf];
268 ((PIXEL_TYPE *)d)[4] = palette[(v >> 12) & 0xf];
269 ((PIXEL_TYPE *)d)[5] = palette[(v >> 8) & 0xf];
270 ((PIXEL_TYPE *)d)[6] = palette[(v >> 4) & 0xf];
271 ((PIXEL_TYPE *)d)[7] = palette[(v >> 0) & 0xf];
272 d += BPP * 8;
273 s += 4;
274 }
275}
276
277/*
278 * 16 color mode, dup2 horizontal
279 */
280static void glue(vga_draw_line4d2_, DEPTH)(VGAState *s1, uint8_t *d,
281 const uint8_t *s, int width)
282{
283 uint32_t plane_mask, data, v, *palette;
284 int x;
285
286 palette = s1->last_palette;
287 plane_mask = mask16[s1->ar[0x12] & 0xf];
288 width >>= 3;
289 for(x = 0; x < width; x++) {
290 data = ((uint32_t *)s)[0];
291 data &= plane_mask;
292 v = expand4[GET_PLANE(data, 0)];
293 v |= expand4[GET_PLANE(data, 1)] << 1;
294 v |= expand4[GET_PLANE(data, 2)] << 2;
295 v |= expand4[GET_PLANE(data, 3)] << 3;
296 PUT_PIXEL2(d, 0, palette[v >> 28]);
297 PUT_PIXEL2(d, 1, palette[(v >> 24) & 0xf]);
298 PUT_PIXEL2(d, 2, palette[(v >> 20) & 0xf]);
299 PUT_PIXEL2(d, 3, palette[(v >> 16) & 0xf]);
300 PUT_PIXEL2(d, 4, palette[(v >> 12) & 0xf]);
301 PUT_PIXEL2(d, 5, palette[(v >> 8) & 0xf]);
302 PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
303 PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
304 d += BPP * 16;
305 s += 4;
306 }
307}
308
309/*
310 * 256 color mode, double pixels
311 *
312 * XXX: add plane_mask support (never used in standard VGA modes)
313 */
314static void glue(vga_draw_line8d2_, DEPTH)(VGAState *s1, uint8_t *d,
315 const uint8_t *s, int width)
316{
317 uint32_t *palette;
318 int x;
319
320 palette = s1->last_palette;
321 width >>= 3;
322 for(x = 0; x < width; x++) {
323 PUT_PIXEL2(d, 0, palette[s[0]]);
324 PUT_PIXEL2(d, 1, palette[s[1]]);
325 PUT_PIXEL2(d, 2, palette[s[2]]);
326 PUT_PIXEL2(d, 3, palette[s[3]]);
327 d += BPP * 8;
328 s += 4;
329 }
330}
331
332/*
333 * standard 256 color mode
334 *
335 * XXX: add plane_mask support (never used in standard VGA modes)
336 */
337static void glue(vga_draw_line8_, DEPTH)(VGAState *s1, uint8_t *d,
338 const uint8_t *s, int width)
339{
340 uint32_t *palette;
341 int x;
342
343 palette = s1->last_palette;
344 width >>= 3;
345 for(x = 0; x < width; x++) {
346 ((PIXEL_TYPE *)d)[0] = palette[s[0]];
347 ((PIXEL_TYPE *)d)[1] = palette[s[1]];
348 ((PIXEL_TYPE *)d)[2] = palette[s[2]];
349 ((PIXEL_TYPE *)d)[3] = palette[s[3]];
350 ((PIXEL_TYPE *)d)[4] = palette[s[4]];
351 ((PIXEL_TYPE *)d)[5] = palette[s[5]];
352 ((PIXEL_TYPE *)d)[6] = palette[s[6]];
353 ((PIXEL_TYPE *)d)[7] = palette[s[7]];
354 d += BPP * 8;
355 s += 8;
356 }
357}
358
359#endif /* DEPTH != 15 */
360
361
362/* XXX: optimize */
363
364/*
365 * 15 bit color
366 */
367static void glue(vga_draw_line15_, DEPTH)(VGAState *s1, uint8_t *d,
368 const uint8_t *s, int width)
369{
370#if DEPTH == 15 && defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
371 memcpy(d, s, width * 2);
372#else
373 int w;
374 uint32_t v, r, g, b;
375
376 w = width;
377 do {
378 v = lduw_raw((void *)s);
379 r = (v >> 7) & 0xf8;
380 g = (v >> 2) & 0xf8;
381 b = (v << 3) & 0xf8;
382 ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
383 s += 2;
384 d += BPP;
385 } while (--w != 0);
386#endif
387}
388
389/*
390 * 16 bit color
391 */
392static void glue(vga_draw_line16_, DEPTH)(VGAState *s1, uint8_t *d,
393 const uint8_t *s, int width)
394{
395#if DEPTH == 16 && defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
396 memcpy(d, s, width * 2);
397#else
398 int w;
399 uint32_t v, r, g, b;
400
401 w = width;
402 do {
403 v = lduw_raw((void *)s);
404 r = (v >> 8) & 0xf8;
405 g = (v >> 3) & 0xfc;
406 b = (v << 3) & 0xf8;
407 ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
408 s += 2;
409 d += BPP;
410 } while (--w != 0);
411#endif
412}
413
414/*
415 * 24 bit color
416 */
417static void glue(vga_draw_line24_, DEPTH)(VGAState *s1, uint8_t *d,
418 const uint8_t *s, int width)
419{
420 int w;
421 uint32_t r, g, b;
422
423 w = width;
424 do {
425#if defined(TARGET_WORDS_BIGENDIAN)
426 r = s[0];
427 g = s[1];
428 b = s[2];
429#else
430 b = s[0];
431 g = s[1];
432 r = s[2];
433#endif
434 ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
435 s += 3;
436 d += BPP;
437 } while (--w != 0);
438}
439
440/*
441 * 32 bit color
442 */
443static void glue(vga_draw_line32_, DEPTH)(VGAState *s1, uint8_t *d,
444 const uint8_t *s, int width)
445{
446#if DEPTH == 32 && defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
447 memcpy(d, s, width * 4);
448#else
449 int w;
450 uint32_t r, g, b;
451
452 w = width;
453 do {
454#if defined(TARGET_WORDS_BIGENDIAN)
455 r = s[1];
456 g = s[2];
457 b = s[3];
458#else
459 b = s[0];
460 g = s[1];
461 r = s[2];
462#endif
463 ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
464 s += 4;
465 d += BPP;
466 } while (--w != 0);
467#endif
468}
469
470#if DEPTH != 15
471#ifndef VBOX
472#ifdef VBOX
473static
474#endif/* VBOX */
475void glue(vga_draw_cursor_line_, DEPTH)(uint8_t *d1,
476 const uint8_t *src1,
477 int poffset, int w,
478 unsigned int color0,
479 unsigned int color1,
480 unsigned int color_xor)
481{
482 const uint8_t *plane0, *plane1;
483 int x, b0, b1;
484 uint8_t *d;
485
486 d = d1;
487 plane0 = src1;
488 plane1 = src1 + poffset;
489 for(x = 0; x < w; x++) {
490 b0 = (plane0[x >> 3] >> (7 - (x & 7))) & 1;
491 b1 = (plane1[x >> 3] >> (7 - (x & 7))) & 1;
492#if DEPTH == 8
493 switch(b0 | (b1 << 1)) {
494 case 0:
495 break;
496 case 1:
497 d[0] ^= color_xor;
498 break;
499 case 2:
500 d[0] = color0;
501 break;
502 case 3:
503 d[0] = color1;
504 break;
505 }
506#elif DEPTH == 16
507 switch(b0 | (b1 << 1)) {
508 case 0:
509 break;
510 case 1:
511 ((uint16_t *)d)[0] ^= color_xor;
512 break;
513 case 2:
514 ((uint16_t *)d)[0] = color0;
515 break;
516 case 3:
517 ((uint16_t *)d)[0] = color1;
518 break;
519 }
520#elif DEPTH == 32
521 switch(b0 | (b1 << 1)) {
522 case 0:
523 break;
524 case 1:
525 ((uint32_t *)d)[0] ^= color_xor;
526 break;
527 case 2:
528 ((uint32_t *)d)[0] = color0;
529 break;
530 case 3:
531 ((uint32_t *)d)[0] = color1;
532 break;
533 }
534#else
535#error unsupported depth
536#endif
537 d += BPP;
538 }
539}
540#endif /* !VBOX */
541#endif
542
543#undef PUT_PIXEL2
544#undef DEPTH
545#undef BPP
546#undef PIXEL_TYPE
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette