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