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