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