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