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