xref: /openbmc/qemu/hw/display/vga.c (revision 47b43a1f)
1 /*
2  * QEMU VGA Emulator.
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 #include "hw/hw.h"
25 #include "vga.h"
26 #include "ui/console.h"
27 #include "hw/i386/pc.h"
28 #include "hw/pci/pci.h"
29 #include "vga_int.h"
30 #include "ui/pixel_ops.h"
31 #include "qemu/timer.h"
32 #include "hw/xen/xen.h"
33 #include "trace.h"
34 
35 //#define DEBUG_VGA
36 //#define DEBUG_VGA_MEM
37 //#define DEBUG_VGA_REG
38 
39 //#define DEBUG_BOCHS_VBE
40 
41 /* 16 state changes per vertical frame @60 Hz */
42 #define VGA_TEXT_CURSOR_PERIOD_MS       (1000 * 2 * 16 / 60)
43 
44 /*
45  * Video Graphics Array (VGA)
46  *
47  * Chipset docs for original IBM VGA:
48  * http://www.mcamafia.de/pdf/ibm_vgaxga_trm2.pdf
49  *
50  * FreeVGA site:
51  * http://www.osdever.net/FreeVGA/home.htm
52  *
53  * Standard VGA features and Bochs VBE extensions are implemented.
54  */
55 
56 /* force some bits to zero */
57 const uint8_t sr_mask[8] = {
58     0x03,
59     0x3d,
60     0x0f,
61     0x3f,
62     0x0e,
63     0x00,
64     0x00,
65     0xff,
66 };
67 
68 const uint8_t gr_mask[16] = {
69     0x0f, /* 0x00 */
70     0x0f, /* 0x01 */
71     0x0f, /* 0x02 */
72     0x1f, /* 0x03 */
73     0x03, /* 0x04 */
74     0x7b, /* 0x05 */
75     0x0f, /* 0x06 */
76     0x0f, /* 0x07 */
77     0xff, /* 0x08 */
78     0x00, /* 0x09 */
79     0x00, /* 0x0a */
80     0x00, /* 0x0b */
81     0x00, /* 0x0c */
82     0x00, /* 0x0d */
83     0x00, /* 0x0e */
84     0x00, /* 0x0f */
85 };
86 
87 #define cbswap_32(__x) \
88 ((uint32_t)( \
89 		(((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \
90 		(((uint32_t)(__x) & (uint32_t)0x0000ff00UL) <<  8) | \
91 		(((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >>  8) | \
92 		(((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) ))
93 
94 #ifdef HOST_WORDS_BIGENDIAN
95 #define PAT(x) cbswap_32(x)
96 #else
97 #define PAT(x) (x)
98 #endif
99 
100 #ifdef HOST_WORDS_BIGENDIAN
101 #define BIG 1
102 #else
103 #define BIG 0
104 #endif
105 
106 #ifdef HOST_WORDS_BIGENDIAN
107 #define GET_PLANE(data, p) (((data) >> (24 - (p) * 8)) & 0xff)
108 #else
109 #define GET_PLANE(data, p) (((data) >> ((p) * 8)) & 0xff)
110 #endif
111 
112 static const uint32_t mask16[16] = {
113     PAT(0x00000000),
114     PAT(0x000000ff),
115     PAT(0x0000ff00),
116     PAT(0x0000ffff),
117     PAT(0x00ff0000),
118     PAT(0x00ff00ff),
119     PAT(0x00ffff00),
120     PAT(0x00ffffff),
121     PAT(0xff000000),
122     PAT(0xff0000ff),
123     PAT(0xff00ff00),
124     PAT(0xff00ffff),
125     PAT(0xffff0000),
126     PAT(0xffff00ff),
127     PAT(0xffffff00),
128     PAT(0xffffffff),
129 };
130 
131 #undef PAT
132 
133 #ifdef HOST_WORDS_BIGENDIAN
134 #define PAT(x) (x)
135 #else
136 #define PAT(x) cbswap_32(x)
137 #endif
138 
139 static const uint32_t dmask16[16] = {
140     PAT(0x00000000),
141     PAT(0x000000ff),
142     PAT(0x0000ff00),
143     PAT(0x0000ffff),
144     PAT(0x00ff0000),
145     PAT(0x00ff00ff),
146     PAT(0x00ffff00),
147     PAT(0x00ffffff),
148     PAT(0xff000000),
149     PAT(0xff0000ff),
150     PAT(0xff00ff00),
151     PAT(0xff00ffff),
152     PAT(0xffff0000),
153     PAT(0xffff00ff),
154     PAT(0xffffff00),
155     PAT(0xffffffff),
156 };
157 
158 static const uint32_t dmask4[4] = {
159     PAT(0x00000000),
160     PAT(0x0000ffff),
161     PAT(0xffff0000),
162     PAT(0xffffffff),
163 };
164 
165 static uint32_t expand4[256];
166 static uint16_t expand2[256];
167 static uint8_t expand4to8[16];
168 
169 static void vga_screen_dump(void *opaque, const char *filename, bool cswitch,
170                             Error **errp);
171 
172 static void vga_update_memory_access(VGACommonState *s)
173 {
174     MemoryRegion *region, *old_region = s->chain4_alias;
175     hwaddr base, offset, size;
176 
177     s->chain4_alias = NULL;
178 
179     if ((s->sr[VGA_SEQ_PLANE_WRITE] & VGA_SR02_ALL_PLANES) ==
180         VGA_SR02_ALL_PLANES && s->sr[VGA_SEQ_MEMORY_MODE] & VGA_SR04_CHN_4M) {
181         offset = 0;
182         switch ((s->gr[VGA_GFX_MISC] >> 2) & 3) {
183         case 0:
184             base = 0xa0000;
185             size = 0x20000;
186             break;
187         case 1:
188             base = 0xa0000;
189             size = 0x10000;
190             offset = s->bank_offset;
191             break;
192         case 2:
193             base = 0xb0000;
194             size = 0x8000;
195             break;
196         case 3:
197         default:
198             base = 0xb8000;
199             size = 0x8000;
200             break;
201         }
202         base += isa_mem_base;
203         region = g_malloc(sizeof(*region));
204         memory_region_init_alias(region, "vga.chain4", &s->vram, offset, size);
205         memory_region_add_subregion_overlap(s->legacy_address_space, base,
206                                             region, 2);
207         s->chain4_alias = region;
208     }
209     if (old_region) {
210         memory_region_del_subregion(s->legacy_address_space, old_region);
211         memory_region_destroy(old_region);
212         g_free(old_region);
213         s->plane_updated = 0xf;
214     }
215 }
216 
217 static void vga_dumb_update_retrace_info(VGACommonState *s)
218 {
219     (void) s;
220 }
221 
222 static void vga_precise_update_retrace_info(VGACommonState *s)
223 {
224     int htotal_chars;
225     int hretr_start_char;
226     int hretr_skew_chars;
227     int hretr_end_char;
228 
229     int vtotal_lines;
230     int vretr_start_line;
231     int vretr_end_line;
232 
233     int dots;
234 #if 0
235     int div2, sldiv2;
236 #endif
237     int clocking_mode;
238     int clock_sel;
239     const int clk_hz[] = {25175000, 28322000, 25175000, 25175000};
240     int64_t chars_per_sec;
241     struct vga_precise_retrace *r = &s->retrace_info.precise;
242 
243     htotal_chars = s->cr[VGA_CRTC_H_TOTAL] + 5;
244     hretr_start_char = s->cr[VGA_CRTC_H_SYNC_START];
245     hretr_skew_chars = (s->cr[VGA_CRTC_H_SYNC_END] >> 5) & 3;
246     hretr_end_char = s->cr[VGA_CRTC_H_SYNC_END] & 0x1f;
247 
248     vtotal_lines = (s->cr[VGA_CRTC_V_TOTAL] |
249                     (((s->cr[VGA_CRTC_OVERFLOW] & 1) |
250                       ((s->cr[VGA_CRTC_OVERFLOW] >> 4) & 2)) << 8)) + 2;
251     vretr_start_line = s->cr[VGA_CRTC_V_SYNC_START] |
252         ((((s->cr[VGA_CRTC_OVERFLOW] >> 2) & 1) |
253           ((s->cr[VGA_CRTC_OVERFLOW] >> 6) & 2)) << 8);
254     vretr_end_line = s->cr[VGA_CRTC_V_SYNC_END] & 0xf;
255 
256     clocking_mode = (s->sr[VGA_SEQ_CLOCK_MODE] >> 3) & 1;
257     clock_sel = (s->msr >> 2) & 3;
258     dots = (s->msr & 1) ? 8 : 9;
259 
260     chars_per_sec = clk_hz[clock_sel] / dots;
261 
262     htotal_chars <<= clocking_mode;
263 
264     r->total_chars = vtotal_lines * htotal_chars;
265     if (r->freq) {
266         r->ticks_per_char = get_ticks_per_sec() / (r->total_chars * r->freq);
267     } else {
268         r->ticks_per_char = get_ticks_per_sec() / chars_per_sec;
269     }
270 
271     r->vstart = vretr_start_line;
272     r->vend = r->vstart + vretr_end_line + 1;
273 
274     r->hstart = hretr_start_char + hretr_skew_chars;
275     r->hend = r->hstart + hretr_end_char + 1;
276     r->htotal = htotal_chars;
277 
278 #if 0
279     div2 = (s->cr[VGA_CRTC_MODE] >> 2) & 1;
280     sldiv2 = (s->cr[VGA_CRTC_MODE] >> 3) & 1;
281     printf (
282         "hz=%f\n"
283         "htotal = %d\n"
284         "hretr_start = %d\n"
285         "hretr_skew = %d\n"
286         "hretr_end = %d\n"
287         "vtotal = %d\n"
288         "vretr_start = %d\n"
289         "vretr_end = %d\n"
290         "div2 = %d sldiv2 = %d\n"
291         "clocking_mode = %d\n"
292         "clock_sel = %d %d\n"
293         "dots = %d\n"
294         "ticks/char = %" PRId64 "\n"
295         "\n",
296         (double) get_ticks_per_sec() / (r->ticks_per_char * r->total_chars),
297         htotal_chars,
298         hretr_start_char,
299         hretr_skew_chars,
300         hretr_end_char,
301         vtotal_lines,
302         vretr_start_line,
303         vretr_end_line,
304         div2, sldiv2,
305         clocking_mode,
306         clock_sel,
307         clk_hz[clock_sel],
308         dots,
309         r->ticks_per_char
310         );
311 #endif
312 }
313 
314 static uint8_t vga_precise_retrace(VGACommonState *s)
315 {
316     struct vga_precise_retrace *r = &s->retrace_info.precise;
317     uint8_t val = s->st01 & ~(ST01_V_RETRACE | ST01_DISP_ENABLE);
318 
319     if (r->total_chars) {
320         int cur_line, cur_line_char, cur_char;
321         int64_t cur_tick;
322 
323         cur_tick = qemu_get_clock_ns(vm_clock);
324 
325         cur_char = (cur_tick / r->ticks_per_char) % r->total_chars;
326         cur_line = cur_char / r->htotal;
327 
328         if (cur_line >= r->vstart && cur_line <= r->vend) {
329             val |= ST01_V_RETRACE | ST01_DISP_ENABLE;
330         } else {
331             cur_line_char = cur_char % r->htotal;
332             if (cur_line_char >= r->hstart && cur_line_char <= r->hend) {
333                 val |= ST01_DISP_ENABLE;
334             }
335         }
336 
337         return val;
338     } else {
339         return s->st01 ^ (ST01_V_RETRACE | ST01_DISP_ENABLE);
340     }
341 }
342 
343 static uint8_t vga_dumb_retrace(VGACommonState *s)
344 {
345     return s->st01 ^ (ST01_V_RETRACE | ST01_DISP_ENABLE);
346 }
347 
348 int vga_ioport_invalid(VGACommonState *s, uint32_t addr)
349 {
350     if (s->msr & VGA_MIS_COLOR) {
351         /* Color */
352         return (addr >= 0x3b0 && addr <= 0x3bf);
353     } else {
354         /* Monochrome */
355         return (addr >= 0x3d0 && addr <= 0x3df);
356     }
357 }
358 
359 uint32_t vga_ioport_read(void *opaque, uint32_t addr)
360 {
361     VGACommonState *s = opaque;
362     int val, index;
363 
364     qemu_flush_coalesced_mmio_buffer();
365 
366     if (vga_ioport_invalid(s, addr)) {
367         val = 0xff;
368     } else {
369         switch(addr) {
370         case VGA_ATT_W:
371             if (s->ar_flip_flop == 0) {
372                 val = s->ar_index;
373             } else {
374                 val = 0;
375             }
376             break;
377         case VGA_ATT_R:
378             index = s->ar_index & 0x1f;
379             if (index < VGA_ATT_C) {
380                 val = s->ar[index];
381             } else {
382                 val = 0;
383             }
384             break;
385         case VGA_MIS_W:
386             val = s->st00;
387             break;
388         case VGA_SEQ_I:
389             val = s->sr_index;
390             break;
391         case VGA_SEQ_D:
392             val = s->sr[s->sr_index];
393 #ifdef DEBUG_VGA_REG
394             printf("vga: read SR%x = 0x%02x\n", s->sr_index, val);
395 #endif
396             break;
397         case VGA_PEL_IR:
398             val = s->dac_state;
399             break;
400         case VGA_PEL_IW:
401             val = s->dac_write_index;
402             break;
403         case VGA_PEL_D:
404             val = s->palette[s->dac_read_index * 3 + s->dac_sub_index];
405             if (++s->dac_sub_index == 3) {
406                 s->dac_sub_index = 0;
407                 s->dac_read_index++;
408             }
409             break;
410         case VGA_FTC_R:
411             val = s->fcr;
412             break;
413         case VGA_MIS_R:
414             val = s->msr;
415             break;
416         case VGA_GFX_I:
417             val = s->gr_index;
418             break;
419         case VGA_GFX_D:
420             val = s->gr[s->gr_index];
421 #ifdef DEBUG_VGA_REG
422             printf("vga: read GR%x = 0x%02x\n", s->gr_index, val);
423 #endif
424             break;
425         case VGA_CRT_IM:
426         case VGA_CRT_IC:
427             val = s->cr_index;
428             break;
429         case VGA_CRT_DM:
430         case VGA_CRT_DC:
431             val = s->cr[s->cr_index];
432 #ifdef DEBUG_VGA_REG
433             printf("vga: read CR%x = 0x%02x\n", s->cr_index, val);
434 #endif
435             break;
436         case VGA_IS1_RM:
437         case VGA_IS1_RC:
438             /* just toggle to fool polling */
439             val = s->st01 = s->retrace(s);
440             s->ar_flip_flop = 0;
441             break;
442         default:
443             val = 0x00;
444             break;
445         }
446     }
447 #if defined(DEBUG_VGA)
448     printf("VGA: read addr=0x%04x data=0x%02x\n", addr, val);
449 #endif
450     return val;
451 }
452 
453 void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
454 {
455     VGACommonState *s = opaque;
456     int index;
457 
458     qemu_flush_coalesced_mmio_buffer();
459 
460     /* check port range access depending on color/monochrome mode */
461     if (vga_ioport_invalid(s, addr)) {
462         return;
463     }
464 #ifdef DEBUG_VGA
465     printf("VGA: write addr=0x%04x data=0x%02x\n", addr, val);
466 #endif
467 
468     switch(addr) {
469     case VGA_ATT_W:
470         if (s->ar_flip_flop == 0) {
471             val &= 0x3f;
472             s->ar_index = val;
473         } else {
474             index = s->ar_index & 0x1f;
475             switch(index) {
476             case VGA_ATC_PALETTE0 ... VGA_ATC_PALETTEF:
477                 s->ar[index] = val & 0x3f;
478                 break;
479             case VGA_ATC_MODE:
480                 s->ar[index] = val & ~0x10;
481                 break;
482             case VGA_ATC_OVERSCAN:
483                 s->ar[index] = val;
484                 break;
485             case VGA_ATC_PLANE_ENABLE:
486                 s->ar[index] = val & ~0xc0;
487                 break;
488             case VGA_ATC_PEL:
489                 s->ar[index] = val & ~0xf0;
490                 break;
491             case VGA_ATC_COLOR_PAGE:
492                 s->ar[index] = val & ~0xf0;
493                 break;
494             default:
495                 break;
496             }
497         }
498         s->ar_flip_flop ^= 1;
499         break;
500     case VGA_MIS_W:
501         s->msr = val & ~0x10;
502         s->update_retrace_info(s);
503         break;
504     case VGA_SEQ_I:
505         s->sr_index = val & 7;
506         break;
507     case VGA_SEQ_D:
508 #ifdef DEBUG_VGA_REG
509         printf("vga: write SR%x = 0x%02x\n", s->sr_index, val);
510 #endif
511         s->sr[s->sr_index] = val & sr_mask[s->sr_index];
512         if (s->sr_index == VGA_SEQ_CLOCK_MODE) {
513             s->update_retrace_info(s);
514         }
515         vga_update_memory_access(s);
516         break;
517     case VGA_PEL_IR:
518         s->dac_read_index = val;
519         s->dac_sub_index = 0;
520         s->dac_state = 3;
521         break;
522     case VGA_PEL_IW:
523         s->dac_write_index = val;
524         s->dac_sub_index = 0;
525         s->dac_state = 0;
526         break;
527     case VGA_PEL_D:
528         s->dac_cache[s->dac_sub_index] = val;
529         if (++s->dac_sub_index == 3) {
530             memcpy(&s->palette[s->dac_write_index * 3], s->dac_cache, 3);
531             s->dac_sub_index = 0;
532             s->dac_write_index++;
533         }
534         break;
535     case VGA_GFX_I:
536         s->gr_index = val & 0x0f;
537         break;
538     case VGA_GFX_D:
539 #ifdef DEBUG_VGA_REG
540         printf("vga: write GR%x = 0x%02x\n", s->gr_index, val);
541 #endif
542         s->gr[s->gr_index] = val & gr_mask[s->gr_index];
543         vga_update_memory_access(s);
544         break;
545     case VGA_CRT_IM:
546     case VGA_CRT_IC:
547         s->cr_index = val;
548         break;
549     case VGA_CRT_DM:
550     case VGA_CRT_DC:
551 #ifdef DEBUG_VGA_REG
552         printf("vga: write CR%x = 0x%02x\n", s->cr_index, val);
553 #endif
554         /* handle CR0-7 protection */
555         if ((s->cr[VGA_CRTC_V_SYNC_END] & VGA_CR11_LOCK_CR0_CR7) &&
556             s->cr_index <= VGA_CRTC_OVERFLOW) {
557             /* can always write bit 4 of CR7 */
558             if (s->cr_index == VGA_CRTC_OVERFLOW) {
559                 s->cr[VGA_CRTC_OVERFLOW] = (s->cr[VGA_CRTC_OVERFLOW] & ~0x10) |
560                     (val & 0x10);
561             }
562             return;
563         }
564         s->cr[s->cr_index] = val;
565 
566         switch(s->cr_index) {
567         case VGA_CRTC_H_TOTAL:
568         case VGA_CRTC_H_SYNC_START:
569         case VGA_CRTC_H_SYNC_END:
570         case VGA_CRTC_V_TOTAL:
571         case VGA_CRTC_OVERFLOW:
572         case VGA_CRTC_V_SYNC_END:
573         case VGA_CRTC_MODE:
574             s->update_retrace_info(s);
575             break;
576         }
577         break;
578     case VGA_IS1_RM:
579     case VGA_IS1_RC:
580         s->fcr = val & 0x10;
581         break;
582     }
583 }
584 
585 static uint32_t vbe_ioport_read_index(void *opaque, uint32_t addr)
586 {
587     VGACommonState *s = opaque;
588     uint32_t val;
589     val = s->vbe_index;
590     return val;
591 }
592 
593 uint32_t vbe_ioport_read_data(void *opaque, uint32_t addr)
594 {
595     VGACommonState *s = opaque;
596     uint32_t val;
597 
598     if (s->vbe_index < VBE_DISPI_INDEX_NB) {
599         if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_GETCAPS) {
600             switch(s->vbe_index) {
601                 /* XXX: do not hardcode ? */
602             case VBE_DISPI_INDEX_XRES:
603                 val = VBE_DISPI_MAX_XRES;
604                 break;
605             case VBE_DISPI_INDEX_YRES:
606                 val = VBE_DISPI_MAX_YRES;
607                 break;
608             case VBE_DISPI_INDEX_BPP:
609                 val = VBE_DISPI_MAX_BPP;
610                 break;
611             default:
612                 val = s->vbe_regs[s->vbe_index];
613                 break;
614             }
615         } else {
616             val = s->vbe_regs[s->vbe_index];
617         }
618     } else if (s->vbe_index == VBE_DISPI_INDEX_VIDEO_MEMORY_64K) {
619         val = s->vram_size / (64 * 1024);
620     } else {
621         val = 0;
622     }
623 #ifdef DEBUG_BOCHS_VBE
624     printf("VBE: read index=0x%x val=0x%x\n", s->vbe_index, val);
625 #endif
626     return val;
627 }
628 
629 void vbe_ioport_write_index(void *opaque, uint32_t addr, uint32_t val)
630 {
631     VGACommonState *s = opaque;
632     s->vbe_index = val;
633 }
634 
635 void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
636 {
637     VGACommonState *s = opaque;
638 
639     if (s->vbe_index <= VBE_DISPI_INDEX_NB) {
640 #ifdef DEBUG_BOCHS_VBE
641         printf("VBE: write index=0x%x val=0x%x\n", s->vbe_index, val);
642 #endif
643         switch(s->vbe_index) {
644         case VBE_DISPI_INDEX_ID:
645             if (val == VBE_DISPI_ID0 ||
646                 val == VBE_DISPI_ID1 ||
647                 val == VBE_DISPI_ID2 ||
648                 val == VBE_DISPI_ID3 ||
649                 val == VBE_DISPI_ID4) {
650                 s->vbe_regs[s->vbe_index] = val;
651             }
652             break;
653         case VBE_DISPI_INDEX_XRES:
654             if ((val <= VBE_DISPI_MAX_XRES) && ((val & 7) == 0)) {
655                 s->vbe_regs[s->vbe_index] = val;
656             }
657             break;
658         case VBE_DISPI_INDEX_YRES:
659             if (val <= VBE_DISPI_MAX_YRES) {
660                 s->vbe_regs[s->vbe_index] = val;
661             }
662             break;
663         case VBE_DISPI_INDEX_BPP:
664             if (val == 0)
665                 val = 8;
666             if (val == 4 || val == 8 || val == 15 ||
667                 val == 16 || val == 24 || val == 32) {
668                 s->vbe_regs[s->vbe_index] = val;
669             }
670             break;
671         case VBE_DISPI_INDEX_BANK:
672             if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
673               val &= (s->vbe_bank_mask >> 2);
674             } else {
675               val &= s->vbe_bank_mask;
676             }
677             s->vbe_regs[s->vbe_index] = val;
678             s->bank_offset = (val << 16);
679             vga_update_memory_access(s);
680             break;
681         case VBE_DISPI_INDEX_ENABLE:
682             if ((val & VBE_DISPI_ENABLED) &&
683                 !(s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED)) {
684                 int h, shift_control;
685 
686                 s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] =
687                     s->vbe_regs[VBE_DISPI_INDEX_XRES];
688                 s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] =
689                     s->vbe_regs[VBE_DISPI_INDEX_YRES];
690                 s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0;
691                 s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0;
692 
693                 if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4)
694                     s->vbe_line_offset = s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 1;
695                 else
696                     s->vbe_line_offset = s->vbe_regs[VBE_DISPI_INDEX_XRES] *
697                         ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
698                 s->vbe_start_addr = 0;
699 
700                 /* clear the screen (should be done in BIOS) */
701                 if (!(val & VBE_DISPI_NOCLEARMEM)) {
702                     memset(s->vram_ptr, 0,
703                            s->vbe_regs[VBE_DISPI_INDEX_YRES] * s->vbe_line_offset);
704                 }
705 
706                 /* we initialize the VGA graphic mode (should be done
707                    in BIOS) */
708                 /* graphic mode + memory map 1 */
709                 s->gr[VGA_GFX_MISC] = (s->gr[VGA_GFX_MISC] & ~0x0c) | 0x04 |
710                     VGA_GR06_GRAPHICS_MODE;
711                 s->cr[VGA_CRTC_MODE] |= 3; /* no CGA modes */
712                 s->cr[VGA_CRTC_OFFSET] = s->vbe_line_offset >> 3;
713                 /* width */
714                 s->cr[VGA_CRTC_H_DISP] =
715                     (s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 3) - 1;
716                 /* height (only meaningful if < 1024) */
717                 h = s->vbe_regs[VBE_DISPI_INDEX_YRES] - 1;
718                 s->cr[VGA_CRTC_V_DISP_END] = h;
719                 s->cr[VGA_CRTC_OVERFLOW] = (s->cr[VGA_CRTC_OVERFLOW] & ~0x42) |
720                     ((h >> 7) & 0x02) | ((h >> 3) & 0x40);
721                 /* line compare to 1023 */
722                 s->cr[VGA_CRTC_LINE_COMPARE] = 0xff;
723                 s->cr[VGA_CRTC_OVERFLOW] |= 0x10;
724                 s->cr[VGA_CRTC_MAX_SCAN] |= 0x40;
725 
726                 if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
727                     shift_control = 0;
728                     s->sr[VGA_SEQ_CLOCK_MODE] &= ~8; /* no double line */
729                 } else {
730                     shift_control = 2;
731                     /* set chain 4 mode */
732                     s->sr[VGA_SEQ_MEMORY_MODE] |= VGA_SR04_CHN_4M;
733                     /* activate all planes */
734                     s->sr[VGA_SEQ_PLANE_WRITE] |= VGA_SR02_ALL_PLANES;
735                 }
736                 s->gr[VGA_GFX_MODE] = (s->gr[VGA_GFX_MODE] & ~0x60) |
737                     (shift_control << 5);
738                 s->cr[VGA_CRTC_MAX_SCAN] &= ~0x9f; /* no double scan */
739             } else {
740                 /* XXX: the bios should do that */
741                 s->bank_offset = 0;
742             }
743             s->dac_8bit = (val & VBE_DISPI_8BIT_DAC) > 0;
744             s->vbe_regs[s->vbe_index] = val;
745             vga_update_memory_access(s);
746             break;
747         case VBE_DISPI_INDEX_VIRT_WIDTH:
748             {
749                 int w, h, line_offset;
750 
751                 if (val < s->vbe_regs[VBE_DISPI_INDEX_XRES])
752                     return;
753                 w = val;
754                 if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4)
755                     line_offset = w >> 1;
756                 else
757                     line_offset = w * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
758                 h = s->vram_size / line_offset;
759                 /* XXX: support weird bochs semantics ? */
760                 if (h < s->vbe_regs[VBE_DISPI_INDEX_YRES])
761                     return;
762                 s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = w;
763                 s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] = h;
764                 s->vbe_line_offset = line_offset;
765             }
766             break;
767         case VBE_DISPI_INDEX_X_OFFSET:
768         case VBE_DISPI_INDEX_Y_OFFSET:
769             {
770                 int x;
771                 s->vbe_regs[s->vbe_index] = val;
772                 s->vbe_start_addr = s->vbe_line_offset * s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET];
773                 x = s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET];
774                 if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4)
775                     s->vbe_start_addr += x >> 1;
776                 else
777                     s->vbe_start_addr += x * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
778                 s->vbe_start_addr >>= 2;
779             }
780             break;
781         default:
782             break;
783         }
784     }
785 }
786 
787 /* called for accesses between 0xa0000 and 0xc0000 */
788 uint32_t vga_mem_readb(VGACommonState *s, hwaddr addr)
789 {
790     int memory_map_mode, plane;
791     uint32_t ret;
792 
793     /* convert to VGA memory offset */
794     memory_map_mode = (s->gr[VGA_GFX_MISC] >> 2) & 3;
795     addr &= 0x1ffff;
796     switch(memory_map_mode) {
797     case 0:
798         break;
799     case 1:
800         if (addr >= 0x10000)
801             return 0xff;
802         addr += s->bank_offset;
803         break;
804     case 2:
805         addr -= 0x10000;
806         if (addr >= 0x8000)
807             return 0xff;
808         break;
809     default:
810     case 3:
811         addr -= 0x18000;
812         if (addr >= 0x8000)
813             return 0xff;
814         break;
815     }
816 
817     if (s->sr[VGA_SEQ_MEMORY_MODE] & VGA_SR04_CHN_4M) {
818         /* chain 4 mode : simplest access */
819         ret = s->vram_ptr[addr];
820     } else if (s->gr[VGA_GFX_MODE] & 0x10) {
821         /* odd/even mode (aka text mode mapping) */
822         plane = (s->gr[VGA_GFX_PLANE_READ] & 2) | (addr & 1);
823         ret = s->vram_ptr[((addr & ~1) << 1) | plane];
824     } else {
825         /* standard VGA latched access */
826         s->latch = ((uint32_t *)s->vram_ptr)[addr];
827 
828         if (!(s->gr[VGA_GFX_MODE] & 0x08)) {
829             /* read mode 0 */
830             plane = s->gr[VGA_GFX_PLANE_READ];
831             ret = GET_PLANE(s->latch, plane);
832         } else {
833             /* read mode 1 */
834             ret = (s->latch ^ mask16[s->gr[VGA_GFX_COMPARE_VALUE]]) &
835                 mask16[s->gr[VGA_GFX_COMPARE_MASK]];
836             ret |= ret >> 16;
837             ret |= ret >> 8;
838             ret = (~ret) & 0xff;
839         }
840     }
841     return ret;
842 }
843 
844 /* called for accesses between 0xa0000 and 0xc0000 */
845 void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val)
846 {
847     int memory_map_mode, plane, write_mode, b, func_select, mask;
848     uint32_t write_mask, bit_mask, set_mask;
849 
850 #ifdef DEBUG_VGA_MEM
851     printf("vga: [0x" TARGET_FMT_plx "] = 0x%02x\n", addr, val);
852 #endif
853     /* convert to VGA memory offset */
854     memory_map_mode = (s->gr[VGA_GFX_MISC] >> 2) & 3;
855     addr &= 0x1ffff;
856     switch(memory_map_mode) {
857     case 0:
858         break;
859     case 1:
860         if (addr >= 0x10000)
861             return;
862         addr += s->bank_offset;
863         break;
864     case 2:
865         addr -= 0x10000;
866         if (addr >= 0x8000)
867             return;
868         break;
869     default:
870     case 3:
871         addr -= 0x18000;
872         if (addr >= 0x8000)
873             return;
874         break;
875     }
876 
877     if (s->sr[VGA_SEQ_MEMORY_MODE] & VGA_SR04_CHN_4M) {
878         /* chain 4 mode : simplest access */
879         plane = addr & 3;
880         mask = (1 << plane);
881         if (s->sr[VGA_SEQ_PLANE_WRITE] & mask) {
882             s->vram_ptr[addr] = val;
883 #ifdef DEBUG_VGA_MEM
884             printf("vga: chain4: [0x" TARGET_FMT_plx "]\n", addr);
885 #endif
886             s->plane_updated |= mask; /* only used to detect font change */
887             memory_region_set_dirty(&s->vram, addr, 1);
888         }
889     } else if (s->gr[VGA_GFX_MODE] & 0x10) {
890         /* odd/even mode (aka text mode mapping) */
891         plane = (s->gr[VGA_GFX_PLANE_READ] & 2) | (addr & 1);
892         mask = (1 << plane);
893         if (s->sr[VGA_SEQ_PLANE_WRITE] & mask) {
894             addr = ((addr & ~1) << 1) | plane;
895             s->vram_ptr[addr] = val;
896 #ifdef DEBUG_VGA_MEM
897             printf("vga: odd/even: [0x" TARGET_FMT_plx "]\n", addr);
898 #endif
899             s->plane_updated |= mask; /* only used to detect font change */
900             memory_region_set_dirty(&s->vram, addr, 1);
901         }
902     } else {
903         /* standard VGA latched access */
904         write_mode = s->gr[VGA_GFX_MODE] & 3;
905         switch(write_mode) {
906         default:
907         case 0:
908             /* rotate */
909             b = s->gr[VGA_GFX_DATA_ROTATE] & 7;
910             val = ((val >> b) | (val << (8 - b))) & 0xff;
911             val |= val << 8;
912             val |= val << 16;
913 
914             /* apply set/reset mask */
915             set_mask = mask16[s->gr[VGA_GFX_SR_ENABLE]];
916             val = (val & ~set_mask) |
917                 (mask16[s->gr[VGA_GFX_SR_VALUE]] & set_mask);
918             bit_mask = s->gr[VGA_GFX_BIT_MASK];
919             break;
920         case 1:
921             val = s->latch;
922             goto do_write;
923         case 2:
924             val = mask16[val & 0x0f];
925             bit_mask = s->gr[VGA_GFX_BIT_MASK];
926             break;
927         case 3:
928             /* rotate */
929             b = s->gr[VGA_GFX_DATA_ROTATE] & 7;
930             val = (val >> b) | (val << (8 - b));
931 
932             bit_mask = s->gr[VGA_GFX_BIT_MASK] & val;
933             val = mask16[s->gr[VGA_GFX_SR_VALUE]];
934             break;
935         }
936 
937         /* apply logical operation */
938         func_select = s->gr[VGA_GFX_DATA_ROTATE] >> 3;
939         switch(func_select) {
940         case 0:
941         default:
942             /* nothing to do */
943             break;
944         case 1:
945             /* and */
946             val &= s->latch;
947             break;
948         case 2:
949             /* or */
950             val |= s->latch;
951             break;
952         case 3:
953             /* xor */
954             val ^= s->latch;
955             break;
956         }
957 
958         /* apply bit mask */
959         bit_mask |= bit_mask << 8;
960         bit_mask |= bit_mask << 16;
961         val = (val & bit_mask) | (s->latch & ~bit_mask);
962 
963     do_write:
964         /* mask data according to sr[2] */
965         mask = s->sr[VGA_SEQ_PLANE_WRITE];
966         s->plane_updated |= mask; /* only used to detect font change */
967         write_mask = mask16[mask];
968         ((uint32_t *)s->vram_ptr)[addr] =
969             (((uint32_t *)s->vram_ptr)[addr] & ~write_mask) |
970             (val & write_mask);
971 #ifdef DEBUG_VGA_MEM
972         printf("vga: latch: [0x" TARGET_FMT_plx "] mask=0x%08x val=0x%08x\n",
973                addr * 4, write_mask, val);
974 #endif
975         memory_region_set_dirty(&s->vram, addr << 2, sizeof(uint32_t));
976     }
977 }
978 
979 typedef void vga_draw_glyph8_func(uint8_t *d, int linesize,
980                              const uint8_t *font_ptr, int h,
981                              uint32_t fgcol, uint32_t bgcol);
982 typedef void vga_draw_glyph9_func(uint8_t *d, int linesize,
983                                   const uint8_t *font_ptr, int h,
984                                   uint32_t fgcol, uint32_t bgcol, int dup9);
985 typedef void vga_draw_line_func(VGACommonState *s1, uint8_t *d,
986                                 const uint8_t *s, int width);
987 
988 #define DEPTH 8
989 #include "vga_template.h"
990 
991 #define DEPTH 15
992 #include "vga_template.h"
993 
994 #define BGR_FORMAT
995 #define DEPTH 15
996 #include "vga_template.h"
997 
998 #define DEPTH 16
999 #include "vga_template.h"
1000 
1001 #define BGR_FORMAT
1002 #define DEPTH 16
1003 #include "vga_template.h"
1004 
1005 #define DEPTH 32
1006 #include "vga_template.h"
1007 
1008 #define BGR_FORMAT
1009 #define DEPTH 32
1010 #include "vga_template.h"
1011 
1012 static unsigned int rgb_to_pixel8_dup(unsigned int r, unsigned int g, unsigned b)
1013 {
1014     unsigned int col;
1015     col = rgb_to_pixel8(r, g, b);
1016     col |= col << 8;
1017     col |= col << 16;
1018     return col;
1019 }
1020 
1021 static unsigned int rgb_to_pixel15_dup(unsigned int r, unsigned int g, unsigned b)
1022 {
1023     unsigned int col;
1024     col = rgb_to_pixel15(r, g, b);
1025     col |= col << 16;
1026     return col;
1027 }
1028 
1029 static unsigned int rgb_to_pixel15bgr_dup(unsigned int r, unsigned int g,
1030                                           unsigned int b)
1031 {
1032     unsigned int col;
1033     col = rgb_to_pixel15bgr(r, g, b);
1034     col |= col << 16;
1035     return col;
1036 }
1037 
1038 static unsigned int rgb_to_pixel16_dup(unsigned int r, unsigned int g, unsigned b)
1039 {
1040     unsigned int col;
1041     col = rgb_to_pixel16(r, g, b);
1042     col |= col << 16;
1043     return col;
1044 }
1045 
1046 static unsigned int rgb_to_pixel16bgr_dup(unsigned int r, unsigned int g,
1047                                           unsigned int b)
1048 {
1049     unsigned int col;
1050     col = rgb_to_pixel16bgr(r, g, b);
1051     col |= col << 16;
1052     return col;
1053 }
1054 
1055 static unsigned int rgb_to_pixel32_dup(unsigned int r, unsigned int g, unsigned b)
1056 {
1057     unsigned int col;
1058     col = rgb_to_pixel32(r, g, b);
1059     return col;
1060 }
1061 
1062 static unsigned int rgb_to_pixel32bgr_dup(unsigned int r, unsigned int g, unsigned b)
1063 {
1064     unsigned int col;
1065     col = rgb_to_pixel32bgr(r, g, b);
1066     return col;
1067 }
1068 
1069 /* return true if the palette was modified */
1070 static int update_palette16(VGACommonState *s)
1071 {
1072     int full_update, i;
1073     uint32_t v, col, *palette;
1074 
1075     full_update = 0;
1076     palette = s->last_palette;
1077     for(i = 0; i < 16; i++) {
1078         v = s->ar[i];
1079         if (s->ar[VGA_ATC_MODE] & 0x80) {
1080             v = ((s->ar[VGA_ATC_COLOR_PAGE] & 0xf) << 4) | (v & 0xf);
1081         } else {
1082             v = ((s->ar[VGA_ATC_COLOR_PAGE] & 0xc) << 4) | (v & 0x3f);
1083         }
1084         v = v * 3;
1085         col = s->rgb_to_pixel(c6_to_8(s->palette[v]),
1086                               c6_to_8(s->palette[v + 1]),
1087                               c6_to_8(s->palette[v + 2]));
1088         if (col != palette[i]) {
1089             full_update = 1;
1090             palette[i] = col;
1091         }
1092     }
1093     return full_update;
1094 }
1095 
1096 /* return true if the palette was modified */
1097 static int update_palette256(VGACommonState *s)
1098 {
1099     int full_update, i;
1100     uint32_t v, col, *palette;
1101 
1102     full_update = 0;
1103     palette = s->last_palette;
1104     v = 0;
1105     for(i = 0; i < 256; i++) {
1106         if (s->dac_8bit) {
1107           col = s->rgb_to_pixel(s->palette[v],
1108                                 s->palette[v + 1],
1109                                 s->palette[v + 2]);
1110         } else {
1111           col = s->rgb_to_pixel(c6_to_8(s->palette[v]),
1112                                 c6_to_8(s->palette[v + 1]),
1113                                 c6_to_8(s->palette[v + 2]));
1114         }
1115         if (col != palette[i]) {
1116             full_update = 1;
1117             palette[i] = col;
1118         }
1119         v += 3;
1120     }
1121     return full_update;
1122 }
1123 
1124 static void vga_get_offsets(VGACommonState *s,
1125                             uint32_t *pline_offset,
1126                             uint32_t *pstart_addr,
1127                             uint32_t *pline_compare)
1128 {
1129     uint32_t start_addr, line_offset, line_compare;
1130 
1131     if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
1132         line_offset = s->vbe_line_offset;
1133         start_addr = s->vbe_start_addr;
1134         line_compare = 65535;
1135     } else {
1136         /* compute line_offset in bytes */
1137         line_offset = s->cr[VGA_CRTC_OFFSET];
1138         line_offset <<= 3;
1139 
1140         /* starting address */
1141         start_addr = s->cr[VGA_CRTC_START_LO] |
1142             (s->cr[VGA_CRTC_START_HI] << 8);
1143 
1144         /* line compare */
1145         line_compare = s->cr[VGA_CRTC_LINE_COMPARE] |
1146             ((s->cr[VGA_CRTC_OVERFLOW] & 0x10) << 4) |
1147             ((s->cr[VGA_CRTC_MAX_SCAN] & 0x40) << 3);
1148     }
1149     *pline_offset = line_offset;
1150     *pstart_addr = start_addr;
1151     *pline_compare = line_compare;
1152 }
1153 
1154 /* update start_addr and line_offset. Return TRUE if modified */
1155 static int update_basic_params(VGACommonState *s)
1156 {
1157     int full_update;
1158     uint32_t start_addr, line_offset, line_compare;
1159 
1160     full_update = 0;
1161 
1162     s->get_offsets(s, &line_offset, &start_addr, &line_compare);
1163 
1164     if (line_offset != s->line_offset ||
1165         start_addr != s->start_addr ||
1166         line_compare != s->line_compare) {
1167         s->line_offset = line_offset;
1168         s->start_addr = start_addr;
1169         s->line_compare = line_compare;
1170         full_update = 1;
1171     }
1172     return full_update;
1173 }
1174 
1175 #define NB_DEPTHS 7
1176 
1177 static inline int get_depth_index(DisplaySurface *s)
1178 {
1179     switch (surface_bits_per_pixel(s)) {
1180     default:
1181     case 8:
1182         return 0;
1183     case 15:
1184         return 1;
1185     case 16:
1186         return 2;
1187     case 32:
1188         if (is_surface_bgr(s)) {
1189             return 4;
1190         } else {
1191             return 3;
1192         }
1193     }
1194 }
1195 
1196 static vga_draw_glyph8_func * const vga_draw_glyph8_table[NB_DEPTHS] = {
1197     vga_draw_glyph8_8,
1198     vga_draw_glyph8_16,
1199     vga_draw_glyph8_16,
1200     vga_draw_glyph8_32,
1201     vga_draw_glyph8_32,
1202     vga_draw_glyph8_16,
1203     vga_draw_glyph8_16,
1204 };
1205 
1206 static vga_draw_glyph8_func * const vga_draw_glyph16_table[NB_DEPTHS] = {
1207     vga_draw_glyph16_8,
1208     vga_draw_glyph16_16,
1209     vga_draw_glyph16_16,
1210     vga_draw_glyph16_32,
1211     vga_draw_glyph16_32,
1212     vga_draw_glyph16_16,
1213     vga_draw_glyph16_16,
1214 };
1215 
1216 static vga_draw_glyph9_func * const vga_draw_glyph9_table[NB_DEPTHS] = {
1217     vga_draw_glyph9_8,
1218     vga_draw_glyph9_16,
1219     vga_draw_glyph9_16,
1220     vga_draw_glyph9_32,
1221     vga_draw_glyph9_32,
1222     vga_draw_glyph9_16,
1223     vga_draw_glyph9_16,
1224 };
1225 
1226 static const uint8_t cursor_glyph[32 * 4] = {
1227     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1228     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1229     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1230     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1231     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1232     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1233     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1234     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1235     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1236     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1237     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1238     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1239     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1240     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1241     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1242     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1243 };
1244 
1245 static void vga_get_text_resolution(VGACommonState *s, int *pwidth, int *pheight,
1246                                     int *pcwidth, int *pcheight)
1247 {
1248     int width, cwidth, height, cheight;
1249 
1250     /* total width & height */
1251     cheight = (s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1;
1252     cwidth = 8;
1253     if (!(s->sr[VGA_SEQ_CLOCK_MODE] & VGA_SR01_CHAR_CLK_8DOTS)) {
1254         cwidth = 9;
1255     }
1256     if (s->sr[VGA_SEQ_CLOCK_MODE] & 0x08) {
1257         cwidth = 16; /* NOTE: no 18 pixel wide */
1258     }
1259     width = (s->cr[VGA_CRTC_H_DISP] + 1);
1260     if (s->cr[VGA_CRTC_V_TOTAL] == 100) {
1261         /* ugly hack for CGA 160x100x16 - explain me the logic */
1262         height = 100;
1263     } else {
1264         height = s->cr[VGA_CRTC_V_DISP_END] |
1265             ((s->cr[VGA_CRTC_OVERFLOW] & 0x02) << 7) |
1266             ((s->cr[VGA_CRTC_OVERFLOW] & 0x40) << 3);
1267         height = (height + 1) / cheight;
1268     }
1269 
1270     *pwidth = width;
1271     *pheight = height;
1272     *pcwidth = cwidth;
1273     *pcheight = cheight;
1274 }
1275 
1276 typedef unsigned int rgb_to_pixel_dup_func(unsigned int r, unsigned int g, unsigned b);
1277 
1278 static rgb_to_pixel_dup_func * const rgb_to_pixel_dup_table[NB_DEPTHS] = {
1279     rgb_to_pixel8_dup,
1280     rgb_to_pixel15_dup,
1281     rgb_to_pixel16_dup,
1282     rgb_to_pixel32_dup,
1283     rgb_to_pixel32bgr_dup,
1284     rgb_to_pixel15bgr_dup,
1285     rgb_to_pixel16bgr_dup,
1286 };
1287 
1288 /*
1289  * Text mode update
1290  * Missing:
1291  * - double scan
1292  * - double width
1293  * - underline
1294  * - flashing
1295  */
1296 static void vga_draw_text(VGACommonState *s, int full_update)
1297 {
1298     DisplaySurface *surface = qemu_console_surface(s->con);
1299     int cx, cy, cheight, cw, ch, cattr, height, width, ch_attr;
1300     int cx_min, cx_max, linesize, x_incr, line, line1;
1301     uint32_t offset, fgcol, bgcol, v, cursor_offset;
1302     uint8_t *d1, *d, *src, *dest, *cursor_ptr;
1303     const uint8_t *font_ptr, *font_base[2];
1304     int dup9, line_offset, depth_index;
1305     uint32_t *palette;
1306     uint32_t *ch_attr_ptr;
1307     vga_draw_glyph8_func *vga_draw_glyph8;
1308     vga_draw_glyph9_func *vga_draw_glyph9;
1309     int64_t now = qemu_get_clock_ms(vm_clock);
1310 
1311     /* compute font data address (in plane 2) */
1312     v = s->sr[VGA_SEQ_CHARACTER_MAP];
1313     offset = (((v >> 4) & 1) | ((v << 1) & 6)) * 8192 * 4 + 2;
1314     if (offset != s->font_offsets[0]) {
1315         s->font_offsets[0] = offset;
1316         full_update = 1;
1317     }
1318     font_base[0] = s->vram_ptr + offset;
1319 
1320     offset = (((v >> 5) & 1) | ((v >> 1) & 6)) * 8192 * 4 + 2;
1321     font_base[1] = s->vram_ptr + offset;
1322     if (offset != s->font_offsets[1]) {
1323         s->font_offsets[1] = offset;
1324         full_update = 1;
1325     }
1326     if (s->plane_updated & (1 << 2) || s->chain4_alias) {
1327         /* if the plane 2 was modified since the last display, it
1328            indicates the font may have been modified */
1329         s->plane_updated = 0;
1330         full_update = 1;
1331     }
1332     full_update |= update_basic_params(s);
1333 
1334     line_offset = s->line_offset;
1335 
1336     vga_get_text_resolution(s, &width, &height, &cw, &cheight);
1337     if ((height * width) <= 1) {
1338         /* better than nothing: exit if transient size is too small */
1339         return;
1340     }
1341     if ((height * width) > CH_ATTR_SIZE) {
1342         /* better than nothing: exit if transient size is too big */
1343         return;
1344     }
1345 
1346     if (width != s->last_width || height != s->last_height ||
1347         cw != s->last_cw || cheight != s->last_ch || s->last_depth) {
1348         s->last_scr_width = width * cw;
1349         s->last_scr_height = height * cheight;
1350         qemu_console_resize(s->con, s->last_scr_width, s->last_scr_height);
1351         surface = qemu_console_surface(s->con);
1352         dpy_text_resize(s->con, width, height);
1353         s->last_depth = 0;
1354         s->last_width = width;
1355         s->last_height = height;
1356         s->last_ch = cheight;
1357         s->last_cw = cw;
1358         full_update = 1;
1359     }
1360     s->rgb_to_pixel =
1361         rgb_to_pixel_dup_table[get_depth_index(surface)];
1362     full_update |= update_palette16(s);
1363     palette = s->last_palette;
1364     x_incr = cw * surface_bytes_per_pixel(surface);
1365 
1366     if (full_update) {
1367         s->full_update_text = 1;
1368     }
1369     if (s->full_update_gfx) {
1370         s->full_update_gfx = 0;
1371         full_update |= 1;
1372     }
1373 
1374     cursor_offset = ((s->cr[VGA_CRTC_CURSOR_HI] << 8) |
1375                      s->cr[VGA_CRTC_CURSOR_LO]) - s->start_addr;
1376     if (cursor_offset != s->cursor_offset ||
1377         s->cr[VGA_CRTC_CURSOR_START] != s->cursor_start ||
1378         s->cr[VGA_CRTC_CURSOR_END] != s->cursor_end) {
1379       /* if the cursor position changed, we update the old and new
1380          chars */
1381         if (s->cursor_offset < CH_ATTR_SIZE)
1382             s->last_ch_attr[s->cursor_offset] = -1;
1383         if (cursor_offset < CH_ATTR_SIZE)
1384             s->last_ch_attr[cursor_offset] = -1;
1385         s->cursor_offset = cursor_offset;
1386         s->cursor_start = s->cr[VGA_CRTC_CURSOR_START];
1387         s->cursor_end = s->cr[VGA_CRTC_CURSOR_END];
1388     }
1389     cursor_ptr = s->vram_ptr + (s->start_addr + cursor_offset) * 4;
1390     if (now >= s->cursor_blink_time) {
1391         s->cursor_blink_time = now + VGA_TEXT_CURSOR_PERIOD_MS / 2;
1392         s->cursor_visible_phase = !s->cursor_visible_phase;
1393     }
1394 
1395     depth_index = get_depth_index(surface);
1396     if (cw == 16)
1397         vga_draw_glyph8 = vga_draw_glyph16_table[depth_index];
1398     else
1399         vga_draw_glyph8 = vga_draw_glyph8_table[depth_index];
1400     vga_draw_glyph9 = vga_draw_glyph9_table[depth_index];
1401 
1402     dest = surface_data(surface);
1403     linesize = surface_stride(surface);
1404     ch_attr_ptr = s->last_ch_attr;
1405     line = 0;
1406     offset = s->start_addr * 4;
1407     for(cy = 0; cy < height; cy++) {
1408         d1 = dest;
1409         src = s->vram_ptr + offset;
1410         cx_min = width;
1411         cx_max = -1;
1412         for(cx = 0; cx < width; cx++) {
1413             ch_attr = *(uint16_t *)src;
1414             if (full_update || ch_attr != *ch_attr_ptr || src == cursor_ptr) {
1415                 if (cx < cx_min)
1416                     cx_min = cx;
1417                 if (cx > cx_max)
1418                     cx_max = cx;
1419                 *ch_attr_ptr = ch_attr;
1420 #ifdef HOST_WORDS_BIGENDIAN
1421                 ch = ch_attr >> 8;
1422                 cattr = ch_attr & 0xff;
1423 #else
1424                 ch = ch_attr & 0xff;
1425                 cattr = ch_attr >> 8;
1426 #endif
1427                 font_ptr = font_base[(cattr >> 3) & 1];
1428                 font_ptr += 32 * 4 * ch;
1429                 bgcol = palette[cattr >> 4];
1430                 fgcol = palette[cattr & 0x0f];
1431                 if (cw != 9) {
1432                     vga_draw_glyph8(d1, linesize,
1433                                     font_ptr, cheight, fgcol, bgcol);
1434                 } else {
1435                     dup9 = 0;
1436                     if (ch >= 0xb0 && ch <= 0xdf &&
1437                         (s->ar[VGA_ATC_MODE] & 0x04)) {
1438                         dup9 = 1;
1439                     }
1440                     vga_draw_glyph9(d1, linesize,
1441                                     font_ptr, cheight, fgcol, bgcol, dup9);
1442                 }
1443                 if (src == cursor_ptr &&
1444                     !(s->cr[VGA_CRTC_CURSOR_START] & 0x20) &&
1445                     s->cursor_visible_phase) {
1446                     int line_start, line_last, h;
1447                     /* draw the cursor */
1448                     line_start = s->cr[VGA_CRTC_CURSOR_START] & 0x1f;
1449                     line_last = s->cr[VGA_CRTC_CURSOR_END] & 0x1f;
1450                     /* XXX: check that */
1451                     if (line_last > cheight - 1)
1452                         line_last = cheight - 1;
1453                     if (line_last >= line_start && line_start < cheight) {
1454                         h = line_last - line_start + 1;
1455                         d = d1 + linesize * line_start;
1456                         if (cw != 9) {
1457                             vga_draw_glyph8(d, linesize,
1458                                             cursor_glyph, h, fgcol, bgcol);
1459                         } else {
1460                             vga_draw_glyph9(d, linesize,
1461                                             cursor_glyph, h, fgcol, bgcol, 1);
1462                         }
1463                     }
1464                 }
1465             }
1466             d1 += x_incr;
1467             src += 4;
1468             ch_attr_ptr++;
1469         }
1470         if (cx_max != -1) {
1471             dpy_gfx_update(s->con, cx_min * cw, cy * cheight,
1472                            (cx_max - cx_min + 1) * cw, cheight);
1473         }
1474         dest += linesize * cheight;
1475         line1 = line + cheight;
1476         offset += line_offset;
1477         if (line < s->line_compare && line1 >= s->line_compare) {
1478             offset = 0;
1479         }
1480         line = line1;
1481     }
1482 }
1483 
1484 enum {
1485     VGA_DRAW_LINE2,
1486     VGA_DRAW_LINE2D2,
1487     VGA_DRAW_LINE4,
1488     VGA_DRAW_LINE4D2,
1489     VGA_DRAW_LINE8D2,
1490     VGA_DRAW_LINE8,
1491     VGA_DRAW_LINE15,
1492     VGA_DRAW_LINE16,
1493     VGA_DRAW_LINE24,
1494     VGA_DRAW_LINE32,
1495     VGA_DRAW_LINE_NB,
1496 };
1497 
1498 static vga_draw_line_func * const vga_draw_line_table[NB_DEPTHS * VGA_DRAW_LINE_NB] = {
1499     vga_draw_line2_8,
1500     vga_draw_line2_16,
1501     vga_draw_line2_16,
1502     vga_draw_line2_32,
1503     vga_draw_line2_32,
1504     vga_draw_line2_16,
1505     vga_draw_line2_16,
1506 
1507     vga_draw_line2d2_8,
1508     vga_draw_line2d2_16,
1509     vga_draw_line2d2_16,
1510     vga_draw_line2d2_32,
1511     vga_draw_line2d2_32,
1512     vga_draw_line2d2_16,
1513     vga_draw_line2d2_16,
1514 
1515     vga_draw_line4_8,
1516     vga_draw_line4_16,
1517     vga_draw_line4_16,
1518     vga_draw_line4_32,
1519     vga_draw_line4_32,
1520     vga_draw_line4_16,
1521     vga_draw_line4_16,
1522 
1523     vga_draw_line4d2_8,
1524     vga_draw_line4d2_16,
1525     vga_draw_line4d2_16,
1526     vga_draw_line4d2_32,
1527     vga_draw_line4d2_32,
1528     vga_draw_line4d2_16,
1529     vga_draw_line4d2_16,
1530 
1531     vga_draw_line8d2_8,
1532     vga_draw_line8d2_16,
1533     vga_draw_line8d2_16,
1534     vga_draw_line8d2_32,
1535     vga_draw_line8d2_32,
1536     vga_draw_line8d2_16,
1537     vga_draw_line8d2_16,
1538 
1539     vga_draw_line8_8,
1540     vga_draw_line8_16,
1541     vga_draw_line8_16,
1542     vga_draw_line8_32,
1543     vga_draw_line8_32,
1544     vga_draw_line8_16,
1545     vga_draw_line8_16,
1546 
1547     vga_draw_line15_8,
1548     vga_draw_line15_15,
1549     vga_draw_line15_16,
1550     vga_draw_line15_32,
1551     vga_draw_line15_32bgr,
1552     vga_draw_line15_15bgr,
1553     vga_draw_line15_16bgr,
1554 
1555     vga_draw_line16_8,
1556     vga_draw_line16_15,
1557     vga_draw_line16_16,
1558     vga_draw_line16_32,
1559     vga_draw_line16_32bgr,
1560     vga_draw_line16_15bgr,
1561     vga_draw_line16_16bgr,
1562 
1563     vga_draw_line24_8,
1564     vga_draw_line24_15,
1565     vga_draw_line24_16,
1566     vga_draw_line24_32,
1567     vga_draw_line24_32bgr,
1568     vga_draw_line24_15bgr,
1569     vga_draw_line24_16bgr,
1570 
1571     vga_draw_line32_8,
1572     vga_draw_line32_15,
1573     vga_draw_line32_16,
1574     vga_draw_line32_32,
1575     vga_draw_line32_32bgr,
1576     vga_draw_line32_15bgr,
1577     vga_draw_line32_16bgr,
1578 };
1579 
1580 static int vga_get_bpp(VGACommonState *s)
1581 {
1582     int ret;
1583 
1584     if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
1585         ret = s->vbe_regs[VBE_DISPI_INDEX_BPP];
1586     } else {
1587         ret = 0;
1588     }
1589     return ret;
1590 }
1591 
1592 static void vga_get_resolution(VGACommonState *s, int *pwidth, int *pheight)
1593 {
1594     int width, height;
1595 
1596     if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
1597         width = s->vbe_regs[VBE_DISPI_INDEX_XRES];
1598         height = s->vbe_regs[VBE_DISPI_INDEX_YRES];
1599     } else {
1600         width = (s->cr[VGA_CRTC_H_DISP] + 1) * 8;
1601         height = s->cr[VGA_CRTC_V_DISP_END] |
1602             ((s->cr[VGA_CRTC_OVERFLOW] & 0x02) << 7) |
1603             ((s->cr[VGA_CRTC_OVERFLOW] & 0x40) << 3);
1604         height = (height + 1);
1605     }
1606     *pwidth = width;
1607     *pheight = height;
1608 }
1609 
1610 void vga_invalidate_scanlines(VGACommonState *s, int y1, int y2)
1611 {
1612     int y;
1613     if (y1 >= VGA_MAX_HEIGHT)
1614         return;
1615     if (y2 >= VGA_MAX_HEIGHT)
1616         y2 = VGA_MAX_HEIGHT;
1617     for(y = y1; y < y2; y++) {
1618         s->invalidated_y_table[y >> 5] |= 1 << (y & 0x1f);
1619     }
1620 }
1621 
1622 void vga_sync_dirty_bitmap(VGACommonState *s)
1623 {
1624     memory_region_sync_dirty_bitmap(&s->vram);
1625 }
1626 
1627 void vga_dirty_log_start(VGACommonState *s)
1628 {
1629     memory_region_set_log(&s->vram, true, DIRTY_MEMORY_VGA);
1630 }
1631 
1632 void vga_dirty_log_stop(VGACommonState *s)
1633 {
1634     memory_region_set_log(&s->vram, false, DIRTY_MEMORY_VGA);
1635 }
1636 
1637 /*
1638  * graphic modes
1639  */
1640 static void vga_draw_graphic(VGACommonState *s, int full_update)
1641 {
1642     DisplaySurface *surface = qemu_console_surface(s->con);
1643     int y1, y, update, linesize, y_start, double_scan, mask, depth;
1644     int width, height, shift_control, line_offset, bwidth, bits;
1645     ram_addr_t page0, page1, page_min, page_max;
1646     int disp_width, multi_scan, multi_run;
1647     uint8_t *d;
1648     uint32_t v, addr1, addr;
1649     vga_draw_line_func *vga_draw_line;
1650 #if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
1651     static const bool byteswap = false;
1652 #else
1653     static const bool byteswap = true;
1654 #endif
1655 
1656     full_update |= update_basic_params(s);
1657 
1658     if (!full_update)
1659         vga_sync_dirty_bitmap(s);
1660 
1661     s->get_resolution(s, &width, &height);
1662     disp_width = width;
1663 
1664     shift_control = (s->gr[VGA_GFX_MODE] >> 5) & 3;
1665     double_scan = (s->cr[VGA_CRTC_MAX_SCAN] >> 7);
1666     if (shift_control != 1) {
1667         multi_scan = (((s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1) << double_scan)
1668             - 1;
1669     } else {
1670         /* in CGA modes, multi_scan is ignored */
1671         /* XXX: is it correct ? */
1672         multi_scan = double_scan;
1673     }
1674     multi_run = multi_scan;
1675     if (shift_control != s->shift_control ||
1676         double_scan != s->double_scan) {
1677         full_update = 1;
1678         s->shift_control = shift_control;
1679         s->double_scan = double_scan;
1680     }
1681 
1682     if (shift_control == 0) {
1683         if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) {
1684             disp_width <<= 1;
1685         }
1686     } else if (shift_control == 1) {
1687         if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) {
1688             disp_width <<= 1;
1689         }
1690     }
1691 
1692     depth = s->get_bpp(s);
1693     if (s->line_offset != s->last_line_offset ||
1694         disp_width != s->last_width ||
1695         height != s->last_height ||
1696         s->last_depth != depth) {
1697         if (depth == 32 || (depth == 16 && !byteswap)) {
1698             surface = qemu_create_displaysurface_from(disp_width,
1699                     height, depth, s->line_offset,
1700                     s->vram_ptr + (s->start_addr * 4), byteswap);
1701             dpy_gfx_replace_surface(s->con, surface);
1702         } else {
1703             qemu_console_resize(s->con, disp_width, height);
1704             surface = qemu_console_surface(s->con);
1705         }
1706         s->last_scr_width = disp_width;
1707         s->last_scr_height = height;
1708         s->last_width = disp_width;
1709         s->last_height = height;
1710         s->last_line_offset = s->line_offset;
1711         s->last_depth = depth;
1712         full_update = 1;
1713     } else if (is_buffer_shared(surface) &&
1714                (full_update || surface_data(surface) != s->vram_ptr
1715                 + (s->start_addr * 4))) {
1716         DisplaySurface *surface;
1717         surface = qemu_create_displaysurface_from(disp_width,
1718                 height, depth, s->line_offset,
1719                 s->vram_ptr + (s->start_addr * 4), byteswap);
1720         dpy_gfx_replace_surface(s->con, surface);
1721     }
1722 
1723     s->rgb_to_pixel =
1724         rgb_to_pixel_dup_table[get_depth_index(surface)];
1725 
1726     if (shift_control == 0) {
1727         full_update |= update_palette16(s);
1728         if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) {
1729             v = VGA_DRAW_LINE4D2;
1730         } else {
1731             v = VGA_DRAW_LINE4;
1732         }
1733         bits = 4;
1734     } else if (shift_control == 1) {
1735         full_update |= update_palette16(s);
1736         if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) {
1737             v = VGA_DRAW_LINE2D2;
1738         } else {
1739             v = VGA_DRAW_LINE2;
1740         }
1741         bits = 4;
1742     } else {
1743         switch(s->get_bpp(s)) {
1744         default:
1745         case 0:
1746             full_update |= update_palette256(s);
1747             v = VGA_DRAW_LINE8D2;
1748             bits = 4;
1749             break;
1750         case 8:
1751             full_update |= update_palette256(s);
1752             v = VGA_DRAW_LINE8;
1753             bits = 8;
1754             break;
1755         case 15:
1756             v = VGA_DRAW_LINE15;
1757             bits = 16;
1758             break;
1759         case 16:
1760             v = VGA_DRAW_LINE16;
1761             bits = 16;
1762             break;
1763         case 24:
1764             v = VGA_DRAW_LINE24;
1765             bits = 24;
1766             break;
1767         case 32:
1768             v = VGA_DRAW_LINE32;
1769             bits = 32;
1770             break;
1771         }
1772     }
1773     vga_draw_line = vga_draw_line_table[v * NB_DEPTHS +
1774                                         get_depth_index(surface)];
1775 
1776     if (!is_buffer_shared(surface) && s->cursor_invalidate) {
1777         s->cursor_invalidate(s);
1778     }
1779 
1780     line_offset = s->line_offset;
1781 #if 0
1782     printf("w=%d h=%d v=%d line_offset=%d cr[0x09]=0x%02x cr[0x17]=0x%02x linecmp=%d sr[0x01]=0x%02x\n",
1783            width, height, v, line_offset, s->cr[9], s->cr[VGA_CRTC_MODE],
1784            s->line_compare, s->sr[VGA_SEQ_CLOCK_MODE]);
1785 #endif
1786     addr1 = (s->start_addr * 4);
1787     bwidth = (width * bits + 7) / 8;
1788     y_start = -1;
1789     page_min = -1;
1790     page_max = 0;
1791     d = surface_data(surface);
1792     linesize = surface_stride(surface);
1793     y1 = 0;
1794     for(y = 0; y < height; y++) {
1795         addr = addr1;
1796         if (!(s->cr[VGA_CRTC_MODE] & 1)) {
1797             int shift;
1798             /* CGA compatibility handling */
1799             shift = 14 + ((s->cr[VGA_CRTC_MODE] >> 6) & 1);
1800             addr = (addr & ~(1 << shift)) | ((y1 & 1) << shift);
1801         }
1802         if (!(s->cr[VGA_CRTC_MODE] & 2)) {
1803             addr = (addr & ~0x8000) | ((y1 & 2) << 14);
1804         }
1805         update = full_update;
1806         page0 = addr;
1807         page1 = addr + bwidth - 1;
1808         update |= memory_region_get_dirty(&s->vram, page0, page1 - page0,
1809                                           DIRTY_MEMORY_VGA);
1810         /* explicit invalidation for the hardware cursor */
1811         update |= (s->invalidated_y_table[y >> 5] >> (y & 0x1f)) & 1;
1812         if (update) {
1813             if (y_start < 0)
1814                 y_start = y;
1815             if (page0 < page_min)
1816                 page_min = page0;
1817             if (page1 > page_max)
1818                 page_max = page1;
1819             if (!(is_buffer_shared(surface))) {
1820                 vga_draw_line(s, d, s->vram_ptr + addr, width);
1821                 if (s->cursor_draw_line)
1822                     s->cursor_draw_line(s, d, y);
1823             }
1824         } else {
1825             if (y_start >= 0) {
1826                 /* flush to display */
1827                 dpy_gfx_update(s->con, 0, y_start,
1828                                disp_width, y - y_start);
1829                 y_start = -1;
1830             }
1831         }
1832         if (!multi_run) {
1833             mask = (s->cr[VGA_CRTC_MODE] & 3) ^ 3;
1834             if ((y1 & mask) == mask)
1835                 addr1 += line_offset;
1836             y1++;
1837             multi_run = multi_scan;
1838         } else {
1839             multi_run--;
1840         }
1841         /* line compare acts on the displayed lines */
1842         if (y == s->line_compare)
1843             addr1 = 0;
1844         d += linesize;
1845     }
1846     if (y_start >= 0) {
1847         /* flush to display */
1848         dpy_gfx_update(s->con, 0, y_start,
1849                        disp_width, y - y_start);
1850     }
1851     /* reset modified pages */
1852     if (page_max >= page_min) {
1853         memory_region_reset_dirty(&s->vram,
1854                                   page_min,
1855                                   page_max - page_min,
1856                                   DIRTY_MEMORY_VGA);
1857     }
1858     memset(s->invalidated_y_table, 0, ((height + 31) >> 5) * 4);
1859 }
1860 
1861 static void vga_draw_blank(VGACommonState *s, int full_update)
1862 {
1863     DisplaySurface *surface = qemu_console_surface(s->con);
1864     int i, w, val;
1865     uint8_t *d;
1866 
1867     if (!full_update)
1868         return;
1869     if (s->last_scr_width <= 0 || s->last_scr_height <= 0)
1870         return;
1871 
1872     s->rgb_to_pixel =
1873         rgb_to_pixel_dup_table[get_depth_index(surface)];
1874     if (surface_bits_per_pixel(surface) == 8) {
1875         val = s->rgb_to_pixel(0, 0, 0);
1876     } else {
1877         val = 0;
1878     }
1879     w = s->last_scr_width * surface_bytes_per_pixel(surface);
1880     d = surface_data(surface);
1881     for(i = 0; i < s->last_scr_height; i++) {
1882         memset(d, val, w);
1883         d += surface_stride(surface);
1884     }
1885     dpy_gfx_update(s->con, 0, 0,
1886                    s->last_scr_width, s->last_scr_height);
1887 }
1888 
1889 #define GMODE_TEXT     0
1890 #define GMODE_GRAPH    1
1891 #define GMODE_BLANK 2
1892 
1893 static void vga_update_display(void *opaque)
1894 {
1895     VGACommonState *s = opaque;
1896     DisplaySurface *surface = qemu_console_surface(s->con);
1897     int full_update, graphic_mode;
1898 
1899     qemu_flush_coalesced_mmio_buffer();
1900 
1901     if (surface_bits_per_pixel(surface) == 0) {
1902         /* nothing to do */
1903     } else {
1904         full_update = 0;
1905         if (!(s->ar_index & 0x20)) {
1906             graphic_mode = GMODE_BLANK;
1907         } else {
1908             graphic_mode = s->gr[VGA_GFX_MISC] & VGA_GR06_GRAPHICS_MODE;
1909         }
1910         if (graphic_mode != s->graphic_mode) {
1911             s->graphic_mode = graphic_mode;
1912             s->cursor_blink_time = qemu_get_clock_ms(vm_clock);
1913             full_update = 1;
1914         }
1915         switch(graphic_mode) {
1916         case GMODE_TEXT:
1917             vga_draw_text(s, full_update);
1918             break;
1919         case GMODE_GRAPH:
1920             vga_draw_graphic(s, full_update);
1921             break;
1922         case GMODE_BLANK:
1923         default:
1924             vga_draw_blank(s, full_update);
1925             break;
1926         }
1927     }
1928 }
1929 
1930 /* force a full display refresh */
1931 static void vga_invalidate_display(void *opaque)
1932 {
1933     VGACommonState *s = opaque;
1934 
1935     s->last_width = -1;
1936     s->last_height = -1;
1937 }
1938 
1939 void vga_common_reset(VGACommonState *s)
1940 {
1941     s->sr_index = 0;
1942     memset(s->sr, '\0', sizeof(s->sr));
1943     s->gr_index = 0;
1944     memset(s->gr, '\0', sizeof(s->gr));
1945     s->ar_index = 0;
1946     memset(s->ar, '\0', sizeof(s->ar));
1947     s->ar_flip_flop = 0;
1948     s->cr_index = 0;
1949     memset(s->cr, '\0', sizeof(s->cr));
1950     s->msr = 0;
1951     s->fcr = 0;
1952     s->st00 = 0;
1953     s->st01 = 0;
1954     s->dac_state = 0;
1955     s->dac_sub_index = 0;
1956     s->dac_read_index = 0;
1957     s->dac_write_index = 0;
1958     memset(s->dac_cache, '\0', sizeof(s->dac_cache));
1959     s->dac_8bit = 0;
1960     memset(s->palette, '\0', sizeof(s->palette));
1961     s->bank_offset = 0;
1962     s->vbe_index = 0;
1963     memset(s->vbe_regs, '\0', sizeof(s->vbe_regs));
1964     s->vbe_regs[VBE_DISPI_INDEX_ID] = VBE_DISPI_ID5;
1965     s->vbe_start_addr = 0;
1966     s->vbe_line_offset = 0;
1967     s->vbe_bank_mask = (s->vram_size >> 16) - 1;
1968     memset(s->font_offsets, '\0', sizeof(s->font_offsets));
1969     s->graphic_mode = -1; /* force full update */
1970     s->shift_control = 0;
1971     s->double_scan = 0;
1972     s->line_offset = 0;
1973     s->line_compare = 0;
1974     s->start_addr = 0;
1975     s->plane_updated = 0;
1976     s->last_cw = 0;
1977     s->last_ch = 0;
1978     s->last_width = 0;
1979     s->last_height = 0;
1980     s->last_scr_width = 0;
1981     s->last_scr_height = 0;
1982     s->cursor_start = 0;
1983     s->cursor_end = 0;
1984     s->cursor_offset = 0;
1985     memset(s->invalidated_y_table, '\0', sizeof(s->invalidated_y_table));
1986     memset(s->last_palette, '\0', sizeof(s->last_palette));
1987     memset(s->last_ch_attr, '\0', sizeof(s->last_ch_attr));
1988     switch (vga_retrace_method) {
1989     case VGA_RETRACE_DUMB:
1990         break;
1991     case VGA_RETRACE_PRECISE:
1992         memset(&s->retrace_info, 0, sizeof (s->retrace_info));
1993         break;
1994     }
1995     vga_update_memory_access(s);
1996 }
1997 
1998 static void vga_reset(void *opaque)
1999 {
2000     VGACommonState *s =  opaque;
2001     vga_common_reset(s);
2002 }
2003 
2004 #define TEXTMODE_X(x)	((x) % width)
2005 #define TEXTMODE_Y(x)	((x) / width)
2006 #define VMEM2CHTYPE(v)	((v & 0xff0007ff) | \
2007         ((v & 0x00000800) << 10) | ((v & 0x00007000) >> 1))
2008 /* relay text rendering to the display driver
2009  * instead of doing a full vga_update_display() */
2010 static void vga_update_text(void *opaque, console_ch_t *chardata)
2011 {
2012     VGACommonState *s =  opaque;
2013     int graphic_mode, i, cursor_offset, cursor_visible;
2014     int cw, cheight, width, height, size, c_min, c_max;
2015     uint32_t *src;
2016     console_ch_t *dst, val;
2017     char msg_buffer[80];
2018     int full_update = 0;
2019 
2020     qemu_flush_coalesced_mmio_buffer();
2021 
2022     if (!(s->ar_index & 0x20)) {
2023         graphic_mode = GMODE_BLANK;
2024     } else {
2025         graphic_mode = s->gr[VGA_GFX_MISC] & VGA_GR06_GRAPHICS_MODE;
2026     }
2027     if (graphic_mode != s->graphic_mode) {
2028         s->graphic_mode = graphic_mode;
2029         full_update = 1;
2030     }
2031     if (s->last_width == -1) {
2032         s->last_width = 0;
2033         full_update = 1;
2034     }
2035 
2036     switch (graphic_mode) {
2037     case GMODE_TEXT:
2038         /* TODO: update palette */
2039         full_update |= update_basic_params(s);
2040 
2041         /* total width & height */
2042         cheight = (s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1;
2043         cw = 8;
2044         if (!(s->sr[VGA_SEQ_CLOCK_MODE] & VGA_SR01_CHAR_CLK_8DOTS)) {
2045             cw = 9;
2046         }
2047         if (s->sr[VGA_SEQ_CLOCK_MODE] & 0x08) {
2048             cw = 16; /* NOTE: no 18 pixel wide */
2049         }
2050         width = (s->cr[VGA_CRTC_H_DISP] + 1);
2051         if (s->cr[VGA_CRTC_V_TOTAL] == 100) {
2052             /* ugly hack for CGA 160x100x16 - explain me the logic */
2053             height = 100;
2054         } else {
2055             height = s->cr[VGA_CRTC_V_DISP_END] |
2056                 ((s->cr[VGA_CRTC_OVERFLOW] & 0x02) << 7) |
2057                 ((s->cr[VGA_CRTC_OVERFLOW] & 0x40) << 3);
2058             height = (height + 1) / cheight;
2059         }
2060 
2061         size = (height * width);
2062         if (size > CH_ATTR_SIZE) {
2063             if (!full_update)
2064                 return;
2065 
2066             snprintf(msg_buffer, sizeof(msg_buffer), "%i x %i Text mode",
2067                      width, height);
2068             break;
2069         }
2070 
2071         if (width != s->last_width || height != s->last_height ||
2072             cw != s->last_cw || cheight != s->last_ch) {
2073             s->last_scr_width = width * cw;
2074             s->last_scr_height = height * cheight;
2075             qemu_console_resize(s->con, s->last_scr_width, s->last_scr_height);
2076             dpy_text_resize(s->con, width, height);
2077             s->last_depth = 0;
2078             s->last_width = width;
2079             s->last_height = height;
2080             s->last_ch = cheight;
2081             s->last_cw = cw;
2082             full_update = 1;
2083         }
2084 
2085         if (full_update) {
2086             s->full_update_gfx = 1;
2087         }
2088         if (s->full_update_text) {
2089             s->full_update_text = 0;
2090             full_update |= 1;
2091         }
2092 
2093         /* Update "hardware" cursor */
2094         cursor_offset = ((s->cr[VGA_CRTC_CURSOR_HI] << 8) |
2095                          s->cr[VGA_CRTC_CURSOR_LO]) - s->start_addr;
2096         if (cursor_offset != s->cursor_offset ||
2097             s->cr[VGA_CRTC_CURSOR_START] != s->cursor_start ||
2098             s->cr[VGA_CRTC_CURSOR_END] != s->cursor_end || full_update) {
2099             cursor_visible = !(s->cr[VGA_CRTC_CURSOR_START] & 0x20);
2100             if (cursor_visible && cursor_offset < size && cursor_offset >= 0)
2101                 dpy_text_cursor(s->con,
2102                                 TEXTMODE_X(cursor_offset),
2103                                 TEXTMODE_Y(cursor_offset));
2104             else
2105                 dpy_text_cursor(s->con, -1, -1);
2106             s->cursor_offset = cursor_offset;
2107             s->cursor_start = s->cr[VGA_CRTC_CURSOR_START];
2108             s->cursor_end = s->cr[VGA_CRTC_CURSOR_END];
2109         }
2110 
2111         src = (uint32_t *) s->vram_ptr + s->start_addr;
2112         dst = chardata;
2113 
2114         if (full_update) {
2115             for (i = 0; i < size; src ++, dst ++, i ++)
2116                 console_write_ch(dst, VMEM2CHTYPE(le32_to_cpu(*src)));
2117 
2118             dpy_text_update(s->con, 0, 0, width, height);
2119         } else {
2120             c_max = 0;
2121 
2122             for (i = 0; i < size; src ++, dst ++, i ++) {
2123                 console_write_ch(&val, VMEM2CHTYPE(le32_to_cpu(*src)));
2124                 if (*dst != val) {
2125                     *dst = val;
2126                     c_max = i;
2127                     break;
2128                 }
2129             }
2130             c_min = i;
2131             for (; i < size; src ++, dst ++, i ++) {
2132                 console_write_ch(&val, VMEM2CHTYPE(le32_to_cpu(*src)));
2133                 if (*dst != val) {
2134                     *dst = val;
2135                     c_max = i;
2136                 }
2137             }
2138 
2139             if (c_min <= c_max) {
2140                 i = TEXTMODE_Y(c_min);
2141                 dpy_text_update(s->con, 0, i, width, TEXTMODE_Y(c_max) - i + 1);
2142             }
2143         }
2144 
2145         return;
2146     case GMODE_GRAPH:
2147         if (!full_update)
2148             return;
2149 
2150         s->get_resolution(s, &width, &height);
2151         snprintf(msg_buffer, sizeof(msg_buffer), "%i x %i Graphic mode",
2152                  width, height);
2153         break;
2154     case GMODE_BLANK:
2155     default:
2156         if (!full_update)
2157             return;
2158 
2159         snprintf(msg_buffer, sizeof(msg_buffer), "VGA Blank mode");
2160         break;
2161     }
2162 
2163     /* Display a message */
2164     s->last_width = 60;
2165     s->last_height = height = 3;
2166     dpy_text_cursor(s->con, -1, -1);
2167     dpy_text_resize(s->con, s->last_width, height);
2168 
2169     for (dst = chardata, i = 0; i < s->last_width * height; i ++)
2170         console_write_ch(dst ++, ' ');
2171 
2172     size = strlen(msg_buffer);
2173     width = (s->last_width - size) / 2;
2174     dst = chardata + s->last_width + width;
2175     for (i = 0; i < size; i ++)
2176         console_write_ch(dst ++, 0x00200100 | msg_buffer[i]);
2177 
2178     dpy_text_update(s->con, 0, 0, s->last_width, height);
2179 }
2180 
2181 static uint64_t vga_mem_read(void *opaque, hwaddr addr,
2182                              unsigned size)
2183 {
2184     VGACommonState *s = opaque;
2185 
2186     return vga_mem_readb(s, addr);
2187 }
2188 
2189 static void vga_mem_write(void *opaque, hwaddr addr,
2190                           uint64_t data, unsigned size)
2191 {
2192     VGACommonState *s = opaque;
2193 
2194     return vga_mem_writeb(s, addr, data);
2195 }
2196 
2197 const MemoryRegionOps vga_mem_ops = {
2198     .read = vga_mem_read,
2199     .write = vga_mem_write,
2200     .endianness = DEVICE_LITTLE_ENDIAN,
2201     .impl = {
2202         .min_access_size = 1,
2203         .max_access_size = 1,
2204     },
2205 };
2206 
2207 static int vga_common_post_load(void *opaque, int version_id)
2208 {
2209     VGACommonState *s = opaque;
2210 
2211     /* force refresh */
2212     s->graphic_mode = -1;
2213     return 0;
2214 }
2215 
2216 const VMStateDescription vmstate_vga_common = {
2217     .name = "vga",
2218     .version_id = 2,
2219     .minimum_version_id = 2,
2220     .minimum_version_id_old = 2,
2221     .post_load = vga_common_post_load,
2222     .fields      = (VMStateField []) {
2223         VMSTATE_UINT32(latch, VGACommonState),
2224         VMSTATE_UINT8(sr_index, VGACommonState),
2225         VMSTATE_PARTIAL_BUFFER(sr, VGACommonState, 8),
2226         VMSTATE_UINT8(gr_index, VGACommonState),
2227         VMSTATE_PARTIAL_BUFFER(gr, VGACommonState, 16),
2228         VMSTATE_UINT8(ar_index, VGACommonState),
2229         VMSTATE_BUFFER(ar, VGACommonState),
2230         VMSTATE_INT32(ar_flip_flop, VGACommonState),
2231         VMSTATE_UINT8(cr_index, VGACommonState),
2232         VMSTATE_BUFFER(cr, VGACommonState),
2233         VMSTATE_UINT8(msr, VGACommonState),
2234         VMSTATE_UINT8(fcr, VGACommonState),
2235         VMSTATE_UINT8(st00, VGACommonState),
2236         VMSTATE_UINT8(st01, VGACommonState),
2237 
2238         VMSTATE_UINT8(dac_state, VGACommonState),
2239         VMSTATE_UINT8(dac_sub_index, VGACommonState),
2240         VMSTATE_UINT8(dac_read_index, VGACommonState),
2241         VMSTATE_UINT8(dac_write_index, VGACommonState),
2242         VMSTATE_BUFFER(dac_cache, VGACommonState),
2243         VMSTATE_BUFFER(palette, VGACommonState),
2244 
2245         VMSTATE_INT32(bank_offset, VGACommonState),
2246         VMSTATE_UINT8_EQUAL(is_vbe_vmstate, VGACommonState),
2247         VMSTATE_UINT16(vbe_index, VGACommonState),
2248         VMSTATE_UINT16_ARRAY(vbe_regs, VGACommonState, VBE_DISPI_INDEX_NB),
2249         VMSTATE_UINT32(vbe_start_addr, VGACommonState),
2250         VMSTATE_UINT32(vbe_line_offset, VGACommonState),
2251         VMSTATE_UINT32(vbe_bank_mask, VGACommonState),
2252         VMSTATE_END_OF_LIST()
2253     }
2254 };
2255 
2256 void vga_common_init(VGACommonState *s)
2257 {
2258     int i, j, v, b;
2259 
2260     for(i = 0;i < 256; i++) {
2261         v = 0;
2262         for(j = 0; j < 8; j++) {
2263             v |= ((i >> j) & 1) << (j * 4);
2264         }
2265         expand4[i] = v;
2266 
2267         v = 0;
2268         for(j = 0; j < 4; j++) {
2269             v |= ((i >> (2 * j)) & 3) << (j * 4);
2270         }
2271         expand2[i] = v;
2272     }
2273     for(i = 0; i < 16; i++) {
2274         v = 0;
2275         for(j = 0; j < 4; j++) {
2276             b = ((i >> j) & 1);
2277             v |= b << (2 * j);
2278             v |= b << (2 * j + 1);
2279         }
2280         expand4to8[i] = v;
2281     }
2282 
2283     /* valid range: 1 MB -> 256 MB */
2284     s->vram_size = 1024 * 1024;
2285     while (s->vram_size < (s->vram_size_mb << 20) &&
2286            s->vram_size < (256 << 20)) {
2287         s->vram_size <<= 1;
2288     }
2289     s->vram_size_mb = s->vram_size >> 20;
2290 
2291     s->is_vbe_vmstate = 1;
2292     memory_region_init_ram(&s->vram, "vga.vram", s->vram_size);
2293     vmstate_register_ram_global(&s->vram);
2294     xen_register_framebuffer(&s->vram);
2295     s->vram_ptr = memory_region_get_ram_ptr(&s->vram);
2296     s->get_bpp = vga_get_bpp;
2297     s->get_offsets = vga_get_offsets;
2298     s->get_resolution = vga_get_resolution;
2299     s->update = vga_update_display;
2300     s->invalidate = vga_invalidate_display;
2301     s->screen_dump = vga_screen_dump;
2302     s->text_update = vga_update_text;
2303     switch (vga_retrace_method) {
2304     case VGA_RETRACE_DUMB:
2305         s->retrace = vga_dumb_retrace;
2306         s->update_retrace_info = vga_dumb_update_retrace_info;
2307         break;
2308 
2309     case VGA_RETRACE_PRECISE:
2310         s->retrace = vga_precise_retrace;
2311         s->update_retrace_info = vga_precise_update_retrace_info;
2312         break;
2313     }
2314     vga_dirty_log_start(s);
2315 }
2316 
2317 static const MemoryRegionPortio vga_portio_list[] = {
2318     { 0x04,  2, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3b4 */
2319     { 0x0a,  1, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3ba */
2320     { 0x10, 16, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3c0 */
2321     { 0x24,  2, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3d4 */
2322     { 0x2a,  1, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3da */
2323     PORTIO_END_OF_LIST(),
2324 };
2325 
2326 static const MemoryRegionPortio vbe_portio_list[] = {
2327     { 0, 1, 2, .read = vbe_ioport_read_index, .write = vbe_ioport_write_index },
2328 # ifdef TARGET_I386
2329     { 1, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data },
2330 # endif
2331     { 2, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data },
2332     PORTIO_END_OF_LIST(),
2333 };
2334 
2335 /* Used by both ISA and PCI */
2336 MemoryRegion *vga_init_io(VGACommonState *s,
2337                           const MemoryRegionPortio **vga_ports,
2338                           const MemoryRegionPortio **vbe_ports)
2339 {
2340     MemoryRegion *vga_mem;
2341 
2342     *vga_ports = vga_portio_list;
2343     *vbe_ports = vbe_portio_list;
2344 
2345     vga_mem = g_malloc(sizeof(*vga_mem));
2346     memory_region_init_io(vga_mem, &vga_mem_ops, s,
2347                           "vga-lowmem", 0x20000);
2348     memory_region_set_flush_coalesced(vga_mem);
2349 
2350     return vga_mem;
2351 }
2352 
2353 void vga_init(VGACommonState *s, MemoryRegion *address_space,
2354               MemoryRegion *address_space_io, bool init_vga_ports)
2355 {
2356     MemoryRegion *vga_io_memory;
2357     const MemoryRegionPortio *vga_ports, *vbe_ports;
2358     PortioList *vga_port_list = g_new(PortioList, 1);
2359     PortioList *vbe_port_list = g_new(PortioList, 1);
2360 
2361     qemu_register_reset(vga_reset, s);
2362 
2363     s->bank_offset = 0;
2364 
2365     s->legacy_address_space = address_space;
2366 
2367     vga_io_memory = vga_init_io(s, &vga_ports, &vbe_ports);
2368     memory_region_add_subregion_overlap(address_space,
2369                                         isa_mem_base + 0x000a0000,
2370                                         vga_io_memory,
2371                                         1);
2372     memory_region_set_coalescing(vga_io_memory);
2373     if (init_vga_ports) {
2374         portio_list_init(vga_port_list, vga_ports, s, "vga");
2375         portio_list_add(vga_port_list, address_space_io, 0x3b0);
2376     }
2377     if (vbe_ports) {
2378         portio_list_init(vbe_port_list, vbe_ports, s, "vbe");
2379         portio_list_add(vbe_port_list, address_space_io, 0x1ce);
2380     }
2381 }
2382 
2383 void vga_init_vbe(VGACommonState *s, MemoryRegion *system_memory)
2384 {
2385     /* With pc-0.12 and below we map both the PCI BAR and the fixed VBE region,
2386      * so use an alias to avoid double-mapping the same region.
2387      */
2388     memory_region_init_alias(&s->vram_vbe, "vram.vbe",
2389                              &s->vram, 0, memory_region_size(&s->vram));
2390     /* XXX: use optimized standard vga accesses */
2391     memory_region_add_subregion(system_memory,
2392                                 VBE_DISPI_LFB_PHYSICAL_ADDRESS,
2393                                 &s->vram_vbe);
2394     s->vbe_mapped = 1;
2395 }
2396 /********************************************************/
2397 /* vga screen dump */
2398 
2399 void ppm_save(const char *filename, struct DisplaySurface *ds, Error **errp)
2400 {
2401     int width = pixman_image_get_width(ds->image);
2402     int height = pixman_image_get_height(ds->image);
2403     FILE *f;
2404     int y;
2405     int ret;
2406     pixman_image_t *linebuf;
2407 
2408     trace_ppm_save(filename, ds);
2409     f = fopen(filename, "wb");
2410     if (!f) {
2411         error_setg(errp, "failed to open file '%s': %s", filename,
2412                    strerror(errno));
2413         return;
2414     }
2415     ret = fprintf(f, "P6\n%d %d\n%d\n", width, height, 255);
2416     if (ret < 0) {
2417         linebuf = NULL;
2418         goto write_err;
2419     }
2420     linebuf = qemu_pixman_linebuf_create(PIXMAN_BE_r8g8b8, width);
2421     for (y = 0; y < height; y++) {
2422         qemu_pixman_linebuf_fill(linebuf, ds->image, width, 0, y);
2423         clearerr(f);
2424         ret = fwrite(pixman_image_get_data(linebuf), 1,
2425                      pixman_image_get_stride(linebuf), f);
2426         (void)ret;
2427         if (ferror(f)) {
2428             goto write_err;
2429         }
2430     }
2431 
2432 out:
2433     qemu_pixman_image_unref(linebuf);
2434     fclose(f);
2435     return;
2436 
2437 write_err:
2438     error_setg(errp, "failed to write to file '%s': %s", filename,
2439                strerror(errno));
2440     unlink(filename);
2441     goto out;
2442 }
2443 
2444 /* save the vga display in a PPM image even if no display is
2445    available */
2446 static void vga_screen_dump(void *opaque, const char *filename, bool cswitch,
2447                             Error **errp)
2448 {
2449     VGACommonState *s = opaque;
2450     DisplaySurface *surface = qemu_console_surface(s->con);
2451 
2452     if (cswitch) {
2453         vga_invalidate_display(s);
2454     }
2455     vga_hw_update();
2456     ppm_save(filename, surface, errp);
2457 }
2458