xref: /qemu/hw/display/vga.c (revision 9c707525)
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/core/cpu.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 share_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     region_start = (s->params.start_addr * 4);
1505     region_end = region_start + (ram_addr_t)s->params.line_offset * height;
1506     region_end += width * depth / 8; /* scanline length */
1507     region_end -= s->params.line_offset;
1508     if (region_end > s->vbe_size || depth == 0 || depth == 15) {
1509         /*
1510          * We land here on:
1511          *  - wraps around (can happen with cirrus vbe modes)
1512          *  - depth == 0 (256 color palette video mode)
1513          *  - depth == 15
1514          *
1515          * Take the safe and slow route:
1516          *   - create a dirty bitmap snapshot for all vga memory.
1517          *   - force shadowing (so all vga memory access goes
1518          *     through vga_read_*() helpers).
1519          *
1520          * Given this affects only vga features which are pretty much
1521          * unused by modern guests there should be no performance
1522          * impact.
1523          */
1524         region_start = 0;
1525         region_end = s->vbe_size;
1526         force_shadow = true;
1527     }
1528 
1529     /* bits 5-6: 0 = 16-color mode, 1 = 4-color mode, 2 = 256-color mode.  */
1530     shift_control = (s->gr[VGA_GFX_MODE] >> 5) & 3;
1531     double_scan = (s->cr[VGA_CRTC_MAX_SCAN] >> 7);
1532     if (s->cr[VGA_CRTC_MODE] & 1) {
1533         multi_scan = (((s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1) << double_scan)
1534             - 1;
1535     } else {
1536         /* in CGA modes, multi_scan is ignored */
1537         /* XXX: is it correct ? */
1538         multi_scan = double_scan;
1539     }
1540     multi_run = multi_scan;
1541     if (shift_control != s->shift_control ||
1542         double_scan != s->double_scan) {
1543         full_update = 1;
1544         s->shift_control = shift_control;
1545         s->double_scan = double_scan;
1546     }
1547 
1548     if (shift_control == 0) {
1549         if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) {
1550             disp_width <<= 1;
1551         }
1552     } else if (shift_control == 1) {
1553         if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) {
1554             disp_width <<= 1;
1555         }
1556     }
1557 
1558     /*
1559      * Check whether we can share the surface with the backend
1560      * or whether we need a shadow surface. We share native
1561      * endian surfaces for 15bpp and above and byteswapped
1562      * surfaces for 24bpp and above.
1563      */
1564     format = qemu_default_pixman_format(depth, !byteswap);
1565     if (format) {
1566         share_surface = dpy_gfx_check_format(s->con, format)
1567             && !s->force_shadow && !force_shadow;
1568     } else {
1569         share_surface = false;
1570     }
1571 
1572     if (s->params.line_offset != s->last_line_offset ||
1573         disp_width != s->last_width ||
1574         height != s->last_height ||
1575         s->last_depth != depth ||
1576         s->last_byteswap != byteswap ||
1577         share_surface != is_buffer_shared(surface)) {
1578         /* display parameters changed -> need new display surface */
1579         s->last_scr_width = disp_width;
1580         s->last_scr_height = height;
1581         s->last_width = disp_width;
1582         s->last_height = height;
1583         s->last_line_offset = s->params.line_offset;
1584         s->last_depth = depth;
1585         s->last_byteswap = byteswap;
1586         /* 16 extra pixels are needed for double-width planar modes.  */
1587         s->panning_buf = g_realloc(s->panning_buf,
1588                                    (disp_width + 16) * sizeof(uint32_t));
1589         full_update = 1;
1590     }
1591     if (surface_data(surface) != s->vram_ptr + (s->params.start_addr * 4)
1592         && is_buffer_shared(surface)) {
1593         /* base address changed (page flip) -> shared display surfaces
1594          * must be updated with the new base address */
1595         full_update = 1;
1596     }
1597 
1598     if (full_update) {
1599         if (share_surface) {
1600             surface = qemu_create_displaysurface_from(disp_width,
1601                     height, format, s->params.line_offset,
1602                     s->vram_ptr + (s->params.start_addr * 4));
1603             dpy_gfx_replace_surface(s->con, surface);
1604         } else {
1605             qemu_console_resize(s->con, disp_width, height);
1606             surface = qemu_console_surface(s->con);
1607         }
1608     }
1609 
1610     if (shift_control == 0) {
1611         full_update |= update_palette16(s);
1612         if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) {
1613             v = VGA_DRAW_LINE4D2;
1614         } else {
1615             v = VGA_DRAW_LINE4;
1616         }
1617         bits = 4;
1618     } else if (shift_control == 1) {
1619         full_update |= update_palette16(s);
1620         if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) {
1621             v = VGA_DRAW_LINE2D2;
1622         } else {
1623             v = VGA_DRAW_LINE2;
1624         }
1625         bits = 4;
1626     } else {
1627         switch(s->get_bpp(s)) {
1628         default:
1629         case 0:
1630             full_update |= update_palette256(s);
1631             v = VGA_DRAW_LINE8D2;
1632             bits = 4;
1633             break;
1634         case 8:
1635             full_update |= update_palette256(s);
1636             v = VGA_DRAW_LINE8;
1637             bits = 8;
1638             break;
1639         case 15:
1640             v = s->big_endian_fb ? VGA_DRAW_LINE15_BE : VGA_DRAW_LINE15_LE;
1641             bits = 16;
1642             break;
1643         case 16:
1644             v = s->big_endian_fb ? VGA_DRAW_LINE16_BE : VGA_DRAW_LINE16_LE;
1645             bits = 16;
1646             break;
1647         case 24:
1648             v = s->big_endian_fb ? VGA_DRAW_LINE24_BE : VGA_DRAW_LINE24_LE;
1649             bits = 24;
1650             break;
1651         case 32:
1652             v = s->big_endian_fb ? VGA_DRAW_LINE32_BE : VGA_DRAW_LINE32_LE;
1653             bits = 32;
1654             break;
1655         }
1656     }
1657     vga_draw_line = vga_draw_line_table[v];
1658 
1659     if (!is_buffer_shared(surface) && s->cursor_invalidate) {
1660         s->cursor_invalidate(s);
1661     }
1662 
1663 #if 0
1664     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",
1665            width, height, v, line_offset, s->cr[9], s->cr[VGA_CRTC_MODE],
1666            s->params.line_compare, sr(s, VGA_SEQ_CLOCK_MODE));
1667 #endif
1668     hpel = bits <= 8 ? s->params.hpel : 0;
1669     addr1 = (s->params.start_addr * 4);
1670     bwidth = DIV_ROUND_UP(width * bits, 8);
1671     if (hpel) {
1672         bwidth += 4;
1673     }
1674     y_start = -1;
1675     d = surface_data(surface);
1676     linesize = surface_stride(surface);
1677     y1 = 0;
1678 
1679     if (!full_update) {
1680         if (s->params.line_compare < height) {
1681             /* split screen mode */
1682             region_start = 0;
1683         }
1684         snap = memory_region_snapshot_and_clear_dirty(&s->vram, region_start,
1685                                                       region_end - region_start,
1686                                                       DIRTY_MEMORY_VGA);
1687     }
1688 
1689     for(y = 0; y < height; y++) {
1690         addr = addr1;
1691         if (!(s->cr[VGA_CRTC_MODE] & 1)) {
1692             int shift;
1693             /* CGA compatibility handling */
1694             shift = 14 + ((s->cr[VGA_CRTC_MODE] >> 6) & 1);
1695             addr = (addr & ~(1 << shift)) | ((y1 & 1) << shift);
1696         }
1697         if (!(s->cr[VGA_CRTC_MODE] & 2)) {
1698             addr = (addr & ~0x8000) | ((y1 & 2) << 14);
1699         }
1700         page0 = addr & s->vbe_size_mask;
1701         page1 = (addr + bwidth - 1) & s->vbe_size_mask;
1702         if (full_update) {
1703             update = 1;
1704         } else if (page1 < page0) {
1705             /* scanline wraps from end of video memory to the start */
1706             assert(force_shadow);
1707             update = memory_region_snapshot_get_dirty(&s->vram, snap,
1708                                                       page0, s->vbe_size - page0);
1709             update |= memory_region_snapshot_get_dirty(&s->vram, snap,
1710                                                        0, page1);
1711         } else {
1712             update = memory_region_snapshot_get_dirty(&s->vram, snap,
1713                                                       page0, page1 - page0);
1714         }
1715         /* explicit invalidation for the hardware cursor (cirrus only) */
1716         update |= vga_scanline_invalidated(s, y);
1717         if (update) {
1718             if (y_start < 0)
1719                 y_start = y;
1720             if (!(is_buffer_shared(surface))) {
1721                 uint8_t *p;
1722                 p = vga_draw_line(s, d, addr, width, hpel);
1723                 if (p) {
1724                     memcpy(d, p, disp_width * sizeof(uint32_t));
1725                 }
1726                 if (s->cursor_draw_line)
1727                     s->cursor_draw_line(s, d, y);
1728             }
1729         } else {
1730             if (y_start >= 0) {
1731                 /* flush to display */
1732                 dpy_gfx_update(s->con, 0, y_start,
1733                                disp_width, y - y_start);
1734                 y_start = -1;
1735             }
1736         }
1737         if (!multi_run) {
1738             mask = (s->cr[VGA_CRTC_MODE] & 3) ^ 3;
1739             if ((y1 & mask) == mask)
1740                 addr1 += s->params.line_offset;
1741             y1++;
1742             multi_run = multi_scan;
1743         } else {
1744             multi_run--;
1745         }
1746         /* line compare acts on the displayed lines */
1747         if (y == s->params.line_compare) {
1748             if (s->params.hpel_split) {
1749                 hpel = VGA_HPEL_NEUTRAL;
1750             }
1751             addr1 = 0;
1752         }
1753         d += linesize;
1754     }
1755     if (y_start >= 0) {
1756         /* flush to display */
1757         dpy_gfx_update(s->con, 0, y_start,
1758                        disp_width, y - y_start);
1759     }
1760     g_free(snap);
1761     memset(s->invalidated_y_table, 0, sizeof(s->invalidated_y_table));
1762 }
1763 
1764 static void vga_draw_blank(VGACommonState *s, int full_update)
1765 {
1766     DisplaySurface *surface = qemu_console_surface(s->con);
1767     int i, w;
1768     uint8_t *d;
1769 
1770     if (!full_update)
1771         return;
1772     if (s->last_scr_width <= 0 || s->last_scr_height <= 0)
1773         return;
1774 
1775     w = s->last_scr_width * surface_bytes_per_pixel(surface);
1776     d = surface_data(surface);
1777     for(i = 0; i < s->last_scr_height; i++) {
1778         memset(d, 0, w);
1779         d += surface_stride(surface);
1780     }
1781     dpy_gfx_update_full(s->con);
1782 }
1783 
1784 #define GMODE_TEXT     0
1785 #define GMODE_GRAPH    1
1786 #define GMODE_BLANK 2
1787 
1788 static void vga_update_display(void *opaque)
1789 {
1790     VGACommonState *s = opaque;
1791     DisplaySurface *surface = qemu_console_surface(s->con);
1792     int full_update, graphic_mode;
1793 
1794     qemu_flush_coalesced_mmio_buffer();
1795 
1796     if (surface_bits_per_pixel(surface) == 0) {
1797         /* nothing to do */
1798     } else {
1799         full_update = 0;
1800         if (!(s->ar_index & 0x20)) {
1801             graphic_mode = GMODE_BLANK;
1802         } else {
1803             graphic_mode = s->gr[VGA_GFX_MISC] & VGA_GR06_GRAPHICS_MODE;
1804         }
1805         if (graphic_mode != s->graphic_mode) {
1806             s->graphic_mode = graphic_mode;
1807             s->cursor_blink_time = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
1808             full_update = 1;
1809         }
1810         switch(graphic_mode) {
1811         case GMODE_TEXT:
1812             vga_draw_text(s, full_update);
1813             break;
1814         case GMODE_GRAPH:
1815             vga_draw_graphic(s, full_update);
1816             break;
1817         case GMODE_BLANK:
1818         default:
1819             vga_draw_blank(s, full_update);
1820             break;
1821         }
1822     }
1823 }
1824 
1825 /* force a full display refresh */
1826 static void vga_invalidate_display(void *opaque)
1827 {
1828     VGACommonState *s = opaque;
1829 
1830     s->last_width = -1;
1831     s->last_height = -1;
1832 }
1833 
1834 void vga_common_reset(VGACommonState *s)
1835 {
1836     s->sr_index = 0;
1837     memset(s->sr, '\0', sizeof(s->sr));
1838     memset(s->sr_vbe, '\0', sizeof(s->sr_vbe));
1839     s->gr_index = 0;
1840     memset(s->gr, '\0', sizeof(s->gr));
1841     s->ar_index = 0;
1842     memset(s->ar, '\0', sizeof(s->ar));
1843     s->ar_flip_flop = 0;
1844     s->cr_index = 0;
1845     memset(s->cr, '\0', sizeof(s->cr));
1846     s->msr = 0;
1847     s->fcr = 0;
1848     s->st00 = 0;
1849     s->st01 = 0;
1850     s->dac_state = 0;
1851     s->dac_sub_index = 0;
1852     s->dac_read_index = 0;
1853     s->dac_write_index = 0;
1854     memset(s->dac_cache, '\0', sizeof(s->dac_cache));
1855     s->dac_8bit = 0;
1856     memset(s->palette, '\0', sizeof(s->palette));
1857     s->bank_offset = 0;
1858     s->vbe_index = 0;
1859     memset(s->vbe_regs, '\0', sizeof(s->vbe_regs));
1860     s->vbe_regs[VBE_DISPI_INDEX_ID] = VBE_DISPI_ID5;
1861     s->vbe_start_addr = 0;
1862     s->vbe_line_offset = 0;
1863     s->vbe_bank_mask = (s->vram_size >> 16) - 1;
1864     memset(s->font_offsets, '\0', sizeof(s->font_offsets));
1865     s->graphic_mode = -1; /* force full update */
1866     s->shift_control = 0;
1867     s->double_scan = 0;
1868     memset(&s->params, '\0', sizeof(s->params));
1869     s->plane_updated = 0;
1870     s->last_cw = 0;
1871     s->last_ch = 0;
1872     s->last_width = 0;
1873     s->last_height = 0;
1874     s->last_scr_width = 0;
1875     s->last_scr_height = 0;
1876     s->cursor_start = 0;
1877     s->cursor_end = 0;
1878     s->cursor_offset = 0;
1879     s->big_endian_fb = s->default_endian_fb;
1880     memset(s->invalidated_y_table, '\0', sizeof(s->invalidated_y_table));
1881     memset(s->last_palette, '\0', sizeof(s->last_palette));
1882     memset(s->last_ch_attr, '\0', sizeof(s->last_ch_attr));
1883     switch (vga_retrace_method) {
1884     case VGA_RETRACE_DUMB:
1885         break;
1886     case VGA_RETRACE_PRECISE:
1887         memset(&s->retrace_info, 0, sizeof (s->retrace_info));
1888         break;
1889     }
1890     vga_update_memory_access(s);
1891 }
1892 
1893 static void vga_reset(void *opaque)
1894 {
1895     VGACommonState *s =  opaque;
1896     vga_common_reset(s);
1897 }
1898 
1899 #define TEXTMODE_X(x)	((x) % width)
1900 #define TEXTMODE_Y(x)	((x) / width)
1901 #define VMEM2CHTYPE(v)	((v & 0xff0007ff) | \
1902         ((v & 0x00000800) << 10) | ((v & 0x00007000) >> 1))
1903 /* relay text rendering to the display driver
1904  * instead of doing a full vga_update_display() */
1905 static void vga_update_text(void *opaque, console_ch_t *chardata)
1906 {
1907     VGACommonState *s =  opaque;
1908     int graphic_mode, i, cursor_offset, cursor_visible;
1909     int cw, cheight, width, height, size, c_min, c_max;
1910     uint32_t *src;
1911     console_ch_t *dst, val;
1912     char msg_buffer[80];
1913     int full_update = 0;
1914 
1915     qemu_flush_coalesced_mmio_buffer();
1916 
1917     if (!(s->ar_index & 0x20)) {
1918         graphic_mode = GMODE_BLANK;
1919     } else {
1920         graphic_mode = s->gr[VGA_GFX_MISC] & VGA_GR06_GRAPHICS_MODE;
1921     }
1922     if (graphic_mode != s->graphic_mode) {
1923         s->graphic_mode = graphic_mode;
1924         full_update = 1;
1925     }
1926     if (s->last_width == -1) {
1927         s->last_width = 0;
1928         full_update = 1;
1929     }
1930 
1931     switch (graphic_mode) {
1932     case GMODE_TEXT:
1933         /* TODO: update palette */
1934         full_update |= update_basic_params(s);
1935 
1936         /* total width & height */
1937         cheight = (s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1;
1938         cw = 8;
1939         if (!(sr(s, VGA_SEQ_CLOCK_MODE) & VGA_SR01_CHAR_CLK_8DOTS)) {
1940             cw = 9;
1941         }
1942         if (sr(s, VGA_SEQ_CLOCK_MODE) & 0x08) {
1943             cw = 16; /* NOTE: no 18 pixel wide */
1944         }
1945         width = (s->cr[VGA_CRTC_H_DISP] + 1);
1946         if (s->cr[VGA_CRTC_V_TOTAL] == 100) {
1947             /* ugly hack for CGA 160x100x16 - explain me the logic */
1948             height = 100;
1949         } else {
1950             height = s->cr[VGA_CRTC_V_DISP_END] |
1951                 ((s->cr[VGA_CRTC_OVERFLOW] & 0x02) << 7) |
1952                 ((s->cr[VGA_CRTC_OVERFLOW] & 0x40) << 3);
1953             height = (height + 1) / cheight;
1954         }
1955 
1956         size = (height * width);
1957         if (size > CH_ATTR_SIZE) {
1958             if (!full_update)
1959                 return;
1960 
1961             snprintf(msg_buffer, sizeof(msg_buffer), "%i x %i Text mode",
1962                      width, height);
1963             break;
1964         }
1965 
1966         if (width != s->last_width || height != s->last_height ||
1967             cw != s->last_cw || cheight != s->last_ch) {
1968             s->last_scr_width = width * cw;
1969             s->last_scr_height = height * cheight;
1970             qemu_console_resize(s->con, s->last_scr_width, s->last_scr_height);
1971             dpy_text_resize(s->con, width, height);
1972             s->last_depth = 0;
1973             s->last_width = width;
1974             s->last_height = height;
1975             s->last_ch = cheight;
1976             s->last_cw = cw;
1977             full_update = 1;
1978         }
1979 
1980         if (full_update) {
1981             s->full_update_gfx = 1;
1982         }
1983         if (s->full_update_text) {
1984             s->full_update_text = 0;
1985             full_update |= 1;
1986         }
1987 
1988         /* Update "hardware" cursor */
1989         cursor_offset = ((s->cr[VGA_CRTC_CURSOR_HI] << 8) |
1990                          s->cr[VGA_CRTC_CURSOR_LO]) - s->params.start_addr;
1991         if (cursor_offset != s->cursor_offset ||
1992             s->cr[VGA_CRTC_CURSOR_START] != s->cursor_start ||
1993             s->cr[VGA_CRTC_CURSOR_END] != s->cursor_end || full_update) {
1994             cursor_visible = !(s->cr[VGA_CRTC_CURSOR_START] & 0x20);
1995             if (cursor_visible && cursor_offset < size && cursor_offset >= 0)
1996                 dpy_text_cursor(s->con,
1997                                 TEXTMODE_X(cursor_offset),
1998                                 TEXTMODE_Y(cursor_offset));
1999             else
2000                 dpy_text_cursor(s->con, -1, -1);
2001             s->cursor_offset = cursor_offset;
2002             s->cursor_start = s->cr[VGA_CRTC_CURSOR_START];
2003             s->cursor_end = s->cr[VGA_CRTC_CURSOR_END];
2004         }
2005 
2006         src = (uint32_t *) s->vram_ptr + s->params.start_addr;
2007         dst = chardata;
2008 
2009         if (full_update) {
2010             for (i = 0; i < size; src ++, dst ++, i ++)
2011                 console_write_ch(dst, VMEM2CHTYPE(le32_to_cpu(*src)));
2012 
2013             dpy_text_update(s->con, 0, 0, width, height);
2014         } else {
2015             c_max = 0;
2016 
2017             for (i = 0; i < size; src ++, dst ++, i ++) {
2018                 console_write_ch(&val, VMEM2CHTYPE(le32_to_cpu(*src)));
2019                 if (*dst != val) {
2020                     *dst = val;
2021                     c_max = i;
2022                     break;
2023                 }
2024             }
2025             c_min = i;
2026             for (; i < size; src ++, dst ++, i ++) {
2027                 console_write_ch(&val, VMEM2CHTYPE(le32_to_cpu(*src)));
2028                 if (*dst != val) {
2029                     *dst = val;
2030                     c_max = i;
2031                 }
2032             }
2033 
2034             if (c_min <= c_max) {
2035                 i = TEXTMODE_Y(c_min);
2036                 dpy_text_update(s->con, 0, i, width, TEXTMODE_Y(c_max) - i + 1);
2037             }
2038         }
2039 
2040         return;
2041     case GMODE_GRAPH:
2042         if (!full_update)
2043             return;
2044 
2045         s->get_resolution(s, &width, &height);
2046         snprintf(msg_buffer, sizeof(msg_buffer), "%i x %i Graphic mode",
2047                  width, height);
2048         break;
2049     case GMODE_BLANK:
2050     default:
2051         if (!full_update)
2052             return;
2053 
2054         snprintf(msg_buffer, sizeof(msg_buffer), "VGA Blank mode");
2055         break;
2056     }
2057 
2058     /* Display a message */
2059     s->last_width = 60;
2060     s->last_height = height = 3;
2061     dpy_text_cursor(s->con, -1, -1);
2062     dpy_text_resize(s->con, s->last_width, height);
2063 
2064     for (dst = chardata, i = 0; i < s->last_width * height; i ++)
2065         console_write_ch(dst ++, ' ');
2066 
2067     size = strlen(msg_buffer);
2068     width = (s->last_width - size) / 2;
2069     dst = chardata + s->last_width + width;
2070     for (i = 0; i < size; i ++)
2071         console_write_ch(dst ++, ATTR2CHTYPE(msg_buffer[i], QEMU_COLOR_BLUE,
2072                                              QEMU_COLOR_BLACK, 1));
2073 
2074     dpy_text_update(s->con, 0, 0, s->last_width, height);
2075 }
2076 
2077 static uint64_t vga_mem_read(void *opaque, hwaddr addr,
2078                              unsigned size)
2079 {
2080     VGACommonState *s = opaque;
2081 
2082     return vga_mem_readb(s, addr);
2083 }
2084 
2085 static void vga_mem_write(void *opaque, hwaddr addr,
2086                           uint64_t data, unsigned size)
2087 {
2088     VGACommonState *s = opaque;
2089 
2090     vga_mem_writeb(s, addr, data);
2091 }
2092 
2093 const MemoryRegionOps vga_mem_ops = {
2094     .read = vga_mem_read,
2095     .write = vga_mem_write,
2096     .endianness = DEVICE_LITTLE_ENDIAN,
2097     .impl = {
2098         .min_access_size = 1,
2099         .max_access_size = 1,
2100     },
2101 };
2102 
2103 static int vga_common_post_load(void *opaque, int version_id)
2104 {
2105     VGACommonState *s = opaque;
2106 
2107     /* force refresh */
2108     s->graphic_mode = -1;
2109     vbe_update_vgaregs(s);
2110     vga_update_memory_access(s);
2111     return 0;
2112 }
2113 
2114 static bool vga_endian_state_needed(void *opaque)
2115 {
2116     VGACommonState *s = opaque;
2117 
2118     /*
2119      * Only send the endian state if it's different from the
2120      * default one, thus ensuring backward compatibility for
2121      * migration of the common case
2122      */
2123     return s->default_endian_fb != s->big_endian_fb;
2124 }
2125 
2126 static const VMStateDescription vmstate_vga_endian = {
2127     .name = "vga.endian",
2128     .version_id = 1,
2129     .minimum_version_id = 1,
2130     .needed = vga_endian_state_needed,
2131     .fields = (const VMStateField[]) {
2132         VMSTATE_BOOL(big_endian_fb, VGACommonState),
2133         VMSTATE_END_OF_LIST()
2134     }
2135 };
2136 
2137 const VMStateDescription vmstate_vga_common = {
2138     .name = "vga",
2139     .version_id = 2,
2140     .minimum_version_id = 2,
2141     .post_load = vga_common_post_load,
2142     .fields = (const VMStateField[]) {
2143         VMSTATE_UINT32(latch, VGACommonState),
2144         VMSTATE_UINT8(sr_index, VGACommonState),
2145         VMSTATE_PARTIAL_BUFFER(sr, VGACommonState, 8),
2146         VMSTATE_UINT8(gr_index, VGACommonState),
2147         VMSTATE_PARTIAL_BUFFER(gr, VGACommonState, 16),
2148         VMSTATE_UINT8(ar_index, VGACommonState),
2149         VMSTATE_BUFFER(ar, VGACommonState),
2150         VMSTATE_INT32(ar_flip_flop, VGACommonState),
2151         VMSTATE_UINT8(cr_index, VGACommonState),
2152         VMSTATE_BUFFER(cr, VGACommonState),
2153         VMSTATE_UINT8(msr, VGACommonState),
2154         VMSTATE_UINT8(fcr, VGACommonState),
2155         VMSTATE_UINT8(st00, VGACommonState),
2156         VMSTATE_UINT8(st01, VGACommonState),
2157 
2158         VMSTATE_UINT8(dac_state, VGACommonState),
2159         VMSTATE_UINT8(dac_sub_index, VGACommonState),
2160         VMSTATE_UINT8(dac_read_index, VGACommonState),
2161         VMSTATE_UINT8(dac_write_index, VGACommonState),
2162         VMSTATE_BUFFER(dac_cache, VGACommonState),
2163         VMSTATE_BUFFER(palette, VGACommonState),
2164 
2165         VMSTATE_INT32(bank_offset, VGACommonState),
2166         VMSTATE_UINT8_EQUAL(is_vbe_vmstate, VGACommonState, NULL),
2167         VMSTATE_UINT16(vbe_index, VGACommonState),
2168         VMSTATE_UINT16_ARRAY(vbe_regs, VGACommonState, VBE_DISPI_INDEX_NB),
2169         VMSTATE_UINT32(vbe_start_addr, VGACommonState),
2170         VMSTATE_UINT32(vbe_line_offset, VGACommonState),
2171         VMSTATE_UINT32(vbe_bank_mask, VGACommonState),
2172         VMSTATE_END_OF_LIST()
2173     },
2174     .subsections = (const VMStateDescription * const []) {
2175         &vmstate_vga_endian,
2176         NULL
2177     }
2178 };
2179 
2180 static const GraphicHwOps vga_ops = {
2181     .invalidate  = vga_invalidate_display,
2182     .gfx_update  = vga_update_display,
2183     .text_update = vga_update_text,
2184 };
2185 
2186 static inline uint32_t uint_clamp(uint32_t val, uint32_t vmin, uint32_t vmax)
2187 {
2188     if (val < vmin) {
2189         return vmin;
2190     }
2191     if (val > vmax) {
2192         return vmax;
2193     }
2194     return val;
2195 }
2196 
2197 bool vga_common_init(VGACommonState *s, Object *obj, Error **errp)
2198 {
2199     int i, j, v, b;
2200     Error *local_err = NULL;
2201 
2202     for(i = 0;i < 256; i++) {
2203         v = 0;
2204         for(j = 0; j < 8; j++) {
2205             v |= ((i >> j) & 1) << (j * 4);
2206         }
2207         expand4[i] = v;
2208 
2209         v = 0;
2210         for(j = 0; j < 4; j++) {
2211             v |= ((i >> (2 * j)) & 3) << (j * 4);
2212         }
2213         expand2[i] = v;
2214     }
2215     for(i = 0; i < 16; i++) {
2216         v = 0;
2217         for(j = 0; j < 4; j++) {
2218             b = ((i >> j) & 1);
2219             v |= b << (2 * j);
2220             v |= b << (2 * j + 1);
2221         }
2222         expand4to8[i] = v;
2223     }
2224 
2225     s->vram_size_mb = uint_clamp(s->vram_size_mb, 1, 512);
2226     s->vram_size_mb = pow2ceil(s->vram_size_mb);
2227     s->vram_size = s->vram_size_mb * MiB;
2228 
2229     if (!s->vbe_size) {
2230         s->vbe_size = s->vram_size;
2231     }
2232     s->vbe_size_mask = s->vbe_size - 1;
2233 
2234     s->is_vbe_vmstate = 1;
2235 
2236     if (s->global_vmstate && qemu_ram_block_by_name("vga.vram")) {
2237         error_setg(errp, "Only one global VGA device can be used at a time");
2238         return false;
2239     }
2240 
2241     memory_region_init_ram_nomigrate(&s->vram, obj, "vga.vram", s->vram_size,
2242                                      &local_err);
2243     if (local_err) {
2244         error_propagate(errp, local_err);
2245         return false;
2246     }
2247     vmstate_register_ram(&s->vram, s->global_vmstate ? NULL : DEVICE(obj));
2248     xen_register_framebuffer(&s->vram);
2249     s->vram_ptr = memory_region_get_ram_ptr(&s->vram);
2250     s->get_bpp = vga_get_bpp;
2251     s->get_params = vga_get_params;
2252     s->get_resolution = vga_get_resolution;
2253     s->hw_ops = &vga_ops;
2254     switch (vga_retrace_method) {
2255     case VGA_RETRACE_DUMB:
2256         s->retrace = vga_dumb_retrace;
2257         s->update_retrace_info = vga_dumb_update_retrace_info;
2258         break;
2259 
2260     case VGA_RETRACE_PRECISE:
2261         s->retrace = vga_precise_retrace;
2262         s->update_retrace_info = vga_precise_update_retrace_info;
2263         break;
2264     }
2265 
2266     /*
2267      * Set default fb endian based on target, could probably be turned
2268      * into a device attribute set by the machine/platform to remove
2269      * all target endian dependencies from this file.
2270      */
2271     s->default_endian_fb = target_words_bigendian();
2272 
2273     vga_dirty_log_start(s);
2274 
2275     return true;
2276 }
2277 
2278 static const MemoryRegionPortio vga_portio_list[] = {
2279     { 0x04,  2, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3b4 */
2280     { 0x0a,  1, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3ba */
2281     { 0x10, 16, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3c0 */
2282     { 0x24,  2, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3d4 */
2283     { 0x2a,  1, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3da */
2284     PORTIO_END_OF_LIST(),
2285 };
2286 
2287 static const MemoryRegionPortio vbe_portio_list_x86[] = {
2288     { 0, 1, 2, .read = vbe_ioport_read_index, .write = vbe_ioport_write_index },
2289     { 1, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data },
2290     { 2, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data },
2291     PORTIO_END_OF_LIST(),
2292 };
2293 
2294 static const MemoryRegionPortio vbe_portio_list_no_x86[] = {
2295     { 0, 1, 2, .read = vbe_ioport_read_index, .write = vbe_ioport_write_index },
2296     { 2, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data },
2297     PORTIO_END_OF_LIST(),
2298 };
2299 
2300 /* Used by both ISA and PCI */
2301 MemoryRegion *vga_init_io(VGACommonState *s, Object *obj,
2302                           const MemoryRegionPortio **vga_ports,
2303                           const MemoryRegionPortio **vbe_ports)
2304 {
2305     MemoryRegion *vga_mem;
2306     MachineState *ms = MACHINE(qdev_get_machine());
2307 
2308     /*
2309      * We unfortunately need two VBE lists since non-x86 machines might
2310      * not be able to do 16-bit accesses at unaligned addresses (0x1cf)
2311      */
2312     if (object_dynamic_cast(OBJECT(ms), TYPE_X86_MACHINE)) {
2313         *vbe_ports = vbe_portio_list_x86;
2314     } else {
2315         *vbe_ports = vbe_portio_list_no_x86;
2316     }
2317 
2318     *vga_ports = vga_portio_list;
2319 
2320     vga_mem = g_malloc(sizeof(*vga_mem));
2321     memory_region_init_io(vga_mem, obj, &vga_mem_ops, s,
2322                           "vga-lowmem", 0x20000);
2323     memory_region_set_flush_coalesced(vga_mem);
2324 
2325     return vga_mem;
2326 }
2327 
2328 void vga_init(VGACommonState *s, Object *obj, MemoryRegion *address_space,
2329               MemoryRegion *address_space_io, bool init_vga_ports)
2330 {
2331     MemoryRegion *vga_io_memory;
2332     const MemoryRegionPortio *vga_ports, *vbe_ports;
2333 
2334     qemu_register_reset(vga_reset, s);
2335 
2336     s->bank_offset = 0;
2337 
2338     s->legacy_address_space = address_space;
2339 
2340     vga_io_memory = vga_init_io(s, obj, &vga_ports, &vbe_ports);
2341     memory_region_add_subregion_overlap(address_space,
2342                                         0x000a0000,
2343                                         vga_io_memory,
2344                                         1);
2345     memory_region_set_coalescing(vga_io_memory);
2346     if (init_vga_ports) {
2347         portio_list_init(&s->vga_port_list, obj, vga_ports, s, "vga");
2348         portio_list_set_flush_coalesced(&s->vga_port_list);
2349         portio_list_add(&s->vga_port_list, address_space_io, 0x3b0);
2350     }
2351     if (vbe_ports) {
2352         portio_list_init(&s->vbe_port_list, obj, vbe_ports, s, "vbe");
2353         portio_list_add(&s->vbe_port_list, address_space_io, 0x1ce);
2354     }
2355 }
2356