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