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