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