blob: 2029b61791bf0749e8d9139aadc838d4f9c330c3 [file] [log] [blame]
bellarde89f66e2003-08-04 23:30:47 +00001/*
2 * QEMU VGA Emulator templates
ths5fafdf22007-09-16 21:08:06 +00003 *
bellarde89f66e2003-08-04 23:30:47 +00004 * Copyright (c) 2003 Fabrice Bellard
ths5fafdf22007-09-16 21:08:06 +00005 *
bellarde89f66e2003-08-04 23:30:47 +00006 * 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
Benjamin Herrenschmidtd2e043a2014-06-21 15:51:52 +100025static inline void vga_draw_glyph_line(uint8_t *d, uint32_t font_data,
26 uint32_t xorcol, uint32_t bgcol)
bellarde89f66e2003-08-04 23:30:47 +000027{
bellardb1ba6572003-09-16 21:47:08 +000028 ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol;
29 ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol;
30 ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol;
31 ((uint32_t *)d)[3] = (-((font_data >> 4) & 1) & xorcol) ^ bgcol;
32 ((uint32_t *)d)[4] = (-((font_data >> 3) & 1) & xorcol) ^ bgcol;
33 ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol;
34 ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol;
35 ((uint32_t *)d)[7] = (-((font_data >> 0) & 1) & xorcol) ^ bgcol;
bellard17b00182003-08-08 23:50:57 +000036}
37
Benjamin Herrenschmidtd2e043a2014-06-21 15:51:52 +100038static void vga_draw_glyph8(uint8_t *d, int linesize,
39 const uint8_t *font_ptr, int h,
40 uint32_t fgcol, uint32_t bgcol)
41{
42 uint32_t font_data, xorcol;
43
44 xorcol = bgcol ^ fgcol;
45 do {
46 font_data = font_ptr[0];
47 vga_draw_glyph_line(d, font_data, xorcol, bgcol);
48 font_ptr += 4;
49 d += linesize;
50 } while (--h);
51}
52
53static void vga_draw_glyph16(uint8_t *d, int linesize,
bellard17b00182003-08-08 23:50:57 +000054 const uint8_t *font_ptr, int h,
55 uint32_t fgcol, uint32_t bgcol)
56{
57 uint32_t font_data, xorcol;
ths3b46e622007-09-17 08:09:54 +000058
bellard17b00182003-08-08 23:50:57 +000059 xorcol = bgcol ^ fgcol;
60 do {
61 font_data = font_ptr[0];
Benjamin Herrenschmidtd2e043a2014-06-21 15:51:52 +100062 vga_draw_glyph_line(d, expand4to8[font_data >> 4],
63 xorcol, bgcol);
64 vga_draw_glyph_line(d + 32, expand4to8[font_data & 0x0f],
65 xorcol, bgcol);
bellard17b00182003-08-08 23:50:57 +000066 font_ptr += 4;
67 d += linesize;
68 } while (--h);
69}
70
Benjamin Herrenschmidtd2e043a2014-06-21 15:51:52 +100071static void vga_draw_glyph9(uint8_t *d, int linesize,
72 const uint8_t *font_ptr, int h,
73 uint32_t fgcol, uint32_t bgcol, int dup9)
bellarde89f66e2003-08-04 23:30:47 +000074{
75 uint32_t font_data, xorcol, v;
ths3b46e622007-09-17 08:09:54 +000076
bellarde89f66e2003-08-04 23:30:47 +000077 xorcol = bgcol ^ fgcol;
78 do {
79 font_data = font_ptr[0];
bellardeccabc62004-04-07 20:31:38 +000080 ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol;
81 ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol;
82 ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol;
83 ((uint32_t *)d)[3] = (-((font_data >> 4) & 1) & xorcol) ^ bgcol;
84 ((uint32_t *)d)[4] = (-((font_data >> 3) & 1) & xorcol) ^ bgcol;
85 ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol;
86 ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol;
87 v = (-((font_data >> 0) & 1) & xorcol) ^ bgcol;
bellarde89f66e2003-08-04 23:30:47 +000088 ((uint32_t *)d)[7] = v;
89 if (dup9)
bellard39cf7802003-08-05 23:06:22 +000090 ((uint32_t *)d)[8] = v;
bellarde89f66e2003-08-04 23:30:47 +000091 else
bellard39cf7802003-08-05 23:06:22 +000092 ((uint32_t *)d)[8] = bgcol;
bellarde89f66e2003-08-04 23:30:47 +000093 font_ptr += 4;
94 d += linesize;
95 } while (--h);
96}
97
ths5fafdf22007-09-16 21:08:06 +000098/*
bellarde89f66e2003-08-04 23:30:47 +000099 * 4 color mode
100 */
Paolo Bonzini973a7242014-12-29 14:48:14 +0100101static void *vga_draw_line2(VGACommonState *vga, uint8_t *d,
102 uint32_t addr, int width, int hpel)
bellarde89f66e2003-08-04 23:30:47 +0000103{
104 uint32_t plane_mask, *palette, data, v;
105 int x;
106
Gerd Hoffmann3d90c622017-08-28 14:29:06 +0200107 palette = vga->last_palette;
108 plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
Paolo Bonzini973a7242014-12-29 14:48:14 +0100109 hpel &= 7;
110 if (hpel) {
111 width += 8;
112 d = vga->panning_buf;
113 }
bellarde89f66e2003-08-04 23:30:47 +0000114 width >>= 3;
115 for(x = 0; x < width; x++) {
Paolo Bonzini9b53b952014-12-29 14:43:42 +0100116 data = vga_read_dword_le(vga, addr & (VGA_VRAM_SIZE - 1));
bellarde89f66e2003-08-04 23:30:47 +0000117 data &= plane_mask;
118 v = expand2[GET_PLANE(data, 0)];
119 v |= expand2[GET_PLANE(data, 2)] << 2;
Benjamin Herrenschmidtd2e043a2014-06-21 15:51:52 +1000120 ((uint32_t *)d)[0] = palette[v >> 12];
121 ((uint32_t *)d)[1] = palette[(v >> 8) & 0xf];
122 ((uint32_t *)d)[2] = palette[(v >> 4) & 0xf];
123 ((uint32_t *)d)[3] = palette[(v >> 0) & 0xf];
bellarde89f66e2003-08-04 23:30:47 +0000124
125 v = expand2[GET_PLANE(data, 1)];
126 v |= expand2[GET_PLANE(data, 3)] << 2;
Benjamin Herrenschmidtd2e043a2014-06-21 15:51:52 +1000127 ((uint32_t *)d)[4] = palette[v >> 12];
128 ((uint32_t *)d)[5] = palette[(v >> 8) & 0xf];
129 ((uint32_t *)d)[6] = palette[(v >> 4) & 0xf];
130 ((uint32_t *)d)[7] = palette[(v >> 0) & 0xf];
131 d += 32;
Gerd Hoffmann3d90c622017-08-28 14:29:06 +0200132 addr += 4;
bellarde89f66e2003-08-04 23:30:47 +0000133 }
Paolo Bonzini973a7242014-12-29 14:48:14 +0100134 return hpel ? vga->panning_buf + 4 * hpel : NULL;
bellarde89f66e2003-08-04 23:30:47 +0000135}
136
bellard17b00182003-08-08 23:50:57 +0000137#define PUT_PIXEL2(d, n, v) \
138((uint32_t *)d)[2*(n)] = ((uint32_t *)d)[2*(n)+1] = (v)
bellard17b00182003-08-08 23:50:57 +0000139
ths5fafdf22007-09-16 21:08:06 +0000140/*
bellard17b00182003-08-08 23:50:57 +0000141 * 4 color mode, dup2 horizontal
142 */
Paolo Bonzini973a7242014-12-29 14:48:14 +0100143static void *vga_draw_line2d2(VGACommonState *vga, uint8_t *d,
144 uint32_t addr, int width, int hpel)
bellard17b00182003-08-08 23:50:57 +0000145{
146 uint32_t plane_mask, *palette, data, v;
147 int x;
148
Gerd Hoffmann3d90c622017-08-28 14:29:06 +0200149 palette = vga->last_palette;
150 plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
Paolo Bonzini973a7242014-12-29 14:48:14 +0100151 hpel &= 7;
152 if (hpel) {
153 width += 8;
154 d = vga->panning_buf;
155 }
bellard17b00182003-08-08 23:50:57 +0000156 width >>= 3;
157 for(x = 0; x < width; x++) {
Paolo Bonzini9b53b952014-12-29 14:43:42 +0100158 data = vga_read_dword_le(vga, addr & (VGA_VRAM_SIZE - 1));
bellard17b00182003-08-08 23:50:57 +0000159 data &= plane_mask;
160 v = expand2[GET_PLANE(data, 0)];
161 v |= expand2[GET_PLANE(data, 2)] << 2;
162 PUT_PIXEL2(d, 0, palette[v >> 12]);
163 PUT_PIXEL2(d, 1, palette[(v >> 8) & 0xf]);
164 PUT_PIXEL2(d, 2, palette[(v >> 4) & 0xf]);
165 PUT_PIXEL2(d, 3, palette[(v >> 0) & 0xf]);
166
167 v = expand2[GET_PLANE(data, 1)];
168 v |= expand2[GET_PLANE(data, 3)] << 2;
169 PUT_PIXEL2(d, 4, palette[v >> 12]);
170 PUT_PIXEL2(d, 5, palette[(v >> 8) & 0xf]);
171 PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
172 PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
Benjamin Herrenschmidtd2e043a2014-06-21 15:51:52 +1000173 d += 64;
Gerd Hoffmann3d90c622017-08-28 14:29:06 +0200174 addr += 4;
bellard17b00182003-08-08 23:50:57 +0000175 }
Paolo Bonzini973a7242014-12-29 14:48:14 +0100176 return hpel ? vga->panning_buf + 8 * hpel : NULL;
bellard17b00182003-08-08 23:50:57 +0000177}
178
ths5fafdf22007-09-16 21:08:06 +0000179/*
bellarde89f66e2003-08-04 23:30:47 +0000180 * 16 color mode
181 */
Paolo Bonzini973a7242014-12-29 14:48:14 +0100182static void *vga_draw_line4(VGACommonState *vga, uint8_t *d,
183 uint32_t addr, int width, int hpel)
bellarde89f66e2003-08-04 23:30:47 +0000184{
185 uint32_t plane_mask, data, v, *palette;
186 int x;
187
Gerd Hoffmann3d90c622017-08-28 14:29:06 +0200188 palette = vga->last_palette;
189 plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
Paolo Bonzini973a7242014-12-29 14:48:14 +0100190 hpel &= 7;
191 if (hpel) {
192 width += 8;
193 d = vga->panning_buf;
194 }
bellarde89f66e2003-08-04 23:30:47 +0000195 width >>= 3;
196 for(x = 0; x < width; x++) {
Paolo Bonzini9b53b952014-12-29 14:43:42 +0100197 data = vga_read_dword_le(vga, addr & (VGA_VRAM_SIZE - 1));
bellarde89f66e2003-08-04 23:30:47 +0000198 data &= plane_mask;
199 v = expand4[GET_PLANE(data, 0)];
200 v |= expand4[GET_PLANE(data, 1)] << 1;
201 v |= expand4[GET_PLANE(data, 2)] << 2;
202 v |= expand4[GET_PLANE(data, 3)] << 3;
Benjamin Herrenschmidtd2e043a2014-06-21 15:51:52 +1000203 ((uint32_t *)d)[0] = palette[v >> 28];
204 ((uint32_t *)d)[1] = palette[(v >> 24) & 0xf];
205 ((uint32_t *)d)[2] = palette[(v >> 20) & 0xf];
206 ((uint32_t *)d)[3] = palette[(v >> 16) & 0xf];
207 ((uint32_t *)d)[4] = palette[(v >> 12) & 0xf];
208 ((uint32_t *)d)[5] = palette[(v >> 8) & 0xf];
209 ((uint32_t *)d)[6] = palette[(v >> 4) & 0xf];
210 ((uint32_t *)d)[7] = palette[(v >> 0) & 0xf];
211 d += 32;
Gerd Hoffmann3d90c622017-08-28 14:29:06 +0200212 addr += 4;
bellarde89f66e2003-08-04 23:30:47 +0000213 }
Paolo Bonzini973a7242014-12-29 14:48:14 +0100214 return hpel ? vga->panning_buf + 4 * hpel : NULL;
bellarde89f66e2003-08-04 23:30:47 +0000215}
216
ths5fafdf22007-09-16 21:08:06 +0000217/*
bellard17b00182003-08-08 23:50:57 +0000218 * 16 color mode, dup2 horizontal
219 */
Paolo Bonzini973a7242014-12-29 14:48:14 +0100220static void *vga_draw_line4d2(VGACommonState *vga, uint8_t *d,
221 uint32_t addr, int width, int hpel)
bellard17b00182003-08-08 23:50:57 +0000222{
223 uint32_t plane_mask, data, v, *palette;
224 int x;
225
Gerd Hoffmann3d90c622017-08-28 14:29:06 +0200226 palette = vga->last_palette;
227 plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
Paolo Bonzini973a7242014-12-29 14:48:14 +0100228 hpel &= 7;
229 if (hpel) {
230 width += 8;
231 d = vga->panning_buf;
232 }
bellard17b00182003-08-08 23:50:57 +0000233 width >>= 3;
234 for(x = 0; x < width; x++) {
Paolo Bonzini9b53b952014-12-29 14:43:42 +0100235 data = vga_read_dword_le(vga, addr & (VGA_VRAM_SIZE - 1));
bellard17b00182003-08-08 23:50:57 +0000236 data &= plane_mask;
237 v = expand4[GET_PLANE(data, 0)];
238 v |= expand4[GET_PLANE(data, 1)] << 1;
239 v |= expand4[GET_PLANE(data, 2)] << 2;
240 v |= expand4[GET_PLANE(data, 3)] << 3;
241 PUT_PIXEL2(d, 0, palette[v >> 28]);
242 PUT_PIXEL2(d, 1, palette[(v >> 24) & 0xf]);
243 PUT_PIXEL2(d, 2, palette[(v >> 20) & 0xf]);
244 PUT_PIXEL2(d, 3, palette[(v >> 16) & 0xf]);
245 PUT_PIXEL2(d, 4, palette[(v >> 12) & 0xf]);
246 PUT_PIXEL2(d, 5, palette[(v >> 8) & 0xf]);
247 PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
248 PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
Benjamin Herrenschmidtd2e043a2014-06-21 15:51:52 +1000249 d += 64;
Gerd Hoffmann3d90c622017-08-28 14:29:06 +0200250 addr += 4;
bellard17b00182003-08-08 23:50:57 +0000251 }
Paolo Bonzini973a7242014-12-29 14:48:14 +0100252 return hpel ? vga->panning_buf + 8 * hpel : NULL;
bellard17b00182003-08-08 23:50:57 +0000253}
254
ths5fafdf22007-09-16 21:08:06 +0000255/*
bellard17b00182003-08-08 23:50:57 +0000256 * 256 color mode, double pixels
257 *
258 * XXX: add plane_mask support (never used in standard VGA modes)
259 */
Paolo Bonzini973a7242014-12-29 14:48:14 +0100260static void *vga_draw_line8d2(VGACommonState *vga, uint8_t *d,
261 uint32_t addr, int width, int hpel)
bellard17b00182003-08-08 23:50:57 +0000262{
263 uint32_t *palette;
264 int x;
265
Gerd Hoffmann3d90c622017-08-28 14:29:06 +0200266 palette = vga->last_palette;
Paolo Bonzini973a7242014-12-29 14:48:14 +0100267 hpel = (hpel >> 1) & 3;
Paolo Bonzini4d6c3102014-12-29 14:46:59 +0100268
269 /* For 256 color modes, we can adjust the source address and write directly
270 * to the destination, even if horizontal pel panning is active. However,
271 * the loop below assumes that the address does not wrap in the middle of a
272 * plane. If that happens...
273 */
274 if (addr + (width >> 3) * 4 < VGA_VRAM_SIZE) {
275 addr += hpel * 4;
276 hpel = 0;
277 }
278
279 /* ... use the panning buffer as in planar modes. */
Paolo Bonzini973a7242014-12-29 14:48:14 +0100280 if (hpel) {
281 width += 8;
282 d = vga->panning_buf;
283 }
bellard17b00182003-08-08 23:50:57 +0000284 width >>= 3;
285 for(x = 0; x < width; x++) {
Paolo Bonzini9b53b952014-12-29 14:43:42 +0100286 addr &= VGA_VRAM_SIZE - 1;
Gerd Hoffmann3d90c622017-08-28 14:29:06 +0200287 PUT_PIXEL2(d, 0, palette[vga_read_byte(vga, addr + 0)]);
288 PUT_PIXEL2(d, 1, palette[vga_read_byte(vga, addr + 1)]);
289 PUT_PIXEL2(d, 2, palette[vga_read_byte(vga, addr + 2)]);
290 PUT_PIXEL2(d, 3, palette[vga_read_byte(vga, addr + 3)]);
Benjamin Herrenschmidtd2e043a2014-06-21 15:51:52 +1000291 d += 32;
Gerd Hoffmann3d90c622017-08-28 14:29:06 +0200292 addr += 4;
bellard17b00182003-08-08 23:50:57 +0000293 }
Paolo Bonzini973a7242014-12-29 14:48:14 +0100294 return hpel ? vga->panning_buf + 8 * hpel : NULL;
bellard17b00182003-08-08 23:50:57 +0000295}
296
ths5fafdf22007-09-16 21:08:06 +0000297/*
bellard17b00182003-08-08 23:50:57 +0000298 * standard 256 color mode
bellarde89f66e2003-08-04 23:30:47 +0000299 *
300 * XXX: add plane_mask support (never used in standard VGA modes)
301 */
Paolo Bonzini973a7242014-12-29 14:48:14 +0100302static void *vga_draw_line8(VGACommonState *vga, uint8_t *d,
303 uint32_t addr, int width, int hpel)
bellarde89f66e2003-08-04 23:30:47 +0000304{
305 uint32_t *palette;
306 int x;
307
Gerd Hoffmann3d90c622017-08-28 14:29:06 +0200308 palette = vga->last_palette;
Paolo Bonzini973a7242014-12-29 14:48:14 +0100309 hpel = (hpel >> 1) & 3;
310 if (hpel) {
311 width += 8;
312 d = vga->panning_buf;
313 }
bellarde89f66e2003-08-04 23:30:47 +0000314 width >>= 3;
315 for(x = 0; x < width; x++) {
Gerd Hoffmann3d90c622017-08-28 14:29:06 +0200316 ((uint32_t *)d)[0] = palette[vga_read_byte(vga, addr + 0)];
317 ((uint32_t *)d)[1] = palette[vga_read_byte(vga, addr + 1)];
318 ((uint32_t *)d)[2] = palette[vga_read_byte(vga, addr + 2)];
319 ((uint32_t *)d)[3] = palette[vga_read_byte(vga, addr + 3)];
320 ((uint32_t *)d)[4] = palette[vga_read_byte(vga, addr + 4)];
321 ((uint32_t *)d)[5] = palette[vga_read_byte(vga, addr + 5)];
322 ((uint32_t *)d)[6] = palette[vga_read_byte(vga, addr + 6)];
323 ((uint32_t *)d)[7] = palette[vga_read_byte(vga, addr + 7)];
Benjamin Herrenschmidtd2e043a2014-06-21 15:51:52 +1000324 d += 32;
Gerd Hoffmann3d90c622017-08-28 14:29:06 +0200325 addr += 8;
bellarde89f66e2003-08-04 23:30:47 +0000326 }
Paolo Bonzini973a7242014-12-29 14:48:14 +0100327 return hpel ? vga->panning_buf + 4 * hpel : NULL;
bellarde89f66e2003-08-04 23:30:47 +0000328}
329
ths5fafdf22007-09-16 21:08:06 +0000330/*
bellardd3079cd2006-05-10 22:17:36 +0000331 * 15 bit color
332 */
Paolo Bonzini973a7242014-12-29 14:48:14 +0100333static void *vga_draw_line15_le(VGACommonState *vga, uint8_t *d,
334 uint32_t addr, int width, int hpel)
bellardd3079cd2006-05-10 22:17:36 +0000335{
bellardd3079cd2006-05-10 22:17:36 +0000336 int w;
337 uint32_t v, r, g, b;
338
339 w = width;
340 do {
Gerd Hoffmann3d90c622017-08-28 14:29:06 +0200341 v = vga_read_word_le(vga, addr);
Benjamin Herrenschmidt46c3a8c2014-07-07 09:48:28 +1000342 r = (v >> 7) & 0xf8;
343 g = (v >> 2) & 0xf8;
344 b = (v << 3) & 0xf8;
345 ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
Gerd Hoffmann3d90c622017-08-28 14:29:06 +0200346 addr += 2;
Benjamin Herrenschmidt46c3a8c2014-07-07 09:48:28 +1000347 d += 4;
348 } while (--w != 0);
Paolo Bonzini973a7242014-12-29 14:48:14 +0100349 return NULL;
Benjamin Herrenschmidt46c3a8c2014-07-07 09:48:28 +1000350}
351
Paolo Bonzini973a7242014-12-29 14:48:14 +0100352static void *vga_draw_line15_be(VGACommonState *vga, uint8_t *d,
353 uint32_t addr, int width, int hpel)
Benjamin Herrenschmidt46c3a8c2014-07-07 09:48:28 +1000354{
355 int w;
356 uint32_t v, r, g, b;
357
358 w = width;
359 do {
Gerd Hoffmann3d90c622017-08-28 14:29:06 +0200360 v = vga_read_word_be(vga, addr);
bellardd3079cd2006-05-10 22:17:36 +0000361 r = (v >> 7) & 0xf8;
362 g = (v >> 2) & 0xf8;
363 b = (v << 3) & 0xf8;
Benjamin Herrenschmidtd2e043a2014-06-21 15:51:52 +1000364 ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
Gerd Hoffmann3d90c622017-08-28 14:29:06 +0200365 addr += 2;
Benjamin Herrenschmidtd2e043a2014-06-21 15:51:52 +1000366 d += 4;
bellardd3079cd2006-05-10 22:17:36 +0000367 } while (--w != 0);
Paolo Bonzini973a7242014-12-29 14:48:14 +0100368 return NULL;
bellardd3079cd2006-05-10 22:17:36 +0000369}
370
ths5fafdf22007-09-16 21:08:06 +0000371/*
bellardd3079cd2006-05-10 22:17:36 +0000372 * 16 bit color
373 */
Paolo Bonzini973a7242014-12-29 14:48:14 +0100374static void *vga_draw_line16_le(VGACommonState *vga, uint8_t *d,
375 uint32_t addr, int width, int hpel)
bellardd3079cd2006-05-10 22:17:36 +0000376{
bellardd3079cd2006-05-10 22:17:36 +0000377 int w;
378 uint32_t v, r, g, b;
379
380 w = width;
381 do {
Gerd Hoffmann3d90c622017-08-28 14:29:06 +0200382 v = vga_read_word_le(vga, addr);
Benjamin Herrenschmidt46c3a8c2014-07-07 09:48:28 +1000383 r = (v >> 8) & 0xf8;
384 g = (v >> 3) & 0xfc;
385 b = (v << 3) & 0xf8;
386 ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
Gerd Hoffmann3d90c622017-08-28 14:29:06 +0200387 addr += 2;
Benjamin Herrenschmidt46c3a8c2014-07-07 09:48:28 +1000388 d += 4;
389 } while (--w != 0);
Paolo Bonzini973a7242014-12-29 14:48:14 +0100390 return NULL;
Benjamin Herrenschmidt46c3a8c2014-07-07 09:48:28 +1000391}
392
Paolo Bonzini973a7242014-12-29 14:48:14 +0100393static void *vga_draw_line16_be(VGACommonState *vga, uint8_t *d,
394 uint32_t addr, int width, int hpel)
Benjamin Herrenschmidt46c3a8c2014-07-07 09:48:28 +1000395{
396 int w;
397 uint32_t v, r, g, b;
398
399 w = width;
400 do {
Gerd Hoffmann3d90c622017-08-28 14:29:06 +0200401 v = vga_read_word_be(vga, addr);
bellardd3079cd2006-05-10 22:17:36 +0000402 r = (v >> 8) & 0xf8;
403 g = (v >> 3) & 0xfc;
404 b = (v << 3) & 0xf8;
Benjamin Herrenschmidtd2e043a2014-06-21 15:51:52 +1000405 ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
Gerd Hoffmann3d90c622017-08-28 14:29:06 +0200406 addr += 2;
Benjamin Herrenschmidtd2e043a2014-06-21 15:51:52 +1000407 d += 4;
bellardd3079cd2006-05-10 22:17:36 +0000408 } while (--w != 0);
Paolo Bonzini973a7242014-12-29 14:48:14 +0100409 return NULL;
bellardd3079cd2006-05-10 22:17:36 +0000410}
411
ths5fafdf22007-09-16 21:08:06 +0000412/*
bellardd3079cd2006-05-10 22:17:36 +0000413 * 24 bit color
414 */
Paolo Bonzini973a7242014-12-29 14:48:14 +0100415static void *vga_draw_line24_le(VGACommonState *vga, uint8_t *d,
416 uint32_t addr, int width, int hpel)
bellardd3079cd2006-05-10 22:17:36 +0000417{
418 int w;
419 uint32_t r, g, b;
420
421 w = width;
422 do {
Gerd Hoffmann3d90c622017-08-28 14:29:06 +0200423 b = vga_read_byte(vga, addr + 0);
424 g = vga_read_byte(vga, addr + 1);
425 r = vga_read_byte(vga, addr + 2);
Benjamin Herrenschmidt46c3a8c2014-07-07 09:48:28 +1000426 ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
Gerd Hoffmann3d90c622017-08-28 14:29:06 +0200427 addr += 3;
Benjamin Herrenschmidt46c3a8c2014-07-07 09:48:28 +1000428 d += 4;
429 } while (--w != 0);
Paolo Bonzini973a7242014-12-29 14:48:14 +0100430 return NULL;
Benjamin Herrenschmidt46c3a8c2014-07-07 09:48:28 +1000431}
432
Paolo Bonzini973a7242014-12-29 14:48:14 +0100433static void *vga_draw_line24_be(VGACommonState *vga, uint8_t *d,
434 uint32_t addr, int width, int hpel)
Benjamin Herrenschmidt46c3a8c2014-07-07 09:48:28 +1000435{
436 int w;
437 uint32_t r, g, b;
438
439 w = width;
440 do {
Gerd Hoffmann3d90c622017-08-28 14:29:06 +0200441 r = vga_read_byte(vga, addr + 0);
442 g = vga_read_byte(vga, addr + 1);
443 b = vga_read_byte(vga, addr + 2);
Benjamin Herrenschmidtd2e043a2014-06-21 15:51:52 +1000444 ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
Gerd Hoffmann3d90c622017-08-28 14:29:06 +0200445 addr += 3;
Benjamin Herrenschmidtd2e043a2014-06-21 15:51:52 +1000446 d += 4;
bellardd3079cd2006-05-10 22:17:36 +0000447 } while (--w != 0);
Paolo Bonzini973a7242014-12-29 14:48:14 +0100448 return NULL;
bellardd3079cd2006-05-10 22:17:36 +0000449}
450
ths5fafdf22007-09-16 21:08:06 +0000451/*
bellardd3079cd2006-05-10 22:17:36 +0000452 * 32 bit color
453 */
Paolo Bonzini973a7242014-12-29 14:48:14 +0100454static void *vga_draw_line32_le(VGACommonState *vga, uint8_t *d,
455 uint32_t addr, int width, int hpel)
bellardd3079cd2006-05-10 22:17:36 +0000456{
bellardd3079cd2006-05-10 22:17:36 +0000457 int w;
458 uint32_t r, g, b;
459
460 w = width;
461 do {
Gerd Hoffmann3d90c622017-08-28 14:29:06 +0200462 b = vga_read_byte(vga, addr + 0);
463 g = vga_read_byte(vga, addr + 1);
464 r = vga_read_byte(vga, addr + 2);
Benjamin Herrenschmidt46c3a8c2014-07-07 09:48:28 +1000465 ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
Gerd Hoffmann3d90c622017-08-28 14:29:06 +0200466 addr += 4;
Benjamin Herrenschmidt46c3a8c2014-07-07 09:48:28 +1000467 d += 4;
468 } while (--w != 0);
Paolo Bonzini973a7242014-12-29 14:48:14 +0100469 return NULL;
Benjamin Herrenschmidt46c3a8c2014-07-07 09:48:28 +1000470}
471
Paolo Bonzini973a7242014-12-29 14:48:14 +0100472static void *vga_draw_line32_be(VGACommonState *vga, uint8_t *d,
473 uint32_t addr, int width, int hpel)
Benjamin Herrenschmidt46c3a8c2014-07-07 09:48:28 +1000474{
Benjamin Herrenschmidt46c3a8c2014-07-07 09:48:28 +1000475 int w;
476 uint32_t r, g, b;
477
478 w = width;
479 do {
Gerd Hoffmann3d90c622017-08-28 14:29:06 +0200480 r = vga_read_byte(vga, addr + 1);
481 g = vga_read_byte(vga, addr + 2);
482 b = vga_read_byte(vga, addr + 3);
Benjamin Herrenschmidtd2e043a2014-06-21 15:51:52 +1000483 ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
Gerd Hoffmann3d90c622017-08-28 14:29:06 +0200484 addr += 4;
Benjamin Herrenschmidtd2e043a2014-06-21 15:51:52 +1000485 d += 4;
bellardd3079cd2006-05-10 22:17:36 +0000486 } while (--w != 0);
Paolo Bonzini973a7242014-12-29 14:48:14 +0100487 return NULL;
bellardd3079cd2006-05-10 22:17:36 +0000488}