VirtualBox

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

Last change on this file since 2685 was 1, checked in by vboxsync, 55 years ago

import

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