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