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