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