VirtualBox

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

Last change on this file since 33974 was 33974, checked in by vboxsync, 15 years ago

Fixed MSVC warnings (unary minus applied to unsigned type).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 16.5 KB
Line 
1/* $Id: DevVGATmpl.h 33974 2010-11-11 11:12:27Z vboxsync $ */
2/** @file
3 * DevVGA - VBox VGA/VESA device, code templates.
4 */
5
6/*
7 * Copyright (C) 2006-2007 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.215389.xyz. 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 int 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 xorcol;
88 int font_data;
89
90 xorcol = bgcol ^ fgcol;
91 do {
92 font_data = font_ptr[0];
93 glue(vga_draw_glyph_line_, DEPTH)(d, font_data, xorcol, bgcol);
94 font_ptr += 4;
95 d += linesize;
96 } while (--h);
97}
98
99static void glue(vga_draw_glyph16_, DEPTH)(uint8_t *d, int linesize,
100 const uint8_t *font_ptr, int h,
101 uint32_t fgcol, uint32_t bgcol)
102{
103 uint32_t xorcol;
104 int font_data;
105
106 xorcol = bgcol ^ fgcol;
107 do {
108 font_data = font_ptr[0];
109 glue(vga_draw_glyph_line_, DEPTH)(d,
110 expand4to8[font_data >> 4],
111 xorcol, bgcol);
112 glue(vga_draw_glyph_line_, DEPTH)(d + 8 * BPP,
113 expand4to8[font_data & 0x0f],
114 xorcol, bgcol);
115 font_ptr += 4;
116 d += linesize;
117 } while (--h);
118}
119
120static void glue(vga_draw_glyph9_, DEPTH)(uint8_t *d, int linesize,
121 const uint8_t *font_ptr, int h,
122 uint32_t fgcol, uint32_t bgcol, int dup9)
123{
124 uint32_t xorcol, v;
125 int font_data;
126
127 xorcol = bgcol ^ fgcol;
128 do {
129 font_data = font_ptr[0];
130#if BPP == 1
131 cpu_to_32wu((uint32_t *)d, (dmask16[(font_data >> 4)] & xorcol) ^ bgcol);
132 v = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol;
133 cpu_to_32wu(((uint32_t *)d)+1, v);
134 if (dup9)
135 ((uint8_t *)d)[8] = v >> (24 * (1 - BIG));
136 else
137 ((uint8_t *)d)[8] = bgcol;
138
139#elif BPP == 2
140 cpu_to_32wu(((uint32_t *)d)+0, (dmask4[(font_data >> 6)] & xorcol) ^ bgcol);
141 cpu_to_32wu(((uint32_t *)d)+1, (dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol);
142 cpu_to_32wu(((uint32_t *)d)+2, (dmask4[(font_data >> 2) & 3] & xorcol) ^ bgcol);
143 v = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol;
144 cpu_to_32wu(((uint32_t *)d)+3, v);
145 if (dup9)
146 ((uint16_t *)d)[8] = v >> (16 * (1 - BIG));
147 else
148 ((uint16_t *)d)[8] = bgcol;
149#else
150 ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol;
151 ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol;
152 ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol;
153 ((uint32_t *)d)[3] = (-((font_data >> 4) & 1) & xorcol) ^ bgcol;
154 ((uint32_t *)d)[4] = (-((font_data >> 3) & 1) & xorcol) ^ bgcol;
155 ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol;
156 ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol;
157 v = (-((font_data >> 0) & 1) & xorcol) ^ bgcol;
158 ((uint32_t *)d)[7] = v;
159 if (dup9)
160 ((uint32_t *)d)[8] = v;
161 else
162 ((uint32_t *)d)[8] = bgcol;
163#endif
164 font_ptr += 4;
165 d += linesize;
166 } while (--h);
167}
168
169/*
170 * 4 color mode
171 */
172static void glue(vga_draw_line2_, DEPTH)(VGAState *s1, uint8_t *d,
173 const uint8_t *s, int width)
174{
175 uint32_t plane_mask, *palette, data, v, src_inc, dwb_mode;
176 int x;
177
178 palette = s1->last_palette;
179 plane_mask = mask16[s1->ar[0x12] & 0xf];
180 dwb_mode = (s1->cr[0x14] & 0x40) ? 2 : (s1->cr[0x17] & 0x40) ? 0 : 1;
181 src_inc = 4 << dwb_mode;
182 width >>= 3;
183 for(x = 0; x < width; x++) {
184 data = ((uint32_t *)s)[0];
185 data &= plane_mask;
186 v = expand2[GET_PLANE(data, 0)];
187 v |= expand2[GET_PLANE(data, 2)] << 2;
188 ((PIXEL_TYPE *)d)[0] = palette[v >> 12];
189 ((PIXEL_TYPE *)d)[1] = palette[(v >> 8) & 0xf];
190 ((PIXEL_TYPE *)d)[2] = palette[(v >> 4) & 0xf];
191 ((PIXEL_TYPE *)d)[3] = palette[(v >> 0) & 0xf];
192
193 v = expand2[GET_PLANE(data, 1)];
194 v |= expand2[GET_PLANE(data, 3)] << 2;
195 ((PIXEL_TYPE *)d)[4] = palette[v >> 12];
196 ((PIXEL_TYPE *)d)[5] = palette[(v >> 8) & 0xf];
197 ((PIXEL_TYPE *)d)[6] = palette[(v >> 4) & 0xf];
198 ((PIXEL_TYPE *)d)[7] = palette[(v >> 0) & 0xf];
199 d += BPP * 8;
200 s += src_inc;
201 }
202}
203
204#if BPP == 1
205#define PUT_PIXEL2(d, n, v) ((uint16_t *)d)[(n)] = (v)
206#elif BPP == 2
207#define PUT_PIXEL2(d, n, v) ((uint32_t *)d)[(n)] = (v)
208#else
209#define PUT_PIXEL2(d, n, v) \
210((uint32_t *)d)[2*(n)] = ((uint32_t *)d)[2*(n)+1] = (v)
211#endif
212
213/*
214 * 4 color mode, dup2 horizontal
215 */
216static void glue(vga_draw_line2d2_, DEPTH)(VGAState *s1, uint8_t *d,
217 const uint8_t *s, int width)
218{
219 uint32_t plane_mask, *palette, data, v, src_inc, dwb_mode;
220 int x;
221
222 palette = s1->last_palette;
223 plane_mask = mask16[s1->ar[0x12] & 0xf];
224 dwb_mode = (s1->cr[0x14] & 0x40) ? 2 : (s1->cr[0x17] & 0x40) ? 0 : 1;
225 src_inc = 4 << dwb_mode;
226 width >>= 3;
227 for(x = 0; x < width; x++) {
228 data = ((uint32_t *)s)[0];
229 data &= plane_mask;
230 v = expand2[GET_PLANE(data, 0)];
231 v |= expand2[GET_PLANE(data, 2)] << 2;
232 PUT_PIXEL2(d, 0, palette[v >> 12]);
233 PUT_PIXEL2(d, 1, palette[(v >> 8) & 0xf]);
234 PUT_PIXEL2(d, 2, palette[(v >> 4) & 0xf]);
235 PUT_PIXEL2(d, 3, palette[(v >> 0) & 0xf]);
236
237 v = expand2[GET_PLANE(data, 1)];
238 v |= expand2[GET_PLANE(data, 3)] << 2;
239 PUT_PIXEL2(d, 4, palette[v >> 12]);
240 PUT_PIXEL2(d, 5, palette[(v >> 8) & 0xf]);
241 PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
242 PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
243 d += BPP * 16;
244 s += src_inc;
245 }
246}
247
248/*
249 * 16 color mode
250 */
251static void glue(vga_draw_line4_, DEPTH)(VGAState *s1, uint8_t *d,
252 const uint8_t *s, int width)
253{
254 uint32_t plane_mask, data, v, *palette;
255 int x;
256
257 palette = s1->last_palette;
258 plane_mask = mask16[s1->ar[0x12] & 0xf];
259 width >>= 3;
260 for(x = 0; x < width; x++) {
261 data = ((uint32_t *)s)[0];
262 data &= plane_mask;
263 v = expand4[GET_PLANE(data, 0)];
264 v |= expand4[GET_PLANE(data, 1)] << 1;
265 v |= expand4[GET_PLANE(data, 2)] << 2;
266 v |= expand4[GET_PLANE(data, 3)] << 3;
267 ((PIXEL_TYPE *)d)[0] = palette[v >> 28];
268 ((PIXEL_TYPE *)d)[1] = palette[(v >> 24) & 0xf];
269 ((PIXEL_TYPE *)d)[2] = palette[(v >> 20) & 0xf];
270 ((PIXEL_TYPE *)d)[3] = palette[(v >> 16) & 0xf];
271 ((PIXEL_TYPE *)d)[4] = palette[(v >> 12) & 0xf];
272 ((PIXEL_TYPE *)d)[5] = palette[(v >> 8) & 0xf];
273 ((PIXEL_TYPE *)d)[6] = palette[(v >> 4) & 0xf];
274 ((PIXEL_TYPE *)d)[7] = palette[(v >> 0) & 0xf];
275 d += BPP * 8;
276 s += 4;
277 }
278}
279
280/*
281 * 16 color mode, dup2 horizontal
282 */
283static void glue(vga_draw_line4d2_, DEPTH)(VGAState *s1, uint8_t *d,
284 const uint8_t *s, int width)
285{
286 uint32_t plane_mask, data, v, *palette;
287 int x;
288
289 palette = s1->last_palette;
290 plane_mask = mask16[s1->ar[0x12] & 0xf];
291 width >>= 3;
292 for(x = 0; x < width; x++) {
293 data = ((uint32_t *)s)[0];
294 data &= plane_mask;
295 v = expand4[GET_PLANE(data, 0)];
296 v |= expand4[GET_PLANE(data, 1)] << 1;
297 v |= expand4[GET_PLANE(data, 2)] << 2;
298 v |= expand4[GET_PLANE(data, 3)] << 3;
299 PUT_PIXEL2(d, 0, palette[v >> 28]);
300 PUT_PIXEL2(d, 1, palette[(v >> 24) & 0xf]);
301 PUT_PIXEL2(d, 2, palette[(v >> 20) & 0xf]);
302 PUT_PIXEL2(d, 3, palette[(v >> 16) & 0xf]);
303 PUT_PIXEL2(d, 4, palette[(v >> 12) & 0xf]);
304 PUT_PIXEL2(d, 5, palette[(v >> 8) & 0xf]);
305 PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
306 PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
307 d += BPP * 16;
308 s += 4;
309 }
310}
311
312/*
313 * 256 color mode, double pixels
314 *
315 * XXX: add plane_mask support (never used in standard VGA modes)
316 */
317static void glue(vga_draw_line8d2_, DEPTH)(VGAState *s1, uint8_t *d,
318 const uint8_t *s, int width)
319{
320 uint32_t *palette;
321 int x;
322
323 palette = s1->last_palette;
324 width >>= 3;
325 for(x = 0; x < width; x++) {
326 PUT_PIXEL2(d, 0, palette[s[0]]);
327 PUT_PIXEL2(d, 1, palette[s[1]]);
328 PUT_PIXEL2(d, 2, palette[s[2]]);
329 PUT_PIXEL2(d, 3, palette[s[3]]);
330 d += BPP * 8;
331 s += 4;
332 }
333}
334
335/*
336 * standard 256 color mode
337 *
338 * XXX: add plane_mask support (never used in standard VGA modes)
339 */
340static void glue(vga_draw_line8_, DEPTH)(VGAState *s1, uint8_t *d,
341 const uint8_t *s, int width)
342{
343 uint32_t *palette;
344 int x;
345
346 palette = s1->last_palette;
347 width >>= 3;
348 for(x = 0; x < width; x++) {
349 ((PIXEL_TYPE *)d)[0] = palette[s[0]];
350 ((PIXEL_TYPE *)d)[1] = palette[s[1]];
351 ((PIXEL_TYPE *)d)[2] = palette[s[2]];
352 ((PIXEL_TYPE *)d)[3] = palette[s[3]];
353 ((PIXEL_TYPE *)d)[4] = palette[s[4]];
354 ((PIXEL_TYPE *)d)[5] = palette[s[5]];
355 ((PIXEL_TYPE *)d)[6] = palette[s[6]];
356 ((PIXEL_TYPE *)d)[7] = palette[s[7]];
357 d += BPP * 8;
358 s += 8;
359 }
360}
361
362#endif /* DEPTH != 15 */
363
364
365/* XXX: optimize */
366
367/*
368 * 15 bit color
369 */
370static void glue(vga_draw_line15_, DEPTH)(VGAState *s1, uint8_t *d,
371 const uint8_t *s, int width)
372{
373#if DEPTH == 15 && defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
374 memcpy(d, s, width * 2);
375#else
376 int w;
377 uint32_t v, r, g, b;
378
379 w = width;
380 do {
381 v = lduw_raw((void *)s);
382 r = (v >> 7) & 0xf8;
383 g = (v >> 2) & 0xf8;
384 b = (v << 3) & 0xf8;
385 ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
386 s += 2;
387 d += BPP;
388 } while (--w != 0);
389#endif
390}
391
392/*
393 * 16 bit color
394 */
395static void glue(vga_draw_line16_, DEPTH)(VGAState *s1, uint8_t *d,
396 const uint8_t *s, int width)
397{
398#if DEPTH == 16 && defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
399 memcpy(d, s, width * 2);
400#else
401 int w;
402 uint32_t v, r, g, b;
403
404 w = width;
405 do {
406 v = lduw_raw((void *)s);
407 r = (v >> 8) & 0xf8;
408 g = (v >> 3) & 0xfc;
409 b = (v << 3) & 0xf8;
410 ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
411 s += 2;
412 d += BPP;
413 } while (--w != 0);
414#endif
415}
416
417/*
418 * 24 bit color
419 */
420static void glue(vga_draw_line24_, DEPTH)(VGAState *s1, uint8_t *d,
421 const uint8_t *s, int width)
422{
423 int w;
424 uint32_t r, g, b;
425
426 w = width;
427 do {
428#if defined(TARGET_WORDS_BIGENDIAN)
429 r = s[0];
430 g = s[1];
431 b = s[2];
432#else
433 b = s[0];
434 g = s[1];
435 r = s[2];
436#endif
437 ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
438 s += 3;
439 d += BPP;
440 } while (--w != 0);
441}
442
443/*
444 * 32 bit color
445 */
446static void glue(vga_draw_line32_, DEPTH)(VGAState *s1, uint8_t *d,
447 const uint8_t *s, int width)
448{
449#if DEPTH == 32 && defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
450 memcpy(d, s, width * 4);
451#else
452 int w;
453 uint32_t r, g, b;
454
455 w = width;
456 do {
457#if defined(TARGET_WORDS_BIGENDIAN)
458 r = s[1];
459 g = s[2];
460 b = s[3];
461#else
462 b = s[0];
463 g = s[1];
464 r = s[2];
465#endif
466 ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
467 s += 4;
468 d += BPP;
469 } while (--w != 0);
470#endif
471}
472
473#if DEPTH != 15
474#ifndef VBOX
475#ifdef VBOX
476static
477#endif/* VBOX */
478void glue(vga_draw_cursor_line_, DEPTH)(uint8_t *d1,
479 const uint8_t *src1,
480 int poffset, int w,
481 unsigned int color0,
482 unsigned int color1,
483 unsigned int color_xor)
484{
485 const uint8_t *plane0, *plane1;
486 int x, b0, b1;
487 uint8_t *d;
488
489 d = d1;
490 plane0 = src1;
491 plane1 = src1 + poffset;
492 for(x = 0; x < w; x++) {
493 b0 = (plane0[x >> 3] >> (7 - (x & 7))) & 1;
494 b1 = (plane1[x >> 3] >> (7 - (x & 7))) & 1;
495#if DEPTH == 8
496 switch(b0 | (b1 << 1)) {
497 case 0:
498 break;
499 case 1:
500 d[0] ^= color_xor;
501 break;
502 case 2:
503 d[0] = color0;
504 break;
505 case 3:
506 d[0] = color1;
507 break;
508 }
509#elif DEPTH == 16
510 switch(b0 | (b1 << 1)) {
511 case 0:
512 break;
513 case 1:
514 ((uint16_t *)d)[0] ^= color_xor;
515 break;
516 case 2:
517 ((uint16_t *)d)[0] = color0;
518 break;
519 case 3:
520 ((uint16_t *)d)[0] = color1;
521 break;
522 }
523#elif DEPTH == 32
524 switch(b0 | (b1 << 1)) {
525 case 0:
526 break;
527 case 1:
528 ((uint32_t *)d)[0] ^= color_xor;
529 break;
530 case 2:
531 ((uint32_t *)d)[0] = color0;
532 break;
533 case 3:
534 ((uint32_t *)d)[0] = color1;
535 break;
536 }
537#else
538#error unsupported depth
539#endif
540 d += BPP;
541 }
542}
543#endif /* !VBOX */
544#endif
545
546#undef PUT_PIXEL2
547#undef DEPTH
548#undef BPP
549#undef PIXEL_TYPE
Note: See TracBrowser for help on using the repository browser.

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