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