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