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