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