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