xref: /openbmc/qemu/hw/display/vga.c (revision 8fa3b702)
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-access.h"
1013 #include "vga-helpers.h"
1014 
1015 /* return true if the palette was modified */
1016 static int update_palette16(VGACommonState *s)
1017 {
1018     int full_update, i;
1019     uint32_t v, col, *palette;
1020 
1021     full_update = 0;
1022     palette = s->last_palette;
1023     for(i = 0; i < 16; i++) {
1024         v = s->ar[i];
1025         if (s->ar[VGA_ATC_MODE] & 0x80) {
1026             v = ((s->ar[VGA_ATC_COLOR_PAGE] & 0xf) << 4) | (v & 0xf);
1027         } else {
1028             v = ((s->ar[VGA_ATC_COLOR_PAGE] & 0xc) << 4) | (v & 0x3f);
1029         }
1030         v = v * 3;
1031         col = rgb_to_pixel32(c6_to_8(s->palette[v]),
1032                              c6_to_8(s->palette[v + 1]),
1033                              c6_to_8(s->palette[v + 2]));
1034         if (col != palette[i]) {
1035             full_update = 1;
1036             palette[i] = col;
1037         }
1038     }
1039     return full_update;
1040 }
1041 
1042 /* return true if the palette was modified */
1043 static int update_palette256(VGACommonState *s)
1044 {
1045     int full_update, i;
1046     uint32_t v, col, *palette;
1047 
1048     full_update = 0;
1049     palette = s->last_palette;
1050     v = 0;
1051     for(i = 0; i < 256; i++) {
1052         if (s->dac_8bit) {
1053             col = rgb_to_pixel32(s->palette[v],
1054                                  s->palette[v + 1],
1055                                  s->palette[v + 2]);
1056         } else {
1057             col = rgb_to_pixel32(c6_to_8(s->palette[v]),
1058                                  c6_to_8(s->palette[v + 1]),
1059                                  c6_to_8(s->palette[v + 2]));
1060         }
1061         if (col != palette[i]) {
1062             full_update = 1;
1063             palette[i] = col;
1064         }
1065         v += 3;
1066     }
1067     return full_update;
1068 }
1069 
1070 static void vga_get_offsets(VGACommonState *s,
1071                             uint32_t *pline_offset,
1072                             uint32_t *pstart_addr,
1073                             uint32_t *pline_compare)
1074 {
1075     uint32_t start_addr, line_offset, line_compare;
1076 
1077     if (vbe_enabled(s)) {
1078         line_offset = s->vbe_line_offset;
1079         start_addr = s->vbe_start_addr;
1080         line_compare = 65535;
1081     } else {
1082         /* compute line_offset in bytes */
1083         line_offset = s->cr[VGA_CRTC_OFFSET];
1084         line_offset <<= 3;
1085 
1086         /* starting address */
1087         start_addr = s->cr[VGA_CRTC_START_LO] |
1088             (s->cr[VGA_CRTC_START_HI] << 8);
1089 
1090         /* line compare */
1091         line_compare = s->cr[VGA_CRTC_LINE_COMPARE] |
1092             ((s->cr[VGA_CRTC_OVERFLOW] & 0x10) << 4) |
1093             ((s->cr[VGA_CRTC_MAX_SCAN] & 0x40) << 3);
1094     }
1095     *pline_offset = line_offset;
1096     *pstart_addr = start_addr;
1097     *pline_compare = line_compare;
1098 }
1099 
1100 /* update start_addr and line_offset. Return TRUE if modified */
1101 static int update_basic_params(VGACommonState *s)
1102 {
1103     int full_update;
1104     uint32_t start_addr, line_offset, line_compare;
1105 
1106     full_update = 0;
1107 
1108     s->get_offsets(s, &line_offset, &start_addr, &line_compare);
1109 
1110     if (line_offset != s->line_offset ||
1111         start_addr != s->start_addr ||
1112         line_compare != s->line_compare) {
1113         s->line_offset = line_offset;
1114         s->start_addr = start_addr;
1115         s->line_compare = line_compare;
1116         full_update = 1;
1117     }
1118     return full_update;
1119 }
1120 
1121 
1122 static const uint8_t cursor_glyph[32 * 4] = {
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     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1139 };
1140 
1141 static void vga_get_text_resolution(VGACommonState *s, int *pwidth, int *pheight,
1142                                     int *pcwidth, int *pcheight)
1143 {
1144     int width, cwidth, height, cheight;
1145 
1146     /* total width & height */
1147     cheight = (s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1;
1148     cwidth = 8;
1149     if (!(sr(s, VGA_SEQ_CLOCK_MODE) & VGA_SR01_CHAR_CLK_8DOTS)) {
1150         cwidth = 9;
1151     }
1152     if (sr(s, VGA_SEQ_CLOCK_MODE) & 0x08) {
1153         cwidth = 16; /* NOTE: no 18 pixel wide */
1154     }
1155     width = (s->cr[VGA_CRTC_H_DISP] + 1);
1156     if (s->cr[VGA_CRTC_V_TOTAL] == 100) {
1157         /* ugly hack for CGA 160x100x16 - explain me the logic */
1158         height = 100;
1159     } else {
1160         height = s->cr[VGA_CRTC_V_DISP_END] |
1161             ((s->cr[VGA_CRTC_OVERFLOW] & 0x02) << 7) |
1162             ((s->cr[VGA_CRTC_OVERFLOW] & 0x40) << 3);
1163         height = (height + 1) / cheight;
1164     }
1165 
1166     *pwidth = width;
1167     *pheight = height;
1168     *pcwidth = cwidth;
1169     *pcheight = cheight;
1170 }
1171 
1172 /*
1173  * Text mode update
1174  * Missing:
1175  * - double scan
1176  * - double width
1177  * - underline
1178  * - flashing
1179  */
1180 static void vga_draw_text(VGACommonState *s, int full_update)
1181 {
1182     DisplaySurface *surface = qemu_console_surface(s->con);
1183     int cx, cy, cheight, cw, ch, cattr, height, width, ch_attr;
1184     int cx_min, cx_max, linesize, x_incr, line, line1;
1185     uint32_t offset, fgcol, bgcol, v, cursor_offset;
1186     uint8_t *d1, *d, *src, *dest, *cursor_ptr;
1187     const uint8_t *font_ptr, *font_base[2];
1188     int dup9, line_offset;
1189     uint32_t *palette;
1190     uint32_t *ch_attr_ptr;
1191     int64_t now = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
1192 
1193     /* compute font data address (in plane 2) */
1194     v = sr(s, VGA_SEQ_CHARACTER_MAP);
1195     offset = (((v >> 4) & 1) | ((v << 1) & 6)) * 8192 * 4 + 2;
1196     if (offset != s->font_offsets[0]) {
1197         s->font_offsets[0] = offset;
1198         full_update = 1;
1199     }
1200     font_base[0] = s->vram_ptr + offset;
1201 
1202     offset = (((v >> 5) & 1) | ((v >> 1) & 6)) * 8192 * 4 + 2;
1203     font_base[1] = s->vram_ptr + offset;
1204     if (offset != s->font_offsets[1]) {
1205         s->font_offsets[1] = offset;
1206         full_update = 1;
1207     }
1208     if (s->plane_updated & (1 << 2) || s->has_chain4_alias) {
1209         /* if the plane 2 was modified since the last display, it
1210            indicates the font may have been modified */
1211         s->plane_updated = 0;
1212         full_update = 1;
1213     }
1214     full_update |= update_basic_params(s);
1215 
1216     line_offset = s->line_offset;
1217 
1218     vga_get_text_resolution(s, &width, &height, &cw, &cheight);
1219     if ((height * width) <= 1) {
1220         /* better than nothing: exit if transient size is too small */
1221         return;
1222     }
1223     if ((height * width) > CH_ATTR_SIZE) {
1224         /* better than nothing: exit if transient size is too big */
1225         return;
1226     }
1227 
1228     if (width != s->last_width || height != s->last_height ||
1229         cw != s->last_cw || cheight != s->last_ch || s->last_depth) {
1230         s->last_scr_width = width * cw;
1231         s->last_scr_height = height * cheight;
1232         qemu_console_resize(s->con, s->last_scr_width, s->last_scr_height);
1233         surface = qemu_console_surface(s->con);
1234         dpy_text_resize(s->con, width, height);
1235         s->last_depth = 0;
1236         s->last_width = width;
1237         s->last_height = height;
1238         s->last_ch = cheight;
1239         s->last_cw = cw;
1240         full_update = 1;
1241     }
1242     full_update |= update_palette16(s);
1243     palette = s->last_palette;
1244     x_incr = cw * surface_bytes_per_pixel(surface);
1245 
1246     if (full_update) {
1247         s->full_update_text = 1;
1248     }
1249     if (s->full_update_gfx) {
1250         s->full_update_gfx = 0;
1251         full_update |= 1;
1252     }
1253 
1254     cursor_offset = ((s->cr[VGA_CRTC_CURSOR_HI] << 8) |
1255                      s->cr[VGA_CRTC_CURSOR_LO]) - s->start_addr;
1256     if (cursor_offset != s->cursor_offset ||
1257         s->cr[VGA_CRTC_CURSOR_START] != s->cursor_start ||
1258         s->cr[VGA_CRTC_CURSOR_END] != s->cursor_end) {
1259       /* if the cursor position changed, we update the old and new
1260          chars */
1261         if (s->cursor_offset < CH_ATTR_SIZE)
1262             s->last_ch_attr[s->cursor_offset] = -1;
1263         if (cursor_offset < CH_ATTR_SIZE)
1264             s->last_ch_attr[cursor_offset] = -1;
1265         s->cursor_offset = cursor_offset;
1266         s->cursor_start = s->cr[VGA_CRTC_CURSOR_START];
1267         s->cursor_end = s->cr[VGA_CRTC_CURSOR_END];
1268     }
1269     cursor_ptr = s->vram_ptr + (s->start_addr + cursor_offset) * 4;
1270     if (now >= s->cursor_blink_time) {
1271         s->cursor_blink_time = now + VGA_TEXT_CURSOR_PERIOD_MS / 2;
1272         s->cursor_visible_phase = !s->cursor_visible_phase;
1273     }
1274 
1275     dest = surface_data(surface);
1276     linesize = surface_stride(surface);
1277     ch_attr_ptr = s->last_ch_attr;
1278     line = 0;
1279     offset = s->start_addr * 4;
1280     for(cy = 0; cy < height; cy++) {
1281         d1 = dest;
1282         src = s->vram_ptr + offset;
1283         cx_min = width;
1284         cx_max = -1;
1285         for(cx = 0; cx < width; cx++) {
1286             if (src + sizeof(uint16_t) > s->vram_ptr + s->vram_size) {
1287                 break;
1288             }
1289             ch_attr = *(uint16_t *)src;
1290             if (full_update || ch_attr != *ch_attr_ptr || src == cursor_ptr) {
1291                 if (cx < cx_min)
1292                     cx_min = cx;
1293                 if (cx > cx_max)
1294                     cx_max = cx;
1295                 *ch_attr_ptr = ch_attr;
1296 #ifdef HOST_WORDS_BIGENDIAN
1297                 ch = ch_attr >> 8;
1298                 cattr = ch_attr & 0xff;
1299 #else
1300                 ch = ch_attr & 0xff;
1301                 cattr = ch_attr >> 8;
1302 #endif
1303                 font_ptr = font_base[(cattr >> 3) & 1];
1304                 font_ptr += 32 * 4 * ch;
1305                 bgcol = palette[cattr >> 4];
1306                 fgcol = palette[cattr & 0x0f];
1307                 if (cw == 16) {
1308                     vga_draw_glyph16(d1, linesize,
1309                                      font_ptr, cheight, fgcol, bgcol);
1310                 } else if (cw != 9) {
1311                     vga_draw_glyph8(d1, linesize,
1312                                     font_ptr, cheight, fgcol, bgcol);
1313                 } else {
1314                     dup9 = 0;
1315                     if (ch >= 0xb0 && ch <= 0xdf &&
1316                         (s->ar[VGA_ATC_MODE] & 0x04)) {
1317                         dup9 = 1;
1318                     }
1319                     vga_draw_glyph9(d1, linesize,
1320                                     font_ptr, cheight, fgcol, bgcol, dup9);
1321                 }
1322                 if (src == cursor_ptr &&
1323                     !(s->cr[VGA_CRTC_CURSOR_START] & 0x20) &&
1324                     s->cursor_visible_phase) {
1325                     int line_start, line_last, h;
1326                     /* draw the cursor */
1327                     line_start = s->cr[VGA_CRTC_CURSOR_START] & 0x1f;
1328                     line_last = s->cr[VGA_CRTC_CURSOR_END] & 0x1f;
1329                     /* XXX: check that */
1330                     if (line_last > cheight - 1)
1331                         line_last = cheight - 1;
1332                     if (line_last >= line_start && line_start < cheight) {
1333                         h = line_last - line_start + 1;
1334                         d = d1 + linesize * line_start;
1335                         if (cw == 16) {
1336                             vga_draw_glyph16(d, linesize,
1337                                              cursor_glyph, h, fgcol, bgcol);
1338                         } else if (cw != 9) {
1339                             vga_draw_glyph8(d, linesize,
1340                                             cursor_glyph, h, fgcol, bgcol);
1341                         } else {
1342                             vga_draw_glyph9(d, linesize,
1343                                             cursor_glyph, h, fgcol, bgcol, 1);
1344                         }
1345                     }
1346                 }
1347             }
1348             d1 += x_incr;
1349             src += 4;
1350             ch_attr_ptr++;
1351         }
1352         if (cx_max != -1) {
1353             dpy_gfx_update(s->con, cx_min * cw, cy * cheight,
1354                            (cx_max - cx_min + 1) * cw, cheight);
1355         }
1356         dest += linesize * cheight;
1357         line1 = line + cheight;
1358         offset += line_offset;
1359         if (line < s->line_compare && line1 >= s->line_compare) {
1360             offset = 0;
1361         }
1362         line = line1;
1363     }
1364 }
1365 
1366 enum {
1367     VGA_DRAW_LINE2,
1368     VGA_DRAW_LINE2D2,
1369     VGA_DRAW_LINE4,
1370     VGA_DRAW_LINE4D2,
1371     VGA_DRAW_LINE8D2,
1372     VGA_DRAW_LINE8,
1373     VGA_DRAW_LINE15_LE,
1374     VGA_DRAW_LINE16_LE,
1375     VGA_DRAW_LINE24_LE,
1376     VGA_DRAW_LINE32_LE,
1377     VGA_DRAW_LINE15_BE,
1378     VGA_DRAW_LINE16_BE,
1379     VGA_DRAW_LINE24_BE,
1380     VGA_DRAW_LINE32_BE,
1381     VGA_DRAW_LINE_NB,
1382 };
1383 
1384 static vga_draw_line_func * const vga_draw_line_table[VGA_DRAW_LINE_NB] = {
1385     vga_draw_line2,
1386     vga_draw_line2d2,
1387     vga_draw_line4,
1388     vga_draw_line4d2,
1389     vga_draw_line8d2,
1390     vga_draw_line8,
1391     vga_draw_line15_le,
1392     vga_draw_line16_le,
1393     vga_draw_line24_le,
1394     vga_draw_line32_le,
1395     vga_draw_line15_be,
1396     vga_draw_line16_be,
1397     vga_draw_line24_be,
1398     vga_draw_line32_be,
1399 };
1400 
1401 static int vga_get_bpp(VGACommonState *s)
1402 {
1403     int ret;
1404 
1405     if (vbe_enabled(s)) {
1406         ret = s->vbe_regs[VBE_DISPI_INDEX_BPP];
1407     } else {
1408         ret = 0;
1409     }
1410     return ret;
1411 }
1412 
1413 static void vga_get_resolution(VGACommonState *s, int *pwidth, int *pheight)
1414 {
1415     int width, height;
1416 
1417     if (vbe_enabled(s)) {
1418         width = s->vbe_regs[VBE_DISPI_INDEX_XRES];
1419         height = s->vbe_regs[VBE_DISPI_INDEX_YRES];
1420     } else {
1421         width = (s->cr[VGA_CRTC_H_DISP] + 1) * 8;
1422         height = s->cr[VGA_CRTC_V_DISP_END] |
1423             ((s->cr[VGA_CRTC_OVERFLOW] & 0x02) << 7) |
1424             ((s->cr[VGA_CRTC_OVERFLOW] & 0x40) << 3);
1425         height = (height + 1);
1426     }
1427     *pwidth = width;
1428     *pheight = height;
1429 }
1430 
1431 void vga_invalidate_scanlines(VGACommonState *s, int y1, int y2)
1432 {
1433     int y;
1434     if (y1 >= VGA_MAX_HEIGHT)
1435         return;
1436     if (y2 >= VGA_MAX_HEIGHT)
1437         y2 = VGA_MAX_HEIGHT;
1438     for(y = y1; y < y2; y++) {
1439         s->invalidated_y_table[y >> 5] |= 1 << (y & 0x1f);
1440     }
1441 }
1442 
1443 static bool vga_scanline_invalidated(VGACommonState *s, int y)
1444 {
1445     if (y >= VGA_MAX_HEIGHT) {
1446         return false;
1447     }
1448     return s->invalidated_y_table[y >> 5] & (1 << (y & 0x1f));
1449 }
1450 
1451 void vga_dirty_log_start(VGACommonState *s)
1452 {
1453     memory_region_set_log(&s->vram, true, DIRTY_MEMORY_VGA);
1454 }
1455 
1456 void vga_dirty_log_stop(VGACommonState *s)
1457 {
1458     memory_region_set_log(&s->vram, false, DIRTY_MEMORY_VGA);
1459 }
1460 
1461 /*
1462  * graphic modes
1463  */
1464 static void vga_draw_graphic(VGACommonState *s, int full_update)
1465 {
1466     DisplaySurface *surface = qemu_console_surface(s->con);
1467     int y1, y, update, linesize, y_start, double_scan, mask, depth;
1468     int width, height, shift_control, bwidth, bits;
1469     ram_addr_t page0, page1, region_start, region_end;
1470     DirtyBitmapSnapshot *snap = NULL;
1471     int disp_width, multi_scan, multi_run;
1472     uint8_t *d;
1473     uint32_t v, addr1, addr;
1474     vga_draw_line_func *vga_draw_line = NULL;
1475     bool share_surface, force_shadow = false;
1476     pixman_format_code_t format;
1477 #ifdef HOST_WORDS_BIGENDIAN
1478     bool byteswap = !s->big_endian_fb;
1479 #else
1480     bool byteswap = s->big_endian_fb;
1481 #endif
1482 
1483     full_update |= update_basic_params(s);
1484 
1485     s->get_resolution(s, &width, &height);
1486     disp_width = width;
1487     depth = s->get_bpp(s);
1488 
1489     region_start = (s->start_addr * 4);
1490     region_end = region_start + (ram_addr_t)s->line_offset * height;
1491     region_end += width * depth / 8; /* scanline length */
1492     region_end -= s->line_offset;
1493     if (region_end > s->vbe_size || depth == 0 || depth == 15) {
1494         /*
1495          * We land here on:
1496          *  - wraps around (can happen with cirrus vbe modes)
1497          *  - depth == 0 (256 color palette video mode)
1498          *  - depth == 15
1499          *
1500          * Take the safe and slow route:
1501          *   - create a dirty bitmap snapshot for all vga memory.
1502          *   - force shadowing (so all vga memory access goes
1503          *     through vga_read_*() helpers).
1504          *
1505          * Given this affects only vga features which are pretty much
1506          * unused by modern guests there should be no performance
1507          * impact.
1508          */
1509         region_start = 0;
1510         region_end = s->vbe_size;
1511         force_shadow = true;
1512     }
1513 
1514     shift_control = (s->gr[VGA_GFX_MODE] >> 5) & 3;
1515     double_scan = (s->cr[VGA_CRTC_MAX_SCAN] >> 7);
1516     if (shift_control != 1) {
1517         multi_scan = (((s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1) << double_scan)
1518             - 1;
1519     } else {
1520         /* in CGA modes, multi_scan is ignored */
1521         /* XXX: is it correct ? */
1522         multi_scan = double_scan;
1523     }
1524     multi_run = multi_scan;
1525     if (shift_control != s->shift_control ||
1526         double_scan != s->double_scan) {
1527         full_update = 1;
1528         s->shift_control = shift_control;
1529         s->double_scan = double_scan;
1530     }
1531 
1532     if (shift_control == 0) {
1533         if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) {
1534             disp_width <<= 1;
1535         }
1536     } else if (shift_control == 1) {
1537         if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) {
1538             disp_width <<= 1;
1539         }
1540     }
1541 
1542     /*
1543      * Check whether we can share the surface with the backend
1544      * or whether we need a shadow surface. We share native
1545      * endian surfaces for 15bpp and above and byteswapped
1546      * surfaces for 24bpp and above.
1547      */
1548     format = qemu_default_pixman_format(depth, !byteswap);
1549     if (format) {
1550         share_surface = dpy_gfx_check_format(s->con, format)
1551             && !s->force_shadow && !force_shadow;
1552     } else {
1553         share_surface = false;
1554     }
1555 
1556     if (s->line_offset != s->last_line_offset ||
1557         disp_width != s->last_width ||
1558         height != s->last_height ||
1559         s->last_depth != depth ||
1560         s->last_byteswap != byteswap ||
1561         share_surface != is_buffer_shared(surface)) {
1562         /* display parameters changed -> need new display surface */
1563         s->last_scr_width = disp_width;
1564         s->last_scr_height = height;
1565         s->last_width = disp_width;
1566         s->last_height = height;
1567         s->last_line_offset = s->line_offset;
1568         s->last_depth = depth;
1569         s->last_byteswap = byteswap;
1570         full_update = 1;
1571     }
1572     if (surface_data(surface) != s->vram_ptr + (s->start_addr * 4)
1573         && is_buffer_shared(surface)) {
1574         /* base address changed (page flip) -> shared display surfaces
1575          * must be updated with the new base address */
1576         full_update = 1;
1577     }
1578 
1579     if (full_update) {
1580         if (share_surface) {
1581             surface = qemu_create_displaysurface_from(disp_width,
1582                     height, format, s->line_offset,
1583                     s->vram_ptr + (s->start_addr * 4));
1584             dpy_gfx_replace_surface(s->con, surface);
1585         } else {
1586             qemu_console_resize(s->con, disp_width, height);
1587             surface = qemu_console_surface(s->con);
1588         }
1589     }
1590 
1591     if (shift_control == 0) {
1592         full_update |= update_palette16(s);
1593         if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) {
1594             v = VGA_DRAW_LINE4D2;
1595         } else {
1596             v = VGA_DRAW_LINE4;
1597         }
1598         bits = 4;
1599     } else if (shift_control == 1) {
1600         full_update |= update_palette16(s);
1601         if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) {
1602             v = VGA_DRAW_LINE2D2;
1603         } else {
1604             v = VGA_DRAW_LINE2;
1605         }
1606         bits = 4;
1607     } else {
1608         switch(s->get_bpp(s)) {
1609         default:
1610         case 0:
1611             full_update |= update_palette256(s);
1612             v = VGA_DRAW_LINE8D2;
1613             bits = 4;
1614             break;
1615         case 8:
1616             full_update |= update_palette256(s);
1617             v = VGA_DRAW_LINE8;
1618             bits = 8;
1619             break;
1620         case 15:
1621             v = s->big_endian_fb ? VGA_DRAW_LINE15_BE : VGA_DRAW_LINE15_LE;
1622             bits = 16;
1623             break;
1624         case 16:
1625             v = s->big_endian_fb ? VGA_DRAW_LINE16_BE : VGA_DRAW_LINE16_LE;
1626             bits = 16;
1627             break;
1628         case 24:
1629             v = s->big_endian_fb ? VGA_DRAW_LINE24_BE : VGA_DRAW_LINE24_LE;
1630             bits = 24;
1631             break;
1632         case 32:
1633             v = s->big_endian_fb ? VGA_DRAW_LINE32_BE : VGA_DRAW_LINE32_LE;
1634             bits = 32;
1635             break;
1636         }
1637     }
1638     vga_draw_line = vga_draw_line_table[v];
1639 
1640     if (!is_buffer_shared(surface) && s->cursor_invalidate) {
1641         s->cursor_invalidate(s);
1642     }
1643 
1644 #if 0
1645     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",
1646            width, height, v, line_offset, s->cr[9], s->cr[VGA_CRTC_MODE],
1647            s->line_compare, sr(s, VGA_SEQ_CLOCK_MODE));
1648 #endif
1649     addr1 = (s->start_addr * 4);
1650     bwidth = DIV_ROUND_UP(width * bits, 8);
1651     y_start = -1;
1652     d = surface_data(surface);
1653     linesize = surface_stride(surface);
1654     y1 = 0;
1655 
1656     if (!full_update) {
1657         if (s->line_compare < height) {
1658             /* split screen mode */
1659             region_start = 0;
1660         }
1661         snap = memory_region_snapshot_and_clear_dirty(&s->vram, region_start,
1662                                                       region_end - region_start,
1663                                                       DIRTY_MEMORY_VGA);
1664     }
1665 
1666     for(y = 0; y < height; y++) {
1667         addr = addr1;
1668         if (!(s->cr[VGA_CRTC_MODE] & 1)) {
1669             int shift;
1670             /* CGA compatibility handling */
1671             shift = 14 + ((s->cr[VGA_CRTC_MODE] >> 6) & 1);
1672             addr = (addr & ~(1 << shift)) | ((y1 & 1) << shift);
1673         }
1674         if (!(s->cr[VGA_CRTC_MODE] & 2)) {
1675             addr = (addr & ~0x8000) | ((y1 & 2) << 14);
1676         }
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