xref: /openbmc/qemu/hw/display/vga.c (revision 5aa8136020f47fbd38c458b9834c783cb7063db8)
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 "hw/hw.h"
25 #include "vga.h"
26 #include "ui/console.h"
27 #include "hw/i386/pc.h"
28 #include "hw/pci/pci.h"
29 #include "vga_int.h"
30 #include "ui/pixel_ops.h"
31 #include "qemu/timer.h"
32 #include "hw/xen/xen.h"
33 #include "trace.h"
34 
35 //#define DEBUG_VGA
36 //#define DEBUG_VGA_MEM
37 //#define DEBUG_VGA_REG
38 
39 //#define DEBUG_BOCHS_VBE
40 
41 /* 16 state changes per vertical frame @60 Hz */
42 #define VGA_TEXT_CURSOR_PERIOD_MS       (1000 * 2 * 16 / 60)
43 
44 /*
45  * Video Graphics Array (VGA)
46  *
47  * Chipset docs for original IBM VGA:
48  * http://www.mcamafia.de/pdf/ibm_vgaxga_trm2.pdf
49  *
50  * FreeVGA site:
51  * http://www.osdever.net/FreeVGA/home.htm
52  *
53  * Standard VGA features and Bochs VBE extensions are implemented.
54  */
55 
56 /* force some bits to zero */
57 const uint8_t sr_mask[8] = {
58     0x03,
59     0x3d,
60     0x0f,
61     0x3f,
62     0x0e,
63     0x00,
64     0x00,
65     0xff,
66 };
67 
68 const uint8_t gr_mask[16] = {
69     0x0f, /* 0x00 */
70     0x0f, /* 0x01 */
71     0x0f, /* 0x02 */
72     0x1f, /* 0x03 */
73     0x03, /* 0x04 */
74     0x7b, /* 0x05 */
75     0x0f, /* 0x06 */
76     0x0f, /* 0x07 */
77     0xff, /* 0x08 */
78     0x00, /* 0x09 */
79     0x00, /* 0x0a */
80     0x00, /* 0x0b */
81     0x00, /* 0x0c */
82     0x00, /* 0x0d */
83     0x00, /* 0x0e */
84     0x00, /* 0x0f */
85 };
86 
87 #define cbswap_32(__x) \
88 ((uint32_t)( \
89 		(((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \
90 		(((uint32_t)(__x) & (uint32_t)0x0000ff00UL) <<  8) | \
91 		(((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >>  8) | \
92 		(((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) ))
93 
94 #ifdef HOST_WORDS_BIGENDIAN
95 #define PAT(x) cbswap_32(x)
96 #else
97 #define PAT(x) (x)
98 #endif
99 
100 #ifdef HOST_WORDS_BIGENDIAN
101 #define BIG 1
102 #else
103 #define BIG 0
104 #endif
105 
106 #ifdef HOST_WORDS_BIGENDIAN
107 #define GET_PLANE(data, p) (((data) >> (24 - (p) * 8)) & 0xff)
108 #else
109 #define GET_PLANE(data, p) (((data) >> ((p) * 8)) & 0xff)
110 #endif
111 
112 static const uint32_t mask16[16] = {
113     PAT(0x00000000),
114     PAT(0x000000ff),
115     PAT(0x0000ff00),
116     PAT(0x0000ffff),
117     PAT(0x00ff0000),
118     PAT(0x00ff00ff),
119     PAT(0x00ffff00),
120     PAT(0x00ffffff),
121     PAT(0xff000000),
122     PAT(0xff0000ff),
123     PAT(0xff00ff00),
124     PAT(0xff00ffff),
125     PAT(0xffff0000),
126     PAT(0xffff00ff),
127     PAT(0xffffff00),
128     PAT(0xffffffff),
129 };
130 
131 #undef PAT
132 
133 #ifdef HOST_WORDS_BIGENDIAN
134 #define PAT(x) (x)
135 #else
136 #define PAT(x) cbswap_32(x)
137 #endif
138 
139 static uint32_t expand4[256];
140 static uint16_t expand2[256];
141 static uint8_t expand4to8[16];
142 
143 static void vga_update_memory_access(VGACommonState *s)
144 {
145     hwaddr base, offset, size;
146 
147     if (s->legacy_address_space == NULL) {
148         return;
149     }
150 
151     if (s->has_chain4_alias) {
152         memory_region_del_subregion(s->legacy_address_space, &s->chain4_alias);
153         object_unparent(OBJECT(&s->chain4_alias));
154         s->has_chain4_alias = false;
155         s->plane_updated = 0xf;
156     }
157     if ((s->sr[VGA_SEQ_PLANE_WRITE] & VGA_SR02_ALL_PLANES) ==
158         VGA_SR02_ALL_PLANES && s->sr[VGA_SEQ_MEMORY_MODE] & VGA_SR04_CHN_4M) {
159         offset = 0;
160         switch ((s->gr[VGA_GFX_MISC] >> 2) & 3) {
161         case 0:
162             base = 0xa0000;
163             size = 0x20000;
164             break;
165         case 1:
166             base = 0xa0000;
167             size = 0x10000;
168             offset = s->bank_offset;
169             break;
170         case 2:
171             base = 0xb0000;
172             size = 0x8000;
173             break;
174         case 3:
175         default:
176             base = 0xb8000;
177             size = 0x8000;
178             break;
179         }
180         base += isa_mem_base;
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 #ifdef HOST_WORDS_BIGENDIAN
1441     bool byteswap = !s->big_endian_fb;
1442 #else
1443     bool byteswap = s->big_endian_fb;
1444 #endif
1445 
1446     full_update |= update_basic_params(s);
1447 
1448     if (!full_update)
1449         vga_sync_dirty_bitmap(s);
1450 
1451     s->get_resolution(s, &width, &height);
1452     disp_width = width;
1453 
1454     shift_control = (s->gr[VGA_GFX_MODE] >> 5) & 3;
1455     double_scan = (s->cr[VGA_CRTC_MAX_SCAN] >> 7);
1456     if (shift_control != 1) {
1457         multi_scan = (((s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1) << double_scan)
1458             - 1;
1459     } else {
1460         /* in CGA modes, multi_scan is ignored */
1461         /* XXX: is it correct ? */
1462         multi_scan = double_scan;
1463     }
1464     multi_run = multi_scan;
1465     if (shift_control != s->shift_control ||
1466         double_scan != s->double_scan) {
1467         full_update = 1;
1468         s->shift_control = shift_control;
1469         s->double_scan = double_scan;
1470     }
1471 
1472     if (shift_control == 0) {
1473         if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) {
1474             disp_width <<= 1;
1475         }
1476     } else if (shift_control == 1) {
1477         if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) {
1478             disp_width <<= 1;
1479         }
1480     }
1481 
1482     depth = s->get_bpp(s);
1483 
1484     share_surface = (!s->force_shadow) &&
1485             ( depth == 32 || (depth == 16 && !byteswap) );
1486     if (s->line_offset != s->last_line_offset ||
1487         disp_width != s->last_width ||
1488         height != s->last_height ||
1489         s->last_depth != depth ||
1490         s->last_byteswap != byteswap ||
1491         share_surface != is_buffer_shared(surface)) {
1492         if (share_surface) {
1493             pixman_format_code_t format =
1494                 qemu_default_pixman_format(depth, !byteswap);
1495             surface = qemu_create_displaysurface_from(disp_width,
1496                     height, format, s->line_offset,
1497                     s->vram_ptr + (s->start_addr * 4));
1498             dpy_gfx_replace_surface(s->con, surface);
1499 #ifdef DEBUG_VGA
1500             printf("VGA: Using shared surface for depth=%d swap=%d\n",
1501                    depth, byteswap);
1502 #endif
1503         } else {
1504             qemu_console_resize(s->con, disp_width, height);
1505             surface = qemu_console_surface(s->con);
1506 #ifdef DEBUG_VGA
1507             printf("VGA: Using shadow surface for depth=%d swap=%d\n",
1508                    depth, byteswap);
1509 #endif
1510         }
1511         s->last_scr_width = disp_width;
1512         s->last_scr_height = height;
1513         s->last_width = disp_width;
1514         s->last_height = height;
1515         s->last_line_offset = s->line_offset;
1516         s->last_depth = depth;
1517         s->last_byteswap = byteswap;
1518         full_update = 1;
1519     } else if (is_buffer_shared(surface) &&
1520                (full_update || surface_data(surface) != s->vram_ptr
1521                 + (s->start_addr * 4))) {
1522         pixman_format_code_t format =
1523             qemu_default_pixman_format(depth, !byteswap);
1524         surface = qemu_create_displaysurface_from(disp_width,
1525                 height, format, s->line_offset,
1526                 s->vram_ptr + (s->start_addr * 4));
1527         dpy_gfx_replace_surface(s->con, surface);
1528     }
1529 
1530     if (shift_control == 0) {
1531         full_update |= update_palette16(s);
1532         if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) {
1533             v = VGA_DRAW_LINE4D2;
1534         } else {
1535             v = VGA_DRAW_LINE4;
1536         }
1537         bits = 4;
1538     } else if (shift_control == 1) {
1539         full_update |= update_palette16(s);
1540         if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) {
1541             v = VGA_DRAW_LINE2D2;
1542         } else {
1543             v = VGA_DRAW_LINE2;
1544         }
1545         bits = 4;
1546     } else {
1547         switch(s->get_bpp(s)) {
1548         default:
1549         case 0:
1550             full_update |= update_palette256(s);
1551             v = VGA_DRAW_LINE8D2;
1552             bits = 4;
1553             break;
1554         case 8:
1555             full_update |= update_palette256(s);
1556             v = VGA_DRAW_LINE8;
1557             bits = 8;
1558             break;
1559         case 15:
1560             v = s->big_endian_fb ? VGA_DRAW_LINE15_BE : VGA_DRAW_LINE15_LE;
1561             bits = 16;
1562             break;
1563         case 16:
1564             v = s->big_endian_fb ? VGA_DRAW_LINE16_BE : VGA_DRAW_LINE16_LE;
1565             bits = 16;
1566             break;
1567         case 24:
1568             v = s->big_endian_fb ? VGA_DRAW_LINE24_BE : VGA_DRAW_LINE24_LE;
1569             bits = 24;
1570             break;
1571         case 32:
1572             v = s->big_endian_fb ? VGA_DRAW_LINE32_BE : VGA_DRAW_LINE32_LE;
1573             bits = 32;
1574             break;
1575         }
1576     }
1577     vga_draw_line = vga_draw_line_table[v];
1578 
1579     if (!is_buffer_shared(surface) && s->cursor_invalidate) {
1580         s->cursor_invalidate(s);
1581     }
1582 
1583     line_offset = s->line_offset;
1584 #if 0
1585     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",
1586            width, height, v, line_offset, s->cr[9], s->cr[VGA_CRTC_MODE],
1587            s->line_compare, s->sr[VGA_SEQ_CLOCK_MODE]);
1588 #endif
1589     addr1 = (s->start_addr * 4);
1590     bwidth = (width * bits + 7) / 8;
1591     y_start = -1;
1592     page_min = -1;
1593     page_max = 0;
1594     d = surface_data(surface);
1595     linesize = surface_stride(surface);
1596     y1 = 0;
1597     for(y = 0; y < height; y++) {
1598         addr = addr1;
1599         if (!(s->cr[VGA_CRTC_MODE] & 1)) {
1600             int shift;
1601             /* CGA compatibility handling */
1602             shift = 14 + ((s->cr[VGA_CRTC_MODE] >> 6) & 1);
1603             addr = (addr & ~(1 << shift)) | ((y1 & 1) << shift);
1604         }
1605         if (!(s->cr[VGA_CRTC_MODE] & 2)) {
1606             addr = (addr & ~0x8000) | ((y1 & 2) << 14);
1607         }
1608         update = full_update;
1609         page0 = addr;
1610         page1 = addr + bwidth - 1;
1611         update |= memory_region_get_dirty(&s->vram, page0, page1 - page0,
1612                                           DIRTY_MEMORY_VGA);
1613         /* explicit invalidation for the hardware cursor */
1614         update |= (s->invalidated_y_table[y >> 5] >> (y & 0x1f)) & 1;
1615         if (update) {
1616             if (y_start < 0)
1617                 y_start = y;
1618             if (page0 < page_min)
1619                 page_min = page0;
1620             if (page1 > page_max)
1621                 page_max = page1;
1622             if (!(is_buffer_shared(surface))) {
1623                 vga_draw_line(s, d, s->vram_ptr + addr, width);
1624                 if (s->cursor_draw_line)
1625                     s->cursor_draw_line(s, d, y);
1626             }
1627         } else {
1628             if (y_start >= 0) {
1629                 /* flush to display */
1630                 dpy_gfx_update(s->con, 0, y_start,
1631                                disp_width, y - y_start);
1632                 y_start = -1;
1633             }
1634         }
1635         if (!multi_run) {
1636             mask = (s->cr[VGA_CRTC_MODE] & 3) ^ 3;
1637             if ((y1 & mask) == mask)
1638                 addr1 += line_offset;
1639             y1++;
1640             multi_run = multi_scan;
1641         } else {
1642             multi_run--;
1643         }
1644         /* line compare acts on the displayed lines */
1645         if (y == s->line_compare)
1646             addr1 = 0;
1647         d += linesize;
1648     }
1649     if (y_start >= 0) {
1650         /* flush to display */
1651         dpy_gfx_update(s->con, 0, y_start,
1652                        disp_width, y - y_start);
1653     }
1654     /* reset modified pages */
1655     if (page_max >= page_min) {
1656         memory_region_reset_dirty(&s->vram,
1657                                   page_min,
1658                                   page_max - page_min,
1659                                   DIRTY_MEMORY_VGA);
1660     }
1661     memset(s->invalidated_y_table, 0, ((height + 31) >> 5) * 4);
1662 }
1663 
1664 static void vga_draw_blank(VGACommonState *s, int full_update)
1665 {
1666     DisplaySurface *surface = qemu_console_surface(s->con);
1667     int i, w;
1668     uint8_t *d;
1669 
1670     if (!full_update)
1671         return;
1672     if (s->last_scr_width <= 0 || s->last_scr_height <= 0)
1673         return;
1674 
1675     w = s->last_scr_width * surface_bytes_per_pixel(surface);
1676     d = surface_data(surface);
1677     for(i = 0; i < s->last_scr_height; i++) {
1678         memset(d, 0, w);
1679         d += surface_stride(surface);
1680     }
1681     dpy_gfx_update(s->con, 0, 0,
1682                    s->last_scr_width, s->last_scr_height);
1683 }
1684 
1685 #define GMODE_TEXT     0
1686 #define GMODE_GRAPH    1
1687 #define GMODE_BLANK 2
1688 
1689 static void vga_update_display(void *opaque)
1690 {
1691     VGACommonState *s = opaque;
1692     DisplaySurface *surface = qemu_console_surface(s->con);
1693     int full_update, graphic_mode;
1694 
1695     qemu_flush_coalesced_mmio_buffer();
1696 
1697     if (surface_bits_per_pixel(surface) == 0) {
1698         /* nothing to do */
1699     } else {
1700         full_update = 0;
1701         if (!(s->ar_index & 0x20)) {
1702             graphic_mode = GMODE_BLANK;
1703         } else {
1704             graphic_mode = s->gr[VGA_GFX_MISC] & VGA_GR06_GRAPHICS_MODE;
1705         }
1706         if (graphic_mode != s->graphic_mode) {
1707             s->graphic_mode = graphic_mode;
1708             s->cursor_blink_time = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
1709             full_update = 1;
1710         }
1711         switch(graphic_mode) {
1712         case GMODE_TEXT:
1713             vga_draw_text(s, full_update);
1714             break;
1715         case GMODE_GRAPH:
1716             vga_draw_graphic(s, full_update);
1717             break;
1718         case GMODE_BLANK:
1719         default:
1720             vga_draw_blank(s, full_update);
1721             break;
1722         }
1723     }
1724 }
1725 
1726 /* force a full display refresh */
1727 static void vga_invalidate_display(void *opaque)
1728 {
1729     VGACommonState *s = opaque;
1730 
1731     s->last_width = -1;
1732     s->last_height = -1;
1733 }
1734 
1735 void vga_common_reset(VGACommonState *s)
1736 {
1737     s->sr_index = 0;
1738     memset(s->sr, '\0', sizeof(s->sr));
1739     s->gr_index = 0;
1740     memset(s->gr, '\0', sizeof(s->gr));
1741     s->ar_index = 0;
1742     memset(s->ar, '\0', sizeof(s->ar));
1743     s->ar_flip_flop = 0;
1744     s->cr_index = 0;
1745     memset(s->cr, '\0', sizeof(s->cr));
1746     s->msr = 0;
1747     s->fcr = 0;
1748     s->st00 = 0;
1749     s->st01 = 0;
1750     s->dac_state = 0;
1751     s->dac_sub_index = 0;
1752     s->dac_read_index = 0;
1753     s->dac_write_index = 0;
1754     memset(s->dac_cache, '\0', sizeof(s->dac_cache));
1755     s->dac_8bit = 0;
1756     memset(s->palette, '\0', sizeof(s->palette));
1757     s->bank_offset = 0;
1758     s->vbe_index = 0;
1759     memset(s->vbe_regs, '\0', sizeof(s->vbe_regs));
1760     s->vbe_regs[VBE_DISPI_INDEX_ID] = VBE_DISPI_ID5;
1761     s->vbe_start_addr = 0;
1762     s->vbe_line_offset = 0;
1763     s->vbe_bank_mask = (s->vram_size >> 16) - 1;
1764     memset(s->font_offsets, '\0', sizeof(s->font_offsets));
1765     s->graphic_mode = -1; /* force full update */
1766     s->shift_control = 0;
1767     s->double_scan = 0;
1768     s->line_offset = 0;
1769     s->line_compare = 0;
1770     s->start_addr = 0;
1771     s->plane_updated = 0;
1772     s->last_cw = 0;
1773     s->last_ch = 0;
1774     s->last_width = 0;
1775     s->last_height = 0;
1776     s->last_scr_width = 0;
1777     s->last_scr_height = 0;
1778     s->cursor_start = 0;
1779     s->cursor_end = 0;
1780     s->cursor_offset = 0;
1781     s->big_endian_fb = s->default_endian_fb;
1782     memset(s->invalidated_y_table, '\0', sizeof(s->invalidated_y_table));
1783     memset(s->last_palette, '\0', sizeof(s->last_palette));
1784     memset(s->last_ch_attr, '\0', sizeof(s->last_ch_attr));
1785     switch (vga_retrace_method) {
1786     case VGA_RETRACE_DUMB:
1787         break;
1788     case VGA_RETRACE_PRECISE:
1789         memset(&s->retrace_info, 0, sizeof (s->retrace_info));
1790         break;
1791     }
1792     vga_update_memory_access(s);
1793 }
1794 
1795 static void vga_reset(void *opaque)
1796 {
1797     VGACommonState *s =  opaque;
1798     vga_common_reset(s);
1799 }
1800 
1801 #define TEXTMODE_X(x)	((x) % width)
1802 #define TEXTMODE_Y(x)	((x) / width)
1803 #define VMEM2CHTYPE(v)	((v & 0xff0007ff) | \
1804         ((v & 0x00000800) << 10) | ((v & 0x00007000) >> 1))
1805 /* relay text rendering to the display driver
1806  * instead of doing a full vga_update_display() */
1807 static void vga_update_text(void *opaque, console_ch_t *chardata)
1808 {
1809     VGACommonState *s =  opaque;
1810     int graphic_mode, i, cursor_offset, cursor_visible;
1811     int cw, cheight, width, height, size, c_min, c_max;
1812     uint32_t *src;
1813     console_ch_t *dst, val;
1814     char msg_buffer[80];
1815     int full_update = 0;
1816 
1817     qemu_flush_coalesced_mmio_buffer();
1818 
1819     if (!(s->ar_index & 0x20)) {
1820         graphic_mode = GMODE_BLANK;
1821     } else {
1822         graphic_mode = s->gr[VGA_GFX_MISC] & VGA_GR06_GRAPHICS_MODE;
1823     }
1824     if (graphic_mode != s->graphic_mode) {
1825         s->graphic_mode = graphic_mode;
1826         full_update = 1;
1827     }
1828     if (s->last_width == -1) {
1829         s->last_width = 0;
1830         full_update = 1;
1831     }
1832 
1833     switch (graphic_mode) {
1834     case GMODE_TEXT:
1835         /* TODO: update palette */
1836         full_update |= update_basic_params(s);
1837 
1838         /* total width & height */
1839         cheight = (s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1;
1840         cw = 8;
1841         if (!(s->sr[VGA_SEQ_CLOCK_MODE] & VGA_SR01_CHAR_CLK_8DOTS)) {
1842             cw = 9;
1843         }
1844         if (s->sr[VGA_SEQ_CLOCK_MODE] & 0x08) {
1845             cw = 16; /* NOTE: no 18 pixel wide */
1846         }
1847         width = (s->cr[VGA_CRTC_H_DISP] + 1);
1848         if (s->cr[VGA_CRTC_V_TOTAL] == 100) {
1849             /* ugly hack for CGA 160x100x16 - explain me the logic */
1850             height = 100;
1851         } else {
1852             height = s->cr[VGA_CRTC_V_DISP_END] |
1853                 ((s->cr[VGA_CRTC_OVERFLOW] & 0x02) << 7) |
1854                 ((s->cr[VGA_CRTC_OVERFLOW] & 0x40) << 3);
1855             height = (height + 1) / cheight;
1856         }
1857 
1858         size = (height * width);
1859         if (size > CH_ATTR_SIZE) {
1860             if (!full_update)
1861                 return;
1862 
1863             snprintf(msg_buffer, sizeof(msg_buffer), "%i x %i Text mode",
1864                      width, height);
1865             break;
1866         }
1867 
1868         if (width != s->last_width || height != s->last_height ||
1869             cw != s->last_cw || cheight != s->last_ch) {
1870             s->last_scr_width = width * cw;
1871             s->last_scr_height = height * cheight;
1872             qemu_console_resize(s->con, s->last_scr_width, s->last_scr_height);
1873             dpy_text_resize(s->con, width, height);
1874             s->last_depth = 0;
1875             s->last_width = width;
1876             s->last_height = height;
1877             s->last_ch = cheight;
1878             s->last_cw = cw;
1879             full_update = 1;
1880         }
1881 
1882         if (full_update) {
1883             s->full_update_gfx = 1;
1884         }
1885         if (s->full_update_text) {
1886             s->full_update_text = 0;
1887             full_update |= 1;
1888         }
1889 
1890         /* Update "hardware" cursor */
1891         cursor_offset = ((s->cr[VGA_CRTC_CURSOR_HI] << 8) |
1892                          s->cr[VGA_CRTC_CURSOR_LO]) - s->start_addr;
1893         if (cursor_offset != s->cursor_offset ||
1894             s->cr[VGA_CRTC_CURSOR_START] != s->cursor_start ||
1895             s->cr[VGA_CRTC_CURSOR_END] != s->cursor_end || full_update) {
1896             cursor_visible = !(s->cr[VGA_CRTC_CURSOR_START] & 0x20);
1897             if (cursor_visible && cursor_offset < size && cursor_offset >= 0)
1898                 dpy_text_cursor(s->con,
1899                                 TEXTMODE_X(cursor_offset),
1900                                 TEXTMODE_Y(cursor_offset));
1901             else
1902                 dpy_text_cursor(s->con, -1, -1);
1903             s->cursor_offset = cursor_offset;
1904             s->cursor_start = s->cr[VGA_CRTC_CURSOR_START];
1905             s->cursor_end = s->cr[VGA_CRTC_CURSOR_END];
1906         }
1907 
1908         src = (uint32_t *) s->vram_ptr + s->start_addr;
1909         dst = chardata;
1910 
1911         if (full_update) {
1912             for (i = 0; i < size; src ++, dst ++, i ++)
1913                 console_write_ch(dst, VMEM2CHTYPE(le32_to_cpu(*src)));
1914 
1915             dpy_text_update(s->con, 0, 0, width, height);
1916         } else {
1917             c_max = 0;
1918 
1919             for (i = 0; i < size; src ++, dst ++, i ++) {
1920                 console_write_ch(&val, VMEM2CHTYPE(le32_to_cpu(*src)));
1921                 if (*dst != val) {
1922                     *dst = val;
1923                     c_max = i;
1924                     break;
1925                 }
1926             }
1927             c_min = i;
1928             for (; i < size; src ++, dst ++, i ++) {
1929                 console_write_ch(&val, VMEM2CHTYPE(le32_to_cpu(*src)));
1930                 if (*dst != val) {
1931                     *dst = val;
1932                     c_max = i;
1933                 }
1934             }
1935 
1936             if (c_min <= c_max) {
1937                 i = TEXTMODE_Y(c_min);
1938                 dpy_text_update(s->con, 0, i, width, TEXTMODE_Y(c_max) - i + 1);
1939             }
1940         }
1941 
1942         return;
1943     case GMODE_GRAPH:
1944         if (!full_update)
1945             return;
1946 
1947         s->get_resolution(s, &width, &height);
1948         snprintf(msg_buffer, sizeof(msg_buffer), "%i x %i Graphic mode",
1949                  width, height);
1950         break;
1951     case GMODE_BLANK:
1952     default:
1953         if (!full_update)
1954             return;
1955 
1956         snprintf(msg_buffer, sizeof(msg_buffer), "VGA Blank mode");
1957         break;
1958     }
1959 
1960     /* Display a message */
1961     s->last_width = 60;
1962     s->last_height = height = 3;
1963     dpy_text_cursor(s->con, -1, -1);
1964     dpy_text_resize(s->con, s->last_width, height);
1965 
1966     for (dst = chardata, i = 0; i < s->last_width * height; i ++)
1967         console_write_ch(dst ++, ' ');
1968 
1969     size = strlen(msg_buffer);
1970     width = (s->last_width - size) / 2;
1971     dst = chardata + s->last_width + width;
1972     for (i = 0; i < size; i ++)
1973         console_write_ch(dst ++, 0x00200100 | msg_buffer[i]);
1974 
1975     dpy_text_update(s->con, 0, 0, s->last_width, height);
1976 }
1977 
1978 static uint64_t vga_mem_read(void *opaque, hwaddr addr,
1979                              unsigned size)
1980 {
1981     VGACommonState *s = opaque;
1982 
1983     return vga_mem_readb(s, addr);
1984 }
1985 
1986 static void vga_mem_write(void *opaque, hwaddr addr,
1987                           uint64_t data, unsigned size)
1988 {
1989     VGACommonState *s = opaque;
1990 
1991     return vga_mem_writeb(s, addr, data);
1992 }
1993 
1994 const MemoryRegionOps vga_mem_ops = {
1995     .read = vga_mem_read,
1996     .write = vga_mem_write,
1997     .endianness = DEVICE_LITTLE_ENDIAN,
1998     .impl = {
1999         .min_access_size = 1,
2000         .max_access_size = 1,
2001     },
2002 };
2003 
2004 static int vga_common_post_load(void *opaque, int version_id)
2005 {
2006     VGACommonState *s = opaque;
2007 
2008     /* force refresh */
2009     s->graphic_mode = -1;
2010     return 0;
2011 }
2012 
2013 static bool vga_endian_state_needed(void *opaque)
2014 {
2015     VGACommonState *s = opaque;
2016 
2017     /*
2018      * Only send the endian state if it's different from the
2019      * default one, thus ensuring backward compatibility for
2020      * migration of the common case
2021      */
2022     return s->default_endian_fb != s->big_endian_fb;
2023 }
2024 
2025 const VMStateDescription vmstate_vga_endian = {
2026     .name = "vga.endian",
2027     .version_id = 1,
2028     .minimum_version_id = 1,
2029     .fields = (VMStateField[]) {
2030         VMSTATE_BOOL(big_endian_fb, VGACommonState),
2031         VMSTATE_END_OF_LIST()
2032     }
2033 };
2034 
2035 const VMStateDescription vmstate_vga_common = {
2036     .name = "vga",
2037     .version_id = 2,
2038     .minimum_version_id = 2,
2039     .post_load = vga_common_post_load,
2040     .fields = (VMStateField[]) {
2041         VMSTATE_UINT32(latch, VGACommonState),
2042         VMSTATE_UINT8(sr_index, VGACommonState),
2043         VMSTATE_PARTIAL_BUFFER(sr, VGACommonState, 8),
2044         VMSTATE_UINT8(gr_index, VGACommonState),
2045         VMSTATE_PARTIAL_BUFFER(gr, VGACommonState, 16),
2046         VMSTATE_UINT8(ar_index, VGACommonState),
2047         VMSTATE_BUFFER(ar, VGACommonState),
2048         VMSTATE_INT32(ar_flip_flop, VGACommonState),
2049         VMSTATE_UINT8(cr_index, VGACommonState),
2050         VMSTATE_BUFFER(cr, VGACommonState),
2051         VMSTATE_UINT8(msr, VGACommonState),
2052         VMSTATE_UINT8(fcr, VGACommonState),
2053         VMSTATE_UINT8(st00, VGACommonState),
2054         VMSTATE_UINT8(st01, VGACommonState),
2055 
2056         VMSTATE_UINT8(dac_state, VGACommonState),
2057         VMSTATE_UINT8(dac_sub_index, VGACommonState),
2058         VMSTATE_UINT8(dac_read_index, VGACommonState),
2059         VMSTATE_UINT8(dac_write_index, VGACommonState),
2060         VMSTATE_BUFFER(dac_cache, VGACommonState),
2061         VMSTATE_BUFFER(palette, VGACommonState),
2062 
2063         VMSTATE_INT32(bank_offset, VGACommonState),
2064         VMSTATE_UINT8_EQUAL(is_vbe_vmstate, VGACommonState),
2065         VMSTATE_UINT16(vbe_index, VGACommonState),
2066         VMSTATE_UINT16_ARRAY(vbe_regs, VGACommonState, VBE_DISPI_INDEX_NB),
2067         VMSTATE_UINT32(vbe_start_addr, VGACommonState),
2068         VMSTATE_UINT32(vbe_line_offset, VGACommonState),
2069         VMSTATE_UINT32(vbe_bank_mask, VGACommonState),
2070         VMSTATE_END_OF_LIST()
2071     },
2072     .subsections = (VMStateSubsection []) {
2073         {
2074             .vmsd = &vmstate_vga_endian,
2075             .needed = vga_endian_state_needed,
2076         }, {
2077             /* empty */
2078         }
2079     }
2080 };
2081 
2082 static const GraphicHwOps vga_ops = {
2083     .invalidate  = vga_invalidate_display,
2084     .gfx_update  = vga_update_display,
2085     .text_update = vga_update_text,
2086 };
2087 
2088 void vga_common_init(VGACommonState *s, Object *obj, bool global_vmstate)
2089 {
2090     int i, j, v, b;
2091 
2092     for(i = 0;i < 256; i++) {
2093         v = 0;
2094         for(j = 0; j < 8; j++) {
2095             v |= ((i >> j) & 1) << (j * 4);
2096         }
2097         expand4[i] = v;
2098 
2099         v = 0;
2100         for(j = 0; j < 4; j++) {
2101             v |= ((i >> (2 * j)) & 3) << (j * 4);
2102         }
2103         expand2[i] = v;
2104     }
2105     for(i = 0; i < 16; i++) {
2106         v = 0;
2107         for(j = 0; j < 4; j++) {
2108             b = ((i >> j) & 1);
2109             v |= b << (2 * j);
2110             v |= b << (2 * j + 1);
2111         }
2112         expand4to8[i] = v;
2113     }
2114 
2115     /* valid range: 1 MB -> 256 MB */
2116     s->vram_size = 1024 * 1024;
2117     while (s->vram_size < (s->vram_size_mb << 20) &&
2118            s->vram_size < (256 << 20)) {
2119         s->vram_size <<= 1;
2120     }
2121     s->vram_size_mb = s->vram_size >> 20;
2122     if (!s->vbe_size) {
2123         s->vbe_size = s->vram_size;
2124     }
2125 
2126     s->is_vbe_vmstate = 1;
2127     memory_region_init_ram(&s->vram, obj, "vga.vram", s->vram_size,
2128                            &error_abort);
2129     vmstate_register_ram(&s->vram, global_vmstate ? NULL : DEVICE(obj));
2130     xen_register_framebuffer(&s->vram);
2131     s->vram_ptr = memory_region_get_ram_ptr(&s->vram);
2132     s->get_bpp = vga_get_bpp;
2133     s->get_offsets = vga_get_offsets;
2134     s->get_resolution = vga_get_resolution;
2135     s->hw_ops = &vga_ops;
2136     switch (vga_retrace_method) {
2137     case VGA_RETRACE_DUMB:
2138         s->retrace = vga_dumb_retrace;
2139         s->update_retrace_info = vga_dumb_update_retrace_info;
2140         break;
2141 
2142     case VGA_RETRACE_PRECISE:
2143         s->retrace = vga_precise_retrace;
2144         s->update_retrace_info = vga_precise_update_retrace_info;
2145         break;
2146     }
2147 
2148     /*
2149      * Set default fb endian based on target, could probably be turned
2150      * into a device attribute set by the machine/platform to remove
2151      * all target endian dependencies from this file.
2152      */
2153 #ifdef TARGET_WORDS_BIGENDIAN
2154     s->default_endian_fb = true;
2155 #else
2156     s->default_endian_fb = false;
2157 #endif
2158     vga_dirty_log_start(s);
2159 }
2160 
2161 static const MemoryRegionPortio vga_portio_list[] = {
2162     { 0x04,  2, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3b4 */
2163     { 0x0a,  1, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3ba */
2164     { 0x10, 16, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3c0 */
2165     { 0x24,  2, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3d4 */
2166     { 0x2a,  1, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3da */
2167     PORTIO_END_OF_LIST(),
2168 };
2169 
2170 static const MemoryRegionPortio vbe_portio_list[] = {
2171     { 0, 1, 2, .read = vbe_ioport_read_index, .write = vbe_ioport_write_index },
2172 # ifdef TARGET_I386
2173     { 1, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data },
2174 # endif
2175     { 2, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data },
2176     PORTIO_END_OF_LIST(),
2177 };
2178 
2179 /* Used by both ISA and PCI */
2180 MemoryRegion *vga_init_io(VGACommonState *s, Object *obj,
2181                           const MemoryRegionPortio **vga_ports,
2182                           const MemoryRegionPortio **vbe_ports)
2183 {
2184     MemoryRegion *vga_mem;
2185 
2186     *vga_ports = vga_portio_list;
2187     *vbe_ports = vbe_portio_list;
2188 
2189     vga_mem = g_malloc(sizeof(*vga_mem));
2190     memory_region_init_io(vga_mem, obj, &vga_mem_ops, s,
2191                           "vga-lowmem", 0x20000);
2192     memory_region_set_flush_coalesced(vga_mem);
2193 
2194     return vga_mem;
2195 }
2196 
2197 void vga_init(VGACommonState *s, Object *obj, MemoryRegion *address_space,
2198               MemoryRegion *address_space_io, bool init_vga_ports)
2199 {
2200     MemoryRegion *vga_io_memory;
2201     const MemoryRegionPortio *vga_ports, *vbe_ports;
2202 
2203     qemu_register_reset(vga_reset, s);
2204 
2205     s->bank_offset = 0;
2206 
2207     s->legacy_address_space = address_space;
2208 
2209     vga_io_memory = vga_init_io(s, obj, &vga_ports, &vbe_ports);
2210     memory_region_add_subregion_overlap(address_space,
2211                                         isa_mem_base + 0x000a0000,
2212                                         vga_io_memory,
2213                                         1);
2214     memory_region_set_coalescing(vga_io_memory);
2215     if (init_vga_ports) {
2216         portio_list_init(&s->vga_port_list, obj, vga_ports, s, "vga");
2217         portio_list_set_flush_coalesced(&s->vga_port_list);
2218         portio_list_add(&s->vga_port_list, address_space_io, 0x3b0);
2219     }
2220     if (vbe_ports) {
2221         portio_list_init(&s->vbe_port_list, obj, vbe_ports, s, "vbe");
2222         portio_list_add(&s->vbe_port_list, address_space_io, 0x1ce);
2223     }
2224 }
2225 
2226 void vga_init_vbe(VGACommonState *s, Object *obj, MemoryRegion *system_memory)
2227 {
2228     /* With pc-0.12 and below we map both the PCI BAR and the fixed VBE region,
2229      * so use an alias to avoid double-mapping the same region.
2230      */
2231     memory_region_init_alias(&s->vram_vbe, obj, "vram.vbe",
2232                              &s->vram, 0, memory_region_size(&s->vram));
2233     /* XXX: use optimized standard vga accesses */
2234     memory_region_add_subregion(system_memory,
2235                                 VBE_DISPI_LFB_PHYSICAL_ADDRESS,
2236                                 &s->vram_vbe);
2237     s->vbe_mapped = 1;
2238 }
2239