xref: /openbmc/qemu/hw/display/vga.c (revision ae9d71a003c8cfd2f035c8f768341a40bcef8ed4)
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         /* chain 4 mode : simplest access (but it should use the same
819          * algorithms as below; see e.g. vga_mem_writeb's plane mask check).
820          */
821         assert(addr < s->vram_size);
822         return s->vram_ptr[addr];
823     }
824 
825     if (s->gr[VGA_GFX_MODE] & 0x10) {
826         /* odd/even mode (aka text mode mapping) */
827         plane = (s->gr[VGA_GFX_PLANE_READ] & 2) | (addr & 1);
828         addr = ((addr & ~1) << 1) | plane;
829         if (addr >= s->vram_size) {
830             return 0xff;
831         }
832         return s->vram_ptr[addr];
833     }
834 
835     /* standard VGA latched access */
836     plane = s->gr[VGA_GFX_PLANE_READ];
837     if (addr * sizeof(uint32_t) >= s->vram_size) {
838         return 0xff;
839     }
840     s->latch = ((uint32_t *)s->vram_ptr)[addr];
841     if (!(s->gr[VGA_GFX_MODE] & 0x08)) {
842         /* read mode 0 */
843         ret = GET_PLANE(s->latch, plane);
844     } else {
845         /* read mode 1 */
846         ret = (s->latch ^ mask16[s->gr[VGA_GFX_COMPARE_VALUE]]) &
847             mask16[s->gr[VGA_GFX_COMPARE_MASK]];
848         ret |= ret >> 16;
849         ret |= ret >> 8;
850         ret = (~ret) & 0xff;
851     }
852 
853     return ret;
854 }
855 
856 /* called for accesses between 0xa0000 and 0xc0000 */
857 void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val)
858 {
859     int memory_map_mode, plane, write_mode, b, func_select, mask;
860     uint32_t write_mask, bit_mask, set_mask;
861 
862 #ifdef DEBUG_VGA_MEM
863     printf("vga: [0x" HWADDR_FMT_plx "] = 0x%02x\n", addr, val);
864 #endif
865     /* convert to VGA memory offset */
866     memory_map_mode = (s->gr[VGA_GFX_MISC] >> 2) & 3;
867     addr &= 0x1ffff;
868     switch(memory_map_mode) {
869     case 0:
870         break;
871     case 1:
872         if (addr >= 0x10000)
873             return;
874         addr += s->bank_offset;
875         break;
876     case 2:
877         addr -= 0x10000;
878         if (addr >= 0x8000)
879             return;
880         break;
881     default:
882     case 3:
883         addr -= 0x18000;
884         if (addr >= 0x8000)
885             return;
886         break;
887     }
888 
889     if (sr(s, VGA_SEQ_MEMORY_MODE) & VGA_SR04_CHN_4M) {
890         /* chain 4 mode : simplest access */
891         plane = addr & 3;
892         mask = (1 << plane);
893         if (sr(s, VGA_SEQ_PLANE_WRITE) & mask) {
894             assert(addr < s->vram_size);
895             s->vram_ptr[addr] = val;
896 #ifdef DEBUG_VGA_MEM
897             printf("vga: chain4: [0x" HWADDR_FMT_plx "]\n", addr);
898 #endif
899             s->plane_updated |= mask; /* only used to detect font change */
900             memory_region_set_dirty(&s->vram, addr, 1);
901         }
902         return;
903     }
904 
905     if (s->gr[VGA_GFX_MODE] & 0x10) {
906         /* odd/even mode (aka text mode mapping) */
907         plane = (s->gr[VGA_GFX_PLANE_READ] & 2) | (addr & 1);
908         mask = (1 << plane);
909         if (sr(s, VGA_SEQ_PLANE_WRITE) & mask) {
910             addr = ((addr & ~1) << 1) | plane;
911             if (addr >= s->vram_size) {
912                 return;
913             }
914             s->vram_ptr[addr] = val;
915 #ifdef DEBUG_VGA_MEM
916             printf("vga: odd/even: [0x" HWADDR_FMT_plx "]\n", addr);
917 #endif
918             s->plane_updated |= mask; /* only used to detect font change */
919             memory_region_set_dirty(&s->vram, addr, 1);
920         }
921         return;
922     }
923 
924     mask = sr(s, VGA_SEQ_PLANE_WRITE);
925 
926     /* standard VGA latched access */
927     write_mode = s->gr[VGA_GFX_MODE] & 3;
928     switch(write_mode) {
929     default:
930     case 0:
931         /* rotate */
932         b = s->gr[VGA_GFX_DATA_ROTATE] & 7;
933         val = ((val >> b) | (val << (8 - b))) & 0xff;
934         val |= val << 8;
935         val |= val << 16;
936 
937         /* apply set/reset mask */
938         set_mask = mask16[s->gr[VGA_GFX_SR_ENABLE]];
939         val = (val & ~set_mask) |
940             (mask16[s->gr[VGA_GFX_SR_VALUE]] & set_mask);
941         bit_mask = s->gr[VGA_GFX_BIT_MASK];
942         break;
943     case 1:
944         val = s->latch;
945         goto do_write;
946     case 2:
947         val = mask16[val & 0x0f];
948         bit_mask = s->gr[VGA_GFX_BIT_MASK];
949         break;
950     case 3:
951         /* rotate */
952         b = s->gr[VGA_GFX_DATA_ROTATE] & 7;
953         val = (val >> b) | (val << (8 - b));
954 
955         bit_mask = s->gr[VGA_GFX_BIT_MASK] & val;
956         val = mask16[s->gr[VGA_GFX_SR_VALUE]];
957         break;
958     }
959 
960     /* apply logical operation */
961     func_select = s->gr[VGA_GFX_DATA_ROTATE] >> 3;
962     switch(func_select) {
963     case 0:
964     default:
965         /* nothing to do */
966         break;
967     case 1:
968         /* and */
969         val &= s->latch;
970         break;
971     case 2:
972         /* or */
973         val |= s->latch;
974         break;
975     case 3:
976         /* xor */
977         val ^= s->latch;
978         break;
979     }
980 
981     /* apply bit mask */
982     bit_mask |= bit_mask << 8;
983     bit_mask |= bit_mask << 16;
984     val = (val & bit_mask) | (s->latch & ~bit_mask);
985 
986 do_write:
987     /* mask data according to sr[2] */
988     s->plane_updated |= mask; /* only used to detect font change */
989     write_mask = mask16[mask];
990     if (addr * sizeof(uint32_t) >= s->vram_size) {
991         return;
992     }
993     ((uint32_t *)s->vram_ptr)[addr] =
994         (((uint32_t *)s->vram_ptr)[addr] & ~write_mask) |
995         (val & write_mask);
996 #ifdef DEBUG_VGA_MEM
997     printf("vga: latch: [0x" HWADDR_FMT_plx "] mask=0x%08x val=0x%08x\n",
998            addr * 4, write_mask, val);
999 #endif
1000     memory_region_set_dirty(&s->vram, addr << 2, sizeof(uint32_t));
1001 }
1002 
1003 typedef void *vga_draw_line_func(VGACommonState *s1, uint8_t *d,
1004                                  uint32_t srcaddr, int width, int hpel);
1005 
1006 #include "vga-access.h"
1007 #include "vga-helpers.h"
1008 
1009 /* return true if the palette was modified */
1010 static int update_palette16(VGACommonState *s)
1011 {
1012     int full_update, i;
1013     uint32_t v, col, *palette;
1014 
1015     full_update = 0;
1016     palette = s->last_palette;
1017     for(i = 0; i < 16; i++) {
1018         v = s->ar[i];
1019         if (s->ar[VGA_ATC_MODE] & 0x80) {
1020             v = ((s->ar[VGA_ATC_COLOR_PAGE] & 0xf) << 4) | (v & 0xf);
1021         } else {
1022             v = ((s->ar[VGA_ATC_COLOR_PAGE] & 0xc) << 4) | (v & 0x3f);
1023         }
1024         v = v * 3;
1025         col = rgb_to_pixel32(c6_to_8(s->palette[v]),
1026                              c6_to_8(s->palette[v + 1]),
1027                              c6_to_8(s->palette[v + 2]));
1028         if (col != palette[i]) {
1029             full_update = 1;
1030             palette[i] = col;
1031         }
1032     }
1033     return full_update;
1034 }
1035 
1036 /* return true if the palette was modified */
1037 static int update_palette256(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     v = 0;
1045     for(i = 0; i < 256; i++) {
1046         if (s->dac_8bit) {
1047             col = rgb_to_pixel32(s->palette[v],
1048                                  s->palette[v + 1],
1049                                  s->palette[v + 2]);
1050         } else {
1051             col = rgb_to_pixel32(c6_to_8(s->palette[v]),
1052                                  c6_to_8(s->palette[v + 1]),
1053                                  c6_to_8(s->palette[v + 2]));
1054         }
1055         if (col != palette[i]) {
1056             full_update = 1;
1057             palette[i] = col;
1058         }
1059         v += 3;
1060     }
1061     return full_update;
1062 }
1063 
1064 static void vga_get_params(VGACommonState *s,
1065                            VGADisplayParams *params)
1066 {
1067     if (vbe_enabled(s)) {
1068         params->line_offset = s->vbe_line_offset;
1069         params->start_addr = s->vbe_start_addr;
1070         params->line_compare = 65535;
1071         params->hpel = VGA_HPEL_NEUTRAL;
1072         params->hpel_split = false;
1073     } else {
1074         /* compute line_offset in bytes */
1075         params->line_offset = s->cr[VGA_CRTC_OFFSET] << 3;
1076 
1077         /* starting address */
1078         params->start_addr = s->cr[VGA_CRTC_START_LO] |
1079             (s->cr[VGA_CRTC_START_HI] << 8);
1080 
1081         /* line compare */
1082         params->line_compare = s->cr[VGA_CRTC_LINE_COMPARE] |
1083             ((s->cr[VGA_CRTC_OVERFLOW] & 0x10) << 4) |
1084             ((s->cr[VGA_CRTC_MAX_SCAN] & 0x40) << 3);
1085 
1086         params->hpel = s->ar[VGA_ATC_PEL];
1087         params->hpel_split = s->ar[VGA_ATC_MODE] & 0x20;
1088     }
1089 }
1090 
1091 /* update start_addr and line_offset. Return TRUE if modified */
1092 static int update_basic_params(VGACommonState *s)
1093 {
1094     int full_update;
1095     VGADisplayParams current;
1096 
1097     full_update = 0;
1098 
1099     s->get_params(s, &current);
1100 
1101     if (memcmp(&current, &s->params, sizeof(current))) {
1102         s->params = current;
1103         full_update = 1;
1104     }
1105     return full_update;
1106 }
1107 
1108 
1109 static const uint8_t cursor_glyph[32 * 4] = {
1110     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1111     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1112     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1113     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1114     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1115     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1116     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1117     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1118     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1119     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1120     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1121     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1122     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1123     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1124     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1125     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1126 };
1127 
1128 static void vga_get_text_resolution(VGACommonState *s, int *pwidth, int *pheight,
1129                                     int *pcwidth, int *pcheight)
1130 {
1131     int width, cwidth, height, cheight;
1132 
1133     /* total width & height */
1134     cheight = (s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1;
1135     cwidth = 8;
1136     if (!(sr(s, VGA_SEQ_CLOCK_MODE) & VGA_SR01_CHAR_CLK_8DOTS)) {
1137         cwidth = 9;
1138     }
1139     if (sr(s, VGA_SEQ_CLOCK_MODE) & 0x08) {
1140         cwidth = 16; /* NOTE: no 18 pixel wide */
1141     }
1142     width = (s->cr[VGA_CRTC_H_DISP] + 1);
1143     if (s->cr[VGA_CRTC_V_TOTAL] == 100) {
1144         /* ugly hack for CGA 160x100x16 - explain me the logic */
1145         height = 100;
1146     } else {
1147         height = s->cr[VGA_CRTC_V_DISP_END] |
1148             ((s->cr[VGA_CRTC_OVERFLOW] & 0x02) << 7) |
1149             ((s->cr[VGA_CRTC_OVERFLOW] & 0x40) << 3);
1150         height = (height + 1) / cheight;
1151     }
1152 
1153     *pwidth = width;
1154     *pheight = height;
1155     *pcwidth = cwidth;
1156     *pcheight = cheight;
1157 }
1158 
1159 /*
1160  * Text mode update
1161  * Missing:
1162  * - double scan
1163  * - double width
1164  * - underline
1165  * - flashing
1166  */
1167 static void vga_draw_text(VGACommonState *s, int full_update)
1168 {
1169     DisplaySurface *surface = qemu_console_surface(s->con);
1170     int cx, cy, cheight, cw, ch, cattr, height, width, ch_attr;
1171     int cx_min, cx_max, linesize, x_incr, line, line1;
1172     uint32_t offset, fgcol, bgcol, v, cursor_offset;
1173     uint8_t *d1, *d, *src, *dest, *cursor_ptr;
1174     const uint8_t *font_ptr, *font_base[2];
1175     int dup9, line_offset;
1176     uint32_t *palette;
1177     uint32_t *ch_attr_ptr;
1178     int64_t now = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
1179 
1180     /* compute font data address (in plane 2) */
1181     v = sr(s, VGA_SEQ_CHARACTER_MAP);
1182     offset = (((v >> 4) & 1) | ((v << 1) & 6)) * 8192 * 4 + 2;
1183     if (offset != s->font_offsets[0]) {
1184         s->font_offsets[0] = offset;
1185         full_update = 1;
1186     }
1187     font_base[0] = s->vram_ptr + offset;
1188 
1189     offset = (((v >> 5) & 1) | ((v >> 1) & 6)) * 8192 * 4 + 2;
1190     font_base[1] = s->vram_ptr + offset;
1191     if (offset != s->font_offsets[1]) {
1192         s->font_offsets[1] = offset;
1193         full_update = 1;
1194     }
1195     if (s->plane_updated & (1 << 2) || s->has_chain4_alias) {
1196         /* if the plane 2 was modified since the last display, it
1197            indicates the font may have been modified */
1198         s->plane_updated = 0;
1199         full_update = 1;
1200     }
1201     full_update |= update_basic_params(s);
1202 
1203     line_offset = s->params.line_offset;
1204 
1205     vga_get_text_resolution(s, &width, &height, &cw, &cheight);
1206     if ((height * width) <= 1) {
1207         /* better than nothing: exit if transient size is too small */
1208         return;
1209     }
1210     if ((height * width) > CH_ATTR_SIZE) {
1211         /* better than nothing: exit if transient size is too big */
1212         return;
1213     }
1214 
1215     if (width != s->last_width || height != s->last_height ||
1216         cw != s->last_cw || cheight != s->last_ch || s->last_depth) {
1217         s->last_scr_width = width * cw;
1218         s->last_scr_height = height * cheight;
1219         qemu_console_resize(s->con, s->last_scr_width, s->last_scr_height);
1220         surface = qemu_console_surface(s->con);
1221         dpy_text_resize(s->con, width, height);
1222         s->last_depth = 0;
1223         s->last_width = width;
1224         s->last_height = height;
1225         s->last_ch = cheight;
1226         s->last_cw = cw;
1227         full_update = 1;
1228     }
1229     full_update |= update_palette16(s);
1230     palette = s->last_palette;
1231     x_incr = cw * surface_bytes_per_pixel(surface);
1232 
1233     if (full_update) {
1234         s->full_update_text = 1;
1235     }
1236     if (s->full_update_gfx) {
1237         s->full_update_gfx = 0;
1238         full_update |= 1;
1239     }
1240 
1241     cursor_offset = ((s->cr[VGA_CRTC_CURSOR_HI] << 8) |
1242                      s->cr[VGA_CRTC_CURSOR_LO]) - s->params.start_addr;
1243     if (cursor_offset != s->cursor_offset ||
1244         s->cr[VGA_CRTC_CURSOR_START] != s->cursor_start ||
1245         s->cr[VGA_CRTC_CURSOR_END] != s->cursor_end) {
1246       /* if the cursor position changed, we update the old and new
1247          chars */
1248         if (s->cursor_offset < CH_ATTR_SIZE)
1249             s->last_ch_attr[s->cursor_offset] = -1;
1250         if (cursor_offset < CH_ATTR_SIZE)
1251             s->last_ch_attr[cursor_offset] = -1;
1252         s->cursor_offset = cursor_offset;
1253         s->cursor_start = s->cr[VGA_CRTC_CURSOR_START];
1254         s->cursor_end = s->cr[VGA_CRTC_CURSOR_END];
1255     }
1256     cursor_ptr = s->vram_ptr + (s->params.start_addr + cursor_offset) * 4;
1257     if (now >= s->cursor_blink_time) {
1258         s->cursor_blink_time = now + VGA_TEXT_CURSOR_PERIOD_MS / 2;
1259         s->cursor_visible_phase = !s->cursor_visible_phase;
1260     }
1261 
1262     dest = surface_data(surface);
1263     linesize = surface_stride(surface);
1264     ch_attr_ptr = s->last_ch_attr;
1265     line = 0;
1266     offset = s->params.start_addr * 4;
1267     for(cy = 0; cy < height; cy++) {
1268         d1 = dest;
1269         src = s->vram_ptr + offset;
1270         cx_min = width;
1271         cx_max = -1;
1272         for(cx = 0; cx < width; cx++) {
1273             if (src + sizeof(uint16_t) > s->vram_ptr + s->vram_size) {
1274                 break;
1275             }
1276             ch_attr = *(uint16_t *)src;
1277             if (full_update || ch_attr != *ch_attr_ptr || src == cursor_ptr) {
1278                 if (cx < cx_min)
1279                     cx_min = cx;
1280                 if (cx > cx_max)
1281                     cx_max = cx;
1282                 *ch_attr_ptr = ch_attr;
1283 #if HOST_BIG_ENDIAN
1284                 ch = ch_attr >> 8;
1285                 cattr = ch_attr & 0xff;
1286 #else
1287                 ch = ch_attr & 0xff;
1288                 cattr = ch_attr >> 8;
1289 #endif
1290                 font_ptr = font_base[(cattr >> 3) & 1];
1291                 font_ptr += 32 * 4 * ch;
1292                 bgcol = palette[cattr >> 4];
1293                 fgcol = palette[cattr & 0x0f];
1294                 if (cw == 16) {
1295                     vga_draw_glyph16(d1, linesize,
1296                                      font_ptr, cheight, fgcol, bgcol);
1297                 } else if (cw != 9) {
1298                     vga_draw_glyph8(d1, linesize,
1299                                     font_ptr, cheight, fgcol, bgcol);
1300                 } else {
1301                     dup9 = 0;
1302                     if (ch >= 0xb0 && ch <= 0xdf &&
1303                         (s->ar[VGA_ATC_MODE] & 0x04)) {
1304                         dup9 = 1;
1305                     }
1306                     vga_draw_glyph9(d1, linesize,
1307                                     font_ptr, cheight, fgcol, bgcol, dup9);
1308                 }
1309                 if (src == cursor_ptr &&
1310                     !(s->cr[VGA_CRTC_CURSOR_START] & 0x20) &&
1311                     s->cursor_visible_phase) {
1312                     int line_start, line_last, h;
1313                     /* draw the cursor */
1314                     line_start = s->cr[VGA_CRTC_CURSOR_START] & 0x1f;
1315                     line_last = s->cr[VGA_CRTC_CURSOR_END] & 0x1f;
1316                     /* XXX: check that */
1317                     if (line_last > cheight - 1)
1318                         line_last = cheight - 1;
1319                     if (line_last >= line_start && line_start < cheight) {
1320                         h = line_last - line_start + 1;
1321                         d = d1 + linesize * line_start;
1322                         if (cw == 16) {
1323                             vga_draw_glyph16(d, linesize,
1324                                              cursor_glyph, h, fgcol, bgcol);
1325                         } else if (cw != 9) {
1326                             vga_draw_glyph8(d, linesize,
1327                                             cursor_glyph, h, fgcol, bgcol);
1328                         } else {
1329                             vga_draw_glyph9(d, linesize,
1330                                             cursor_glyph, h, fgcol, bgcol, 1);
1331                         }
1332                     }
1333                 }
1334             }
1335             d1 += x_incr;
1336             src += 4;
1337             ch_attr_ptr++;
1338         }
1339         if (cx_max != -1) {
1340             dpy_gfx_update(s->con, cx_min * cw, cy * cheight,
1341                            (cx_max - cx_min + 1) * cw, cheight);
1342         }
1343         dest += linesize * cheight;
1344         line1 = line + cheight;
1345         offset += line_offset;
1346         if (line < s->params.line_compare && line1 >= s->params.line_compare) {
1347             offset = 0;
1348         }
1349         line = line1;
1350     }
1351 }
1352 
1353 enum {
1354     VGA_DRAW_LINE2,
1355     VGA_DRAW_LINE2D2,
1356     VGA_DRAW_LINE4,
1357     VGA_DRAW_LINE4D2,
1358     VGA_DRAW_LINE8D2,
1359     VGA_DRAW_LINE8,
1360     VGA_DRAW_LINE15_LE,
1361     VGA_DRAW_LINE16_LE,
1362     VGA_DRAW_LINE24_LE,
1363     VGA_DRAW_LINE32_LE,
1364     VGA_DRAW_LINE15_BE,
1365     VGA_DRAW_LINE16_BE,
1366     VGA_DRAW_LINE24_BE,
1367     VGA_DRAW_LINE32_BE,
1368     VGA_DRAW_LINE_NB,
1369 };
1370 
1371 static vga_draw_line_func * const vga_draw_line_table[VGA_DRAW_LINE_NB] = {
1372     vga_draw_line2,
1373     vga_draw_line2d2,
1374     vga_draw_line4,
1375     vga_draw_line4d2,
1376     vga_draw_line8d2,
1377     vga_draw_line8,
1378     vga_draw_line15_le,
1379     vga_draw_line16_le,
1380     vga_draw_line24_le,
1381     vga_draw_line32_le,
1382     vga_draw_line15_be,
1383     vga_draw_line16_be,
1384     vga_draw_line24_be,
1385     vga_draw_line32_be,
1386 };
1387 
1388 static int vga_get_bpp(VGACommonState *s)
1389 {
1390     int ret;
1391 
1392     if (vbe_enabled(s)) {
1393         ret = s->vbe_regs[VBE_DISPI_INDEX_BPP];
1394     } else {
1395         ret = 0;
1396     }
1397     return ret;
1398 }
1399 
1400 static void vga_get_resolution(VGACommonState *s, int *pwidth, int *pheight)
1401 {
1402     int width, height;
1403 
1404     if (vbe_enabled(s)) {
1405         width = s->vbe_regs[VBE_DISPI_INDEX_XRES];
1406         height = s->vbe_regs[VBE_DISPI_INDEX_YRES];
1407     } else {
1408         width = (s->cr[VGA_CRTC_H_DISP] + 1) * 8;
1409         height = s->cr[VGA_CRTC_V_DISP_END] |
1410             ((s->cr[VGA_CRTC_OVERFLOW] & 0x02) << 7) |
1411             ((s->cr[VGA_CRTC_OVERFLOW] & 0x40) << 3);
1412         height = (height + 1);
1413     }
1414     *pwidth = width;
1415     *pheight = height;
1416 }
1417 
1418 void vga_invalidate_scanlines(VGACommonState *s, int y1, int y2)
1419 {
1420     int y;
1421     if (y1 >= VGA_MAX_HEIGHT)
1422         return;
1423     if (y2 >= VGA_MAX_HEIGHT)
1424         y2 = VGA_MAX_HEIGHT;
1425     for(y = y1; y < y2; y++) {
1426         s->invalidated_y_table[y >> 5] |= 1 << (y & 0x1f);
1427     }
1428 }
1429 
1430 static bool vga_scanline_invalidated(VGACommonState *s, int y)
1431 {
1432     if (y >= VGA_MAX_HEIGHT) {
1433         return false;
1434     }
1435     return s->invalidated_y_table[y >> 5] & (1 << (y & 0x1f));
1436 }
1437 
1438 void vga_dirty_log_start(VGACommonState *s)
1439 {
1440     memory_region_set_log(&s->vram, true, DIRTY_MEMORY_VGA);
1441 }
1442 
1443 void vga_dirty_log_stop(VGACommonState *s)
1444 {
1445     memory_region_set_log(&s->vram, false, DIRTY_MEMORY_VGA);
1446 }
1447 
1448 /*
1449  * graphic modes
1450  */
1451 static void vga_draw_graphic(VGACommonState *s, int full_update)
1452 {
1453     DisplaySurface *surface = qemu_console_surface(s->con);
1454     int y1, y, update, linesize, y_start, double_scan, mask, depth;
1455     int width, height, shift_control, bwidth, bits;
1456     ram_addr_t page0, page1, region_start, region_end;
1457     DirtyBitmapSnapshot *snap = NULL;
1458     int disp_width, multi_scan, multi_run;
1459     int hpel;
1460     uint8_t *d;
1461     uint32_t v, addr1, addr;
1462     vga_draw_line_func *vga_draw_line = NULL;
1463     bool share_surface, force_shadow = false;
1464     pixman_format_code_t format;
1465 #if HOST_BIG_ENDIAN
1466     bool byteswap = !s->big_endian_fb;
1467 #else
1468     bool byteswap = s->big_endian_fb;
1469 #endif
1470 
1471     full_update |= update_basic_params(s);
1472 
1473     s->get_resolution(s, &width, &height);
1474     disp_width = width;
1475     depth = s->get_bpp(s);
1476 
1477     region_start = (s->params.start_addr * 4);
1478     region_end = region_start + (ram_addr_t)s->params.line_offset * height;
1479     region_end += width * depth / 8; /* scanline length */
1480     region_end -= s->params.line_offset;
1481     if (region_end > s->vbe_size || depth == 0 || depth == 15) {
1482         /*
1483          * We land here on:
1484          *  - wraps around (can happen with cirrus vbe modes)
1485          *  - depth == 0 (256 color palette video mode)
1486          *  - depth == 15
1487          *
1488          * Take the safe and slow route:
1489          *   - create a dirty bitmap snapshot for all vga memory.
1490          *   - force shadowing (so all vga memory access goes
1491          *     through vga_read_*() helpers).
1492          *
1493          * Given this affects only vga features which are pretty much
1494          * unused by modern guests there should be no performance
1495          * impact.
1496          */
1497         region_start = 0;
1498         region_end = s->vbe_size;
1499         force_shadow = true;
1500     }
1501 
1502     /* bits 5-6: 0 = 16-color mode, 1 = 4-color mode, 2 = 256-color mode.  */
1503     shift_control = (s->gr[VGA_GFX_MODE] >> 5) & 3;
1504     double_scan = (s->cr[VGA_CRTC_MAX_SCAN] >> 7);
1505     if (s->cr[VGA_CRTC_MODE] & 1) {
1506         multi_scan = (((s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1) << double_scan)
1507             - 1;
1508     } else {
1509         /* in CGA modes, multi_scan is ignored */
1510         /* XXX: is it correct ? */
1511         multi_scan = double_scan;
1512     }
1513     multi_run = multi_scan;
1514     if (shift_control != s->shift_control ||
1515         double_scan != s->double_scan) {
1516         full_update = 1;
1517         s->shift_control = shift_control;
1518         s->double_scan = double_scan;
1519     }
1520 
1521     if (shift_control == 0) {
1522         if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) {
1523             disp_width <<= 1;
1524         }
1525     } else if (shift_control == 1) {
1526         if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) {
1527             disp_width <<= 1;
1528         }
1529     }
1530 
1531     /*
1532      * Check whether we can share the surface with the backend
1533      * or whether we need a shadow surface. We share native
1534      * endian surfaces for 15bpp and above and byteswapped
1535      * surfaces for 24bpp and above.
1536      */
1537     format = qemu_default_pixman_format(depth, !byteswap);
1538     if (format) {
1539         share_surface = dpy_gfx_check_format(s->con, format)
1540             && !s->force_shadow && !force_shadow;
1541     } else {
1542         share_surface = false;
1543     }
1544 
1545     if (s->params.line_offset != s->last_line_offset ||
1546         disp_width != s->last_width ||
1547         height != s->last_height ||
1548         s->last_depth != depth ||
1549         s->last_byteswap != byteswap ||
1550         share_surface != is_buffer_shared(surface)) {
1551         /* display parameters changed -> need new display surface */
1552         s->last_scr_width = disp_width;
1553         s->last_scr_height = height;
1554         s->last_width = disp_width;
1555         s->last_height = height;
1556         s->last_line_offset = s->params.line_offset;
1557         s->last_depth = depth;
1558         s->last_byteswap = byteswap;
1559         /* 16 extra pixels are needed for double-width planar modes.  */
1560         s->panning_buf = g_realloc(s->panning_buf,
1561                                    (disp_width + 16) * sizeof(uint32_t));
1562         full_update = 1;
1563     }
1564     if (surface_data(surface) != s->vram_ptr + (s->params.start_addr * 4)
1565         && is_buffer_shared(surface)) {
1566         /* base address changed (page flip) -> shared display surfaces
1567          * must be updated with the new base address */
1568         full_update = 1;
1569     }
1570 
1571     if (full_update) {
1572         if (share_surface) {
1573             surface = qemu_create_displaysurface_from(disp_width,
1574                     height, format, s->params.line_offset,
1575                     s->vram_ptr + (s->params.start_addr * 4));
1576             dpy_gfx_replace_surface(s->con, surface);
1577         } else {
1578             qemu_console_resize(s->con, disp_width, height);
1579             surface = qemu_console_surface(s->con);
1580         }
1581     }
1582 
1583     if (shift_control == 0) {
1584         full_update |= update_palette16(s);
1585         if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) {
1586             v = VGA_DRAW_LINE4D2;
1587         } else {
1588             v = VGA_DRAW_LINE4;
1589         }
1590         bits = 4;
1591     } else if (shift_control == 1) {
1592         full_update |= update_palette16(s);
1593         if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) {
1594             v = VGA_DRAW_LINE2D2;
1595         } else {
1596             v = VGA_DRAW_LINE2;
1597         }
1598         bits = 4;
1599     } else {
1600         switch(s->get_bpp(s)) {
1601         default:
1602         case 0:
1603             full_update |= update_palette256(s);
1604             v = VGA_DRAW_LINE8D2;
1605             bits = 4;
1606             break;
1607         case 8:
1608             full_update |= update_palette256(s);
1609             v = VGA_DRAW_LINE8;
1610             bits = 8;
1611             break;
1612         case 15:
1613             v = s->big_endian_fb ? VGA_DRAW_LINE15_BE : VGA_DRAW_LINE15_LE;
1614             bits = 16;
1615             break;
1616         case 16:
1617             v = s->big_endian_fb ? VGA_DRAW_LINE16_BE : VGA_DRAW_LINE16_LE;
1618             bits = 16;
1619             break;
1620         case 24:
1621             v = s->big_endian_fb ? VGA_DRAW_LINE24_BE : VGA_DRAW_LINE24_LE;
1622             bits = 24;
1623             break;
1624         case 32:
1625             v = s->big_endian_fb ? VGA_DRAW_LINE32_BE : VGA_DRAW_LINE32_LE;
1626             bits = 32;
1627             break;
1628         }
1629     }
1630     vga_draw_line = vga_draw_line_table[v];
1631 
1632     if (!is_buffer_shared(surface) && s->cursor_invalidate) {
1633         s->cursor_invalidate(s);
1634     }
1635 
1636 #if 0
1637     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",
1638            width, height, v, line_offset, s->cr[9], s->cr[VGA_CRTC_MODE],
1639            s->params.line_compare, sr(s, VGA_SEQ_CLOCK_MODE));
1640 #endif
1641     hpel = bits <= 8 ? s->params.hpel : 0;
1642     addr1 = (s->params.start_addr * 4);
1643     bwidth = DIV_ROUND_UP(width * bits, 8);
1644     if (hpel) {
1645         bwidth += 4;
1646     }
1647     y_start = -1;
1648     d = surface_data(surface);
1649     linesize = surface_stride(surface);
1650     y1 = 0;
1651 
1652     if (!full_update) {
1653         if (s->params.line_compare < height) {
1654             /* split screen mode */
1655             region_start = 0;
1656         }
1657         snap = memory_region_snapshot_and_clear_dirty(&s->vram, region_start,
1658                                                       region_end - region_start,
1659                                                       DIRTY_MEMORY_VGA);
1660     }
1661 
1662     for(y = 0; y < height; y++) {
1663         addr = addr1;
1664         if (!(s->cr[VGA_CRTC_MODE] & 1)) {
1665             int shift;
1666             /* CGA compatibility handling */
1667             shift = 14 + ((s->cr[VGA_CRTC_MODE] >> 6) & 1);
1668             addr = (addr & ~(1 << shift)) | ((y1 & 1) << shift);
1669         }
1670         if (!(s->cr[VGA_CRTC_MODE] & 2)) {
1671             addr = (addr & ~0x8000) | ((y1 & 2) << 14);
1672         }
1673         page0 = addr & s->vbe_size_mask;
1674         page1 = (addr + bwidth - 1) & s->vbe_size_mask;
1675         if (full_update) {
1676             update = 1;
1677         } else if (page1 < page0) {
1678             /* scanline wraps from end of video memory to the start */
1679             assert(force_shadow);
1680             update = memory_region_snapshot_get_dirty(&s->vram, snap,
1681                                                       page0, s->vbe_size - page0);
1682             update |= memory_region_snapshot_get_dirty(&s->vram, snap,
1683                                                        0, page1);
1684         } else {
1685             update = memory_region_snapshot_get_dirty(&s->vram, snap,
1686                                                       page0, page1 - page0);
1687         }
1688         /* explicit invalidation for the hardware cursor (cirrus only) */
1689         update |= vga_scanline_invalidated(s, y);
1690         if (update) {
1691             if (y_start < 0)
1692                 y_start = y;
1693             if (!(is_buffer_shared(surface))) {
1694                 uint8_t *p;
1695                 p = vga_draw_line(s, d, addr, width, hpel);
1696                 if (p) {
1697                     memcpy(d, p, disp_width * sizeof(uint32_t));
1698                 }
1699                 if (s->cursor_draw_line)
1700                     s->cursor_draw_line(s, d, y);
1701             }
1702         } else {
1703             if (y_start >= 0) {
1704                 /* flush to display */
1705                 dpy_gfx_update(s->con, 0, y_start,
1706                                disp_width, y - y_start);
1707                 y_start = -1;
1708             }
1709         }
1710         if (!multi_run) {
1711             mask = (s->cr[VGA_CRTC_MODE] & 3) ^ 3;
1712             if ((y1 & mask) == mask)
1713                 addr1 += s->params.line_offset;
1714             y1++;
1715             multi_run = multi_scan;
1716         } else {
1717             multi_run--;
1718         }
1719         /* line compare acts on the displayed lines */
1720         if (y == s->params.line_compare) {
1721             if (s->params.hpel_split) {
1722                 hpel = VGA_HPEL_NEUTRAL;
1723             }
1724             addr1 = 0;
1725         }
1726         d += linesize;
1727     }
1728     if (y_start >= 0) {
1729         /* flush to display */
1730         dpy_gfx_update(s->con, 0, y_start,
1731                        disp_width, y - y_start);
1732     }
1733     g_free(snap);
1734     memset(s->invalidated_y_table, 0, sizeof(s->invalidated_y_table));
1735 }
1736 
1737 static void vga_draw_blank(VGACommonState *s, int full_update)
1738 {
1739     DisplaySurface *surface = qemu_console_surface(s->con);
1740     int i, w;
1741     uint8_t *d;
1742 
1743     if (!full_update)
1744         return;
1745     if (s->last_scr_width <= 0 || s->last_scr_height <= 0)
1746         return;
1747 
1748     w = s->last_scr_width * surface_bytes_per_pixel(surface);
1749     d = surface_data(surface);
1750     for(i = 0; i < s->last_scr_height; i++) {
1751         memset(d, 0, w);
1752         d += surface_stride(surface);
1753     }
1754     dpy_gfx_update_full(s->con);
1755 }
1756 
1757 #define GMODE_TEXT     0
1758 #define GMODE_GRAPH    1
1759 #define GMODE_BLANK 2
1760 
1761 static void vga_update_display(void *opaque)
1762 {
1763     VGACommonState *s = opaque;
1764     DisplaySurface *surface = qemu_console_surface(s->con);
1765     int full_update, graphic_mode;
1766 
1767     qemu_flush_coalesced_mmio_buffer();
1768 
1769     if (surface_bits_per_pixel(surface) == 0) {
1770         /* nothing to do */
1771     } else {
1772         full_update = 0;
1773         if (!(s->ar_index & 0x20)) {
1774             graphic_mode = GMODE_BLANK;
1775         } else {
1776             graphic_mode = s->gr[VGA_GFX_MISC] & VGA_GR06_GRAPHICS_MODE;
1777         }
1778         if (graphic_mode != s->graphic_mode) {
1779             s->graphic_mode = graphic_mode;
1780             s->cursor_blink_time = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
1781             full_update = 1;
1782         }
1783         switch(graphic_mode) {
1784         case GMODE_TEXT:
1785             vga_draw_text(s, full_update);
1786             break;
1787         case GMODE_GRAPH:
1788             vga_draw_graphic(s, full_update);
1789             break;
1790         case GMODE_BLANK:
1791         default:
1792             vga_draw_blank(s, full_update);
1793             break;
1794         }
1795     }
1796 }
1797 
1798 /* force a full display refresh */
1799 static void vga_invalidate_display(void *opaque)
1800 {
1801     VGACommonState *s = opaque;
1802 
1803     s->last_width = -1;
1804     s->last_height = -1;
1805 }
1806 
1807 void vga_common_reset(VGACommonState *s)
1808 {
1809     s->sr_index = 0;
1810     memset(s->sr, '\0', sizeof(s->sr));
1811     memset(s->sr_vbe, '\0', sizeof(s->sr_vbe));
1812     s->gr_index = 0;
1813     memset(s->gr, '\0', sizeof(s->gr));
1814     s->ar_index = 0;
1815     memset(s->ar, '\0', sizeof(s->ar));
1816     s->ar_flip_flop = 0;
1817     s->cr_index = 0;
1818     memset(s->cr, '\0', sizeof(s->cr));
1819     s->msr = 0;
1820     s->fcr = 0;
1821     s->st00 = 0;
1822     s->st01 = 0;
1823     s->dac_state = 0;
1824     s->dac_sub_index = 0;
1825     s->dac_read_index = 0;
1826     s->dac_write_index = 0;
1827     memset(s->dac_cache, '\0', sizeof(s->dac_cache));
1828     s->dac_8bit = 0;
1829     memset(s->palette, '\0', sizeof(s->palette));
1830     s->bank_offset = 0;
1831     s->vbe_index = 0;
1832     memset(s->vbe_regs, '\0', sizeof(s->vbe_regs));
1833     s->vbe_regs[VBE_DISPI_INDEX_ID] = VBE_DISPI_ID5;
1834     s->vbe_start_addr = 0;
1835     s->vbe_line_offset = 0;
1836     s->vbe_bank_mask = (s->vram_size >> 16) - 1;
1837     memset(s->font_offsets, '\0', sizeof(s->font_offsets));
1838     s->graphic_mode = -1; /* force full update */
1839     s->shift_control = 0;
1840     s->double_scan = 0;
1841     memset(&s->params, '\0', sizeof(s->params));
1842     s->plane_updated = 0;
1843     s->last_cw = 0;
1844     s->last_ch = 0;
1845     s->last_width = 0;
1846     s->last_height = 0;
1847     s->last_scr_width = 0;
1848     s->last_scr_height = 0;
1849     s->cursor_start = 0;
1850     s->cursor_end = 0;
1851     s->cursor_offset = 0;
1852     s->big_endian_fb = s->default_endian_fb;
1853     memset(s->invalidated_y_table, '\0', sizeof(s->invalidated_y_table));
1854     memset(s->last_palette, '\0', sizeof(s->last_palette));
1855     memset(s->last_ch_attr, '\0', sizeof(s->last_ch_attr));
1856     switch (vga_retrace_method) {
1857     case VGA_RETRACE_DUMB:
1858         break;
1859     case VGA_RETRACE_PRECISE:
1860         memset(&s->retrace_info, 0, sizeof (s->retrace_info));
1861         break;
1862     }
1863     vga_update_memory_access(s);
1864 }
1865 
1866 static void vga_reset(void *opaque)
1867 {
1868     VGACommonState *s =  opaque;
1869     vga_common_reset(s);
1870 }
1871 
1872 #define TEXTMODE_X(x)	((x) % width)
1873 #define TEXTMODE_Y(x)	((x) / width)
1874 #define VMEM2CHTYPE(v)	((v & 0xff0007ff) | \
1875         ((v & 0x00000800) << 10) | ((v & 0x00007000) >> 1))
1876 /* relay text rendering to the display driver
1877  * instead of doing a full vga_update_display() */
1878 static void vga_update_text(void *opaque, console_ch_t *chardata)
1879 {
1880     VGACommonState *s =  opaque;
1881     int graphic_mode, i, cursor_offset, cursor_visible;
1882     int cw, cheight, width, height, size, c_min, c_max;
1883     uint32_t *src;
1884     console_ch_t *dst, val;
1885     char msg_buffer[80];
1886     int full_update = 0;
1887 
1888     qemu_flush_coalesced_mmio_buffer();
1889 
1890     if (!(s->ar_index & 0x20)) {
1891         graphic_mode = GMODE_BLANK;
1892     } else {
1893         graphic_mode = s->gr[VGA_GFX_MISC] & VGA_GR06_GRAPHICS_MODE;
1894     }
1895     if (graphic_mode != s->graphic_mode) {
1896         s->graphic_mode = graphic_mode;
1897         full_update = 1;
1898     }
1899     if (s->last_width == -1) {
1900         s->last_width = 0;
1901         full_update = 1;
1902     }
1903 
1904     switch (graphic_mode) {
1905     case GMODE_TEXT:
1906         /* TODO: update palette */
1907         full_update |= update_basic_params(s);
1908 
1909         /* total width & height */
1910         cheight = (s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1;
1911         cw = 8;
1912         if (!(sr(s, VGA_SEQ_CLOCK_MODE) & VGA_SR01_CHAR_CLK_8DOTS)) {
1913             cw = 9;
1914         }
1915         if (sr(s, VGA_SEQ_CLOCK_MODE) & 0x08) {
1916             cw = 16; /* NOTE: no 18 pixel wide */
1917         }
1918         width = (s->cr[VGA_CRTC_H_DISP] + 1);
1919         if (s->cr[VGA_CRTC_V_TOTAL] == 100) {
1920             /* ugly hack for CGA 160x100x16 - explain me the logic */
1921             height = 100;
1922         } else {
1923             height = s->cr[VGA_CRTC_V_DISP_END] |
1924                 ((s->cr[VGA_CRTC_OVERFLOW] & 0x02) << 7) |
1925                 ((s->cr[VGA_CRTC_OVERFLOW] & 0x40) << 3);
1926             height = (height + 1) / cheight;
1927         }
1928 
1929         size = (height * width);
1930         if (size > CH_ATTR_SIZE) {
1931             if (!full_update)
1932                 return;
1933 
1934             snprintf(msg_buffer, sizeof(msg_buffer), "%i x %i Text mode",
1935                      width, height);
1936             break;
1937         }
1938 
1939         if (width != s->last_width || height != s->last_height ||
1940             cw != s->last_cw || cheight != s->last_ch) {
1941             s->last_scr_width = width * cw;
1942             s->last_scr_height = height * cheight;
1943             qemu_console_resize(s->con, s->last_scr_width, s->last_scr_height);
1944             dpy_text_resize(s->con, width, height);
1945             s->last_depth = 0;
1946             s->last_width = width;
1947             s->last_height = height;
1948             s->last_ch = cheight;
1949             s->last_cw = cw;
1950             full_update = 1;
1951         }
1952 
1953         if (full_update) {
1954             s->full_update_gfx = 1;
1955         }
1956         if (s->full_update_text) {
1957             s->full_update_text = 0;
1958             full_update |= 1;
1959         }
1960 
1961         /* Update "hardware" cursor */
1962         cursor_offset = ((s->cr[VGA_CRTC_CURSOR_HI] << 8) |
1963                          s->cr[VGA_CRTC_CURSOR_LO]) - s->params.start_addr;
1964         if (cursor_offset != s->cursor_offset ||
1965             s->cr[VGA_CRTC_CURSOR_START] != s->cursor_start ||
1966             s->cr[VGA_CRTC_CURSOR_END] != s->cursor_end || full_update) {
1967             cursor_visible = !(s->cr[VGA_CRTC_CURSOR_START] & 0x20);
1968             if (cursor_visible && cursor_offset < size && cursor_offset >= 0)
1969                 dpy_text_cursor(s->con,
1970                                 TEXTMODE_X(cursor_offset),
1971                                 TEXTMODE_Y(cursor_offset));
1972             else
1973                 dpy_text_cursor(s->con, -1, -1);
1974             s->cursor_offset = cursor_offset;
1975             s->cursor_start = s->cr[VGA_CRTC_CURSOR_START];
1976             s->cursor_end = s->cr[VGA_CRTC_CURSOR_END];
1977         }
1978 
1979         src = (uint32_t *) s->vram_ptr + s->params.start_addr;
1980         dst = chardata;
1981 
1982         if (full_update) {
1983             for (i = 0; i < size; src ++, dst ++, i ++)
1984                 console_write_ch(dst, VMEM2CHTYPE(le32_to_cpu(*src)));
1985 
1986             dpy_text_update(s->con, 0, 0, width, height);
1987         } else {
1988             c_max = 0;
1989 
1990             for (i = 0; i < size; src ++, dst ++, i ++) {
1991                 console_write_ch(&val, VMEM2CHTYPE(le32_to_cpu(*src)));
1992                 if (*dst != val) {
1993                     *dst = val;
1994                     c_max = i;
1995                     break;
1996                 }
1997             }
1998             c_min = i;
1999             for (; i < size; src ++, dst ++, i ++) {
2000                 console_write_ch(&val, VMEM2CHTYPE(le32_to_cpu(*src)));
2001                 if (*dst != val) {
2002                     *dst = val;
2003                     c_max = i;
2004                 }
2005             }
2006 
2007             if (c_min <= c_max) {
2008                 i = TEXTMODE_Y(c_min);
2009                 dpy_text_update(s->con, 0, i, width, TEXTMODE_Y(c_max) - i + 1);
2010             }
2011         }
2012 
2013         return;
2014     case GMODE_GRAPH:
2015         if (!full_update)
2016             return;
2017 
2018         s->get_resolution(s, &width, &height);
2019         snprintf(msg_buffer, sizeof(msg_buffer), "%i x %i Graphic mode",
2020                  width, height);
2021         break;
2022     case GMODE_BLANK:
2023     default:
2024         if (!full_update)
2025             return;
2026 
2027         snprintf(msg_buffer, sizeof(msg_buffer), "VGA Blank mode");
2028         break;
2029     }
2030 
2031     /* Display a message */
2032     s->last_width = 60;
2033     s->last_height = height = 3;
2034     dpy_text_cursor(s->con, -1, -1);
2035     dpy_text_resize(s->con, s->last_width, height);
2036 
2037     for (dst = chardata, i = 0; i < s->last_width * height; i ++)
2038         console_write_ch(dst ++, ' ');
2039 
2040     size = strlen(msg_buffer);
2041     width = (s->last_width - size) / 2;
2042     dst = chardata + s->last_width + width;
2043     for (i = 0; i < size; i ++)
2044         console_write_ch(dst ++, ATTR2CHTYPE(msg_buffer[i], QEMU_COLOR_BLUE,
2045                                              QEMU_COLOR_BLACK, 1));
2046 
2047     dpy_text_update(s->con, 0, 0, s->last_width, height);
2048 }
2049 
2050 static uint64_t vga_mem_read(void *opaque, hwaddr addr,
2051                              unsigned size)
2052 {
2053     VGACommonState *s = opaque;
2054 
2055     return vga_mem_readb(s, addr);
2056 }
2057 
2058 static void vga_mem_write(void *opaque, hwaddr addr,
2059                           uint64_t data, unsigned size)
2060 {
2061     VGACommonState *s = opaque;
2062 
2063     vga_mem_writeb(s, addr, data);
2064 }
2065 
2066 const MemoryRegionOps vga_mem_ops = {
2067     .read = vga_mem_read,
2068     .write = vga_mem_write,
2069     .endianness = DEVICE_LITTLE_ENDIAN,
2070     .impl = {
2071         .min_access_size = 1,
2072         .max_access_size = 1,
2073     },
2074 };
2075 
2076 static int vga_common_post_load(void *opaque, int version_id)
2077 {
2078     VGACommonState *s = opaque;
2079 
2080     /* force refresh */
2081     s->graphic_mode = -1;
2082     vbe_update_vgaregs(s);
2083     vga_update_memory_access(s);
2084     return 0;
2085 }
2086 
2087 static bool vga_endian_state_needed(void *opaque)
2088 {
2089     VGACommonState *s = opaque;
2090 
2091     /*
2092      * Only send the endian state if it's different from the
2093      * default one, thus ensuring backward compatibility for
2094      * migration of the common case
2095      */
2096     return s->default_endian_fb != s->big_endian_fb;
2097 }
2098 
2099 static const VMStateDescription vmstate_vga_endian = {
2100     .name = "vga.endian",
2101     .version_id = 1,
2102     .minimum_version_id = 1,
2103     .needed = vga_endian_state_needed,
2104     .fields = (const VMStateField[]) {
2105         VMSTATE_BOOL(big_endian_fb, VGACommonState),
2106         VMSTATE_END_OF_LIST()
2107     }
2108 };
2109 
2110 const VMStateDescription vmstate_vga_common = {
2111     .name = "vga",
2112     .version_id = 2,
2113     .minimum_version_id = 2,
2114     .post_load = vga_common_post_load,
2115     .fields = (const VMStateField[]) {
2116         VMSTATE_UINT32(latch, VGACommonState),
2117         VMSTATE_UINT8(sr_index, VGACommonState),
2118         VMSTATE_PARTIAL_BUFFER(sr, VGACommonState, 8),
2119         VMSTATE_UINT8(gr_index, VGACommonState),
2120         VMSTATE_PARTIAL_BUFFER(gr, VGACommonState, 16),
2121         VMSTATE_UINT8(ar_index, VGACommonState),
2122         VMSTATE_BUFFER(ar, VGACommonState),
2123         VMSTATE_INT32(ar_flip_flop, VGACommonState),
2124         VMSTATE_UINT8(cr_index, VGACommonState),
2125         VMSTATE_BUFFER(cr, VGACommonState),
2126         VMSTATE_UINT8(msr, VGACommonState),
2127         VMSTATE_UINT8(fcr, VGACommonState),
2128         VMSTATE_UINT8(st00, VGACommonState),
2129         VMSTATE_UINT8(st01, VGACommonState),
2130 
2131         VMSTATE_UINT8(dac_state, VGACommonState),
2132         VMSTATE_UINT8(dac_sub_index, VGACommonState),
2133         VMSTATE_UINT8(dac_read_index, VGACommonState),
2134         VMSTATE_UINT8(dac_write_index, VGACommonState),
2135         VMSTATE_BUFFER(dac_cache, VGACommonState),
2136         VMSTATE_BUFFER(palette, VGACommonState),
2137 
2138         VMSTATE_INT32(bank_offset, VGACommonState),
2139         VMSTATE_UINT8_EQUAL(is_vbe_vmstate, VGACommonState, NULL),
2140         VMSTATE_UINT16(vbe_index, VGACommonState),
2141         VMSTATE_UINT16_ARRAY(vbe_regs, VGACommonState, VBE_DISPI_INDEX_NB),
2142         VMSTATE_UINT32(vbe_start_addr, VGACommonState),
2143         VMSTATE_UINT32(vbe_line_offset, VGACommonState),
2144         VMSTATE_UINT32(vbe_bank_mask, VGACommonState),
2145         VMSTATE_END_OF_LIST()
2146     },
2147     .subsections = (const VMStateDescription * const []) {
2148         &vmstate_vga_endian,
2149         NULL
2150     }
2151 };
2152 
2153 static const GraphicHwOps vga_ops = {
2154     .invalidate  = vga_invalidate_display,
2155     .gfx_update  = vga_update_display,
2156     .text_update = vga_update_text,
2157 };
2158 
2159 static inline uint32_t uint_clamp(uint32_t val, uint32_t vmin, uint32_t vmax)
2160 {
2161     if (val < vmin) {
2162         return vmin;
2163     }
2164     if (val > vmax) {
2165         return vmax;
2166     }
2167     return val;
2168 }
2169 
2170 bool vga_common_init(VGACommonState *s, Object *obj, Error **errp)
2171 {
2172     int i, j, v, b;
2173     Error *local_err = NULL;
2174 
2175     for(i = 0;i < 256; i++) {
2176         v = 0;
2177         for(j = 0; j < 8; j++) {
2178             v |= ((i >> j) & 1) << (j * 4);
2179         }
2180         expand4[i] = v;
2181 
2182         v = 0;
2183         for(j = 0; j < 4; j++) {
2184             v |= ((i >> (2 * j)) & 3) << (j * 4);
2185         }
2186         expand2[i] = v;
2187     }
2188     for(i = 0; i < 16; i++) {
2189         v = 0;
2190         for(j = 0; j < 4; j++) {
2191             b = ((i >> j) & 1);
2192             v |= b << (2 * j);
2193             v |= b << (2 * j + 1);
2194         }
2195         expand4to8[i] = v;
2196     }
2197 
2198     s->vram_size_mb = uint_clamp(s->vram_size_mb, 1, 512);
2199     s->vram_size_mb = pow2ceil(s->vram_size_mb);
2200     s->vram_size = s->vram_size_mb * MiB;
2201 
2202     if (!s->vbe_size) {
2203         s->vbe_size = s->vram_size;
2204     }
2205     s->vbe_size_mask = s->vbe_size - 1;
2206 
2207     s->is_vbe_vmstate = 1;
2208 
2209     if (s->global_vmstate && qemu_ram_block_by_name("vga.vram")) {
2210         error_setg(errp, "Only one global VGA device can be used at a time");
2211         return false;
2212     }
2213 
2214     memory_region_init_ram_nomigrate(&s->vram, obj, "vga.vram", s->vram_size,
2215                                      &local_err);
2216     if (local_err) {
2217         error_propagate(errp, local_err);
2218         return false;
2219     }
2220     vmstate_register_ram(&s->vram, s->global_vmstate ? NULL : DEVICE(obj));
2221     xen_register_framebuffer(&s->vram);
2222     s->vram_ptr = memory_region_get_ram_ptr(&s->vram);
2223     s->get_bpp = vga_get_bpp;
2224     s->get_params = vga_get_params;
2225     s->get_resolution = vga_get_resolution;
2226     s->hw_ops = &vga_ops;
2227     switch (vga_retrace_method) {
2228     case VGA_RETRACE_DUMB:
2229         s->retrace = vga_dumb_retrace;
2230         s->update_retrace_info = vga_dumb_update_retrace_info;
2231         break;
2232 
2233     case VGA_RETRACE_PRECISE:
2234         s->retrace = vga_precise_retrace;
2235         s->update_retrace_info = vga_precise_update_retrace_info;
2236         break;
2237     }
2238 
2239     /*
2240      * Set default fb endian based on target, could probably be turned
2241      * into a device attribute set by the machine/platform to remove
2242      * all target endian dependencies from this file.
2243      */
2244     s->default_endian_fb = target_words_bigendian();
2245 
2246     vga_dirty_log_start(s);
2247 
2248     return true;
2249 }
2250 
2251 static const MemoryRegionPortio vga_portio_list[] = {
2252     { 0x04,  2, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3b4 */
2253     { 0x0a,  1, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3ba */
2254     { 0x10, 16, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3c0 */
2255     { 0x24,  2, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3d4 */
2256     { 0x2a,  1, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3da */
2257     PORTIO_END_OF_LIST(),
2258 };
2259 
2260 static const MemoryRegionPortio vbe_portio_list_x86[] = {
2261     { 0, 1, 2, .read = vbe_ioport_read_index, .write = vbe_ioport_write_index },
2262     { 1, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data },
2263     { 2, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data },
2264     PORTIO_END_OF_LIST(),
2265 };
2266 
2267 static const MemoryRegionPortio vbe_portio_list_no_x86[] = {
2268     { 0, 1, 2, .read = vbe_ioport_read_index, .write = vbe_ioport_write_index },
2269     { 2, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data },
2270     PORTIO_END_OF_LIST(),
2271 };
2272 
2273 /* Used by both ISA and PCI */
2274 MemoryRegion *vga_init_io(VGACommonState *s, Object *obj,
2275                           const MemoryRegionPortio **vga_ports,
2276                           const MemoryRegionPortio **vbe_ports)
2277 {
2278     MemoryRegion *vga_mem;
2279     MachineState *ms = MACHINE(qdev_get_machine());
2280 
2281     /*
2282      * We unfortunately need two VBE lists since non-x86 machines might
2283      * not be able to do 16-bit accesses at unaligned addresses (0x1cf)
2284      */
2285     if (object_dynamic_cast(OBJECT(ms), TYPE_X86_MACHINE)) {
2286         *vbe_ports = vbe_portio_list_x86;
2287     } else {
2288         *vbe_ports = vbe_portio_list_no_x86;
2289     }
2290 
2291     *vga_ports = vga_portio_list;
2292 
2293     vga_mem = g_malloc(sizeof(*vga_mem));
2294     memory_region_init_io(vga_mem, obj, &vga_mem_ops, s,
2295                           "vga-lowmem", 0x20000);
2296     memory_region_set_flush_coalesced(vga_mem);
2297 
2298     return vga_mem;
2299 }
2300 
2301 void vga_init(VGACommonState *s, Object *obj, MemoryRegion *address_space,
2302               MemoryRegion *address_space_io, bool init_vga_ports)
2303 {
2304     MemoryRegion *vga_io_memory;
2305     const MemoryRegionPortio *vga_ports, *vbe_ports;
2306 
2307     qemu_register_reset(vga_reset, s);
2308 
2309     s->bank_offset = 0;
2310 
2311     s->legacy_address_space = address_space;
2312 
2313     vga_io_memory = vga_init_io(s, obj, &vga_ports, &vbe_ports);
2314     memory_region_add_subregion_overlap(address_space,
2315                                         0x000a0000,
2316                                         vga_io_memory,
2317                                         1);
2318     memory_region_set_coalescing(vga_io_memory);
2319     if (init_vga_ports) {
2320         portio_list_init(&s->vga_port_list, obj, vga_ports, s, "vga");
2321         portio_list_set_flush_coalesced(&s->vga_port_list);
2322         portio_list_add(&s->vga_port_list, address_space_io, 0x3b0);
2323     }
2324     if (vbe_ports) {
2325         portio_list_init(&s->vbe_port_list, obj, vbe_ports, s, "vbe");
2326         portio_list_add(&s->vbe_port_list, address_space_io, 0x1ce);
2327     }
2328 }
2329