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