]> git.proxmox.com Git - qemu.git/blob - hw/vga_template.h
fixed graphical VGA 16 color mode - fixed 9 pixel wide text mode
[qemu.git] / hw / vga_template.h
1 /*
2 * QEMU VGA Emulator templates
3 *
4 * Copyright (c) 2003 Fabrice Bellard
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
25 #if DEPTH == 8
26 #define BPP 1
27 #define PIXEL_TYPE uint8_t
28 #elif DEPTH == 15 || DEPTH == 16
29 #define BPP 2
30 #define PIXEL_TYPE uint16_t
31 #elif DEPTH == 32
32 #define BPP 4
33 #define PIXEL_TYPE uint32_t
34 #else
35 #error unsupport depth
36 #endif
37
38 #if DEPTH != 15
39
40 static void glue(vga_draw_glyph8_, DEPTH)(uint8_t *d, int linesize,
41 const uint8_t *font_ptr, int h,
42 uint32_t fgcol, uint32_t bgcol)
43 {
44 uint32_t font_data, xorcol;
45
46 xorcol = bgcol ^ fgcol;
47 do {
48 font_data = font_ptr[0];
49 #if BPP == 1
50 ((uint32_t *)d)[0] = (dmask16[(font_data >> 4)] & xorcol) ^ bgcol;
51 ((uint32_t *)d)[3] = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol;
52 #elif BPP == 2
53 ((uint32_t *)d)[0] = (dmask4[(font_data >> 6)] & xorcol) ^ bgcol;
54 ((uint32_t *)d)[1] = (dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol;
55 ((uint32_t *)d)[2] = (dmask4[(font_data >> 2) & 3] & xorcol) ^ bgcol;
56 ((uint32_t *)d)[3] = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol;
57 #else
58 ((uint32_t *)d)[0] = ((-(font_data >> 7)) & xorcol) ^ bgcol;
59 ((uint32_t *)d)[1] = ((-(font_data >> 6) & 1) & xorcol) ^ bgcol;
60 ((uint32_t *)d)[2] = ((-(font_data >> 5) & 1) & xorcol) ^ bgcol;
61 ((uint32_t *)d)[3] = ((-(font_data >> 4) & 1) & xorcol) ^ bgcol;
62 ((uint32_t *)d)[4] = ((-(font_data >> 3) & 1) & xorcol) ^ bgcol;
63 ((uint32_t *)d)[5] = ((-(font_data >> 2) & 1) & xorcol) ^ bgcol;
64 ((uint32_t *)d)[6] = ((-(font_data >> 1) & 1) & xorcol) ^ bgcol;
65 ((uint32_t *)d)[7] = ((-(font_data >> 0) & 1) & xorcol) ^ bgcol;
66 #endif
67 font_ptr += 4;
68 d += linesize;
69 } while (--h);
70 }
71
72 static void glue(vga_draw_glyph9_, DEPTH)(uint8_t *d, int linesize,
73 const uint8_t *font_ptr, int h,
74 uint32_t fgcol, uint32_t bgcol, int dup9)
75 {
76 uint32_t font_data, xorcol, v;
77
78 xorcol = bgcol ^ fgcol;
79 do {
80 font_data = font_ptr[0];
81 /* XXX: unaligned accesses are done */
82 #if BPP == 1
83 ((uint32_t *)d)[0] = (dmask16[(font_data >> 4)] & xorcol) ^ bgcol;
84 v = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol;
85 ((uint32_t *)d)[3] = v;
86 if (dup9)
87 ((uint8_t *)d)[8] = v >> (24 * (1 - BIG));
88 else
89 ((uint8_t *)d)[8] = bgcol;
90
91 #elif BPP == 2
92 ((uint32_t *)d)[0] = (dmask4[(font_data >> 6)] & xorcol) ^ bgcol;
93 ((uint32_t *)d)[1] = (dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol;
94 ((uint32_t *)d)[2] = (dmask4[(font_data >> 2) & 3] & xorcol) ^ bgcol;
95 v = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol;
96 ((uint32_t *)d)[3] = v;
97 if (dup9)
98 ((uint16_t *)d)[8] = v >> (16 * (1 - BIG));
99 else
100 ((uint16_t *)d)[8] = bgcol;
101 #else
102 ((uint32_t *)d)[0] = ((-(font_data >> 7)) & xorcol) ^ bgcol;
103 ((uint32_t *)d)[1] = ((-(font_data >> 6) & 1) & xorcol) ^ bgcol;
104 ((uint32_t *)d)[2] = ((-(font_data >> 5) & 1) & xorcol) ^ bgcol;
105 ((uint32_t *)d)[3] = ((-(font_data >> 4) & 1) & xorcol) ^ bgcol;
106 ((uint32_t *)d)[4] = ((-(font_data >> 3) & 1) & xorcol) ^ bgcol;
107 ((uint32_t *)d)[5] = ((-(font_data >> 2) & 1) & xorcol) ^ bgcol;
108 ((uint32_t *)d)[6] = ((-(font_data >> 1) & 1) & xorcol) ^ bgcol;
109 v = ((-(font_data >> 0) & 1) & xorcol) ^ bgcol;
110 ((uint32_t *)d)[7] = v;
111 if (dup9)
112 ((uint32_t *)d)[8] = v;
113 else
114 ((uint32_t *)d)[8] = bgcol;
115 #endif
116 font_ptr += 4;
117 d += linesize;
118 } while (--h);
119 }
120
121 /*
122 * 4 color mode
123 */
124 static void glue(vga_draw_line2_, DEPTH)(VGAState *s1, uint8_t *d,
125 const uint8_t *s, int width)
126 {
127 uint32_t plane_mask, *palette, data, v;
128 int x;
129
130 palette = s1->last_palette;
131 plane_mask = mask16[s1->ar[0x12] & 0xf];
132 width >>= 3;
133 for(x = 0; x < width; x++) {
134 data = ((uint32_t *)s)[0];
135 data &= plane_mask;
136 v = expand2[GET_PLANE(data, 0)];
137 v |= expand2[GET_PLANE(data, 2)] << 2;
138 ((PIXEL_TYPE *)d)[0] = palette[v >> 12];
139 ((PIXEL_TYPE *)d)[1] = palette[(v >> 8) & 0xf];
140 ((PIXEL_TYPE *)d)[2] = palette[(v >> 4) & 0xf];
141 ((PIXEL_TYPE *)d)[3] = palette[(v >> 0) & 0xf];
142
143 v = expand2[GET_PLANE(data, 1)];
144 v |= expand2[GET_PLANE(data, 3)] << 2;
145 ((PIXEL_TYPE *)d)[4] = palette[v >> 12];
146 ((PIXEL_TYPE *)d)[5] = palette[(v >> 8) & 0xf];
147 ((PIXEL_TYPE *)d)[6] = palette[(v >> 4) & 0xf];
148 ((PIXEL_TYPE *)d)[7] = palette[(v >> 0) & 0xf];
149 d += BPP * 8;
150 s += 4;
151 }
152 }
153
154 /*
155 * 16 color mode
156 */
157 static void glue(vga_draw_line4_, DEPTH)(VGAState *s1, uint8_t *d,
158 const uint8_t *s, int width)
159 {
160 uint32_t plane_mask, data, v, *palette;
161 int x;
162
163 palette = s1->last_palette;
164 plane_mask = mask16[s1->ar[0x12] & 0xf];
165 width >>= 3;
166 for(x = 0; x < width; x++) {
167 data = ((uint32_t *)s)[0];
168 data &= plane_mask;
169 v = expand4[GET_PLANE(data, 0)];
170 v |= expand4[GET_PLANE(data, 1)] << 1;
171 v |= expand4[GET_PLANE(data, 2)] << 2;
172 v |= expand4[GET_PLANE(data, 3)] << 3;
173 ((PIXEL_TYPE *)d)[0] = palette[v >> 28];
174 ((PIXEL_TYPE *)d)[1] = palette[(v >> 24) & 0xf];
175 ((PIXEL_TYPE *)d)[2] = palette[(v >> 20) & 0xf];
176 ((PIXEL_TYPE *)d)[3] = palette[(v >> 16) & 0xf];
177 ((PIXEL_TYPE *)d)[4] = palette[(v >> 12) & 0xf];
178 ((PIXEL_TYPE *)d)[5] = palette[(v >> 8) & 0xf];
179 ((PIXEL_TYPE *)d)[6] = palette[(v >> 4) & 0xf];
180 ((PIXEL_TYPE *)d)[7] = palette[(v >> 0) & 0xf];
181 d += BPP * 8;
182 s += 4;
183 }
184 }
185
186 /*
187 * 256 color mode
188 *
189 * XXX: add plane_mask support (never used in standard VGA modes)
190 */
191 static void glue(vga_draw_line8_, DEPTH)(VGAState *s1, uint8_t *d,
192 const uint8_t *s, int width)
193 {
194 uint32_t *palette;
195 int x;
196
197 palette = s1->last_palette;
198 width >>= 3;
199 for(x = 0; x < width; x++) {
200 ((PIXEL_TYPE *)d)[0] = palette[s[0]];
201 ((PIXEL_TYPE *)d)[1] = palette[s[1]];
202 ((PIXEL_TYPE *)d)[2] = palette[s[2]];
203 ((PIXEL_TYPE *)d)[3] = palette[s[3]];
204 ((PIXEL_TYPE *)d)[4] = palette[s[4]];
205 ((PIXEL_TYPE *)d)[5] = palette[s[5]];
206 ((PIXEL_TYPE *)d)[6] = palette[s[6]];
207 ((PIXEL_TYPE *)d)[7] = palette[s[7]];
208 d += BPP * 8;
209 s += 8;
210 }
211 }
212
213 #endif /* DEPTH != 15 */
214
215
216 /* XXX: optimize */
217
218 /*
219 * 15 bit color
220 */
221 static void glue(vga_draw_line15_, DEPTH)(VGAState *s1, uint8_t *d,
222 const uint8_t *s, int width)
223 {
224 #if DEPTH == 15 && !defined(WORDS_BIGENDIAN)
225 memcpy(d, s, width * 2);
226 #else
227 int w;
228 uint32_t v, r, g, b;
229
230 w = width;
231 do {
232 v = lduw((void *)s);
233 r = (v >> 7) & 0xf8;
234 g = (v >> 2) & 0xf8;
235 b = (v << 3) & 0xf8;
236 ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
237 s += 2;
238 d += BPP;
239 } while (--w != 0);
240 #endif
241 }
242
243 /*
244 * 16 bit color
245 */
246 static void glue(vga_draw_line16_, DEPTH)(VGAState *s1, uint8_t *d,
247 const uint8_t *s, int width)
248 {
249 #if DEPTH == 16 && !defined(WORDS_BIGENDIAN)
250 memcpy(d, s, width * 2);
251 #else
252 int w;
253 uint32_t v, r, g, b;
254
255 w = width;
256 do {
257 v = lduw((void *)s);
258 r = (v >> 8) & 0xf8;
259 g = (v >> 3) & 0xfc;
260 b = (v << 3) & 0xf8;
261 ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
262 s += 2;
263 d += BPP;
264 } while (--w != 0);
265 #endif
266 }
267
268 /*
269 * 32 bit color
270 */
271 static void glue(vga_draw_line32_, DEPTH)(VGAState *s1, uint8_t *d,
272 const uint8_t *s, int width)
273 {
274 #if DEPTH == 32 && !defined(WORDS_BIGENDIAN)
275 memcpy(d, s, width * 4);
276 #else
277 int w;
278 uint32_t r, g, b;
279
280 w = width;
281 do {
282 b = s[0];
283 g = s[1];
284 r = s[2];
285 ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
286 s += 4;
287 d += BPP;
288 } while (--w != 0);
289 #endif
290 }
291
292 #undef DEPTH
293 #undef BPP
294 #undef PIXEL_TYPE