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