kvmvapic: Introduce TPR access optimization for Windows guests
[qemu.git] / hw / vga.c
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.h"
25 #include "vga.h"
26 #include "console.h"
27 #include "pc.h"
28 #include "pci.h"
29 #include "vga_int.h"
30 #include "pixel_ops.h"
31 #include "qemu-timer.h"
32 #include "xen.h"
33
34 //#define DEBUG_VGA
35 //#define DEBUG_VGA_MEM
36 //#define DEBUG_VGA_REG
37
38 //#define DEBUG_BOCHS_VBE
39
40 /*
41  * Video Graphics Array (VGA)
42  *
43  * Chipset docs for original IBM VGA:
44  * http://www.mcamafia.de/pdf/ibm_vgaxga_trm2.pdf
45  *
46  * FreeVGA site:
47  * http://www.osdever.net/FreeVGA/home.htm
48  *
49  * Standard VGA features and Bochs VBE extensions are implemented.
50  */
51
52 /* force some bits to zero */
53 const uint8_t sr_mask[8] = {
54     0x03,
55     0x3d,
56     0x0f,
57     0x3f,
58     0x0e,
59     0x00,
60     0x00,
61     0xff,
62 };
63
64 const uint8_t gr_mask[16] = {
65     0x0f, /* 0x00 */
66     0x0f, /* 0x01 */
67     0x0f, /* 0x02 */
68     0x1f, /* 0x03 */
69     0x03, /* 0x04 */
70     0x7b, /* 0x05 */
71     0x0f, /* 0x06 */
72     0x0f, /* 0x07 */
73     0xff, /* 0x08 */
74     0x00, /* 0x09 */
75     0x00, /* 0x0a */
76     0x00, /* 0x0b */
77     0x00, /* 0x0c */
78     0x00, /* 0x0d */
79     0x00, /* 0x0e */
80     0x00, /* 0x0f */
81 };
82
83 #define cbswap_32(__x) \
84 ((uint32_t)( \
85                 (((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \
86                 (((uint32_t)(__x) & (uint32_t)0x0000ff00UL) <<  8) | \
87                 (((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >>  8) | \
88                 (((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) ))
89
90 #ifdef HOST_WORDS_BIGENDIAN
91 #define PAT(x) cbswap_32(x)
92 #else
93 #define PAT(x) (x)
94 #endif
95
96 #ifdef HOST_WORDS_BIGENDIAN
97 #define BIG 1
98 #else
99 #define BIG 0
100 #endif
101
102 #ifdef HOST_WORDS_BIGENDIAN
103 #define GET_PLANE(data, p) (((data) >> (24 - (p) * 8)) & 0xff)
104 #else
105 #define GET_PLANE(data, p) (((data) >> ((p) * 8)) & 0xff)
106 #endif
107
108 static const uint32_t mask16[16] = {
109     PAT(0x00000000),
110     PAT(0x000000ff),
111     PAT(0x0000ff00),
112     PAT(0x0000ffff),
113     PAT(0x00ff0000),
114     PAT(0x00ff00ff),
115     PAT(0x00ffff00),
116     PAT(0x00ffffff),
117     PAT(0xff000000),
118     PAT(0xff0000ff),
119     PAT(0xff00ff00),
120     PAT(0xff00ffff),
121     PAT(0xffff0000),
122     PAT(0xffff00ff),
123     PAT(0xffffff00),
124     PAT(0xffffffff),
125 };
126
127 #undef PAT
128
129 #ifdef HOST_WORDS_BIGENDIAN
130 #define PAT(x) (x)
131 #else
132 #define PAT(x) cbswap_32(x)
133 #endif
134
135 static const uint32_t dmask16[16] = {
136     PAT(0x00000000),
137     PAT(0x000000ff),
138     PAT(0x0000ff00),
139     PAT(0x0000ffff),
140     PAT(0x00ff0000),
141     PAT(0x00ff00ff),
142     PAT(0x00ffff00),
143     PAT(0x00ffffff),
144     PAT(0xff000000),
145     PAT(0xff0000ff),
146     PAT(0xff00ff00),
147     PAT(0xff00ffff),
148     PAT(0xffff0000),
149     PAT(0xffff00ff),
150     PAT(0xffffff00),
151     PAT(0xffffffff),
152 };
153
154 static const uint32_t dmask4[4] = {
155     PAT(0x00000000),
156     PAT(0x0000ffff),
157     PAT(0xffff0000),
158     PAT(0xffffffff),
159 };
160
161 static uint32_t expand4[256];
162 static uint16_t expand2[256];
163 static uint8_t expand4to8[16];
164
165 static void vga_screen_dump(void *opaque, const char *filename);
166 static const char *screen_dump_filename;
167 static DisplayChangeListener *screen_dump_dcl;
168
169 static void vga_update_memory_access(VGACommonState *s)
170 {
171     MemoryRegion *region, *old_region = s->chain4_alias;
172     target_phys_addr_t 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, "vga.chain4", &s->vram, offset, size);
202         memory_region_add_subregion_overlap(s->legacy_address_space, base,
203                                             region, 2);
204         s->chain4_alias = region;
205     }
206     if (old_region) {
207         memory_region_del_subregion(s->legacy_address_space, old_region);
208         memory_region_destroy(old_region);
209         g_free(old_region);
210         s->plane_updated = 0xf;
211     }
212 }
213
214 static void vga_dumb_update_retrace_info(VGACommonState *s)
215 {
216     (void) s;
217 }
218
219 static void vga_precise_update_retrace_info(VGACommonState *s)
220 {
221     int htotal_chars;
222     int hretr_start_char;
223     int hretr_skew_chars;
224     int hretr_end_char;
225
226     int vtotal_lines;
227     int vretr_start_line;
228     int vretr_end_line;
229
230     int dots;
231 #if 0
232     int div2, sldiv2;
233 #endif
234     int clocking_mode;
235     int clock_sel;
236     const int clk_hz[] = {25175000, 28322000, 25175000, 25175000};
237     int64_t chars_per_sec;
238     struct vga_precise_retrace *r = &s->retrace_info.precise;
239
240     htotal_chars = s->cr[VGA_CRTC_H_TOTAL] + 5;
241     hretr_start_char = s->cr[VGA_CRTC_H_SYNC_START];
242     hretr_skew_chars = (s->cr[VGA_CRTC_H_SYNC_END] >> 5) & 3;
243     hretr_end_char = s->cr[VGA_CRTC_H_SYNC_END] & 0x1f;
244
245     vtotal_lines = (s->cr[VGA_CRTC_V_TOTAL] |
246                     (((s->cr[VGA_CRTC_OVERFLOW] & 1) |
247                       ((s->cr[VGA_CRTC_OVERFLOW] >> 4) & 2)) << 8)) + 2;
248     vretr_start_line = s->cr[VGA_CRTC_V_SYNC_START] |
249         ((((s->cr[VGA_CRTC_OVERFLOW] >> 2) & 1) |
250           ((s->cr[VGA_CRTC_OVERFLOW] >> 6) & 2)) << 8);
251     vretr_end_line = s->cr[VGA_CRTC_V_SYNC_END] & 0xf;
252
253     clocking_mode = (s->sr[VGA_SEQ_CLOCK_MODE] >> 3) & 1;
254     clock_sel = (s->msr >> 2) & 3;
255     dots = (s->msr & 1) ? 8 : 9;
256
257     chars_per_sec = clk_hz[clock_sel] / dots;
258
259     htotal_chars <<= clocking_mode;
260
261     r->total_chars = vtotal_lines * htotal_chars;
262     if (r->freq) {
263         r->ticks_per_char = get_ticks_per_sec() / (r->total_chars * r->freq);
264     } else {
265         r->ticks_per_char = get_ticks_per_sec() / chars_per_sec;
266     }
267
268     r->vstart = vretr_start_line;
269     r->vend = r->vstart + vretr_end_line + 1;
270
271     r->hstart = hretr_start_char + hretr_skew_chars;
272     r->hend = r->hstart + hretr_end_char + 1;
273     r->htotal = htotal_chars;
274
275 #if 0
276     div2 = (s->cr[VGA_CRTC_MODE] >> 2) & 1;
277     sldiv2 = (s->cr[VGA_CRTC_MODE] >> 3) & 1;
278     printf (
279         "hz=%f\n"
280         "htotal = %d\n"
281         "hretr_start = %d\n"
282         "hretr_skew = %d\n"
283         "hretr_end = %d\n"
284         "vtotal = %d\n"
285         "vretr_start = %d\n"
286         "vretr_end = %d\n"
287         "div2 = %d sldiv2 = %d\n"
288         "clocking_mode = %d\n"
289         "clock_sel = %d %d\n"
290         "dots = %d\n"
291         "ticks/char = %" PRId64 "\n"
292         "\n",
293         (double) get_ticks_per_sec() / (r->ticks_per_char * r->total_chars),
294         htotal_chars,
295         hretr_start_char,
296         hretr_skew_chars,
297         hretr_end_char,
298         vtotal_lines,
299         vretr_start_line,
300         vretr_end_line,
301         div2, sldiv2,
302         clocking_mode,
303         clock_sel,
304         clk_hz[clock_sel],
305         dots,
306         r->ticks_per_char
307         );
308 #endif
309 }
310
311 static uint8_t vga_precise_retrace(VGACommonState *s)
312 {
313     struct vga_precise_retrace *r = &s->retrace_info.precise;
314     uint8_t val = s->st01 & ~(ST01_V_RETRACE | ST01_DISP_ENABLE);
315
316     if (r->total_chars) {
317         int cur_line, cur_line_char, cur_char;
318         int64_t cur_tick;
319
320         cur_tick = qemu_get_clock_ns(vm_clock);
321
322         cur_char = (cur_tick / r->ticks_per_char) % r->total_chars;
323         cur_line = cur_char / r->htotal;
324
325         if (cur_line >= r->vstart && cur_line <= r->vend) {
326             val |= ST01_V_RETRACE | ST01_DISP_ENABLE;
327         } else {
328             cur_line_char = cur_char % r->htotal;
329             if (cur_line_char >= r->hstart && cur_line_char <= r->hend) {
330                 val |= ST01_DISP_ENABLE;
331             }
332         }
333
334         return val;
335     } else {
336         return s->st01 ^ (ST01_V_RETRACE | ST01_DISP_ENABLE);
337     }
338 }
339
340 static uint8_t vga_dumb_retrace(VGACommonState *s)
341 {
342     return s->st01 ^ (ST01_V_RETRACE | ST01_DISP_ENABLE);
343 }
344
345 int vga_ioport_invalid(VGACommonState *s, uint32_t addr)
346 {
347     if (s->msr & VGA_MIS_COLOR) {
348         /* Color */
349         return (addr >= 0x3b0 && addr <= 0x3bf);
350     } else {
351         /* Monochrome */
352         return (addr >= 0x3d0 && addr <= 0x3df);
353     }
354 }
355
356 uint32_t vga_ioport_read(void *opaque, uint32_t addr)
357 {
358     VGACommonState *s = opaque;
359     int val, index;
360
361     if (vga_ioport_invalid(s, addr)) {
362         val = 0xff;
363     } else {
364         switch(addr) {
365         case VGA_ATT_W:
366             if (s->ar_flip_flop == 0) {
367                 val = s->ar_index;
368             } else {
369                 val = 0;
370             }
371             break;
372         case VGA_ATT_R:
373             index = s->ar_index & 0x1f;
374             if (index < VGA_ATT_C) {
375                 val = s->ar[index];
376             } else {
377                 val = 0;
378             }
379             break;
380         case VGA_MIS_W:
381             val = s->st00;
382             break;
383         case VGA_SEQ_I:
384             val = s->sr_index;
385             break;
386         case VGA_SEQ_D:
387             val = s->sr[s->sr_index];
388 #ifdef DEBUG_VGA_REG
389             printf("vga: read SR%x = 0x%02x\n", s->sr_index, val);
390 #endif
391             break;
392         case VGA_PEL_IR:
393             val = s->dac_state;
394             break;
395         case VGA_PEL_IW:
396             val = s->dac_write_index;
397             break;
398         case VGA_PEL_D:
399             val = s->palette[s->dac_read_index * 3 + s->dac_sub_index];
400             if (++s->dac_sub_index == 3) {
401                 s->dac_sub_index = 0;
402                 s->dac_read_index++;
403             }
404             break;
405         case VGA_FTC_R:
406             val = s->fcr;
407             break;
408         case VGA_MIS_R:
409             val = s->msr;
410             break;
411         case VGA_GFX_I:
412             val = s->gr_index;
413             break;
414         case VGA_GFX_D:
415             val = s->gr[s->gr_index];
416 #ifdef DEBUG_VGA_REG
417             printf("vga: read GR%x = 0x%02x\n", s->gr_index, val);
418 #endif
419             break;
420         case VGA_CRT_IM:
421         case VGA_CRT_IC:
422             val = s->cr_index;
423             break;
424         case VGA_CRT_DM:
425         case VGA_CRT_DC:
426             val = s->cr[s->cr_index];
427 #ifdef DEBUG_VGA_REG
428             printf("vga: read CR%x = 0x%02x\n", s->cr_index, val);
429 #endif
430             break;
431         case VGA_IS1_RM:
432         case VGA_IS1_RC:
433             /* just toggle to fool polling */
434             val = s->st01 = s->retrace(s);
435             s->ar_flip_flop = 0;
436             break;
437         default:
438             val = 0x00;
439             break;
440         }
441     }
442 #if defined(DEBUG_VGA)
443     printf("VGA: read addr=0x%04x data=0x%02x\n", addr, val);
444 #endif
445     return val;
446 }
447
448 void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
449 {
450     VGACommonState *s = opaque;
451     int index;
452
453     /* check port range access depending on color/monochrome mode */
454     if (vga_ioport_invalid(s, addr)) {
455         return;
456     }
457 #ifdef DEBUG_VGA
458     printf("VGA: write addr=0x%04x data=0x%02x\n", addr, val);
459 #endif
460
461     switch(addr) {
462     case VGA_ATT_W:
463         if (s->ar_flip_flop == 0) {
464             val &= 0x3f;
465             s->ar_index = val;
466         } else {
467             index = s->ar_index & 0x1f;
468             switch(index) {
469             case VGA_ATC_PALETTE0 ... VGA_ATC_PALETTEF:
470                 s->ar[index] = val & 0x3f;
471                 break;
472             case VGA_ATC_MODE:
473                 s->ar[index] = val & ~0x10;
474                 break;
475             case VGA_ATC_OVERSCAN:
476                 s->ar[index] = val;
477                 break;
478             case VGA_ATC_PLANE_ENABLE:
479                 s->ar[index] = val & ~0xc0;
480                 break;
481             case VGA_ATC_PEL:
482                 s->ar[index] = val & ~0xf0;
483                 break;
484             case VGA_ATC_COLOR_PAGE:
485                 s->ar[index] = val & ~0xf0;
486                 break;
487             default:
488                 break;
489             }
490         }
491         s->ar_flip_flop ^= 1;
492         break;
493     case VGA_MIS_W:
494         s->msr = val & ~0x10;
495         s->update_retrace_info(s);
496         break;
497     case VGA_SEQ_I:
498         s->sr_index = val & 7;
499         break;
500     case VGA_SEQ_D:
501 #ifdef DEBUG_VGA_REG
502         printf("vga: write SR%x = 0x%02x\n", s->sr_index, val);
503 #endif
504         s->sr[s->sr_index] = val & sr_mask[s->sr_index];
505         if (s->sr_index == VGA_SEQ_CLOCK_MODE) {
506             s->update_retrace_info(s);
507         }
508         vga_update_memory_access(s);
509         break;
510     case VGA_PEL_IR:
511         s->dac_read_index = val;
512         s->dac_sub_index = 0;
513         s->dac_state = 3;
514         break;
515     case VGA_PEL_IW:
516         s->dac_write_index = val;
517         s->dac_sub_index = 0;
518         s->dac_state = 0;
519         break;
520     case VGA_PEL_D:
521         s->dac_cache[s->dac_sub_index] = val;
522         if (++s->dac_sub_index == 3) {
523             memcpy(&s->palette[s->dac_write_index * 3], s->dac_cache, 3);
524             s->dac_sub_index = 0;
525             s->dac_write_index++;
526         }
527         break;
528     case VGA_GFX_I:
529         s->gr_index = val & 0x0f;
530         break;
531     case VGA_GFX_D:
532 #ifdef DEBUG_VGA_REG
533         printf("vga: write GR%x = 0x%02x\n", s->gr_index, val);
534 #endif
535         s->gr[s->gr_index] = val & gr_mask[s->gr_index];
536         vga_update_memory_access(s);
537         break;
538     case VGA_CRT_IM:
539     case VGA_CRT_IC:
540         s->cr_index = val;
541         break;
542     case VGA_CRT_DM:
543     case VGA_CRT_DC:
544 #ifdef DEBUG_VGA_REG
545         printf("vga: write CR%x = 0x%02x\n", s->cr_index, val);
546 #endif
547         /* handle CR0-7 protection */
548         if ((s->cr[VGA_CRTC_V_SYNC_END] & VGA_CR11_LOCK_CR0_CR7) &&
549             s->cr_index <= VGA_CRTC_OVERFLOW) {
550             /* can always write bit 4 of CR7 */
551             if (s->cr_index == VGA_CRTC_OVERFLOW) {
552                 s->cr[VGA_CRTC_OVERFLOW] = (s->cr[VGA_CRTC_OVERFLOW] & ~0x10) |
553                     (val & 0x10);
554             }
555             return;
556         }
557         s->cr[s->cr_index] = val;
558
559         switch(s->cr_index) {
560         case VGA_CRTC_H_TOTAL:
561         case VGA_CRTC_H_SYNC_START:
562         case VGA_CRTC_H_SYNC_END:
563         case VGA_CRTC_V_TOTAL:
564         case VGA_CRTC_OVERFLOW:
565         case VGA_CRTC_V_SYNC_END:
566         case VGA_CRTC_MODE:
567             s->update_retrace_info(s);
568             break;
569         }
570         break;
571     case VGA_IS1_RM:
572     case VGA_IS1_RC:
573         s->fcr = val & 0x10;
574         break;
575     }
576 }
577
578 #ifdef CONFIG_BOCHS_VBE
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 static 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 static 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 static 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 #endif
781
782 /* called for accesses between 0xa0000 and 0xc0000 */
783 uint32_t vga_mem_readb(VGACommonState *s, target_phys_addr_t addr)
784 {
785     int memory_map_mode, plane;
786     uint32_t ret;
787
788     /* convert to VGA memory offset */
789     memory_map_mode = (s->gr[VGA_GFX_MISC] >> 2) & 3;
790     addr &= 0x1ffff;
791     switch(memory_map_mode) {
792     case 0:
793         break;
794     case 1:
795         if (addr >= 0x10000)
796             return 0xff;
797         addr += s->bank_offset;
798         break;
799     case 2:
800         addr -= 0x10000;
801         if (addr >= 0x8000)
802             return 0xff;
803         break;
804     default:
805     case 3:
806         addr -= 0x18000;
807         if (addr >= 0x8000)
808             return 0xff;
809         break;
810     }
811
812     if (s->sr[VGA_SEQ_MEMORY_MODE] & VGA_SR04_CHN_4M) {
813         /* chain 4 mode : simplest access */
814         ret = s->vram_ptr[addr];
815     } else if (s->gr[VGA_GFX_MODE] & 0x10) {
816         /* odd/even mode (aka text mode mapping) */
817         plane = (s->gr[VGA_GFX_PLANE_READ] & 2) | (addr & 1);
818         ret = s->vram_ptr[((addr & ~1) << 1) | plane];
819     } else {
820         /* standard VGA latched access */
821         s->latch = ((uint32_t *)s->vram_ptr)[addr];
822
823         if (!(s->gr[VGA_GFX_MODE] & 0x08)) {
824             /* read mode 0 */
825             plane = s->gr[VGA_GFX_PLANE_READ];
826             ret = GET_PLANE(s->latch, plane);
827         } else {
828             /* read mode 1 */
829             ret = (s->latch ^ mask16[s->gr[VGA_GFX_COMPARE_VALUE]]) &
830                 mask16[s->gr[VGA_GFX_COMPARE_MASK]];
831             ret |= ret >> 16;
832             ret |= ret >> 8;
833             ret = (~ret) & 0xff;
834         }
835     }
836     return ret;
837 }
838
839 /* called for accesses between 0xa0000 and 0xc0000 */
840 void vga_mem_writeb(VGACommonState *s, target_phys_addr_t addr, uint32_t val)
841 {
842     int memory_map_mode, plane, write_mode, b, func_select, mask;
843     uint32_t write_mask, bit_mask, set_mask;
844
845 #ifdef DEBUG_VGA_MEM
846     printf("vga: [0x" TARGET_FMT_plx "] = 0x%02x\n", addr, val);
847 #endif
848     /* convert to VGA memory offset */
849     memory_map_mode = (s->gr[VGA_GFX_MISC] >> 2) & 3;
850     addr &= 0x1ffff;
851     switch(memory_map_mode) {
852     case 0:
853         break;
854     case 1:
855         if (addr >= 0x10000)
856             return;
857         addr += s->bank_offset;
858         break;
859     case 2:
860         addr -= 0x10000;
861         if (addr >= 0x8000)
862             return;
863         break;
864     default:
865     case 3:
866         addr -= 0x18000;
867         if (addr >= 0x8000)
868             return;
869         break;
870     }
871
872     if (s->sr[VGA_SEQ_MEMORY_MODE] & VGA_SR04_CHN_4M) {
873         /* chain 4 mode : simplest access */
874         plane = addr & 3;
875         mask = (1 << plane);
876         if (s->sr[VGA_SEQ_PLANE_WRITE] & mask) {
877             s->vram_ptr[addr] = val;
878 #ifdef DEBUG_VGA_MEM
879             printf("vga: chain4: [0x" TARGET_FMT_plx "]\n", addr);
880 #endif
881             s->plane_updated |= mask; /* only used to detect font change */
882             memory_region_set_dirty(&s->vram, addr, 1);
883         }
884     } else if (s->gr[VGA_GFX_MODE] & 0x10) {
885         /* odd/even mode (aka text mode mapping) */
886         plane = (s->gr[VGA_GFX_PLANE_READ] & 2) | (addr & 1);
887         mask = (1 << plane);
888         if (s->sr[VGA_SEQ_PLANE_WRITE] & mask) {
889             addr = ((addr & ~1) << 1) | plane;
890             s->vram_ptr[addr] = val;
891 #ifdef DEBUG_VGA_MEM
892             printf("vga: odd/even: [0x" TARGET_FMT_plx "]\n", addr);
893 #endif
894             s->plane_updated |= mask; /* only used to detect font change */
895             memory_region_set_dirty(&s->vram, addr, 1);
896         }
897     } else {
898         /* standard VGA latched access */
899         write_mode = s->gr[VGA_GFX_MODE] & 3;
900         switch(write_mode) {
901         default:
902         case 0:
903             /* rotate */
904             b = s->gr[VGA_GFX_DATA_ROTATE] & 7;
905             val = ((val >> b) | (val << (8 - b))) & 0xff;
906             val |= val << 8;
907             val |= val << 16;
908
909             /* apply set/reset mask */
910             set_mask = mask16[s->gr[VGA_GFX_SR_ENABLE]];
911             val = (val & ~set_mask) |
912                 (mask16[s->gr[VGA_GFX_SR_VALUE]] & set_mask);
913             bit_mask = s->gr[VGA_GFX_BIT_MASK];
914             break;
915         case 1:
916             val = s->latch;
917             goto do_write;
918         case 2:
919             val = mask16[val & 0x0f];
920             bit_mask = s->gr[VGA_GFX_BIT_MASK];
921             break;
922         case 3:
923             /* rotate */
924             b = s->gr[VGA_GFX_DATA_ROTATE] & 7;
925             val = (val >> b) | (val << (8 - b));
926
927             bit_mask = s->gr[VGA_GFX_BIT_MASK] & val;
928             val = mask16[s->gr[VGA_GFX_SR_VALUE]];
929             break;
930         }
931
932         /* apply logical operation */
933         func_select = s->gr[VGA_GFX_DATA_ROTATE] >> 3;
934         switch(func_select) {
935         case 0:
936         default:
937             /* nothing to do */
938             break;
939         case 1:
940             /* and */
941             val &= s->latch;
942             break;
943         case 2:
944             /* or */
945             val |= s->latch;
946             break;
947         case 3:
948             /* xor */
949             val ^= s->latch;
950             break;
951         }
952
953         /* apply bit mask */
954         bit_mask |= bit_mask << 8;
955         bit_mask |= bit_mask << 16;
956         val = (val & bit_mask) | (s->latch & ~bit_mask);
957
958     do_write:
959         /* mask data according to sr[2] */
960         mask = s->sr[VGA_SEQ_PLANE_WRITE];
961         s->plane_updated |= mask; /* only used to detect font change */
962         write_mask = mask16[mask];
963         ((uint32_t *)s->vram_ptr)[addr] =
964             (((uint32_t *)s->vram_ptr)[addr] & ~write_mask) |
965             (val & write_mask);
966 #ifdef DEBUG_VGA_MEM
967         printf("vga: latch: [0x" TARGET_FMT_plx "] mask=0x%08x val=0x%08x\n",
968                addr * 4, write_mask, val);
969 #endif
970         memory_region_set_dirty(&s->vram, addr << 2, sizeof(uint32_t));
971     }
972 }
973
974 typedef void vga_draw_glyph8_func(uint8_t *d, int linesize,
975                              const uint8_t *font_ptr, int h,
976                              uint32_t fgcol, uint32_t bgcol);
977 typedef void vga_draw_glyph9_func(uint8_t *d, int linesize,
978                                   const uint8_t *font_ptr, int h,
979                                   uint32_t fgcol, uint32_t bgcol, int dup9);
980 typedef void vga_draw_line_func(VGACommonState *s1, uint8_t *d,
981                                 const uint8_t *s, int width);
982
983 #define DEPTH 8
984 #include "vga_template.h"
985
986 #define DEPTH 15
987 #include "vga_template.h"
988
989 #define BGR_FORMAT
990 #define DEPTH 15
991 #include "vga_template.h"
992
993 #define DEPTH 16
994 #include "vga_template.h"
995
996 #define BGR_FORMAT
997 #define DEPTH 16
998 #include "vga_template.h"
999
1000 #define DEPTH 32
1001 #include "vga_template.h"
1002
1003 #define BGR_FORMAT
1004 #define DEPTH 32
1005 #include "vga_template.h"
1006
1007 static unsigned int rgb_to_pixel8_dup(unsigned int r, unsigned int g, unsigned b)
1008 {
1009     unsigned int col;
1010     col = rgb_to_pixel8(r, g, b);
1011     col |= col << 8;
1012     col |= col << 16;
1013     return col;
1014 }
1015
1016 static unsigned int rgb_to_pixel15_dup(unsigned int r, unsigned int g, unsigned b)
1017 {
1018     unsigned int col;
1019     col = rgb_to_pixel15(r, g, b);
1020     col |= col << 16;
1021     return col;
1022 }
1023
1024 static unsigned int rgb_to_pixel15bgr_dup(unsigned int r, unsigned int g,
1025                                           unsigned int b)
1026 {
1027     unsigned int col;
1028     col = rgb_to_pixel15bgr(r, g, b);
1029     col |= col << 16;
1030     return col;
1031 }
1032
1033 static unsigned int rgb_to_pixel16_dup(unsigned int r, unsigned int g, unsigned b)
1034 {
1035     unsigned int col;
1036     col = rgb_to_pixel16(r, g, b);
1037     col |= col << 16;
1038     return col;
1039 }
1040
1041 static unsigned int rgb_to_pixel16bgr_dup(unsigned int r, unsigned int g,
1042                                           unsigned int b)
1043 {
1044     unsigned int col;
1045     col = rgb_to_pixel16bgr(r, g, b);
1046     col |= col << 16;
1047     return col;
1048 }
1049
1050 static unsigned int rgb_to_pixel32_dup(unsigned int r, unsigned int g, unsigned b)
1051 {
1052     unsigned int col;
1053     col = rgb_to_pixel32(r, g, b);
1054     return col;
1055 }
1056
1057 static unsigned int rgb_to_pixel32bgr_dup(unsigned int r, unsigned int g, unsigned b)
1058 {
1059     unsigned int col;
1060     col = rgb_to_pixel32bgr(r, g, b);
1061     return col;
1062 }
1063
1064 /* return true if the palette was modified */
1065 static int update_palette16(VGACommonState *s)
1066 {
1067     int full_update, i;
1068     uint32_t v, col, *palette;
1069
1070     full_update = 0;
1071     palette = s->last_palette;
1072     for(i = 0; i < 16; i++) {
1073         v = s->ar[i];
1074         if (s->ar[VGA_ATC_MODE] & 0x80) {
1075             v = ((s->ar[VGA_ATC_COLOR_PAGE] & 0xf) << 4) | (v & 0xf);
1076         } else {
1077             v = ((s->ar[VGA_ATC_COLOR_PAGE] & 0xc) << 4) | (v & 0x3f);
1078         }
1079         v = v * 3;
1080         col = s->rgb_to_pixel(c6_to_8(s->palette[v]),
1081                               c6_to_8(s->palette[v + 1]),
1082                               c6_to_8(s->palette[v + 2]));
1083         if (col != palette[i]) {
1084             full_update = 1;
1085             palette[i] = col;
1086         }
1087     }
1088     return full_update;
1089 }
1090
1091 /* return true if the palette was modified */
1092 static int update_palette256(VGACommonState *s)
1093 {
1094     int full_update, i;
1095     uint32_t v, col, *palette;
1096
1097     full_update = 0;
1098     palette = s->last_palette;
1099     v = 0;
1100     for(i = 0; i < 256; i++) {
1101         if (s->dac_8bit) {
1102           col = s->rgb_to_pixel(s->palette[v],
1103                                 s->palette[v + 1],
1104                                 s->palette[v + 2]);
1105         } else {
1106           col = s->rgb_to_pixel(c6_to_8(s->palette[v]),
1107                                 c6_to_8(s->palette[v + 1]),
1108                                 c6_to_8(s->palette[v + 2]));
1109         }
1110         if (col != palette[i]) {
1111             full_update = 1;
1112             palette[i] = col;
1113         }
1114         v += 3;
1115     }
1116     return full_update;
1117 }
1118
1119 static void vga_get_offsets(VGACommonState *s,
1120                             uint32_t *pline_offset,
1121                             uint32_t *pstart_addr,
1122                             uint32_t *pline_compare)
1123 {
1124     uint32_t start_addr, line_offset, line_compare;
1125 #ifdef CONFIG_BOCHS_VBE
1126     if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
1127         line_offset = s->vbe_line_offset;
1128         start_addr = s->vbe_start_addr;
1129         line_compare = 65535;
1130     } else
1131 #endif
1132     {
1133         /* compute line_offset in bytes */
1134         line_offset = s->cr[VGA_CRTC_OFFSET];
1135         line_offset <<= 3;
1136
1137         /* starting address */
1138         start_addr = s->cr[VGA_CRTC_START_LO] |
1139             (s->cr[VGA_CRTC_START_HI] << 8);
1140
1141         /* line compare */
1142         line_compare = s->cr[VGA_CRTC_LINE_COMPARE] |
1143             ((s->cr[VGA_CRTC_OVERFLOW] & 0x10) << 4) |
1144             ((s->cr[VGA_CRTC_MAX_SCAN] & 0x40) << 3);
1145     }
1146     *pline_offset = line_offset;
1147     *pstart_addr = start_addr;
1148     *pline_compare = line_compare;
1149 }
1150
1151 /* update start_addr and line_offset. Return TRUE if modified */
1152 static int update_basic_params(VGACommonState *s)
1153 {
1154     int full_update;
1155     uint32_t start_addr, line_offset, line_compare;
1156
1157     full_update = 0;
1158
1159     s->get_offsets(s, &line_offset, &start_addr, &line_compare);
1160
1161     if (line_offset != s->line_offset ||
1162         start_addr != s->start_addr ||
1163         line_compare != s->line_compare) {
1164         s->line_offset = line_offset;
1165         s->start_addr = start_addr;
1166         s->line_compare = line_compare;
1167         full_update = 1;
1168     }
1169     return full_update;
1170 }
1171
1172 #define NB_DEPTHS 7
1173
1174 static inline int get_depth_index(DisplayState *s)
1175 {
1176     switch(ds_get_bits_per_pixel(s)) {
1177     default:
1178     case 8:
1179         return 0;
1180     case 15:
1181         return 1;
1182     case 16:
1183         return 2;
1184     case 32:
1185         if (is_surface_bgr(s->surface))
1186             return 4;
1187         else
1188             return 3;
1189     }
1190 }
1191
1192 static vga_draw_glyph8_func * const vga_draw_glyph8_table[NB_DEPTHS] = {
1193     vga_draw_glyph8_8,
1194     vga_draw_glyph8_16,
1195     vga_draw_glyph8_16,
1196     vga_draw_glyph8_32,
1197     vga_draw_glyph8_32,
1198     vga_draw_glyph8_16,
1199     vga_draw_glyph8_16,
1200 };
1201
1202 static vga_draw_glyph8_func * const vga_draw_glyph16_table[NB_DEPTHS] = {
1203     vga_draw_glyph16_8,
1204     vga_draw_glyph16_16,
1205     vga_draw_glyph16_16,
1206     vga_draw_glyph16_32,
1207     vga_draw_glyph16_32,
1208     vga_draw_glyph16_16,
1209     vga_draw_glyph16_16,
1210 };
1211
1212 static vga_draw_glyph9_func * const vga_draw_glyph9_table[NB_DEPTHS] = {
1213     vga_draw_glyph9_8,
1214     vga_draw_glyph9_16,
1215     vga_draw_glyph9_16,
1216     vga_draw_glyph9_32,
1217     vga_draw_glyph9_32,
1218     vga_draw_glyph9_16,
1219     vga_draw_glyph9_16,
1220 };
1221
1222 static const uint8_t cursor_glyph[32 * 4] = {
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     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1238     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1239 };
1240
1241 static void vga_get_text_resolution(VGACommonState *s, int *pwidth, int *pheight,
1242                                     int *pcwidth, int *pcheight)
1243 {
1244     int width, cwidth, height, cheight;
1245
1246     /* total width & height */
1247     cheight = (s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1;
1248     cwidth = 8;
1249     if (!(s->sr[VGA_SEQ_CLOCK_MODE] & VGA_SR01_CHAR_CLK_8DOTS)) {
1250         cwidth = 9;
1251     }
1252     if (s->sr[VGA_SEQ_CLOCK_MODE] & 0x08) {
1253         cwidth = 16; /* NOTE: no 18 pixel wide */
1254     }
1255     width = (s->cr[VGA_CRTC_H_DISP] + 1);
1256     if (s->cr[VGA_CRTC_V_TOTAL] == 100) {
1257         /* ugly hack for CGA 160x100x16 - explain me the logic */
1258         height = 100;
1259     } else {
1260         height = s->cr[VGA_CRTC_V_DISP_END] |
1261             ((s->cr[VGA_CRTC_OVERFLOW] & 0x02) << 7) |
1262             ((s->cr[VGA_CRTC_OVERFLOW] & 0x40) << 3);
1263         height = (height + 1) / cheight;
1264     }
1265
1266     *pwidth = width;
1267     *pheight = height;
1268     *pcwidth = cwidth;
1269     *pcheight = cheight;
1270 }
1271
1272 typedef unsigned int rgb_to_pixel_dup_func(unsigned int r, unsigned int g, unsigned b);
1273
1274 static rgb_to_pixel_dup_func * const rgb_to_pixel_dup_table[NB_DEPTHS] = {
1275     rgb_to_pixel8_dup,
1276     rgb_to_pixel15_dup,
1277     rgb_to_pixel16_dup,
1278     rgb_to_pixel32_dup,
1279     rgb_to_pixel32bgr_dup,
1280     rgb_to_pixel15bgr_dup,
1281     rgb_to_pixel16bgr_dup,
1282 };
1283
1284 /*
1285  * Text mode update
1286  * Missing:
1287  * - double scan
1288  * - double width
1289  * - underline
1290  * - flashing
1291  */
1292 static void vga_draw_text(VGACommonState *s, int full_update)
1293 {
1294     int cx, cy, cheight, cw, ch, cattr, height, width, ch_attr;
1295     int cx_min, cx_max, linesize, x_incr, line, line1;
1296     uint32_t offset, fgcol, bgcol, v, cursor_offset;
1297     uint8_t *d1, *d, *src, *dest, *cursor_ptr;
1298     const uint8_t *font_ptr, *font_base[2];
1299     int dup9, line_offset, depth_index;
1300     uint32_t *palette;
1301     uint32_t *ch_attr_ptr;
1302     vga_draw_glyph8_func *vga_draw_glyph8;
1303     vga_draw_glyph9_func *vga_draw_glyph9;
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) > CH_ATTR_SIZE) {
1332         /* better than nothing: exit if transient size is too big */
1333         return;
1334     }
1335
1336     if (width != s->last_width || height != s->last_height ||
1337         cw != s->last_cw || cheight != s->last_ch || s->last_depth) {
1338         s->last_scr_width = width * cw;
1339         s->last_scr_height = height * cheight;
1340         qemu_console_resize(s->ds, s->last_scr_width, s->last_scr_height);
1341         s->last_depth = 0;
1342         s->last_width = width;
1343         s->last_height = height;
1344         s->last_ch = cheight;
1345         s->last_cw = cw;
1346         full_update = 1;
1347     }
1348     s->rgb_to_pixel =
1349         rgb_to_pixel_dup_table[get_depth_index(s->ds)];
1350     full_update |= update_palette16(s);
1351     palette = s->last_palette;
1352     x_incr = cw * ((ds_get_bits_per_pixel(s->ds) + 7) >> 3);
1353
1354     cursor_offset = ((s->cr[VGA_CRTC_CURSOR_HI] << 8) |
1355                      s->cr[VGA_CRTC_CURSOR_LO]) - s->start_addr;
1356     if (cursor_offset != s->cursor_offset ||
1357         s->cr[VGA_CRTC_CURSOR_START] != s->cursor_start ||
1358         s->cr[VGA_CRTC_CURSOR_END] != s->cursor_end) {
1359       /* if the cursor position changed, we update the old and new
1360          chars */
1361         if (s->cursor_offset < CH_ATTR_SIZE)
1362             s->last_ch_attr[s->cursor_offset] = -1;
1363         if (cursor_offset < CH_ATTR_SIZE)
1364             s->last_ch_attr[cursor_offset] = -1;
1365         s->cursor_offset = cursor_offset;
1366         s->cursor_start = s->cr[VGA_CRTC_CURSOR_START];
1367         s->cursor_end = s->cr[VGA_CRTC_CURSOR_END];
1368     }
1369     cursor_ptr = s->vram_ptr + (s->start_addr + cursor_offset) * 4;
1370
1371     depth_index = get_depth_index(s->ds);
1372     if (cw == 16)
1373         vga_draw_glyph8 = vga_draw_glyph16_table[depth_index];
1374     else
1375         vga_draw_glyph8 = vga_draw_glyph8_table[depth_index];
1376     vga_draw_glyph9 = vga_draw_glyph9_table[depth_index];
1377
1378     dest = ds_get_data(s->ds);
1379     linesize = ds_get_linesize(s->ds);
1380     ch_attr_ptr = s->last_ch_attr;
1381     line = 0;
1382     offset = s->start_addr * 4;
1383     for(cy = 0; cy < height; cy++) {
1384         d1 = dest;
1385         src = s->vram_ptr + offset;
1386         cx_min = width;
1387         cx_max = -1;
1388         for(cx = 0; cx < width; cx++) {
1389             ch_attr = *(uint16_t *)src;
1390             if (full_update || ch_attr != *ch_attr_ptr) {
1391                 if (cx < cx_min)
1392                     cx_min = cx;
1393                 if (cx > cx_max)
1394                     cx_max = cx;
1395                 *ch_attr_ptr = ch_attr;
1396 #ifdef HOST_WORDS_BIGENDIAN
1397                 ch = ch_attr >> 8;
1398                 cattr = ch_attr & 0xff;
1399 #else
1400                 ch = ch_attr & 0xff;
1401                 cattr = ch_attr >> 8;
1402 #endif
1403                 font_ptr = font_base[(cattr >> 3) & 1];
1404                 font_ptr += 32 * 4 * ch;
1405                 bgcol = palette[cattr >> 4];
1406                 fgcol = palette[cattr & 0x0f];
1407                 if (cw != 9) {
1408                     vga_draw_glyph8(d1, linesize,
1409                                     font_ptr, cheight, fgcol, bgcol);
1410                 } else {
1411                     dup9 = 0;
1412                     if (ch >= 0xb0 && ch <= 0xdf &&
1413                         (s->ar[VGA_ATC_MODE] & 0x04)) {
1414                         dup9 = 1;
1415                     }
1416                     vga_draw_glyph9(d1, linesize,
1417                                     font_ptr, cheight, fgcol, bgcol, dup9);
1418                 }
1419                 if (src == cursor_ptr &&
1420                     !(s->cr[VGA_CRTC_CURSOR_START] & 0x20)) {
1421                     int line_start, line_last, h;
1422                     /* draw the cursor */
1423                     line_start = s->cr[VGA_CRTC_CURSOR_START] & 0x1f;
1424                     line_last = s->cr[VGA_CRTC_CURSOR_END] & 0x1f;
1425                     /* XXX: check that */
1426                     if (line_last > cheight - 1)
1427                         line_last = cheight - 1;
1428                     if (line_last >= line_start && line_start < cheight) {
1429                         h = line_last - line_start + 1;
1430                         d = d1 + linesize * line_start;
1431                         if (cw != 9) {
1432                             vga_draw_glyph8(d, linesize,
1433                                             cursor_glyph, h, fgcol, bgcol);
1434                         } else {
1435                             vga_draw_glyph9(d, linesize,
1436                                             cursor_glyph, h, fgcol, bgcol, 1);
1437                         }
1438                     }
1439                 }
1440             }
1441             d1 += x_incr;
1442             src += 4;
1443             ch_attr_ptr++;
1444         }
1445         if (cx_max != -1) {
1446             dpy_update(s->ds, cx_min * cw, cy * cheight,
1447                        (cx_max - cx_min + 1) * cw, cheight);
1448         }
1449         dest += linesize * cheight;
1450         line1 = line + cheight;
1451         offset += line_offset;
1452         if (line < s->line_compare && line1 >= s->line_compare) {
1453             offset = 0;
1454         }
1455         line = line1;
1456     }
1457 }
1458
1459 enum {
1460     VGA_DRAW_LINE2,
1461     VGA_DRAW_LINE2D2,
1462     VGA_DRAW_LINE4,
1463     VGA_DRAW_LINE4D2,
1464     VGA_DRAW_LINE8D2,
1465     VGA_DRAW_LINE8,
1466     VGA_DRAW_LINE15,
1467     VGA_DRAW_LINE16,
1468     VGA_DRAW_LINE24,
1469     VGA_DRAW_LINE32,
1470     VGA_DRAW_LINE_NB,
1471 };
1472
1473 static vga_draw_line_func * const vga_draw_line_table[NB_DEPTHS * VGA_DRAW_LINE_NB] = {
1474     vga_draw_line2_8,
1475     vga_draw_line2_16,
1476     vga_draw_line2_16,
1477     vga_draw_line2_32,
1478     vga_draw_line2_32,
1479     vga_draw_line2_16,
1480     vga_draw_line2_16,
1481
1482     vga_draw_line2d2_8,
1483     vga_draw_line2d2_16,
1484     vga_draw_line2d2_16,
1485     vga_draw_line2d2_32,
1486     vga_draw_line2d2_32,
1487     vga_draw_line2d2_16,
1488     vga_draw_line2d2_16,
1489
1490     vga_draw_line4_8,
1491     vga_draw_line4_16,
1492     vga_draw_line4_16,
1493     vga_draw_line4_32,
1494     vga_draw_line4_32,
1495     vga_draw_line4_16,
1496     vga_draw_line4_16,
1497
1498     vga_draw_line4d2_8,
1499     vga_draw_line4d2_16,
1500     vga_draw_line4d2_16,
1501     vga_draw_line4d2_32,
1502     vga_draw_line4d2_32,
1503     vga_draw_line4d2_16,
1504     vga_draw_line4d2_16,
1505
1506     vga_draw_line8d2_8,
1507     vga_draw_line8d2_16,
1508     vga_draw_line8d2_16,
1509     vga_draw_line8d2_32,
1510     vga_draw_line8d2_32,
1511     vga_draw_line8d2_16,
1512     vga_draw_line8d2_16,
1513
1514     vga_draw_line8_8,
1515     vga_draw_line8_16,
1516     vga_draw_line8_16,
1517     vga_draw_line8_32,
1518     vga_draw_line8_32,
1519     vga_draw_line8_16,
1520     vga_draw_line8_16,
1521
1522     vga_draw_line15_8,
1523     vga_draw_line15_15,
1524     vga_draw_line15_16,
1525     vga_draw_line15_32,
1526     vga_draw_line15_32bgr,
1527     vga_draw_line15_15bgr,
1528     vga_draw_line15_16bgr,
1529
1530     vga_draw_line16_8,
1531     vga_draw_line16_15,
1532     vga_draw_line16_16,
1533     vga_draw_line16_32,
1534     vga_draw_line16_32bgr,
1535     vga_draw_line16_15bgr,
1536     vga_draw_line16_16bgr,
1537
1538     vga_draw_line24_8,
1539     vga_draw_line24_15,
1540     vga_draw_line24_16,
1541     vga_draw_line24_32,
1542     vga_draw_line24_32bgr,
1543     vga_draw_line24_15bgr,
1544     vga_draw_line24_16bgr,
1545
1546     vga_draw_line32_8,
1547     vga_draw_line32_15,
1548     vga_draw_line32_16,
1549     vga_draw_line32_32,
1550     vga_draw_line32_32bgr,
1551     vga_draw_line32_15bgr,
1552     vga_draw_line32_16bgr,
1553 };
1554
1555 static int vga_get_bpp(VGACommonState *s)
1556 {
1557     int ret;
1558 #ifdef CONFIG_BOCHS_VBE
1559     if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
1560         ret = s->vbe_regs[VBE_DISPI_INDEX_BPP];
1561     } else
1562 #endif
1563     {
1564         ret = 0;
1565     }
1566     return ret;
1567 }
1568
1569 static void vga_get_resolution(VGACommonState *s, int *pwidth, int *pheight)
1570 {
1571     int width, height;
1572
1573 #ifdef CONFIG_BOCHS_VBE
1574     if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
1575         width = s->vbe_regs[VBE_DISPI_INDEX_XRES];
1576         height = s->vbe_regs[VBE_DISPI_INDEX_YRES];
1577     } else
1578 #endif
1579     {
1580         width = (s->cr[VGA_CRTC_H_DISP] + 1) * 8;
1581         height = s->cr[VGA_CRTC_V_DISP_END] |
1582             ((s->cr[VGA_CRTC_OVERFLOW] & 0x02) << 7) |
1583             ((s->cr[VGA_CRTC_OVERFLOW] & 0x40) << 3);
1584         height = (height + 1);
1585     }
1586     *pwidth = width;
1587     *pheight = height;
1588 }
1589
1590 void vga_invalidate_scanlines(VGACommonState *s, int y1, int y2)
1591 {
1592     int y;
1593     if (y1 >= VGA_MAX_HEIGHT)
1594         return;
1595     if (y2 >= VGA_MAX_HEIGHT)
1596         y2 = VGA_MAX_HEIGHT;
1597     for(y = y1; y < y2; y++) {
1598         s->invalidated_y_table[y >> 5] |= 1 << (y & 0x1f);
1599     }
1600 }
1601
1602 static void vga_sync_dirty_bitmap(VGACommonState *s)
1603 {
1604     memory_region_sync_dirty_bitmap(&s->vram);
1605 }
1606
1607 void vga_dirty_log_start(VGACommonState *s)
1608 {
1609     memory_region_set_log(&s->vram, true, DIRTY_MEMORY_VGA);
1610 }
1611
1612 void vga_dirty_log_stop(VGACommonState *s)
1613 {
1614     memory_region_set_log(&s->vram, false, DIRTY_MEMORY_VGA);
1615 }
1616
1617 /*
1618  * graphic modes
1619  */
1620 static void vga_draw_graphic(VGACommonState *s, int full_update)
1621 {
1622     int y1, y, update, linesize, y_start, double_scan, mask, depth;
1623     int width, height, shift_control, line_offset, bwidth, bits;
1624     ram_addr_t page0, page1, page_min, page_max;
1625     int disp_width, multi_scan, multi_run;
1626     uint8_t *d;
1627     uint32_t v, addr1, addr;
1628     vga_draw_line_func *vga_draw_line;
1629
1630     full_update |= update_basic_params(s);
1631
1632     if (!full_update)
1633         vga_sync_dirty_bitmap(s);
1634
1635     s->get_resolution(s, &width, &height);
1636     disp_width = width;
1637
1638     shift_control = (s->gr[VGA_GFX_MODE] >> 5) & 3;
1639     double_scan = (s->cr[VGA_CRTC_MAX_SCAN] >> 7);
1640     if (shift_control != 1) {
1641         multi_scan = (((s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1) << double_scan)
1642             - 1;
1643     } else {
1644         /* in CGA modes, multi_scan is ignored */
1645         /* XXX: is it correct ? */
1646         multi_scan = double_scan;
1647     }
1648     multi_run = multi_scan;
1649     if (shift_control != s->shift_control ||
1650         double_scan != s->double_scan) {
1651         full_update = 1;
1652         s->shift_control = shift_control;
1653         s->double_scan = double_scan;
1654     }
1655
1656     if (shift_control == 0) {
1657         if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) {
1658             disp_width <<= 1;
1659         }
1660     } else if (shift_control == 1) {
1661         if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) {
1662             disp_width <<= 1;
1663         }
1664     }
1665
1666     depth = s->get_bpp(s);
1667     if (s->line_offset != s->last_line_offset ||
1668         disp_width != s->last_width ||
1669         height != s->last_height ||
1670         s->last_depth != depth) {
1671 #if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
1672         if (depth == 16 || depth == 32) {
1673 #else
1674         if (depth == 32) {
1675 #endif
1676             qemu_free_displaysurface(s->ds);
1677             s->ds->surface = qemu_create_displaysurface_from(disp_width, height, depth,
1678                     s->line_offset,
1679                     s->vram_ptr + (s->start_addr * 4));
1680 #if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
1681             s->ds->surface->pf = qemu_different_endianness_pixelformat(depth);
1682 #endif
1683             dpy_resize(s->ds);
1684         } else {
1685             qemu_console_resize(s->ds, disp_width, height);
1686         }
1687         s->last_scr_width = disp_width;
1688         s->last_scr_height = height;
1689         s->last_width = disp_width;
1690         s->last_height = height;
1691         s->last_line_offset = s->line_offset;
1692         s->last_depth = depth;
1693         full_update = 1;
1694     } else if (is_buffer_shared(s->ds->surface) &&
1695                (full_update || s->ds->surface->data != s->vram_ptr + (s->start_addr * 4))) {
1696         s->ds->surface->data = s->vram_ptr + (s->start_addr * 4);
1697         dpy_setdata(s->ds);
1698     }
1699
1700     s->rgb_to_pixel =
1701         rgb_to_pixel_dup_table[get_depth_index(s->ds)];
1702
1703     if (shift_control == 0) {
1704         full_update |= update_palette16(s);
1705         if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) {
1706             v = VGA_DRAW_LINE4D2;
1707         } else {
1708             v = VGA_DRAW_LINE4;
1709         }
1710         bits = 4;
1711     } else if (shift_control == 1) {
1712         full_update |= update_palette16(s);
1713         if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) {
1714             v = VGA_DRAW_LINE2D2;
1715         } else {
1716             v = VGA_DRAW_LINE2;
1717         }
1718         bits = 4;
1719     } else {
1720         switch(s->get_bpp(s)) {
1721         default:
1722         case 0:
1723             full_update |= update_palette256(s);
1724             v = VGA_DRAW_LINE8D2;
1725             bits = 4;
1726             break;
1727         case 8:
1728             full_update |= update_palette256(s);
1729             v = VGA_DRAW_LINE8;
1730             bits = 8;
1731             break;
1732         case 15:
1733             v = VGA_DRAW_LINE15;
1734             bits = 16;
1735             break;
1736         case 16:
1737             v = VGA_DRAW_LINE16;
1738             bits = 16;
1739             break;
1740         case 24:
1741             v = VGA_DRAW_LINE24;
1742             bits = 24;
1743             break;
1744         case 32:
1745             v = VGA_DRAW_LINE32;
1746             bits = 32;
1747             break;
1748         }
1749     }
1750     vga_draw_line = vga_draw_line_table[v * NB_DEPTHS + get_depth_index(s->ds)];
1751
1752     if (!is_buffer_shared(s->ds->surface) && s->cursor_invalidate)
1753         s->cursor_invalidate(s);
1754
1755     line_offset = s->line_offset;
1756 #if 0
1757     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",
1758            width, height, v, line_offset, s->cr[9], s->cr[VGA_CRTC_MODE],
1759            s->line_compare, s->sr[VGA_SEQ_CLOCK_MODE]);
1760 #endif
1761     addr1 = (s->start_addr * 4);
1762     bwidth = (width * bits + 7) / 8;
1763     y_start = -1;
1764     page_min = -1;
1765     page_max = 0;
1766     d = ds_get_data(s->ds);
1767     linesize = ds_get_linesize(s->ds);
1768     y1 = 0;
1769     for(y = 0; y < height; y++) {
1770         addr = addr1;
1771         if (!(s->cr[VGA_CRTC_MODE] & 1)) {
1772             int shift;
1773             /* CGA compatibility handling */
1774             shift = 14 + ((s->cr[VGA_CRTC_MODE] >> 6) & 1);
1775             addr = (addr & ~(1 << shift)) | ((y1 & 1) << shift);
1776         }
1777         if (!(s->cr[VGA_CRTC_MODE] & 2)) {
1778             addr = (addr & ~0x8000) | ((y1 & 2) << 14);
1779         }
1780         update = full_update;
1781         page0 = addr;
1782         page1 = addr + bwidth - 1;
1783         update |= memory_region_get_dirty(&s->vram, page0, page1 - page0,
1784                                           DIRTY_MEMORY_VGA);
1785         /* explicit invalidation for the hardware cursor */
1786         update |= (s->invalidated_y_table[y >> 5] >> (y & 0x1f)) & 1;
1787         if (update) {
1788             if (y_start < 0)
1789                 y_start = y;
1790             if (page0 < page_min)
1791                 page_min = page0;
1792             if (page1 > page_max)
1793                 page_max = page1;
1794             if (!(is_buffer_shared(s->ds->surface))) {
1795                 vga_draw_line(s, d, s->vram_ptr + addr, width);
1796                 if (s->cursor_draw_line)
1797                     s->cursor_draw_line(s, d, y);
1798             }
1799         } else {
1800             if (y_start >= 0) {
1801                 /* flush to display */
1802                 dpy_update(s->ds, 0, y_start,
1803                            disp_width, y - y_start);
1804                 y_start = -1;
1805             }
1806         }
1807         if (!multi_run) {
1808             mask = (s->cr[VGA_CRTC_MODE] & 3) ^ 3;
1809             if ((y1 & mask) == mask)
1810                 addr1 += line_offset;
1811             y1++;
1812             multi_run = multi_scan;
1813         } else {
1814             multi_run--;
1815         }
1816         /* line compare acts on the displayed lines */
1817         if (y == s->line_compare)
1818             addr1 = 0;
1819         d += linesize;
1820     }
1821     if (y_start >= 0) {
1822         /* flush to display */
1823         dpy_update(s->ds, 0, y_start,
1824                    disp_width, y - y_start);
1825     }
1826     /* reset modified pages */
1827     if (page_max >= page_min) {
1828         memory_region_reset_dirty(&s->vram,
1829                                   page_min,
1830                                   page_max - page_min,
1831                                   DIRTY_MEMORY_VGA);
1832     }
1833     memset(s->invalidated_y_table, 0, ((height + 31) >> 5) * 4);
1834 }
1835
1836 static void vga_draw_blank(VGACommonState *s, int full_update)
1837 {
1838     int i, w, val;
1839     uint8_t *d;
1840
1841     if (!full_update)
1842         return;
1843     if (s->last_scr_width <= 0 || s->last_scr_height <= 0)
1844         return;
1845
1846     s->rgb_to_pixel =
1847         rgb_to_pixel_dup_table[get_depth_index(s->ds)];
1848     if (ds_get_bits_per_pixel(s->ds) == 8)
1849         val = s->rgb_to_pixel(0, 0, 0);
1850     else
1851         val = 0;
1852     w = s->last_scr_width * ((ds_get_bits_per_pixel(s->ds) + 7) >> 3);
1853     d = ds_get_data(s->ds);
1854     for(i = 0; i < s->last_scr_height; i++) {
1855         memset(d, val, w);
1856         d += ds_get_linesize(s->ds);
1857     }
1858     dpy_update(s->ds, 0, 0,
1859                s->last_scr_width, s->last_scr_height);
1860 }
1861
1862 #define GMODE_TEXT     0
1863 #define GMODE_GRAPH    1
1864 #define GMODE_BLANK 2
1865
1866 static void vga_update_display(void *opaque)
1867 {
1868     VGACommonState *s = opaque;
1869     int full_update, graphic_mode;
1870
1871     qemu_flush_coalesced_mmio_buffer();
1872
1873     if (ds_get_bits_per_pixel(s->ds) == 0) {
1874         /* nothing to do */
1875     } else {
1876         full_update = 0;
1877         if (!(s->ar_index & 0x20)) {
1878             graphic_mode = GMODE_BLANK;
1879         } else {
1880             graphic_mode = s->gr[VGA_GFX_MISC] & VGA_GR06_GRAPHICS_MODE;
1881         }
1882         if (graphic_mode != s->graphic_mode) {
1883             s->graphic_mode = graphic_mode;
1884             full_update = 1;
1885         }
1886         switch(graphic_mode) {
1887         case GMODE_TEXT:
1888             vga_draw_text(s, full_update);
1889             break;
1890         case GMODE_GRAPH:
1891             vga_draw_graphic(s, full_update);
1892             break;
1893         case GMODE_BLANK:
1894         default:
1895             vga_draw_blank(s, full_update);
1896             break;
1897         }
1898     }
1899 }
1900
1901 /* force a full display refresh */
1902 static void vga_invalidate_display(void *opaque)
1903 {
1904     VGACommonState *s = opaque;
1905
1906     s->last_width = -1;
1907     s->last_height = -1;
1908 }
1909
1910 void vga_common_reset(VGACommonState *s)
1911 {
1912     s->sr_index = 0;
1913     memset(s->sr, '\0', sizeof(s->sr));
1914     s->gr_index = 0;
1915     memset(s->gr, '\0', sizeof(s->gr));
1916     s->ar_index = 0;
1917     memset(s->ar, '\0', sizeof(s->ar));
1918     s->ar_flip_flop = 0;
1919     s->cr_index = 0;
1920     memset(s->cr, '\0', sizeof(s->cr));
1921     s->msr = 0;
1922     s->fcr = 0;
1923     s->st00 = 0;
1924     s->st01 = 0;
1925     s->dac_state = 0;
1926     s->dac_sub_index = 0;
1927     s->dac_read_index = 0;
1928     s->dac_write_index = 0;
1929     memset(s->dac_cache, '\0', sizeof(s->dac_cache));
1930     s->dac_8bit = 0;
1931     memset(s->palette, '\0', sizeof(s->palette));
1932     s->bank_offset = 0;
1933 #ifdef CONFIG_BOCHS_VBE
1934     s->vbe_index = 0;
1935     memset(s->vbe_regs, '\0', sizeof(s->vbe_regs));
1936     s->vbe_regs[VBE_DISPI_INDEX_ID] = VBE_DISPI_ID5;
1937     s->vbe_start_addr = 0;
1938     s->vbe_line_offset = 0;
1939     s->vbe_bank_mask = (s->vram_size >> 16) - 1;
1940 #endif
1941     memset(s->font_offsets, '\0', sizeof(s->font_offsets));
1942     s->graphic_mode = -1; /* force full update */
1943     s->shift_control = 0;
1944     s->double_scan = 0;
1945     s->line_offset = 0;
1946     s->line_compare = 0;
1947     s->start_addr = 0;
1948     s->plane_updated = 0;
1949     s->last_cw = 0;
1950     s->last_ch = 0;
1951     s->last_width = 0;
1952     s->last_height = 0;
1953     s->last_scr_width = 0;
1954     s->last_scr_height = 0;
1955     s->cursor_start = 0;
1956     s->cursor_end = 0;
1957     s->cursor_offset = 0;
1958     memset(s->invalidated_y_table, '\0', sizeof(s->invalidated_y_table));
1959     memset(s->last_palette, '\0', sizeof(s->last_palette));
1960     memset(s->last_ch_attr, '\0', sizeof(s->last_ch_attr));
1961     switch (vga_retrace_method) {
1962     case VGA_RETRACE_DUMB:
1963         break;
1964     case VGA_RETRACE_PRECISE:
1965         memset(&s->retrace_info, 0, sizeof (s->retrace_info));
1966         break;
1967     }
1968     vga_update_memory_access(s);
1969 }
1970
1971 static void vga_reset(void *opaque)
1972 {
1973     VGACommonState *s =  opaque;
1974     vga_common_reset(s);
1975 }
1976
1977 #define TEXTMODE_X(x)   ((x) % width)
1978 #define TEXTMODE_Y(x)   ((x) / width)
1979 #define VMEM2CHTYPE(v)  ((v & 0xff0007ff) | \
1980         ((v & 0x00000800) << 10) | ((v & 0x00007000) >> 1))
1981 /* relay text rendering to the display driver
1982  * instead of doing a full vga_update_display() */
1983 static void vga_update_text(void *opaque, console_ch_t *chardata)
1984 {
1985     VGACommonState *s =  opaque;
1986     int graphic_mode, i, cursor_offset, cursor_visible;
1987     int cw, cheight, width, height, size, c_min, c_max;
1988     uint32_t *src;
1989     console_ch_t *dst, val;
1990     char msg_buffer[80];
1991     int full_update = 0;
1992
1993     qemu_flush_coalesced_mmio_buffer();
1994
1995     if (!(s->ar_index & 0x20)) {
1996         graphic_mode = GMODE_BLANK;
1997     } else {
1998         graphic_mode = s->gr[VGA_GFX_MISC] & VGA_GR06_GRAPHICS_MODE;
1999     }
2000     if (graphic_mode != s->graphic_mode) {
2001         s->graphic_mode = graphic_mode;
2002         full_update = 1;
2003     }
2004     if (s->last_width == -1) {
2005         s->last_width = 0;
2006         full_update = 1;
2007     }
2008
2009     switch (graphic_mode) {
2010     case GMODE_TEXT:
2011         /* TODO: update palette */
2012         full_update |= update_basic_params(s);
2013
2014         /* total width & height */
2015         cheight = (s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1;
2016         cw = 8;
2017         if (!(s->sr[VGA_SEQ_CLOCK_MODE] & VGA_SR01_CHAR_CLK_8DOTS)) {
2018             cw = 9;
2019         }
2020         if (s->sr[VGA_SEQ_CLOCK_MODE] & 0x08) {
2021             cw = 16; /* NOTE: no 18 pixel wide */
2022         }
2023         width = (s->cr[VGA_CRTC_H_DISP] + 1);
2024         if (s->cr[VGA_CRTC_V_TOTAL] == 100) {
2025             /* ugly hack for CGA 160x100x16 - explain me the logic */
2026             height = 100;
2027         } else {
2028             height = s->cr[VGA_CRTC_V_DISP_END] |
2029                 ((s->cr[VGA_CRTC_OVERFLOW] & 0x02) << 7) |
2030                 ((s->cr[VGA_CRTC_OVERFLOW] & 0x40) << 3);
2031             height = (height + 1) / cheight;
2032         }
2033
2034         size = (height * width);
2035         if (size > CH_ATTR_SIZE) {
2036             if (!full_update)
2037                 return;
2038
2039             snprintf(msg_buffer, sizeof(msg_buffer), "%i x %i Text mode",
2040                      width, height);
2041             break;
2042         }
2043
2044         if (width != s->last_width || height != s->last_height ||
2045             cw != s->last_cw || cheight != s->last_ch) {
2046             s->last_scr_width = width * cw;
2047             s->last_scr_height = height * cheight;
2048             s->ds->surface->width = width;
2049             s->ds->surface->height = height;
2050             dpy_resize(s->ds);
2051             s->last_width = width;
2052             s->last_height = height;
2053             s->last_ch = cheight;
2054             s->last_cw = cw;
2055             full_update = 1;
2056         }
2057
2058         /* Update "hardware" cursor */
2059         cursor_offset = ((s->cr[VGA_CRTC_CURSOR_HI] << 8) |
2060                          s->cr[VGA_CRTC_CURSOR_LO]) - s->start_addr;
2061         if (cursor_offset != s->cursor_offset ||
2062             s->cr[VGA_CRTC_CURSOR_START] != s->cursor_start ||
2063             s->cr[VGA_CRTC_CURSOR_END] != s->cursor_end || full_update) {
2064             cursor_visible = !(s->cr[VGA_CRTC_CURSOR_START] & 0x20);
2065             if (cursor_visible && cursor_offset < size && cursor_offset >= 0)
2066                 dpy_cursor(s->ds,
2067                            TEXTMODE_X(cursor_offset),
2068                            TEXTMODE_Y(cursor_offset));
2069             else
2070                 dpy_cursor(s->ds, -1, -1);
2071             s->cursor_offset = cursor_offset;
2072             s->cursor_start = s->cr[VGA_CRTC_CURSOR_START];
2073             s->cursor_end = s->cr[VGA_CRTC_CURSOR_END];
2074         }
2075
2076         src = (uint32_t *) s->vram_ptr + s->start_addr;
2077         dst = chardata;
2078
2079         if (full_update) {
2080             for (i = 0; i < size; src ++, dst ++, i ++)
2081                 console_write_ch(dst, VMEM2CHTYPE(le32_to_cpu(*src)));
2082
2083             dpy_update(s->ds, 0, 0, width, height);
2084         } else {
2085             c_max = 0;
2086
2087             for (i = 0; i < size; src ++, dst ++, i ++) {
2088                 console_write_ch(&val, VMEM2CHTYPE(le32_to_cpu(*src)));
2089                 if (*dst != val) {
2090                     *dst = val;
2091                     c_max = i;
2092                     break;
2093                 }
2094             }
2095             c_min = i;
2096             for (; i < size; src ++, dst ++, i ++) {
2097                 console_write_ch(&val, VMEM2CHTYPE(le32_to_cpu(*src)));
2098                 if (*dst != val) {
2099                     *dst = val;
2100                     c_max = i;
2101                 }
2102             }
2103
2104             if (c_min <= c_max) {
2105                 i = TEXTMODE_Y(c_min);
2106                 dpy_update(s->ds, 0, i, width, TEXTMODE_Y(c_max) - i + 1);
2107             }
2108         }
2109
2110         return;
2111     case GMODE_GRAPH:
2112         if (!full_update)
2113             return;
2114
2115         s->get_resolution(s, &width, &height);
2116         snprintf(msg_buffer, sizeof(msg_buffer), "%i x %i Graphic mode",
2117                  width, height);
2118         break;
2119     case GMODE_BLANK:
2120     default:
2121         if (!full_update)
2122             return;
2123
2124         snprintf(msg_buffer, sizeof(msg_buffer), "VGA Blank mode");
2125         break;
2126     }
2127
2128     /* Display a message */
2129     s->last_width = 60;
2130     s->last_height = height = 3;
2131     dpy_cursor(s->ds, -1, -1);
2132     s->ds->surface->width = s->last_width;
2133     s->ds->surface->height = height;
2134     dpy_resize(s->ds);
2135
2136     for (dst = chardata, i = 0; i < s->last_width * height; i ++)
2137         console_write_ch(dst ++, ' ');
2138
2139     size = strlen(msg_buffer);
2140     width = (s->last_width - size) / 2;
2141     dst = chardata + s->last_width + width;
2142     for (i = 0; i < size; i ++)
2143         console_write_ch(dst ++, 0x00200100 | msg_buffer[i]);
2144
2145     dpy_update(s->ds, 0, 0, s->last_width, height);
2146 }
2147
2148 static uint64_t vga_mem_read(void *opaque, target_phys_addr_t addr,
2149                              unsigned size)
2150 {
2151     VGACommonState *s = opaque;
2152
2153     return vga_mem_readb(s, addr);
2154 }
2155
2156 static void vga_mem_write(void *opaque, target_phys_addr_t addr,
2157                           uint64_t data, unsigned size)
2158 {
2159     VGACommonState *s = opaque;
2160
2161     return vga_mem_writeb(s, addr, data);
2162 }
2163
2164 const MemoryRegionOps vga_mem_ops = {
2165     .read = vga_mem_read,
2166     .write = vga_mem_write,
2167     .endianness = DEVICE_LITTLE_ENDIAN,
2168     .impl = {
2169         .min_access_size = 1,
2170         .max_access_size = 1,
2171     },
2172 };
2173
2174 static int vga_common_post_load(void *opaque, int version_id)
2175 {
2176     VGACommonState *s = opaque;
2177
2178     /* force refresh */
2179     s->graphic_mode = -1;
2180     return 0;
2181 }
2182
2183 const VMStateDescription vmstate_vga_common = {
2184     .name = "vga",
2185     .version_id = 2,
2186     .minimum_version_id = 2,
2187     .minimum_version_id_old = 2,
2188     .post_load = vga_common_post_load,
2189     .fields      = (VMStateField []) {
2190         VMSTATE_UINT32(latch, VGACommonState),
2191         VMSTATE_UINT8(sr_index, VGACommonState),
2192         VMSTATE_PARTIAL_BUFFER(sr, VGACommonState, 8),
2193         VMSTATE_UINT8(gr_index, VGACommonState),
2194         VMSTATE_PARTIAL_BUFFER(gr, VGACommonState, 16),
2195         VMSTATE_UINT8(ar_index, VGACommonState),
2196         VMSTATE_BUFFER(ar, VGACommonState),
2197         VMSTATE_INT32(ar_flip_flop, VGACommonState),
2198         VMSTATE_UINT8(cr_index, VGACommonState),
2199         VMSTATE_BUFFER(cr, VGACommonState),
2200         VMSTATE_UINT8(msr, VGACommonState),
2201         VMSTATE_UINT8(fcr, VGACommonState),
2202         VMSTATE_UINT8(st00, VGACommonState),
2203         VMSTATE_UINT8(st01, VGACommonState),
2204
2205         VMSTATE_UINT8(dac_state, VGACommonState),
2206         VMSTATE_UINT8(dac_sub_index, VGACommonState),
2207         VMSTATE_UINT8(dac_read_index, VGACommonState),
2208         VMSTATE_UINT8(dac_write_index, VGACommonState),
2209         VMSTATE_BUFFER(dac_cache, VGACommonState),
2210         VMSTATE_BUFFER(palette, VGACommonState),
2211
2212         VMSTATE_INT32(bank_offset, VGACommonState),
2213         VMSTATE_UINT8_EQUAL(is_vbe_vmstate, VGACommonState),
2214 #ifdef CONFIG_BOCHS_VBE
2215         VMSTATE_UINT16(vbe_index, VGACommonState),
2216         VMSTATE_UINT16_ARRAY(vbe_regs, VGACommonState, VBE_DISPI_INDEX_NB),
2217         VMSTATE_UINT32(vbe_start_addr, VGACommonState),
2218         VMSTATE_UINT32(vbe_line_offset, VGACommonState),
2219         VMSTATE_UINT32(vbe_bank_mask, VGACommonState),
2220 #endif
2221         VMSTATE_END_OF_LIST()
2222     }
2223 };
2224
2225 void vga_common_init(VGACommonState *s, int vga_ram_size)
2226 {
2227     int i, j, v, b;
2228
2229     for(i = 0;i < 256; i++) {
2230         v = 0;
2231         for(j = 0; j < 8; j++) {
2232             v |= ((i >> j) & 1) << (j * 4);
2233         }
2234         expand4[i] = v;
2235
2236         v = 0;
2237         for(j = 0; j < 4; j++) {
2238             v |= ((i >> (2 * j)) & 3) << (j * 4);
2239         }
2240         expand2[i] = v;
2241     }
2242     for(i = 0; i < 16; i++) {
2243         v = 0;
2244         for(j = 0; j < 4; j++) {
2245             b = ((i >> j) & 1);
2246             v |= b << (2 * j);
2247             v |= b << (2 * j + 1);
2248         }
2249         expand4to8[i] = v;
2250     }
2251
2252 #ifdef CONFIG_BOCHS_VBE
2253     s->is_vbe_vmstate = 1;
2254 #else
2255     s->is_vbe_vmstate = 0;
2256 #endif
2257     memory_region_init_ram(&s->vram, "vga.vram", vga_ram_size);
2258     vmstate_register_ram_global(&s->vram);
2259     xen_register_framebuffer(&s->vram);
2260     s->vram_ptr = memory_region_get_ram_ptr(&s->vram);
2261     s->vram_size = vga_ram_size;
2262     s->get_bpp = vga_get_bpp;
2263     s->get_offsets = vga_get_offsets;
2264     s->get_resolution = vga_get_resolution;
2265     s->update = vga_update_display;
2266     s->invalidate = vga_invalidate_display;
2267     s->screen_dump = vga_screen_dump;
2268     s->text_update = vga_update_text;
2269     switch (vga_retrace_method) {
2270     case VGA_RETRACE_DUMB:
2271         s->retrace = vga_dumb_retrace;
2272         s->update_retrace_info = vga_dumb_update_retrace_info;
2273         break;
2274
2275     case VGA_RETRACE_PRECISE:
2276         s->retrace = vga_precise_retrace;
2277         s->update_retrace_info = vga_precise_update_retrace_info;
2278         break;
2279     }
2280     vga_dirty_log_start(s);
2281 }
2282
2283 static const MemoryRegionPortio vga_portio_list[] = {
2284     { 0x04,  2, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3b4 */
2285     { 0x0a,  1, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3ba */
2286     { 0x10, 16, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3c0 */
2287     { 0x24,  2, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3d4 */
2288     { 0x2a,  1, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3da */
2289     PORTIO_END_OF_LIST(),
2290 };
2291
2292 #ifdef CONFIG_BOCHS_VBE
2293 static const MemoryRegionPortio vbe_portio_list[] = {
2294     { 0, 1, 2, .read = vbe_ioport_read_index, .write = vbe_ioport_write_index },
2295 # ifdef TARGET_I386
2296     { 1, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data },
2297 # else
2298     { 2, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data },
2299 # endif
2300     PORTIO_END_OF_LIST(),
2301 };
2302 #endif /* CONFIG_BOCHS_VBE */
2303
2304 /* Used by both ISA and PCI */
2305 MemoryRegion *vga_init_io(VGACommonState *s,
2306                           const MemoryRegionPortio **vga_ports,
2307                           const MemoryRegionPortio **vbe_ports)
2308 {
2309     MemoryRegion *vga_mem;
2310
2311     *vga_ports = vga_portio_list;
2312     *vbe_ports = NULL;
2313 #ifdef CONFIG_BOCHS_VBE
2314     *vbe_ports = vbe_portio_list;
2315 #endif
2316
2317     vga_mem = g_malloc(sizeof(*vga_mem));
2318     memory_region_init_io(vga_mem, &vga_mem_ops, s,
2319                           "vga-lowmem", 0x20000);
2320
2321     return vga_mem;
2322 }
2323
2324 void vga_init(VGACommonState *s, MemoryRegion *address_space,
2325               MemoryRegion *address_space_io, bool init_vga_ports)
2326 {
2327     MemoryRegion *vga_io_memory;
2328     const MemoryRegionPortio *vga_ports, *vbe_ports;
2329     PortioList *vga_port_list = g_new(PortioList, 1);
2330     PortioList *vbe_port_list = g_new(PortioList, 1);
2331
2332     qemu_register_reset(vga_reset, s);
2333
2334     s->bank_offset = 0;
2335
2336     s->legacy_address_space = address_space;
2337
2338     vga_io_memory = vga_init_io(s, &vga_ports, &vbe_ports);
2339     memory_region_add_subregion_overlap(address_space,
2340                                         isa_mem_base + 0x000a0000,
2341                                         vga_io_memory,
2342                                         1);
2343     memory_region_set_coalescing(vga_io_memory);
2344     if (init_vga_ports) {
2345         portio_list_init(vga_port_list, vga_ports, s, "vga");
2346         portio_list_add(vga_port_list, address_space_io, 0x3b0);
2347     }
2348     if (vbe_ports) {
2349         portio_list_init(vbe_port_list, vbe_ports, s, "vbe");
2350         portio_list_add(vbe_port_list, address_space_io, 0x1ce);
2351     }
2352 }
2353
2354 void vga_init_vbe(VGACommonState *s, MemoryRegion *system_memory)
2355 {
2356 #ifdef CONFIG_BOCHS_VBE
2357     /* XXX: use optimized standard vga accesses */
2358     memory_region_add_subregion(system_memory,
2359                                 VBE_DISPI_LFB_PHYSICAL_ADDRESS,
2360                                 &s->vram);
2361     s->vbe_mapped = 1;
2362 #endif 
2363 }
2364 /********************************************************/
2365 /* vga screen dump */
2366
2367 static void vga_save_dpy_update(DisplayState *ds,
2368                                 int x, int y, int w, int h)
2369 {
2370     if (screen_dump_filename) {
2371         ppm_save(screen_dump_filename, ds->surface);
2372     }
2373 }
2374
2375 static void vga_save_dpy_resize(DisplayState *s)
2376 {
2377 }
2378
2379 static void vga_save_dpy_refresh(DisplayState *s)
2380 {
2381 }
2382
2383 int ppm_save(const char *filename, struct DisplaySurface *ds)
2384 {
2385     FILE *f;
2386     uint8_t *d, *d1;
2387     uint32_t v;
2388     int y, x;
2389     uint8_t r, g, b;
2390     int ret;
2391     char *linebuf, *pbuf;
2392
2393     f = fopen(filename, "wb");
2394     if (!f)
2395         return -1;
2396     fprintf(f, "P6\n%d %d\n%d\n",
2397             ds->width, ds->height, 255);
2398     linebuf = g_malloc(ds->width * 3);
2399     d1 = ds->data;
2400     for(y = 0; y < ds->height; y++) {
2401         d = d1;
2402         pbuf = linebuf;
2403         for(x = 0; x < ds->width; x++) {
2404             if (ds->pf.bits_per_pixel == 32)
2405                 v = *(uint32_t *)d;
2406             else
2407                 v = (uint32_t) (*(uint16_t *)d);
2408             /* Limited to 8 or fewer bits per channel: */
2409             r = ((v >> ds->pf.rshift) & ds->pf.rmax) << (8 - ds->pf.rbits);
2410             g = ((v >> ds->pf.gshift) & ds->pf.gmax) << (8 - ds->pf.gbits);
2411             b = ((v >> ds->pf.bshift) & ds->pf.bmax) << (8 - ds->pf.bbits);
2412             *pbuf++ = r;
2413             *pbuf++ = g;
2414             *pbuf++ = b;
2415             d += ds->pf.bytes_per_pixel;
2416         }
2417         d1 += ds->linesize;
2418         ret = fwrite(linebuf, 1, pbuf - linebuf, f);
2419         (void)ret;
2420     }
2421     g_free(linebuf);
2422     fclose(f);
2423     return 0;
2424 }
2425
2426 static DisplayChangeListener* vga_screen_dump_init(DisplayState *ds)
2427 {
2428     DisplayChangeListener *dcl;
2429
2430     dcl = g_malloc0(sizeof(DisplayChangeListener));
2431     dcl->dpy_update = vga_save_dpy_update;
2432     dcl->dpy_resize = vga_save_dpy_resize;
2433     dcl->dpy_refresh = vga_save_dpy_refresh;
2434     register_displaychangelistener(ds, dcl);
2435     return dcl;
2436 }
2437
2438 /* save the vga display in a PPM image even if no display is
2439    available */
2440 static void vga_screen_dump(void *opaque, const char *filename)
2441 {
2442     VGACommonState *s = opaque;
2443
2444     if (!screen_dump_dcl)
2445         screen_dump_dcl = vga_screen_dump_init(s->ds);
2446
2447     screen_dump_filename = filename;
2448     vga_invalidate_display(s);
2449     vga_hw_update();
2450     screen_dump_filename = NULL;
2451 }
This page took 0.149909 seconds and 4 git commands to generate.