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