xref: /openbmc/qemu/hw/display/vga.c (revision 1b111dc1)
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     MemoryRegion *region, *old_region = s->chain4_alias;
172     hwaddr base, offset, size;
173 
174     s->chain4_alias = NULL;
175 
176     if ((s->sr[VGA_SEQ_PLANE_WRITE] & VGA_SR02_ALL_PLANES) ==
177         VGA_SR02_ALL_PLANES && s->sr[VGA_SEQ_MEMORY_MODE] & VGA_SR04_CHN_4M) {
178         offset = 0;
179         switch ((s->gr[VGA_GFX_MISC] >> 2) & 3) {
180         case 0:
181             base = 0xa0000;
182             size = 0x20000;
183             break;
184         case 1:
185             base = 0xa0000;
186             size = 0x10000;
187             offset = s->bank_offset;
188             break;
189         case 2:
190             base = 0xb0000;
191             size = 0x8000;
192             break;
193         case 3:
194         default:
195             base = 0xb8000;
196             size = 0x8000;
197             break;
198         }
199         base += isa_mem_base;
200         region = g_malloc(sizeof(*region));
201         memory_region_init_alias(region, memory_region_owner(&s->vram),
202                                  "vga.chain4", &s->vram, offset, size);
203         memory_region_add_subregion_overlap(s->legacy_address_space, base,
204                                             region, 2);
205         s->chain4_alias = region;
206     }
207     if (old_region) {
208         memory_region_del_subregion(s->legacy_address_space, old_region);
209         memory_region_destroy(old_region);
210         g_free(old_region);
211         s->plane_updated = 0xf;
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 static uint32_t vbe_ioport_read_index(void *opaque, uint32_t addr)
580 {
581     VGACommonState *s = opaque;
582     uint32_t val;
583     val = s->vbe_index;
584     return val;
585 }
586 
587 uint32_t vbe_ioport_read_data(void *opaque, uint32_t addr)
588 {
589     VGACommonState *s = opaque;
590     uint32_t val;
591 
592     if (s->vbe_index < VBE_DISPI_INDEX_NB) {
593         if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_GETCAPS) {
594             switch(s->vbe_index) {
595                 /* XXX: do not hardcode ? */
596             case VBE_DISPI_INDEX_XRES:
597                 val = VBE_DISPI_MAX_XRES;
598                 break;
599             case VBE_DISPI_INDEX_YRES:
600                 val = VBE_DISPI_MAX_YRES;
601                 break;
602             case VBE_DISPI_INDEX_BPP:
603                 val = VBE_DISPI_MAX_BPP;
604                 break;
605             default:
606                 val = s->vbe_regs[s->vbe_index];
607                 break;
608             }
609         } else {
610             val = s->vbe_regs[s->vbe_index];
611         }
612     } else if (s->vbe_index == VBE_DISPI_INDEX_VIDEO_MEMORY_64K) {
613         val = s->vram_size / (64 * 1024);
614     } else {
615         val = 0;
616     }
617 #ifdef DEBUG_BOCHS_VBE
618     printf("VBE: read index=0x%x val=0x%x\n", s->vbe_index, val);
619 #endif
620     return val;
621 }
622 
623 void vbe_ioport_write_index(void *opaque, uint32_t addr, uint32_t val)
624 {
625     VGACommonState *s = opaque;
626     s->vbe_index = val;
627 }
628 
629 void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
630 {
631     VGACommonState *s = opaque;
632 
633     if (s->vbe_index <= VBE_DISPI_INDEX_NB) {
634 #ifdef DEBUG_BOCHS_VBE
635         printf("VBE: write index=0x%x val=0x%x\n", s->vbe_index, val);
636 #endif
637         switch(s->vbe_index) {
638         case VBE_DISPI_INDEX_ID:
639             if (val == VBE_DISPI_ID0 ||
640                 val == VBE_DISPI_ID1 ||
641                 val == VBE_DISPI_ID2 ||
642                 val == VBE_DISPI_ID3 ||
643                 val == VBE_DISPI_ID4) {
644                 s->vbe_regs[s->vbe_index] = val;
645             }
646             break;
647         case VBE_DISPI_INDEX_XRES:
648             if ((val <= VBE_DISPI_MAX_XRES) && ((val & 7) == 0)) {
649                 s->vbe_regs[s->vbe_index] = val;
650             }
651             break;
652         case VBE_DISPI_INDEX_YRES:
653             if (val <= VBE_DISPI_MAX_YRES) {
654                 s->vbe_regs[s->vbe_index] = val;
655             }
656             break;
657         case VBE_DISPI_INDEX_BPP:
658             if (val == 0)
659                 val = 8;
660             if (val == 4 || val == 8 || val == 15 ||
661                 val == 16 || val == 24 || val == 32) {
662                 s->vbe_regs[s->vbe_index] = val;
663             }
664             break;
665         case VBE_DISPI_INDEX_BANK:
666             if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
667               val &= (s->vbe_bank_mask >> 2);
668             } else {
669               val &= s->vbe_bank_mask;
670             }
671             s->vbe_regs[s->vbe_index] = val;
672             s->bank_offset = (val << 16);
673             vga_update_memory_access(s);
674             break;
675         case VBE_DISPI_INDEX_ENABLE:
676             if ((val & VBE_DISPI_ENABLED) &&
677                 !(s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED)) {
678                 int h, shift_control;
679 
680                 s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] =
681                     s->vbe_regs[VBE_DISPI_INDEX_XRES];
682                 s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] =
683                     s->vbe_regs[VBE_DISPI_INDEX_YRES];
684                 s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0;
685                 s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0;
686 
687                 if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4)
688                     s->vbe_line_offset = s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 1;
689                 else
690                     s->vbe_line_offset = s->vbe_regs[VBE_DISPI_INDEX_XRES] *
691                         ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
692                 s->vbe_start_addr = 0;
693 
694                 /* clear the screen (should be done in BIOS) */
695                 if (!(val & VBE_DISPI_NOCLEARMEM)) {
696                     memset(s->vram_ptr, 0,
697                            s->vbe_regs[VBE_DISPI_INDEX_YRES] * s->vbe_line_offset);
698                 }
699 
700                 /* we initialize the VGA graphic mode (should be done
701                    in BIOS) */
702                 /* graphic mode + memory map 1 */
703                 s->gr[VGA_GFX_MISC] = (s->gr[VGA_GFX_MISC] & ~0x0c) | 0x04 |
704                     VGA_GR06_GRAPHICS_MODE;
705                 s->cr[VGA_CRTC_MODE] |= 3; /* no CGA modes */
706                 s->cr[VGA_CRTC_OFFSET] = s->vbe_line_offset >> 3;
707                 /* width */
708                 s->cr[VGA_CRTC_H_DISP] =
709                     (s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 3) - 1;
710                 /* height (only meaningful if < 1024) */
711                 h = s->vbe_regs[VBE_DISPI_INDEX_YRES] - 1;
712                 s->cr[VGA_CRTC_V_DISP_END] = h;
713                 s->cr[VGA_CRTC_OVERFLOW] = (s->cr[VGA_CRTC_OVERFLOW] & ~0x42) |
714                     ((h >> 7) & 0x02) | ((h >> 3) & 0x40);
715                 /* line compare to 1023 */
716                 s->cr[VGA_CRTC_LINE_COMPARE] = 0xff;
717                 s->cr[VGA_CRTC_OVERFLOW] |= 0x10;
718                 s->cr[VGA_CRTC_MAX_SCAN] |= 0x40;
719 
720                 if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
721                     shift_control = 0;
722                     s->sr[VGA_SEQ_CLOCK_MODE] &= ~8; /* no double line */
723                 } else {
724                     shift_control = 2;
725                     /* set chain 4 mode */
726                     s->sr[VGA_SEQ_MEMORY_MODE] |= VGA_SR04_CHN_4M;
727                     /* activate all planes */
728                     s->sr[VGA_SEQ_PLANE_WRITE] |= VGA_SR02_ALL_PLANES;
729                 }
730                 s->gr[VGA_GFX_MODE] = (s->gr[VGA_GFX_MODE] & ~0x60) |
731                     (shift_control << 5);
732                 s->cr[VGA_CRTC_MAX_SCAN] &= ~0x9f; /* no double scan */
733             } else {
734                 /* XXX: the bios should do that */
735                 s->bank_offset = 0;
736             }
737             s->dac_8bit = (val & VBE_DISPI_8BIT_DAC) > 0;
738             s->vbe_regs[s->vbe_index] = val;
739             vga_update_memory_access(s);
740             break;
741         case VBE_DISPI_INDEX_VIRT_WIDTH:
742             {
743                 int w, h, line_offset;
744 
745                 if (val < s->vbe_regs[VBE_DISPI_INDEX_XRES])
746                     return;
747                 w = val;
748                 if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4)
749                     line_offset = w >> 1;
750                 else
751                     line_offset = w * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
752                 h = s->vram_size / line_offset;
753                 /* XXX: support weird bochs semantics ? */
754                 if (h < s->vbe_regs[VBE_DISPI_INDEX_YRES])
755                     return;
756                 s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = w;
757                 s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] = h;
758                 s->vbe_line_offset = line_offset;
759             }
760             break;
761         case VBE_DISPI_INDEX_X_OFFSET:
762         case VBE_DISPI_INDEX_Y_OFFSET:
763             {
764                 int x;
765                 s->vbe_regs[s->vbe_index] = val;
766                 s->vbe_start_addr = s->vbe_line_offset * s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET];
767                 x = s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET];
768                 if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4)
769                     s->vbe_start_addr += x >> 1;
770                 else
771                     s->vbe_start_addr += x * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
772                 s->vbe_start_addr >>= 2;
773             }
774             break;
775         default:
776             break;
777         }
778     }
779 }
780 
781 /* called for accesses between 0xa0000 and 0xc0000 */
782 uint32_t vga_mem_readb(VGACommonState *s, hwaddr addr)
783 {
784     int memory_map_mode, plane;
785     uint32_t ret;
786 
787     /* convert to VGA memory offset */
788     memory_map_mode = (s->gr[VGA_GFX_MISC] >> 2) & 3;
789     addr &= 0x1ffff;
790     switch(memory_map_mode) {
791     case 0:
792         break;
793     case 1:
794         if (addr >= 0x10000)
795             return 0xff;
796         addr += s->bank_offset;
797         break;
798     case 2:
799         addr -= 0x10000;
800         if (addr >= 0x8000)
801             return 0xff;
802         break;
803     default:
804     case 3:
805         addr -= 0x18000;
806         if (addr >= 0x8000)
807             return 0xff;
808         break;
809     }
810 
811     if (s->sr[VGA_SEQ_MEMORY_MODE] & VGA_SR04_CHN_4M) {
812         /* chain 4 mode : simplest access */
813         ret = s->vram_ptr[addr];
814     } else if (s->gr[VGA_GFX_MODE] & 0x10) {
815         /* odd/even mode (aka text mode mapping) */
816         plane = (s->gr[VGA_GFX_PLANE_READ] & 2) | (addr & 1);
817         ret = s->vram_ptr[((addr & ~1) << 1) | plane];
818     } else {
819         /* standard VGA latched access */
820         s->latch = ((uint32_t *)s->vram_ptr)[addr];
821 
822         if (!(s->gr[VGA_GFX_MODE] & 0x08)) {
823             /* read mode 0 */
824             plane = s->gr[VGA_GFX_PLANE_READ];
825             ret = GET_PLANE(s->latch, plane);
826         } else {
827             /* read mode 1 */
828             ret = (s->latch ^ mask16[s->gr[VGA_GFX_COMPARE_VALUE]]) &
829                 mask16[s->gr[VGA_GFX_COMPARE_MASK]];
830             ret |= ret >> 16;
831             ret |= ret >> 8;
832             ret = (~ret) & 0xff;
833         }
834     }
835     return ret;
836 }
837 
838 /* called for accesses between 0xa0000 and 0xc0000 */
839 void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val)
840 {
841     int memory_map_mode, plane, write_mode, b, func_select, mask;
842     uint32_t write_mask, bit_mask, set_mask;
843 
844 #ifdef DEBUG_VGA_MEM
845     printf("vga: [0x" TARGET_FMT_plx "] = 0x%02x\n", addr, val);
846 #endif
847     /* convert to VGA memory offset */
848     memory_map_mode = (s->gr[VGA_GFX_MISC] >> 2) & 3;
849     addr &= 0x1ffff;
850     switch(memory_map_mode) {
851     case 0:
852         break;
853     case 1:
854         if (addr >= 0x10000)
855             return;
856         addr += s->bank_offset;
857         break;
858     case 2:
859         addr -= 0x10000;
860         if (addr >= 0x8000)
861             return;
862         break;
863     default:
864     case 3:
865         addr -= 0x18000;
866         if (addr >= 0x8000)
867             return;
868         break;
869     }
870 
871     if (s->sr[VGA_SEQ_MEMORY_MODE] & VGA_SR04_CHN_4M) {
872         /* chain 4 mode : simplest access */
873         plane = addr & 3;
874         mask = (1 << plane);
875         if (s->sr[VGA_SEQ_PLANE_WRITE] & mask) {
876             s->vram_ptr[addr] = val;
877 #ifdef DEBUG_VGA_MEM
878             printf("vga: chain4: [0x" TARGET_FMT_plx "]\n", addr);
879 #endif
880             s->plane_updated |= mask; /* only used to detect font change */
881             memory_region_set_dirty(&s->vram, addr, 1);
882         }
883     } else if (s->gr[VGA_GFX_MODE] & 0x10) {
884         /* odd/even mode (aka text mode mapping) */
885         plane = (s->gr[VGA_GFX_PLANE_READ] & 2) | (addr & 1);
886         mask = (1 << plane);
887         if (s->sr[VGA_SEQ_PLANE_WRITE] & mask) {
888             addr = ((addr & ~1) << 1) | plane;
889             s->vram_ptr[addr] = val;
890 #ifdef DEBUG_VGA_MEM
891             printf("vga: odd/even: [0x" TARGET_FMT_plx "]\n", addr);
892 #endif
893             s->plane_updated |= mask; /* only used to detect font change */
894             memory_region_set_dirty(&s->vram, addr, 1);
895         }
896     } else {
897         /* standard VGA latched access */
898         write_mode = s->gr[VGA_GFX_MODE] & 3;
899         switch(write_mode) {
900         default:
901         case 0:
902             /* rotate */
903             b = s->gr[VGA_GFX_DATA_ROTATE] & 7;
904             val = ((val >> b) | (val << (8 - b))) & 0xff;
905             val |= val << 8;
906             val |= val << 16;
907 
908             /* apply set/reset mask */
909             set_mask = mask16[s->gr[VGA_GFX_SR_ENABLE]];
910             val = (val & ~set_mask) |
911                 (mask16[s->gr[VGA_GFX_SR_VALUE]] & set_mask);
912             bit_mask = s->gr[VGA_GFX_BIT_MASK];
913             break;
914         case 1:
915             val = s->latch;
916             goto do_write;
917         case 2:
918             val = mask16[val & 0x0f];
919             bit_mask = s->gr[VGA_GFX_BIT_MASK];
920             break;
921         case 3:
922             /* rotate */
923             b = s->gr[VGA_GFX_DATA_ROTATE] & 7;
924             val = (val >> b) | (val << (8 - b));
925 
926             bit_mask = s->gr[VGA_GFX_BIT_MASK] & val;
927             val = mask16[s->gr[VGA_GFX_SR_VALUE]];
928             break;
929         }
930 
931         /* apply logical operation */
932         func_select = s->gr[VGA_GFX_DATA_ROTATE] >> 3;
933         switch(func_select) {
934         case 0:
935         default:
936             /* nothing to do */
937             break;
938         case 1:
939             /* and */
940             val &= s->latch;
941             break;
942         case 2:
943             /* or */
944             val |= s->latch;
945             break;
946         case 3:
947             /* xor */
948             val ^= s->latch;
949             break;
950         }
951 
952         /* apply bit mask */
953         bit_mask |= bit_mask << 8;
954         bit_mask |= bit_mask << 16;
955         val = (val & bit_mask) | (s->latch & ~bit_mask);
956 
957     do_write:
958         /* mask data according to sr[2] */
959         mask = s->sr[VGA_SEQ_PLANE_WRITE];
960         s->plane_updated |= mask; /* only used to detect font change */
961         write_mask = mask16[mask];
962         ((uint32_t *)s->vram_ptr)[addr] =
963             (((uint32_t *)s->vram_ptr)[addr] & ~write_mask) |
964             (val & write_mask);
965 #ifdef DEBUG_VGA_MEM
966         printf("vga: latch: [0x" TARGET_FMT_plx "] mask=0x%08x val=0x%08x\n",
967                addr * 4, write_mask, val);
968 #endif
969         memory_region_set_dirty(&s->vram, addr << 2, sizeof(uint32_t));
970     }
971 }
972 
973 typedef void vga_draw_glyph8_func(uint8_t *d, int linesize,
974                              const uint8_t *font_ptr, int h,
975                              uint32_t fgcol, uint32_t bgcol);
976 typedef void vga_draw_glyph9_func(uint8_t *d, int linesize,
977                                   const uint8_t *font_ptr, int h,
978                                   uint32_t fgcol, uint32_t bgcol, int dup9);
979 typedef void vga_draw_line_func(VGACommonState *s1, uint8_t *d,
980                                 const uint8_t *s, int width);
981 
982 #define DEPTH 8
983 #include "vga_template.h"
984 
985 #define DEPTH 15
986 #include "vga_template.h"
987 
988 #define BGR_FORMAT
989 #define DEPTH 15
990 #include "vga_template.h"
991 
992 #define DEPTH 16
993 #include "vga_template.h"
994 
995 #define BGR_FORMAT
996 #define DEPTH 16
997 #include "vga_template.h"
998 
999 #define DEPTH 32
1000 #include "vga_template.h"
1001 
1002 #define BGR_FORMAT
1003 #define DEPTH 32
1004 #include "vga_template.h"
1005 
1006 static unsigned int rgb_to_pixel8_dup(unsigned int r, unsigned int g, unsigned b)
1007 {
1008     unsigned int col;
1009     col = rgb_to_pixel8(r, g, b);
1010     col |= col << 8;
1011     col |= col << 16;
1012     return col;
1013 }
1014 
1015 static unsigned int rgb_to_pixel15_dup(unsigned int r, unsigned int g, unsigned b)
1016 {
1017     unsigned int col;
1018     col = rgb_to_pixel15(r, g, b);
1019     col |= col << 16;
1020     return col;
1021 }
1022 
1023 static unsigned int rgb_to_pixel15bgr_dup(unsigned int r, unsigned int g,
1024                                           unsigned int b)
1025 {
1026     unsigned int col;
1027     col = rgb_to_pixel15bgr(r, g, b);
1028     col |= col << 16;
1029     return col;
1030 }
1031 
1032 static unsigned int rgb_to_pixel16_dup(unsigned int r, unsigned int g, unsigned b)
1033 {
1034     unsigned int col;
1035     col = rgb_to_pixel16(r, g, b);
1036     col |= col << 16;
1037     return col;
1038 }
1039 
1040 static unsigned int rgb_to_pixel16bgr_dup(unsigned int r, unsigned int g,
1041                                           unsigned int b)
1042 {
1043     unsigned int col;
1044     col = rgb_to_pixel16bgr(r, g, b);
1045     col |= col << 16;
1046     return col;
1047 }
1048 
1049 static unsigned int rgb_to_pixel32_dup(unsigned int r, unsigned int g, unsigned b)
1050 {
1051     unsigned int col;
1052     col = rgb_to_pixel32(r, g, b);
1053     return col;
1054 }
1055 
1056 static unsigned int rgb_to_pixel32bgr_dup(unsigned int r, unsigned int g, unsigned b)
1057 {
1058     unsigned int col;
1059     col = rgb_to_pixel32bgr(r, g, b);
1060     return col;
1061 }
1062 
1063 /* return true if the palette was modified */
1064 static int update_palette16(VGACommonState *s)
1065 {
1066     int full_update, i;
1067     uint32_t v, col, *palette;
1068 
1069     full_update = 0;
1070     palette = s->last_palette;
1071     for(i = 0; i < 16; i++) {
1072         v = s->ar[i];
1073         if (s->ar[VGA_ATC_MODE] & 0x80) {
1074             v = ((s->ar[VGA_ATC_COLOR_PAGE] & 0xf) << 4) | (v & 0xf);
1075         } else {
1076             v = ((s->ar[VGA_ATC_COLOR_PAGE] & 0xc) << 4) | (v & 0x3f);
1077         }
1078         v = v * 3;
1079         col = s->rgb_to_pixel(c6_to_8(s->palette[v]),
1080                               c6_to_8(s->palette[v + 1]),
1081                               c6_to_8(s->palette[v + 2]));
1082         if (col != palette[i]) {
1083             full_update = 1;
1084             palette[i] = col;
1085         }
1086     }
1087     return full_update;
1088 }
1089 
1090 /* return true if the palette was modified */
1091 static int update_palette256(VGACommonState *s)
1092 {
1093     int full_update, i;
1094     uint32_t v, col, *palette;
1095 
1096     full_update = 0;
1097     palette = s->last_palette;
1098     v = 0;
1099     for(i = 0; i < 256; i++) {
1100         if (s->dac_8bit) {
1101           col = s->rgb_to_pixel(s->palette[v],
1102                                 s->palette[v + 1],
1103                                 s->palette[v + 2]);
1104         } else {
1105           col = s->rgb_to_pixel(c6_to_8(s->palette[v]),
1106                                 c6_to_8(s->palette[v + 1]),
1107                                 c6_to_8(s->palette[v + 2]));
1108         }
1109         if (col != palette[i]) {
1110             full_update = 1;
1111             palette[i] = col;
1112         }
1113         v += 3;
1114     }
1115     return full_update;
1116 }
1117 
1118 static void vga_get_offsets(VGACommonState *s,
1119                             uint32_t *pline_offset,
1120                             uint32_t *pstart_addr,
1121                             uint32_t *pline_compare)
1122 {
1123     uint32_t start_addr, line_offset, line_compare;
1124 
1125     if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
1126         line_offset = s->vbe_line_offset;
1127         start_addr = s->vbe_start_addr;
1128         line_compare = 65535;
1129     } else {
1130         /* compute line_offset in bytes */
1131         line_offset = s->cr[VGA_CRTC_OFFSET];
1132         line_offset <<= 3;
1133 
1134         /* starting address */
1135         start_addr = s->cr[VGA_CRTC_START_LO] |
1136             (s->cr[VGA_CRTC_START_HI] << 8);
1137 
1138         /* line compare */
1139         line_compare = s->cr[VGA_CRTC_LINE_COMPARE] |
1140             ((s->cr[VGA_CRTC_OVERFLOW] & 0x10) << 4) |
1141             ((s->cr[VGA_CRTC_MAX_SCAN] & 0x40) << 3);
1142     }
1143     *pline_offset = line_offset;
1144     *pstart_addr = start_addr;
1145     *pline_compare = line_compare;
1146 }
1147 
1148 /* update start_addr and line_offset. Return TRUE if modified */
1149 static int update_basic_params(VGACommonState *s)
1150 {
1151     int full_update;
1152     uint32_t start_addr, line_offset, line_compare;
1153 
1154     full_update = 0;
1155 
1156     s->get_offsets(s, &line_offset, &start_addr, &line_compare);
1157 
1158     if (line_offset != s->line_offset ||
1159         start_addr != s->start_addr ||
1160         line_compare != s->line_compare) {
1161         s->line_offset = line_offset;
1162         s->start_addr = start_addr;
1163         s->line_compare = line_compare;
1164         full_update = 1;
1165     }
1166     return full_update;
1167 }
1168 
1169 #define NB_DEPTHS 7
1170 
1171 static inline int get_depth_index(DisplaySurface *s)
1172 {
1173     switch (surface_bits_per_pixel(s)) {
1174     default:
1175     case 8:
1176         return 0;
1177     case 15:
1178         return 1;
1179     case 16:
1180         return 2;
1181     case 32:
1182         if (is_surface_bgr(s)) {
1183             return 4;
1184         } else {
1185             return 3;
1186         }
1187     }
1188 }
1189 
1190 static vga_draw_glyph8_func * const vga_draw_glyph8_table[NB_DEPTHS] = {
1191     vga_draw_glyph8_8,
1192     vga_draw_glyph8_16,
1193     vga_draw_glyph8_16,
1194     vga_draw_glyph8_32,
1195     vga_draw_glyph8_32,
1196     vga_draw_glyph8_16,
1197     vga_draw_glyph8_16,
1198 };
1199 
1200 static vga_draw_glyph8_func * const vga_draw_glyph16_table[NB_DEPTHS] = {
1201     vga_draw_glyph16_8,
1202     vga_draw_glyph16_16,
1203     vga_draw_glyph16_16,
1204     vga_draw_glyph16_32,
1205     vga_draw_glyph16_32,
1206     vga_draw_glyph16_16,
1207     vga_draw_glyph16_16,
1208 };
1209 
1210 static vga_draw_glyph9_func * const vga_draw_glyph9_table[NB_DEPTHS] = {
1211     vga_draw_glyph9_8,
1212     vga_draw_glyph9_16,
1213     vga_draw_glyph9_16,
1214     vga_draw_glyph9_32,
1215     vga_draw_glyph9_32,
1216     vga_draw_glyph9_16,
1217     vga_draw_glyph9_16,
1218 };
1219 
1220 static const uint8_t cursor_glyph[32 * 4] = {
1221     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1222     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1223     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1224     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1225     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1226     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1227     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1228     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1229     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1230     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1231     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1232     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1233     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1234     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1235     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1236     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1237 };
1238 
1239 static void vga_get_text_resolution(VGACommonState *s, int *pwidth, int *pheight,
1240                                     int *pcwidth, int *pcheight)
1241 {
1242     int width, cwidth, height, cheight;
1243 
1244     /* total width & height */
1245     cheight = (s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1;
1246     cwidth = 8;
1247     if (!(s->sr[VGA_SEQ_CLOCK_MODE] & VGA_SR01_CHAR_CLK_8DOTS)) {
1248         cwidth = 9;
1249     }
1250     if (s->sr[VGA_SEQ_CLOCK_MODE] & 0x08) {
1251         cwidth = 16; /* NOTE: no 18 pixel wide */
1252     }
1253     width = (s->cr[VGA_CRTC_H_DISP] + 1);
1254     if (s->cr[VGA_CRTC_V_TOTAL] == 100) {
1255         /* ugly hack for CGA 160x100x16 - explain me the logic */
1256         height = 100;
1257     } else {
1258         height = s->cr[VGA_CRTC_V_DISP_END] |
1259             ((s->cr[VGA_CRTC_OVERFLOW] & 0x02) << 7) |
1260             ((s->cr[VGA_CRTC_OVERFLOW] & 0x40) << 3);
1261         height = (height + 1) / cheight;
1262     }
1263 
1264     *pwidth = width;
1265     *pheight = height;
1266     *pcwidth = cwidth;
1267     *pcheight = cheight;
1268 }
1269 
1270 typedef unsigned int rgb_to_pixel_dup_func(unsigned int r, unsigned int g, unsigned b);
1271 
1272 static rgb_to_pixel_dup_func * const rgb_to_pixel_dup_table[NB_DEPTHS] = {
1273     rgb_to_pixel8_dup,
1274     rgb_to_pixel15_dup,
1275     rgb_to_pixel16_dup,
1276     rgb_to_pixel32_dup,
1277     rgb_to_pixel32bgr_dup,
1278     rgb_to_pixel15bgr_dup,
1279     rgb_to_pixel16bgr_dup,
1280 };
1281 
1282 /*
1283  * Text mode update
1284  * Missing:
1285  * - double scan
1286  * - double width
1287  * - underline
1288  * - flashing
1289  */
1290 static void vga_draw_text(VGACommonState *s, int full_update)
1291 {
1292     DisplaySurface *surface = qemu_console_surface(s->con);
1293     int cx, cy, cheight, cw, ch, cattr, height, width, ch_attr;
1294     int cx_min, cx_max, linesize, x_incr, line, line1;
1295     uint32_t offset, fgcol, bgcol, v, cursor_offset;
1296     uint8_t *d1, *d, *src, *dest, *cursor_ptr;
1297     const uint8_t *font_ptr, *font_base[2];
1298     int dup9, line_offset, depth_index;
1299     uint32_t *palette;
1300     uint32_t *ch_attr_ptr;
1301     vga_draw_glyph8_func *vga_draw_glyph8;
1302     vga_draw_glyph9_func *vga_draw_glyph9;
1303     int64_t now = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
1304 
1305     /* compute font data address (in plane 2) */
1306     v = s->sr[VGA_SEQ_CHARACTER_MAP];
1307     offset = (((v >> 4) & 1) | ((v << 1) & 6)) * 8192 * 4 + 2;
1308     if (offset != s->font_offsets[0]) {
1309         s->font_offsets[0] = offset;
1310         full_update = 1;
1311     }
1312     font_base[0] = s->vram_ptr + offset;
1313 
1314     offset = (((v >> 5) & 1) | ((v >> 1) & 6)) * 8192 * 4 + 2;
1315     font_base[1] = s->vram_ptr + offset;
1316     if (offset != s->font_offsets[1]) {
1317         s->font_offsets[1] = offset;
1318         full_update = 1;
1319     }
1320     if (s->plane_updated & (1 << 2) || s->chain4_alias) {
1321         /* if the plane 2 was modified since the last display, it
1322            indicates the font may have been modified */
1323         s->plane_updated = 0;
1324         full_update = 1;
1325     }
1326     full_update |= update_basic_params(s);
1327 
1328     line_offset = s->line_offset;
1329 
1330     vga_get_text_resolution(s, &width, &height, &cw, &cheight);
1331     if ((height * width) <= 1) {
1332         /* better than nothing: exit if transient size is too small */
1333         return;
1334     }
1335     if ((height * width) > CH_ATTR_SIZE) {
1336         /* better than nothing: exit if transient size is too big */
1337         return;
1338     }
1339 
1340     if (width != s->last_width || height != s->last_height ||
1341         cw != s->last_cw || cheight != s->last_ch || s->last_depth) {
1342         s->last_scr_width = width * cw;
1343         s->last_scr_height = height * cheight;
1344         qemu_console_resize(s->con, s->last_scr_width, s->last_scr_height);
1345         surface = qemu_console_surface(s->con);
1346         dpy_text_resize(s->con, width, height);
1347         s->last_depth = 0;
1348         s->last_width = width;
1349         s->last_height = height;
1350         s->last_ch = cheight;
1351         s->last_cw = cw;
1352         full_update = 1;
1353     }
1354     s->rgb_to_pixel =
1355         rgb_to_pixel_dup_table[get_depth_index(surface)];
1356     full_update |= update_palette16(s);
1357     palette = s->last_palette;
1358     x_incr = cw * surface_bytes_per_pixel(surface);
1359 
1360     if (full_update) {
1361         s->full_update_text = 1;
1362     }
1363     if (s->full_update_gfx) {
1364         s->full_update_gfx = 0;
1365         full_update |= 1;
1366     }
1367 
1368     cursor_offset = ((s->cr[VGA_CRTC_CURSOR_HI] << 8) |
1369                      s->cr[VGA_CRTC_CURSOR_LO]) - s->start_addr;
1370     if (cursor_offset != s->cursor_offset ||
1371         s->cr[VGA_CRTC_CURSOR_START] != s->cursor_start ||
1372         s->cr[VGA_CRTC_CURSOR_END] != s->cursor_end) {
1373       /* if the cursor position changed, we update the old and new
1374          chars */
1375         if (s->cursor_offset < CH_ATTR_SIZE)
1376             s->last_ch_attr[s->cursor_offset] = -1;
1377         if (cursor_offset < CH_ATTR_SIZE)
1378             s->last_ch_attr[cursor_offset] = -1;
1379         s->cursor_offset = cursor_offset;
1380         s->cursor_start = s->cr[VGA_CRTC_CURSOR_START];
1381         s->cursor_end = s->cr[VGA_CRTC_CURSOR_END];
1382     }
1383     cursor_ptr = s->vram_ptr + (s->start_addr + cursor_offset) * 4;
1384     if (now >= s->cursor_blink_time) {
1385         s->cursor_blink_time = now + VGA_TEXT_CURSOR_PERIOD_MS / 2;
1386         s->cursor_visible_phase = !s->cursor_visible_phase;
1387     }
1388 
1389     depth_index = get_depth_index(surface);
1390     if (cw == 16)
1391         vga_draw_glyph8 = vga_draw_glyph16_table[depth_index];
1392     else
1393         vga_draw_glyph8 = vga_draw_glyph8_table[depth_index];
1394     vga_draw_glyph9 = vga_draw_glyph9_table[depth_index];
1395 
1396     dest = surface_data(surface);
1397     linesize = surface_stride(surface);
1398     ch_attr_ptr = s->last_ch_attr;
1399     line = 0;
1400     offset = s->start_addr * 4;
1401     for(cy = 0; cy < height; cy++) {
1402         d1 = dest;
1403         src = s->vram_ptr + offset;
1404         cx_min = width;
1405         cx_max = -1;
1406         for(cx = 0; cx < width; cx++) {
1407             ch_attr = *(uint16_t *)src;
1408             if (full_update || ch_attr != *ch_attr_ptr || src == cursor_ptr) {
1409                 if (cx < cx_min)
1410                     cx_min = cx;
1411                 if (cx > cx_max)
1412                     cx_max = cx;
1413                 *ch_attr_ptr = ch_attr;
1414 #ifdef HOST_WORDS_BIGENDIAN
1415                 ch = ch_attr >> 8;
1416                 cattr = ch_attr & 0xff;
1417 #else
1418                 ch = ch_attr & 0xff;
1419                 cattr = ch_attr >> 8;
1420 #endif
1421                 font_ptr = font_base[(cattr >> 3) & 1];
1422                 font_ptr += 32 * 4 * ch;
1423                 bgcol = palette[cattr >> 4];
1424                 fgcol = palette[cattr & 0x0f];
1425                 if (cw != 9) {
1426                     vga_draw_glyph8(d1, linesize,
1427                                     font_ptr, cheight, fgcol, bgcol);
1428                 } else {
1429                     dup9 = 0;
1430                     if (ch >= 0xb0 && ch <= 0xdf &&
1431                         (s->ar[VGA_ATC_MODE] & 0x04)) {
1432                         dup9 = 1;
1433                     }
1434                     vga_draw_glyph9(d1, linesize,
1435                                     font_ptr, cheight, fgcol, bgcol, dup9);
1436                 }
1437                 if (src == cursor_ptr &&
1438                     !(s->cr[VGA_CRTC_CURSOR_START] & 0x20) &&
1439                     s->cursor_visible_phase) {
1440                     int line_start, line_last, h;
1441                     /* draw the cursor */
1442                     line_start = s->cr[VGA_CRTC_CURSOR_START] & 0x1f;
1443                     line_last = s->cr[VGA_CRTC_CURSOR_END] & 0x1f;
1444                     /* XXX: check that */
1445                     if (line_last > cheight - 1)
1446                         line_last = cheight - 1;
1447                     if (line_last >= line_start && line_start < cheight) {
1448                         h = line_last - line_start + 1;
1449                         d = d1 + linesize * line_start;
1450                         if (cw != 9) {
1451                             vga_draw_glyph8(d, linesize,
1452                                             cursor_glyph, h, fgcol, bgcol);
1453                         } else {
1454                             vga_draw_glyph9(d, linesize,
1455                                             cursor_glyph, h, fgcol, bgcol, 1);
1456                         }
1457                     }
1458                 }
1459             }
1460             d1 += x_incr;
1461             src += 4;
1462             ch_attr_ptr++;
1463         }
1464         if (cx_max != -1) {
1465             dpy_gfx_update(s->con, cx_min * cw, cy * cheight,
1466                            (cx_max - cx_min + 1) * cw, cheight);
1467         }
1468         dest += linesize * cheight;
1469         line1 = line + cheight;
1470         offset += line_offset;
1471         if (line < s->line_compare && line1 >= s->line_compare) {
1472             offset = 0;
1473         }
1474         line = line1;
1475     }
1476 }
1477 
1478 enum {
1479     VGA_DRAW_LINE2,
1480     VGA_DRAW_LINE2D2,
1481     VGA_DRAW_LINE4,
1482     VGA_DRAW_LINE4D2,
1483     VGA_DRAW_LINE8D2,
1484     VGA_DRAW_LINE8,
1485     VGA_DRAW_LINE15,
1486     VGA_DRAW_LINE16,
1487     VGA_DRAW_LINE24,
1488     VGA_DRAW_LINE32,
1489     VGA_DRAW_LINE_NB,
1490 };
1491 
1492 static vga_draw_line_func * const vga_draw_line_table[NB_DEPTHS * VGA_DRAW_LINE_NB] = {
1493     vga_draw_line2_8,
1494     vga_draw_line2_16,
1495     vga_draw_line2_16,
1496     vga_draw_line2_32,
1497     vga_draw_line2_32,
1498     vga_draw_line2_16,
1499     vga_draw_line2_16,
1500 
1501     vga_draw_line2d2_8,
1502     vga_draw_line2d2_16,
1503     vga_draw_line2d2_16,
1504     vga_draw_line2d2_32,
1505     vga_draw_line2d2_32,
1506     vga_draw_line2d2_16,
1507     vga_draw_line2d2_16,
1508 
1509     vga_draw_line4_8,
1510     vga_draw_line4_16,
1511     vga_draw_line4_16,
1512     vga_draw_line4_32,
1513     vga_draw_line4_32,
1514     vga_draw_line4_16,
1515     vga_draw_line4_16,
1516 
1517     vga_draw_line4d2_8,
1518     vga_draw_line4d2_16,
1519     vga_draw_line4d2_16,
1520     vga_draw_line4d2_32,
1521     vga_draw_line4d2_32,
1522     vga_draw_line4d2_16,
1523     vga_draw_line4d2_16,
1524 
1525     vga_draw_line8d2_8,
1526     vga_draw_line8d2_16,
1527     vga_draw_line8d2_16,
1528     vga_draw_line8d2_32,
1529     vga_draw_line8d2_32,
1530     vga_draw_line8d2_16,
1531     vga_draw_line8d2_16,
1532 
1533     vga_draw_line8_8,
1534     vga_draw_line8_16,
1535     vga_draw_line8_16,
1536     vga_draw_line8_32,
1537     vga_draw_line8_32,
1538     vga_draw_line8_16,
1539     vga_draw_line8_16,
1540 
1541     vga_draw_line15_8,
1542     vga_draw_line15_15,
1543     vga_draw_line15_16,
1544     vga_draw_line15_32,
1545     vga_draw_line15_32bgr,
1546     vga_draw_line15_15bgr,
1547     vga_draw_line15_16bgr,
1548 
1549     vga_draw_line16_8,
1550     vga_draw_line16_15,
1551     vga_draw_line16_16,
1552     vga_draw_line16_32,
1553     vga_draw_line16_32bgr,
1554     vga_draw_line16_15bgr,
1555     vga_draw_line16_16bgr,
1556 
1557     vga_draw_line24_8,
1558     vga_draw_line24_15,
1559     vga_draw_line24_16,
1560     vga_draw_line24_32,
1561     vga_draw_line24_32bgr,
1562     vga_draw_line24_15bgr,
1563     vga_draw_line24_16bgr,
1564 
1565     vga_draw_line32_8,
1566     vga_draw_line32_15,
1567     vga_draw_line32_16,
1568     vga_draw_line32_32,
1569     vga_draw_line32_32bgr,
1570     vga_draw_line32_15bgr,
1571     vga_draw_line32_16bgr,
1572 };
1573 
1574 static int vga_get_bpp(VGACommonState *s)
1575 {
1576     int ret;
1577 
1578     if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
1579         ret = s->vbe_regs[VBE_DISPI_INDEX_BPP];
1580     } else {
1581         ret = 0;
1582     }
1583     return ret;
1584 }
1585 
1586 static void vga_get_resolution(VGACommonState *s, int *pwidth, int *pheight)
1587 {
1588     int width, height;
1589 
1590     if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
1591         width = s->vbe_regs[VBE_DISPI_INDEX_XRES];
1592         height = s->vbe_regs[VBE_DISPI_INDEX_YRES];
1593     } else {
1594         width = (s->cr[VGA_CRTC_H_DISP] + 1) * 8;
1595         height = s->cr[VGA_CRTC_V_DISP_END] |
1596             ((s->cr[VGA_CRTC_OVERFLOW] & 0x02) << 7) |
1597             ((s->cr[VGA_CRTC_OVERFLOW] & 0x40) << 3);
1598         height = (height + 1);
1599     }
1600     *pwidth = width;
1601     *pheight = height;
1602 }
1603 
1604 void vga_invalidate_scanlines(VGACommonState *s, int y1, int y2)
1605 {
1606     int y;
1607     if (y1 >= VGA_MAX_HEIGHT)
1608         return;
1609     if (y2 >= VGA_MAX_HEIGHT)
1610         y2 = VGA_MAX_HEIGHT;
1611     for(y = y1; y < y2; y++) {
1612         s->invalidated_y_table[y >> 5] |= 1 << (y & 0x1f);
1613     }
1614 }
1615 
1616 void vga_sync_dirty_bitmap(VGACommonState *s)
1617 {
1618     memory_region_sync_dirty_bitmap(&s->vram);
1619 }
1620 
1621 void vga_dirty_log_start(VGACommonState *s)
1622 {
1623     memory_region_set_log(&s->vram, true, DIRTY_MEMORY_VGA);
1624 }
1625 
1626 void vga_dirty_log_stop(VGACommonState *s)
1627 {
1628     memory_region_set_log(&s->vram, false, DIRTY_MEMORY_VGA);
1629 }
1630 
1631 /*
1632  * graphic modes
1633  */
1634 static void vga_draw_graphic(VGACommonState *s, int full_update)
1635 {
1636     DisplaySurface *surface = qemu_console_surface(s->con);
1637     int y1, y, update, linesize, y_start, double_scan, mask, depth;
1638     int width, height, shift_control, line_offset, bwidth, bits;
1639     ram_addr_t page0, page1, page_min, page_max;
1640     int disp_width, multi_scan, multi_run;
1641     uint8_t *d;
1642     uint32_t v, addr1, addr;
1643     vga_draw_line_func *vga_draw_line;
1644 #if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
1645     static const bool byteswap = false;
1646 #else
1647     static const bool byteswap = true;
1648 #endif
1649 
1650     full_update |= update_basic_params(s);
1651 
1652     if (!full_update)
1653         vga_sync_dirty_bitmap(s);
1654 
1655     s->get_resolution(s, &width, &height);
1656     disp_width = width;
1657 
1658     shift_control = (s->gr[VGA_GFX_MODE] >> 5) & 3;
1659     double_scan = (s->cr[VGA_CRTC_MAX_SCAN] >> 7);
1660     if (shift_control != 1) {
1661         multi_scan = (((s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1) << double_scan)
1662             - 1;
1663     } else {
1664         /* in CGA modes, multi_scan is ignored */
1665         /* XXX: is it correct ? */
1666         multi_scan = double_scan;
1667     }
1668     multi_run = multi_scan;
1669     if (shift_control != s->shift_control ||
1670         double_scan != s->double_scan) {
1671         full_update = 1;
1672         s->shift_control = shift_control;
1673         s->double_scan = double_scan;
1674     }
1675 
1676     if (shift_control == 0) {
1677         if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) {
1678             disp_width <<= 1;
1679         }
1680     } else if (shift_control == 1) {
1681         if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) {
1682             disp_width <<= 1;
1683         }
1684     }
1685 
1686     depth = s->get_bpp(s);
1687     if (s->line_offset != s->last_line_offset ||
1688         disp_width != s->last_width ||
1689         height != s->last_height ||
1690         s->last_depth != depth) {
1691         if (depth == 32 || (depth == 16 && !byteswap)) {
1692             surface = qemu_create_displaysurface_from(disp_width,
1693                     height, depth, s->line_offset,
1694                     s->vram_ptr + (s->start_addr * 4), byteswap);
1695             dpy_gfx_replace_surface(s->con, surface);
1696         } else {
1697             qemu_console_resize(s->con, disp_width, height);
1698             surface = qemu_console_surface(s->con);
1699         }
1700         s->last_scr_width = disp_width;
1701         s->last_scr_height = height;
1702         s->last_width = disp_width;
1703         s->last_height = height;
1704         s->last_line_offset = s->line_offset;
1705         s->last_depth = depth;
1706         full_update = 1;
1707     } else if (is_buffer_shared(surface) &&
1708                (full_update || surface_data(surface) != s->vram_ptr
1709                 + (s->start_addr * 4))) {
1710         surface = qemu_create_displaysurface_from(disp_width,
1711                 height, depth, s->line_offset,
1712                 s->vram_ptr + (s->start_addr * 4), byteswap);
1713         dpy_gfx_replace_surface(s->con, surface);
1714     }
1715 
1716     s->rgb_to_pixel =
1717         rgb_to_pixel_dup_table[get_depth_index(surface)];
1718 
1719     if (shift_control == 0) {
1720         full_update |= update_palette16(s);
1721         if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) {
1722             v = VGA_DRAW_LINE4D2;
1723         } else {
1724             v = VGA_DRAW_LINE4;
1725         }
1726         bits = 4;
1727     } else if (shift_control == 1) {
1728         full_update |= update_palette16(s);
1729         if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) {
1730             v = VGA_DRAW_LINE2D2;
1731         } else {
1732             v = VGA_DRAW_LINE2;
1733         }
1734         bits = 4;
1735     } else {
1736         switch(s->get_bpp(s)) {
1737         default:
1738         case 0:
1739             full_update |= update_palette256(s);
1740             v = VGA_DRAW_LINE8D2;
1741             bits = 4;
1742             break;
1743         case 8:
1744             full_update |= update_palette256(s);
1745             v = VGA_DRAW_LINE8;
1746             bits = 8;
1747             break;
1748         case 15:
1749             v = VGA_DRAW_LINE15;
1750             bits = 16;
1751             break;
1752         case 16:
1753             v = VGA_DRAW_LINE16;
1754             bits = 16;
1755             break;
1756         case 24:
1757             v = VGA_DRAW_LINE24;
1758             bits = 24;
1759             break;
1760         case 32:
1761             v = VGA_DRAW_LINE32;
1762             bits = 32;
1763             break;
1764         }
1765     }
1766     vga_draw_line = vga_draw_line_table[v * NB_DEPTHS +
1767                                         get_depth_index(surface)];
1768 
1769     if (!is_buffer_shared(surface) && s->cursor_invalidate) {
1770         s->cursor_invalidate(s);
1771     }
1772 
1773     line_offset = s->line_offset;
1774 #if 0
1775     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",
1776            width, height, v, line_offset, s->cr[9], s->cr[VGA_CRTC_MODE],
1777            s->line_compare, s->sr[VGA_SEQ_CLOCK_MODE]);
1778 #endif
1779     addr1 = (s->start_addr * 4);
1780     bwidth = (width * bits + 7) / 8;
1781     y_start = -1;
1782     page_min = -1;
1783     page_max = 0;
1784     d = surface_data(surface);
1785     linesize = surface_stride(surface);
1786     y1 = 0;
1787     for(y = 0; y < height; y++) {
1788         addr = addr1;
1789         if (!(s->cr[VGA_CRTC_MODE] & 1)) {
1790             int shift;
1791             /* CGA compatibility handling */
1792             shift = 14 + ((s->cr[VGA_CRTC_MODE] >> 6) & 1);
1793             addr = (addr & ~(1 << shift)) | ((y1 & 1) << shift);
1794         }
1795         if (!(s->cr[VGA_CRTC_MODE] & 2)) {
1796             addr = (addr & ~0x8000) | ((y1 & 2) << 14);
1797         }
1798         update = full_update;
1799         page0 = addr;
1800         page1 = addr + bwidth - 1;
1801         update |= memory_region_get_dirty(&s->vram, page0, page1 - page0,
1802                                           DIRTY_MEMORY_VGA);
1803         /* explicit invalidation for the hardware cursor */
1804         update |= (s->invalidated_y_table[y >> 5] >> (y & 0x1f)) & 1;
1805         if (update) {
1806             if (y_start < 0)
1807                 y_start = y;
1808             if (page0 < page_min)
1809                 page_min = page0;
1810             if (page1 > page_max)
1811                 page_max = page1;
1812             if (!(is_buffer_shared(surface))) {
1813                 vga_draw_line(s, d, s->vram_ptr + addr, width);
1814                 if (s->cursor_draw_line)
1815                     s->cursor_draw_line(s, d, y);
1816             }
1817         } else {
1818             if (y_start >= 0) {
1819                 /* flush to display */
1820                 dpy_gfx_update(s->con, 0, y_start,
1821                                disp_width, y - y_start);
1822                 y_start = -1;
1823             }
1824         }
1825         if (!multi_run) {
1826             mask = (s->cr[VGA_CRTC_MODE] & 3) ^ 3;
1827             if ((y1 & mask) == mask)
1828                 addr1 += line_offset;
1829             y1++;
1830             multi_run = multi_scan;
1831         } else {
1832             multi_run--;
1833         }
1834         /* line compare acts on the displayed lines */
1835         if (y == s->line_compare)
1836             addr1 = 0;
1837         d += linesize;
1838     }
1839     if (y_start >= 0) {
1840         /* flush to display */
1841         dpy_gfx_update(s->con, 0, y_start,
1842                        disp_width, y - y_start);
1843     }
1844     /* reset modified pages */
1845     if (page_max >= page_min) {
1846         memory_region_reset_dirty(&s->vram,
1847                                   page_min,
1848                                   page_max - page_min,
1849                                   DIRTY_MEMORY_VGA);
1850     }
1851     memset(s->invalidated_y_table, 0, ((height + 31) >> 5) * 4);
1852 }
1853 
1854 static void vga_draw_blank(VGACommonState *s, int full_update)
1855 {
1856     DisplaySurface *surface = qemu_console_surface(s->con);
1857     int i, w, val;
1858     uint8_t *d;
1859 
1860     if (!full_update)
1861         return;
1862     if (s->last_scr_width <= 0 || s->last_scr_height <= 0)
1863         return;
1864 
1865     s->rgb_to_pixel =
1866         rgb_to_pixel_dup_table[get_depth_index(surface)];
1867     if (surface_bits_per_pixel(surface) == 8) {
1868         val = s->rgb_to_pixel(0, 0, 0);
1869     } else {
1870         val = 0;
1871     }
1872     w = s->last_scr_width * surface_bytes_per_pixel(surface);
1873     d = surface_data(surface);
1874     for(i = 0; i < s->last_scr_height; i++) {
1875         memset(d, val, w);
1876         d += surface_stride(surface);
1877     }
1878     dpy_gfx_update(s->con, 0, 0,
1879                    s->last_scr_width, s->last_scr_height);
1880 }
1881 
1882 #define GMODE_TEXT     0
1883 #define GMODE_GRAPH    1
1884 #define GMODE_BLANK 2
1885 
1886 static void vga_update_display(void *opaque)
1887 {
1888     VGACommonState *s = opaque;
1889     DisplaySurface *surface = qemu_console_surface(s->con);
1890     int full_update, graphic_mode;
1891 
1892     qemu_flush_coalesced_mmio_buffer();
1893 
1894     if (surface_bits_per_pixel(surface) == 0) {
1895         /* nothing to do */
1896     } else {
1897         full_update = 0;
1898         if (!(s->ar_index & 0x20)) {
1899             graphic_mode = GMODE_BLANK;
1900         } else {
1901             graphic_mode = s->gr[VGA_GFX_MISC] & VGA_GR06_GRAPHICS_MODE;
1902         }
1903         if (graphic_mode != s->graphic_mode) {
1904             s->graphic_mode = graphic_mode;
1905             s->cursor_blink_time = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
1906             full_update = 1;
1907         }
1908         switch(graphic_mode) {
1909         case GMODE_TEXT:
1910             vga_draw_text(s, full_update);
1911             break;
1912         case GMODE_GRAPH:
1913             vga_draw_graphic(s, full_update);
1914             break;
1915         case GMODE_BLANK:
1916         default:
1917             vga_draw_blank(s, full_update);
1918             break;
1919         }
1920     }
1921 }
1922 
1923 /* force a full display refresh */
1924 static void vga_invalidate_display(void *opaque)
1925 {
1926     VGACommonState *s = opaque;
1927 
1928     s->last_width = -1;
1929     s->last_height = -1;
1930 }
1931 
1932 void vga_common_reset(VGACommonState *s)
1933 {
1934     s->sr_index = 0;
1935     memset(s->sr, '\0', sizeof(s->sr));
1936     s->gr_index = 0;
1937     memset(s->gr, '\0', sizeof(s->gr));
1938     s->ar_index = 0;
1939     memset(s->ar, '\0', sizeof(s->ar));
1940     s->ar_flip_flop = 0;
1941     s->cr_index = 0;
1942     memset(s->cr, '\0', sizeof(s->cr));
1943     s->msr = 0;
1944     s->fcr = 0;
1945     s->st00 = 0;
1946     s->st01 = 0;
1947     s->dac_state = 0;
1948     s->dac_sub_index = 0;
1949     s->dac_read_index = 0;
1950     s->dac_write_index = 0;
1951     memset(s->dac_cache, '\0', sizeof(s->dac_cache));
1952     s->dac_8bit = 0;
1953     memset(s->palette, '\0', sizeof(s->palette));
1954     s->bank_offset = 0;
1955     s->vbe_index = 0;
1956     memset(s->vbe_regs, '\0', sizeof(s->vbe_regs));
1957     s->vbe_regs[VBE_DISPI_INDEX_ID] = VBE_DISPI_ID5;
1958     s->vbe_start_addr = 0;
1959     s->vbe_line_offset = 0;
1960     s->vbe_bank_mask = (s->vram_size >> 16) - 1;
1961     memset(s->font_offsets, '\0', sizeof(s->font_offsets));
1962     s->graphic_mode = -1; /* force full update */
1963     s->shift_control = 0;
1964     s->double_scan = 0;
1965     s->line_offset = 0;
1966     s->line_compare = 0;
1967     s->start_addr = 0;
1968     s->plane_updated = 0;
1969     s->last_cw = 0;
1970     s->last_ch = 0;
1971     s->last_width = 0;
1972     s->last_height = 0;
1973     s->last_scr_width = 0;
1974     s->last_scr_height = 0;
1975     s->cursor_start = 0;
1976     s->cursor_end = 0;
1977     s->cursor_offset = 0;
1978     memset(s->invalidated_y_table, '\0', sizeof(s->invalidated_y_table));
1979     memset(s->last_palette, '\0', sizeof(s->last_palette));
1980     memset(s->last_ch_attr, '\0', sizeof(s->last_ch_attr));
1981     switch (vga_retrace_method) {
1982     case VGA_RETRACE_DUMB:
1983         break;
1984     case VGA_RETRACE_PRECISE:
1985         memset(&s->retrace_info, 0, sizeof (s->retrace_info));
1986         break;
1987     }
1988     vga_update_memory_access(s);
1989 }
1990 
1991 static void vga_reset(void *opaque)
1992 {
1993     VGACommonState *s =  opaque;
1994     vga_common_reset(s);
1995 }
1996 
1997 #define TEXTMODE_X(x)	((x) % width)
1998 #define TEXTMODE_Y(x)	((x) / width)
1999 #define VMEM2CHTYPE(v)	((v & 0xff0007ff) | \
2000         ((v & 0x00000800) << 10) | ((v & 0x00007000) >> 1))
2001 /* relay text rendering to the display driver
2002  * instead of doing a full vga_update_display() */
2003 static void vga_update_text(void *opaque, console_ch_t *chardata)
2004 {
2005     VGACommonState *s =  opaque;
2006     int graphic_mode, i, cursor_offset, cursor_visible;
2007     int cw, cheight, width, height, size, c_min, c_max;
2008     uint32_t *src;
2009     console_ch_t *dst, val;
2010     char msg_buffer[80];
2011     int full_update = 0;
2012 
2013     qemu_flush_coalesced_mmio_buffer();
2014 
2015     if (!(s->ar_index & 0x20)) {
2016         graphic_mode = GMODE_BLANK;
2017     } else {
2018         graphic_mode = s->gr[VGA_GFX_MISC] & VGA_GR06_GRAPHICS_MODE;
2019     }
2020     if (graphic_mode != s->graphic_mode) {
2021         s->graphic_mode = graphic_mode;
2022         full_update = 1;
2023     }
2024     if (s->last_width == -1) {
2025         s->last_width = 0;
2026         full_update = 1;
2027     }
2028 
2029     switch (graphic_mode) {
2030     case GMODE_TEXT:
2031         /* TODO: update palette */
2032         full_update |= update_basic_params(s);
2033 
2034         /* total width & height */
2035         cheight = (s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1;
2036         cw = 8;
2037         if (!(s->sr[VGA_SEQ_CLOCK_MODE] & VGA_SR01_CHAR_CLK_8DOTS)) {
2038             cw = 9;
2039         }
2040         if (s->sr[VGA_SEQ_CLOCK_MODE] & 0x08) {
2041             cw = 16; /* NOTE: no 18 pixel wide */
2042         }
2043         width = (s->cr[VGA_CRTC_H_DISP] + 1);
2044         if (s->cr[VGA_CRTC_V_TOTAL] == 100) {
2045             /* ugly hack for CGA 160x100x16 - explain me the logic */
2046             height = 100;
2047         } else {
2048             height = s->cr[VGA_CRTC_V_DISP_END] |
2049                 ((s->cr[VGA_CRTC_OVERFLOW] & 0x02) << 7) |
2050                 ((s->cr[VGA_CRTC_OVERFLOW] & 0x40) << 3);
2051             height = (height + 1) / cheight;
2052         }
2053 
2054         size = (height * width);
2055         if (size > CH_ATTR_SIZE) {
2056             if (!full_update)
2057                 return;
2058 
2059             snprintf(msg_buffer, sizeof(msg_buffer), "%i x %i Text mode",
2060                      width, height);
2061             break;
2062         }
2063 
2064         if (width != s->last_width || height != s->last_height ||
2065             cw != s->last_cw || cheight != s->last_ch) {
2066             s->last_scr_width = width * cw;
2067             s->last_scr_height = height * cheight;
2068             qemu_console_resize(s->con, s->last_scr_width, s->last_scr_height);
2069             dpy_text_resize(s->con, width, height);
2070             s->last_depth = 0;
2071             s->last_width = width;
2072             s->last_height = height;
2073             s->last_ch = cheight;
2074             s->last_cw = cw;
2075             full_update = 1;
2076         }
2077 
2078         if (full_update) {
2079             s->full_update_gfx = 1;
2080         }
2081         if (s->full_update_text) {
2082             s->full_update_text = 0;
2083             full_update |= 1;
2084         }
2085 
2086         /* Update "hardware" cursor */
2087         cursor_offset = ((s->cr[VGA_CRTC_CURSOR_HI] << 8) |
2088                          s->cr[VGA_CRTC_CURSOR_LO]) - s->start_addr;
2089         if (cursor_offset != s->cursor_offset ||
2090             s->cr[VGA_CRTC_CURSOR_START] != s->cursor_start ||
2091             s->cr[VGA_CRTC_CURSOR_END] != s->cursor_end || full_update) {
2092             cursor_visible = !(s->cr[VGA_CRTC_CURSOR_START] & 0x20);
2093             if (cursor_visible && cursor_offset < size && cursor_offset >= 0)
2094                 dpy_text_cursor(s->con,
2095                                 TEXTMODE_X(cursor_offset),
2096                                 TEXTMODE_Y(cursor_offset));
2097             else
2098                 dpy_text_cursor(s->con, -1, -1);
2099             s->cursor_offset = cursor_offset;
2100             s->cursor_start = s->cr[VGA_CRTC_CURSOR_START];
2101             s->cursor_end = s->cr[VGA_CRTC_CURSOR_END];
2102         }
2103 
2104         src = (uint32_t *) s->vram_ptr + s->start_addr;
2105         dst = chardata;
2106 
2107         if (full_update) {
2108             for (i = 0; i < size; src ++, dst ++, i ++)
2109                 console_write_ch(dst, VMEM2CHTYPE(le32_to_cpu(*src)));
2110 
2111             dpy_text_update(s->con, 0, 0, width, height);
2112         } else {
2113             c_max = 0;
2114 
2115             for (i = 0; i < size; src ++, dst ++, i ++) {
2116                 console_write_ch(&val, VMEM2CHTYPE(le32_to_cpu(*src)));
2117                 if (*dst != val) {
2118                     *dst = val;
2119                     c_max = i;
2120                     break;
2121                 }
2122             }
2123             c_min = i;
2124             for (; i < size; src ++, dst ++, i ++) {
2125                 console_write_ch(&val, VMEM2CHTYPE(le32_to_cpu(*src)));
2126                 if (*dst != val) {
2127                     *dst = val;
2128                     c_max = i;
2129                 }
2130             }
2131 
2132             if (c_min <= c_max) {
2133                 i = TEXTMODE_Y(c_min);
2134                 dpy_text_update(s->con, 0, i, width, TEXTMODE_Y(c_max) - i + 1);
2135             }
2136         }
2137 
2138         return;
2139     case GMODE_GRAPH:
2140         if (!full_update)
2141             return;
2142 
2143         s->get_resolution(s, &width, &height);
2144         snprintf(msg_buffer, sizeof(msg_buffer), "%i x %i Graphic mode",
2145                  width, height);
2146         break;
2147     case GMODE_BLANK:
2148     default:
2149         if (!full_update)
2150             return;
2151 
2152         snprintf(msg_buffer, sizeof(msg_buffer), "VGA Blank mode");
2153         break;
2154     }
2155 
2156     /* Display a message */
2157     s->last_width = 60;
2158     s->last_height = height = 3;
2159     dpy_text_cursor(s->con, -1, -1);
2160     dpy_text_resize(s->con, s->last_width, height);
2161 
2162     for (dst = chardata, i = 0; i < s->last_width * height; i ++)
2163         console_write_ch(dst ++, ' ');
2164 
2165     size = strlen(msg_buffer);
2166     width = (s->last_width - size) / 2;
2167     dst = chardata + s->last_width + width;
2168     for (i = 0; i < size; i ++)
2169         console_write_ch(dst ++, 0x00200100 | msg_buffer[i]);
2170 
2171     dpy_text_update(s->con, 0, 0, s->last_width, height);
2172 }
2173 
2174 static uint64_t vga_mem_read(void *opaque, hwaddr addr,
2175                              unsigned size)
2176 {
2177     VGACommonState *s = opaque;
2178 
2179     return vga_mem_readb(s, addr);
2180 }
2181 
2182 static void vga_mem_write(void *opaque, hwaddr addr,
2183                           uint64_t data, unsigned size)
2184 {
2185     VGACommonState *s = opaque;
2186 
2187     return vga_mem_writeb(s, addr, data);
2188 }
2189 
2190 const MemoryRegionOps vga_mem_ops = {
2191     .read = vga_mem_read,
2192     .write = vga_mem_write,
2193     .endianness = DEVICE_LITTLE_ENDIAN,
2194     .impl = {
2195         .min_access_size = 1,
2196         .max_access_size = 1,
2197     },
2198 };
2199 
2200 static int vga_common_post_load(void *opaque, int version_id)
2201 {
2202     VGACommonState *s = opaque;
2203 
2204     /* force refresh */
2205     s->graphic_mode = -1;
2206     return 0;
2207 }
2208 
2209 const VMStateDescription vmstate_vga_common = {
2210     .name = "vga",
2211     .version_id = 2,
2212     .minimum_version_id = 2,
2213     .minimum_version_id_old = 2,
2214     .post_load = vga_common_post_load,
2215     .fields      = (VMStateField []) {
2216         VMSTATE_UINT32(latch, VGACommonState),
2217         VMSTATE_UINT8(sr_index, VGACommonState),
2218         VMSTATE_PARTIAL_BUFFER(sr, VGACommonState, 8),
2219         VMSTATE_UINT8(gr_index, VGACommonState),
2220         VMSTATE_PARTIAL_BUFFER(gr, VGACommonState, 16),
2221         VMSTATE_UINT8(ar_index, VGACommonState),
2222         VMSTATE_BUFFER(ar, VGACommonState),
2223         VMSTATE_INT32(ar_flip_flop, VGACommonState),
2224         VMSTATE_UINT8(cr_index, VGACommonState),
2225         VMSTATE_BUFFER(cr, VGACommonState),
2226         VMSTATE_UINT8(msr, VGACommonState),
2227         VMSTATE_UINT8(fcr, VGACommonState),
2228         VMSTATE_UINT8(st00, VGACommonState),
2229         VMSTATE_UINT8(st01, VGACommonState),
2230 
2231         VMSTATE_UINT8(dac_state, VGACommonState),
2232         VMSTATE_UINT8(dac_sub_index, VGACommonState),
2233         VMSTATE_UINT8(dac_read_index, VGACommonState),
2234         VMSTATE_UINT8(dac_write_index, VGACommonState),
2235         VMSTATE_BUFFER(dac_cache, VGACommonState),
2236         VMSTATE_BUFFER(palette, VGACommonState),
2237 
2238         VMSTATE_INT32(bank_offset, VGACommonState),
2239         VMSTATE_UINT8_EQUAL(is_vbe_vmstate, VGACommonState),
2240         VMSTATE_UINT16(vbe_index, VGACommonState),
2241         VMSTATE_UINT16_ARRAY(vbe_regs, VGACommonState, VBE_DISPI_INDEX_NB),
2242         VMSTATE_UINT32(vbe_start_addr, VGACommonState),
2243         VMSTATE_UINT32(vbe_line_offset, VGACommonState),
2244         VMSTATE_UINT32(vbe_bank_mask, VGACommonState),
2245         VMSTATE_END_OF_LIST()
2246     }
2247 };
2248 
2249 static const GraphicHwOps vga_ops = {
2250     .invalidate  = vga_invalidate_display,
2251     .gfx_update  = vga_update_display,
2252     .text_update = vga_update_text,
2253 };
2254 
2255 void vga_common_init(VGACommonState *s, Object *obj)
2256 {
2257     int i, j, v, b;
2258 
2259     for(i = 0;i < 256; i++) {
2260         v = 0;
2261         for(j = 0; j < 8; j++) {
2262             v |= ((i >> j) & 1) << (j * 4);
2263         }
2264         expand4[i] = v;
2265 
2266         v = 0;
2267         for(j = 0; j < 4; j++) {
2268             v |= ((i >> (2 * j)) & 3) << (j * 4);
2269         }
2270         expand2[i] = v;
2271     }
2272     for(i = 0; i < 16; i++) {
2273         v = 0;
2274         for(j = 0; j < 4; j++) {
2275             b = ((i >> j) & 1);
2276             v |= b << (2 * j);
2277             v |= b << (2 * j + 1);
2278         }
2279         expand4to8[i] = v;
2280     }
2281 
2282     /* valid range: 1 MB -> 256 MB */
2283     s->vram_size = 1024 * 1024;
2284     while (s->vram_size < (s->vram_size_mb << 20) &&
2285            s->vram_size < (256 << 20)) {
2286         s->vram_size <<= 1;
2287     }
2288     s->vram_size_mb = s->vram_size >> 20;
2289 
2290     s->is_vbe_vmstate = 1;
2291     memory_region_init_ram(&s->vram, obj, "vga.vram", s->vram_size);
2292     vmstate_register_ram_global(&s->vram);
2293     xen_register_framebuffer(&s->vram);
2294     s->vram_ptr = memory_region_get_ram_ptr(&s->vram);
2295     s->get_bpp = vga_get_bpp;
2296     s->get_offsets = vga_get_offsets;
2297     s->get_resolution = vga_get_resolution;
2298     s->hw_ops = &vga_ops;
2299     switch (vga_retrace_method) {
2300     case VGA_RETRACE_DUMB:
2301         s->retrace = vga_dumb_retrace;
2302         s->update_retrace_info = vga_dumb_update_retrace_info;
2303         break;
2304 
2305     case VGA_RETRACE_PRECISE:
2306         s->retrace = vga_precise_retrace;
2307         s->update_retrace_info = vga_precise_update_retrace_info;
2308         break;
2309     }
2310     vga_dirty_log_start(s);
2311 }
2312 
2313 static const MemoryRegionPortio vga_portio_list[] = {
2314     { 0x04,  2, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3b4 */
2315     { 0x0a,  1, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3ba */
2316     { 0x10, 16, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3c0 */
2317     { 0x24,  2, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3d4 */
2318     { 0x2a,  1, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3da */
2319     PORTIO_END_OF_LIST(),
2320 };
2321 
2322 static const MemoryRegionPortio vbe_portio_list[] = {
2323     { 0, 1, 2, .read = vbe_ioport_read_index, .write = vbe_ioport_write_index },
2324 # ifdef TARGET_I386
2325     { 1, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data },
2326 # endif
2327     { 2, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data },
2328     PORTIO_END_OF_LIST(),
2329 };
2330 
2331 /* Used by both ISA and PCI */
2332 MemoryRegion *vga_init_io(VGACommonState *s, Object *obj,
2333                           const MemoryRegionPortio **vga_ports,
2334                           const MemoryRegionPortio **vbe_ports)
2335 {
2336     MemoryRegion *vga_mem;
2337 
2338     *vga_ports = vga_portio_list;
2339     *vbe_ports = vbe_portio_list;
2340 
2341     vga_mem = g_malloc(sizeof(*vga_mem));
2342     memory_region_init_io(vga_mem, obj, &vga_mem_ops, s,
2343                           "vga-lowmem", 0x20000);
2344     memory_region_set_flush_coalesced(vga_mem);
2345 
2346     return vga_mem;
2347 }
2348 
2349 void vga_init(VGACommonState *s, Object *obj, MemoryRegion *address_space,
2350               MemoryRegion *address_space_io, bool init_vga_ports)
2351 {
2352     MemoryRegion *vga_io_memory;
2353     const MemoryRegionPortio *vga_ports, *vbe_ports;
2354     PortioList *vga_port_list = g_new(PortioList, 1);
2355     PortioList *vbe_port_list = g_new(PortioList, 1);
2356 
2357     qemu_register_reset(vga_reset, s);
2358 
2359     s->bank_offset = 0;
2360 
2361     s->legacy_address_space = address_space;
2362 
2363     vga_io_memory = vga_init_io(s, obj, &vga_ports, &vbe_ports);
2364     memory_region_add_subregion_overlap(address_space,
2365                                         isa_mem_base + 0x000a0000,
2366                                         vga_io_memory,
2367                                         1);
2368     memory_region_set_coalescing(vga_io_memory);
2369     if (init_vga_ports) {
2370         portio_list_init(vga_port_list, obj, vga_ports, s, "vga");
2371         portio_list_set_flush_coalesced(vga_port_list);
2372         portio_list_add(vga_port_list, address_space_io, 0x3b0);
2373     }
2374     if (vbe_ports) {
2375         portio_list_init(vbe_port_list, obj, vbe_ports, s, "vbe");
2376         portio_list_add(vbe_port_list, address_space_io, 0x1ce);
2377     }
2378 }
2379 
2380 void vga_init_vbe(VGACommonState *s, Object *obj, MemoryRegion *system_memory)
2381 {
2382     /* With pc-0.12 and below we map both the PCI BAR and the fixed VBE region,
2383      * so use an alias to avoid double-mapping the same region.
2384      */
2385     memory_region_init_alias(&s->vram_vbe, obj, "vram.vbe",
2386                              &s->vram, 0, memory_region_size(&s->vram));
2387     /* XXX: use optimized standard vga accesses */
2388     memory_region_add_subregion(system_memory,
2389                                 VBE_DISPI_LFB_PHYSICAL_ADDRESS,
2390                                 &s->vram_vbe);
2391     s->vbe_mapped = 1;
2392 }
2393