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