xref: /openbmc/qemu/hw/display/vga.c (revision bfb27e60)
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             pixman_format_code_t format =
1729                 qemu_default_pixman_format(depth, !byteswap);
1730             surface = qemu_create_displaysurface_from(disp_width,
1731                     height, format, s->line_offset,
1732                     s->vram_ptr + (s->start_addr * 4));
1733             dpy_gfx_replace_surface(s->con, surface);
1734         } else {
1735             qemu_console_resize(s->con, disp_width, height);
1736             surface = qemu_console_surface(s->con);
1737         }
1738         s->last_scr_width = disp_width;
1739         s->last_scr_height = height;
1740         s->last_width = disp_width;
1741         s->last_height = height;
1742         s->last_line_offset = s->line_offset;
1743         s->last_depth = depth;
1744         full_update = 1;
1745     } else if (is_buffer_shared(surface) &&
1746                (full_update || surface_data(surface) != s->vram_ptr
1747                 + (s->start_addr * 4))) {
1748         pixman_format_code_t format =
1749             qemu_default_pixman_format(depth, !byteswap);
1750         surface = qemu_create_displaysurface_from(disp_width,
1751                 height, format, s->line_offset,
1752                 s->vram_ptr + (s->start_addr * 4));
1753         dpy_gfx_replace_surface(s->con, surface);
1754     }
1755 
1756     s->rgb_to_pixel =
1757         rgb_to_pixel_dup_table[get_depth_index(surface)];
1758 
1759     if (shift_control == 0) {
1760         full_update |= update_palette16(s);
1761         if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) {
1762             v = VGA_DRAW_LINE4D2;
1763         } else {
1764             v = VGA_DRAW_LINE4;
1765         }
1766         bits = 4;
1767     } else if (shift_control == 1) {
1768         full_update |= update_palette16(s);
1769         if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) {
1770             v = VGA_DRAW_LINE2D2;
1771         } else {
1772             v = VGA_DRAW_LINE2;
1773         }
1774         bits = 4;
1775     } else {
1776         switch(s->get_bpp(s)) {
1777         default:
1778         case 0:
1779             full_update |= update_palette256(s);
1780             v = VGA_DRAW_LINE8D2;
1781             bits = 4;
1782             break;
1783         case 8:
1784             full_update |= update_palette256(s);
1785             v = VGA_DRAW_LINE8;
1786             bits = 8;
1787             break;
1788         case 15:
1789             v = VGA_DRAW_LINE15;
1790             bits = 16;
1791             break;
1792         case 16:
1793             v = VGA_DRAW_LINE16;
1794             bits = 16;
1795             break;
1796         case 24:
1797             v = VGA_DRAW_LINE24;
1798             bits = 24;
1799             break;
1800         case 32:
1801             v = VGA_DRAW_LINE32;
1802             bits = 32;
1803             break;
1804         }
1805     }
1806     vga_draw_line = vga_draw_line_table[v * NB_DEPTHS +
1807                                         get_depth_index(surface)];
1808 
1809     if (!is_buffer_shared(surface) && s->cursor_invalidate) {
1810         s->cursor_invalidate(s);
1811     }
1812 
1813     line_offset = s->line_offset;
1814 #if 0
1815     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",
1816            width, height, v, line_offset, s->cr[9], s->cr[VGA_CRTC_MODE],
1817            s->line_compare, s->sr[VGA_SEQ_CLOCK_MODE]);
1818 #endif
1819     addr1 = (s->start_addr * 4);
1820     bwidth = (width * bits + 7) / 8;
1821     y_start = -1;
1822     page_min = -1;
1823     page_max = 0;
1824     d = surface_data(surface);
1825     linesize = surface_stride(surface);
1826     y1 = 0;
1827     for(y = 0; y < height; y++) {
1828         addr = addr1;
1829         if (!(s->cr[VGA_CRTC_MODE] & 1)) {
1830             int shift;
1831             /* CGA compatibility handling */
1832             shift = 14 + ((s->cr[VGA_CRTC_MODE] >> 6) & 1);
1833             addr = (addr & ~(1 << shift)) | ((y1 & 1) << shift);
1834         }
1835         if (!(s->cr[VGA_CRTC_MODE] & 2)) {
1836             addr = (addr & ~0x8000) | ((y1 & 2) << 14);
1837         }
1838         update = full_update;
1839         page0 = addr;
1840         page1 = addr + bwidth - 1;
1841         update |= memory_region_get_dirty(&s->vram, page0, page1 - page0,
1842                                           DIRTY_MEMORY_VGA);
1843         /* explicit invalidation for the hardware cursor */
1844         update |= (s->invalidated_y_table[y >> 5] >> (y & 0x1f)) & 1;
1845         if (update) {
1846             if (y_start < 0)
1847                 y_start = y;
1848             if (page0 < page_min)
1849                 page_min = page0;
1850             if (page1 > page_max)
1851                 page_max = page1;
1852             if (!(is_buffer_shared(surface))) {
1853                 vga_draw_line(s, d, s->vram_ptr + addr, width);
1854                 if (s->cursor_draw_line)
1855                     s->cursor_draw_line(s, d, y);
1856             }
1857         } else {
1858             if (y_start >= 0) {
1859                 /* flush to display */
1860                 dpy_gfx_update(s->con, 0, y_start,
1861                                disp_width, y - y_start);
1862                 y_start = -1;
1863             }
1864         }
1865         if (!multi_run) {
1866             mask = (s->cr[VGA_CRTC_MODE] & 3) ^ 3;
1867             if ((y1 & mask) == mask)
1868                 addr1 += line_offset;
1869             y1++;
1870             multi_run = multi_scan;
1871         } else {
1872             multi_run--;
1873         }
1874         /* line compare acts on the displayed lines */
1875         if (y == s->line_compare)
1876             addr1 = 0;
1877         d += linesize;
1878     }
1879     if (y_start >= 0) {
1880         /* flush to display */
1881         dpy_gfx_update(s->con, 0, y_start,
1882                        disp_width, y - y_start);
1883     }
1884     /* reset modified pages */
1885     if (page_max >= page_min) {
1886         memory_region_reset_dirty(&s->vram,
1887                                   page_min,
1888                                   page_max - page_min,
1889                                   DIRTY_MEMORY_VGA);
1890     }
1891     memset(s->invalidated_y_table, 0, ((height + 31) >> 5) * 4);
1892 }
1893 
1894 static void vga_draw_blank(VGACommonState *s, int full_update)
1895 {
1896     DisplaySurface *surface = qemu_console_surface(s->con);
1897     int i, w, val;
1898     uint8_t *d;
1899 
1900     if (!full_update)
1901         return;
1902     if (s->last_scr_width <= 0 || s->last_scr_height <= 0)
1903         return;
1904 
1905     s->rgb_to_pixel =
1906         rgb_to_pixel_dup_table[get_depth_index(surface)];
1907     if (surface_bits_per_pixel(surface) == 8) {
1908         val = s->rgb_to_pixel(0, 0, 0);
1909     } else {
1910         val = 0;
1911     }
1912     w = s->last_scr_width * surface_bytes_per_pixel(surface);
1913     d = surface_data(surface);
1914     for(i = 0; i < s->last_scr_height; i++) {
1915         memset(d, val, w);
1916         d += surface_stride(surface);
1917     }
1918     dpy_gfx_update(s->con, 0, 0,
1919                    s->last_scr_width, s->last_scr_height);
1920 }
1921 
1922 #define GMODE_TEXT     0
1923 #define GMODE_GRAPH    1
1924 #define GMODE_BLANK 2
1925 
1926 static void vga_update_display(void *opaque)
1927 {
1928     VGACommonState *s = opaque;
1929     DisplaySurface *surface = qemu_console_surface(s->con);
1930     int full_update, graphic_mode;
1931 
1932     qemu_flush_coalesced_mmio_buffer();
1933 
1934     if (surface_bits_per_pixel(surface) == 0) {
1935         /* nothing to do */
1936     } else {
1937         full_update = 0;
1938         if (!(s->ar_index & 0x20)) {
1939             graphic_mode = GMODE_BLANK;
1940         } else {
1941             graphic_mode = s->gr[VGA_GFX_MISC] & VGA_GR06_GRAPHICS_MODE;
1942         }
1943         if (graphic_mode != s->graphic_mode) {
1944             s->graphic_mode = graphic_mode;
1945             s->cursor_blink_time = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
1946             full_update = 1;
1947         }
1948         switch(graphic_mode) {
1949         case GMODE_TEXT:
1950             vga_draw_text(s, full_update);
1951             break;
1952         case GMODE_GRAPH:
1953             vga_draw_graphic(s, full_update);
1954             break;
1955         case GMODE_BLANK:
1956         default:
1957             vga_draw_blank(s, full_update);
1958             break;
1959         }
1960     }
1961 }
1962 
1963 /* force a full display refresh */
1964 static void vga_invalidate_display(void *opaque)
1965 {
1966     VGACommonState *s = opaque;
1967 
1968     s->last_width = -1;
1969     s->last_height = -1;
1970 }
1971 
1972 void vga_common_reset(VGACommonState *s)
1973 {
1974     s->sr_index = 0;
1975     memset(s->sr, '\0', sizeof(s->sr));
1976     s->gr_index = 0;
1977     memset(s->gr, '\0', sizeof(s->gr));
1978     s->ar_index = 0;
1979     memset(s->ar, '\0', sizeof(s->ar));
1980     s->ar_flip_flop = 0;
1981     s->cr_index = 0;
1982     memset(s->cr, '\0', sizeof(s->cr));
1983     s->msr = 0;
1984     s->fcr = 0;
1985     s->st00 = 0;
1986     s->st01 = 0;
1987     s->dac_state = 0;
1988     s->dac_sub_index = 0;
1989     s->dac_read_index = 0;
1990     s->dac_write_index = 0;
1991     memset(s->dac_cache, '\0', sizeof(s->dac_cache));
1992     s->dac_8bit = 0;
1993     memset(s->palette, '\0', sizeof(s->palette));
1994     s->bank_offset = 0;
1995     s->vbe_index = 0;
1996     memset(s->vbe_regs, '\0', sizeof(s->vbe_regs));
1997     s->vbe_regs[VBE_DISPI_INDEX_ID] = VBE_DISPI_ID5;
1998     s->vbe_start_addr = 0;
1999     s->vbe_line_offset = 0;
2000     s->vbe_bank_mask = (s->vram_size >> 16) - 1;
2001     memset(s->font_offsets, '\0', sizeof(s->font_offsets));
2002     s->graphic_mode = -1; /* force full update */
2003     s->shift_control = 0;
2004     s->double_scan = 0;
2005     s->line_offset = 0;
2006     s->line_compare = 0;
2007     s->start_addr = 0;
2008     s->plane_updated = 0;
2009     s->last_cw = 0;
2010     s->last_ch = 0;
2011     s->last_width = 0;
2012     s->last_height = 0;
2013     s->last_scr_width = 0;
2014     s->last_scr_height = 0;
2015     s->cursor_start = 0;
2016     s->cursor_end = 0;
2017     s->cursor_offset = 0;
2018     memset(s->invalidated_y_table, '\0', sizeof(s->invalidated_y_table));
2019     memset(s->last_palette, '\0', sizeof(s->last_palette));
2020     memset(s->last_ch_attr, '\0', sizeof(s->last_ch_attr));
2021     switch (vga_retrace_method) {
2022     case VGA_RETRACE_DUMB:
2023         break;
2024     case VGA_RETRACE_PRECISE:
2025         memset(&s->retrace_info, 0, sizeof (s->retrace_info));
2026         break;
2027     }
2028     vga_update_memory_access(s);
2029 }
2030 
2031 static void vga_reset(void *opaque)
2032 {
2033     VGACommonState *s =  opaque;
2034     vga_common_reset(s);
2035 }
2036 
2037 #define TEXTMODE_X(x)	((x) % width)
2038 #define TEXTMODE_Y(x)	((x) / width)
2039 #define VMEM2CHTYPE(v)	((v & 0xff0007ff) | \
2040         ((v & 0x00000800) << 10) | ((v & 0x00007000) >> 1))
2041 /* relay text rendering to the display driver
2042  * instead of doing a full vga_update_display() */
2043 static void vga_update_text(void *opaque, console_ch_t *chardata)
2044 {
2045     VGACommonState *s =  opaque;
2046     int graphic_mode, i, cursor_offset, cursor_visible;
2047     int cw, cheight, width, height, size, c_min, c_max;
2048     uint32_t *src;
2049     console_ch_t *dst, val;
2050     char msg_buffer[80];
2051     int full_update = 0;
2052 
2053     qemu_flush_coalesced_mmio_buffer();
2054 
2055     if (!(s->ar_index & 0x20)) {
2056         graphic_mode = GMODE_BLANK;
2057     } else {
2058         graphic_mode = s->gr[VGA_GFX_MISC] & VGA_GR06_GRAPHICS_MODE;
2059     }
2060     if (graphic_mode != s->graphic_mode) {
2061         s->graphic_mode = graphic_mode;
2062         full_update = 1;
2063     }
2064     if (s->last_width == -1) {
2065         s->last_width = 0;
2066         full_update = 1;
2067     }
2068 
2069     switch (graphic_mode) {
2070     case GMODE_TEXT:
2071         /* TODO: update palette */
2072         full_update |= update_basic_params(s);
2073 
2074         /* total width & height */
2075         cheight = (s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1;
2076         cw = 8;
2077         if (!(s->sr[VGA_SEQ_CLOCK_MODE] & VGA_SR01_CHAR_CLK_8DOTS)) {
2078             cw = 9;
2079         }
2080         if (s->sr[VGA_SEQ_CLOCK_MODE] & 0x08) {
2081             cw = 16; /* NOTE: no 18 pixel wide */
2082         }
2083         width = (s->cr[VGA_CRTC_H_DISP] + 1);
2084         if (s->cr[VGA_CRTC_V_TOTAL] == 100) {
2085             /* ugly hack for CGA 160x100x16 - explain me the logic */
2086             height = 100;
2087         } else {
2088             height = s->cr[VGA_CRTC_V_DISP_END] |
2089                 ((s->cr[VGA_CRTC_OVERFLOW] & 0x02) << 7) |
2090                 ((s->cr[VGA_CRTC_OVERFLOW] & 0x40) << 3);
2091             height = (height + 1) / cheight;
2092         }
2093 
2094         size = (height * width);
2095         if (size > CH_ATTR_SIZE) {
2096             if (!full_update)
2097                 return;
2098 
2099             snprintf(msg_buffer, sizeof(msg_buffer), "%i x %i Text mode",
2100                      width, height);
2101             break;
2102         }
2103 
2104         if (width != s->last_width || height != s->last_height ||
2105             cw != s->last_cw || cheight != s->last_ch) {
2106             s->last_scr_width = width * cw;
2107             s->last_scr_height = height * cheight;
2108             qemu_console_resize(s->con, s->last_scr_width, s->last_scr_height);
2109             dpy_text_resize(s->con, width, height);
2110             s->last_depth = 0;
2111             s->last_width = width;
2112             s->last_height = height;
2113             s->last_ch = cheight;
2114             s->last_cw = cw;
2115             full_update = 1;
2116         }
2117 
2118         if (full_update) {
2119             s->full_update_gfx = 1;
2120         }
2121         if (s->full_update_text) {
2122             s->full_update_text = 0;
2123             full_update |= 1;
2124         }
2125 
2126         /* Update "hardware" cursor */
2127         cursor_offset = ((s->cr[VGA_CRTC_CURSOR_HI] << 8) |
2128                          s->cr[VGA_CRTC_CURSOR_LO]) - s->start_addr;
2129         if (cursor_offset != s->cursor_offset ||
2130             s->cr[VGA_CRTC_CURSOR_START] != s->cursor_start ||
2131             s->cr[VGA_CRTC_CURSOR_END] != s->cursor_end || full_update) {
2132             cursor_visible = !(s->cr[VGA_CRTC_CURSOR_START] & 0x20);
2133             if (cursor_visible && cursor_offset < size && cursor_offset >= 0)
2134                 dpy_text_cursor(s->con,
2135                                 TEXTMODE_X(cursor_offset),
2136                                 TEXTMODE_Y(cursor_offset));
2137             else
2138                 dpy_text_cursor(s->con, -1, -1);
2139             s->cursor_offset = cursor_offset;
2140             s->cursor_start = s->cr[VGA_CRTC_CURSOR_START];
2141             s->cursor_end = s->cr[VGA_CRTC_CURSOR_END];
2142         }
2143 
2144         src = (uint32_t *) s->vram_ptr + s->start_addr;
2145         dst = chardata;
2146 
2147         if (full_update) {
2148             for (i = 0; i < size; src ++, dst ++, i ++)
2149                 console_write_ch(dst, VMEM2CHTYPE(le32_to_cpu(*src)));
2150 
2151             dpy_text_update(s->con, 0, 0, width, height);
2152         } else {
2153             c_max = 0;
2154 
2155             for (i = 0; i < size; src ++, dst ++, i ++) {
2156                 console_write_ch(&val, VMEM2CHTYPE(le32_to_cpu(*src)));
2157                 if (*dst != val) {
2158                     *dst = val;
2159                     c_max = i;
2160                     break;
2161                 }
2162             }
2163             c_min = i;
2164             for (; i < size; src ++, dst ++, i ++) {
2165                 console_write_ch(&val, VMEM2CHTYPE(le32_to_cpu(*src)));
2166                 if (*dst != val) {
2167                     *dst = val;
2168                     c_max = i;
2169                 }
2170             }
2171 
2172             if (c_min <= c_max) {
2173                 i = TEXTMODE_Y(c_min);
2174                 dpy_text_update(s->con, 0, i, width, TEXTMODE_Y(c_max) - i + 1);
2175             }
2176         }
2177 
2178         return;
2179     case GMODE_GRAPH:
2180         if (!full_update)
2181             return;
2182 
2183         s->get_resolution(s, &width, &height);
2184         snprintf(msg_buffer, sizeof(msg_buffer), "%i x %i Graphic mode",
2185                  width, height);
2186         break;
2187     case GMODE_BLANK:
2188     default:
2189         if (!full_update)
2190             return;
2191 
2192         snprintf(msg_buffer, sizeof(msg_buffer), "VGA Blank mode");
2193         break;
2194     }
2195 
2196     /* Display a message */
2197     s->last_width = 60;
2198     s->last_height = height = 3;
2199     dpy_text_cursor(s->con, -1, -1);
2200     dpy_text_resize(s->con, s->last_width, height);
2201 
2202     for (dst = chardata, i = 0; i < s->last_width * height; i ++)
2203         console_write_ch(dst ++, ' ');
2204 
2205     size = strlen(msg_buffer);
2206     width = (s->last_width - size) / 2;
2207     dst = chardata + s->last_width + width;
2208     for (i = 0; i < size; i ++)
2209         console_write_ch(dst ++, 0x00200100 | msg_buffer[i]);
2210 
2211     dpy_text_update(s->con, 0, 0, s->last_width, height);
2212 }
2213 
2214 static uint64_t vga_mem_read(void *opaque, hwaddr addr,
2215                              unsigned size)
2216 {
2217     VGACommonState *s = opaque;
2218 
2219     return vga_mem_readb(s, addr);
2220 }
2221 
2222 static void vga_mem_write(void *opaque, hwaddr addr,
2223                           uint64_t data, unsigned size)
2224 {
2225     VGACommonState *s = opaque;
2226 
2227     return vga_mem_writeb(s, addr, data);
2228 }
2229 
2230 const MemoryRegionOps vga_mem_ops = {
2231     .read = vga_mem_read,
2232     .write = vga_mem_write,
2233     .endianness = DEVICE_LITTLE_ENDIAN,
2234     .impl = {
2235         .min_access_size = 1,
2236         .max_access_size = 1,
2237     },
2238 };
2239 
2240 static int vga_common_post_load(void *opaque, int version_id)
2241 {
2242     VGACommonState *s = opaque;
2243 
2244     /* force refresh */
2245     s->graphic_mode = -1;
2246     return 0;
2247 }
2248 
2249 const VMStateDescription vmstate_vga_common = {
2250     .name = "vga",
2251     .version_id = 2,
2252     .minimum_version_id = 2,
2253     .post_load = vga_common_post_load,
2254     .fields = (VMStateField[]) {
2255         VMSTATE_UINT32(latch, VGACommonState),
2256         VMSTATE_UINT8(sr_index, VGACommonState),
2257         VMSTATE_PARTIAL_BUFFER(sr, VGACommonState, 8),
2258         VMSTATE_UINT8(gr_index, VGACommonState),
2259         VMSTATE_PARTIAL_BUFFER(gr, VGACommonState, 16),
2260         VMSTATE_UINT8(ar_index, VGACommonState),
2261         VMSTATE_BUFFER(ar, VGACommonState),
2262         VMSTATE_INT32(ar_flip_flop, VGACommonState),
2263         VMSTATE_UINT8(cr_index, VGACommonState),
2264         VMSTATE_BUFFER(cr, VGACommonState),
2265         VMSTATE_UINT8(msr, VGACommonState),
2266         VMSTATE_UINT8(fcr, VGACommonState),
2267         VMSTATE_UINT8(st00, VGACommonState),
2268         VMSTATE_UINT8(st01, VGACommonState),
2269 
2270         VMSTATE_UINT8(dac_state, VGACommonState),
2271         VMSTATE_UINT8(dac_sub_index, VGACommonState),
2272         VMSTATE_UINT8(dac_read_index, VGACommonState),
2273         VMSTATE_UINT8(dac_write_index, VGACommonState),
2274         VMSTATE_BUFFER(dac_cache, VGACommonState),
2275         VMSTATE_BUFFER(palette, VGACommonState),
2276 
2277         VMSTATE_INT32(bank_offset, VGACommonState),
2278         VMSTATE_UINT8_EQUAL(is_vbe_vmstate, VGACommonState),
2279         VMSTATE_UINT16(vbe_index, VGACommonState),
2280         VMSTATE_UINT16_ARRAY(vbe_regs, VGACommonState, VBE_DISPI_INDEX_NB),
2281         VMSTATE_UINT32(vbe_start_addr, VGACommonState),
2282         VMSTATE_UINT32(vbe_line_offset, VGACommonState),
2283         VMSTATE_UINT32(vbe_bank_mask, VGACommonState),
2284         VMSTATE_END_OF_LIST()
2285     }
2286 };
2287 
2288 static const GraphicHwOps vga_ops = {
2289     .invalidate  = vga_invalidate_display,
2290     .gfx_update  = vga_update_display,
2291     .text_update = vga_update_text,
2292 };
2293 
2294 void vga_common_init(VGACommonState *s, Object *obj, bool global_vmstate)
2295 {
2296     int i, j, v, b;
2297 
2298     for(i = 0;i < 256; i++) {
2299         v = 0;
2300         for(j = 0; j < 8; j++) {
2301             v |= ((i >> j) & 1) << (j * 4);
2302         }
2303         expand4[i] = v;
2304 
2305         v = 0;
2306         for(j = 0; j < 4; j++) {
2307             v |= ((i >> (2 * j)) & 3) << (j * 4);
2308         }
2309         expand2[i] = v;
2310     }
2311     for(i = 0; i < 16; i++) {
2312         v = 0;
2313         for(j = 0; j < 4; j++) {
2314             b = ((i >> j) & 1);
2315             v |= b << (2 * j);
2316             v |= b << (2 * j + 1);
2317         }
2318         expand4to8[i] = v;
2319     }
2320 
2321     /* valid range: 1 MB -> 256 MB */
2322     s->vram_size = 1024 * 1024;
2323     while (s->vram_size < (s->vram_size_mb << 20) &&
2324            s->vram_size < (256 << 20)) {
2325         s->vram_size <<= 1;
2326     }
2327     s->vram_size_mb = s->vram_size >> 20;
2328     if (!s->vbe_size) {
2329         s->vbe_size = s->vram_size;
2330     }
2331 
2332     s->is_vbe_vmstate = 1;
2333     memory_region_init_ram(&s->vram, obj, "vga.vram", s->vram_size);
2334     vmstate_register_ram(&s->vram, global_vmstate ? NULL : DEVICE(obj));
2335     xen_register_framebuffer(&s->vram);
2336     s->vram_ptr = memory_region_get_ram_ptr(&s->vram);
2337     s->get_bpp = vga_get_bpp;
2338     s->get_offsets = vga_get_offsets;
2339     s->get_resolution = vga_get_resolution;
2340     s->hw_ops = &vga_ops;
2341     switch (vga_retrace_method) {
2342     case VGA_RETRACE_DUMB:
2343         s->retrace = vga_dumb_retrace;
2344         s->update_retrace_info = vga_dumb_update_retrace_info;
2345         break;
2346 
2347     case VGA_RETRACE_PRECISE:
2348         s->retrace = vga_precise_retrace;
2349         s->update_retrace_info = vga_precise_update_retrace_info;
2350         break;
2351     }
2352     vga_dirty_log_start(s);
2353 }
2354 
2355 static const MemoryRegionPortio vga_portio_list[] = {
2356     { 0x04,  2, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3b4 */
2357     { 0x0a,  1, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3ba */
2358     { 0x10, 16, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3c0 */
2359     { 0x24,  2, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3d4 */
2360     { 0x2a,  1, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3da */
2361     PORTIO_END_OF_LIST(),
2362 };
2363 
2364 static const MemoryRegionPortio vbe_portio_list[] = {
2365     { 0, 1, 2, .read = vbe_ioport_read_index, .write = vbe_ioport_write_index },
2366 # ifdef TARGET_I386
2367     { 1, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data },
2368 # endif
2369     { 2, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data },
2370     PORTIO_END_OF_LIST(),
2371 };
2372 
2373 /* Used by both ISA and PCI */
2374 MemoryRegion *vga_init_io(VGACommonState *s, Object *obj,
2375                           const MemoryRegionPortio **vga_ports,
2376                           const MemoryRegionPortio **vbe_ports)
2377 {
2378     MemoryRegion *vga_mem;
2379 
2380     *vga_ports = vga_portio_list;
2381     *vbe_ports = vbe_portio_list;
2382 
2383     vga_mem = g_malloc(sizeof(*vga_mem));
2384     memory_region_init_io(vga_mem, obj, &vga_mem_ops, s,
2385                           "vga-lowmem", 0x20000);
2386     memory_region_set_flush_coalesced(vga_mem);
2387 
2388     return vga_mem;
2389 }
2390 
2391 void vga_init(VGACommonState *s, Object *obj, MemoryRegion *address_space,
2392               MemoryRegion *address_space_io, bool init_vga_ports)
2393 {
2394     MemoryRegion *vga_io_memory;
2395     const MemoryRegionPortio *vga_ports, *vbe_ports;
2396 
2397     qemu_register_reset(vga_reset, s);
2398 
2399     s->bank_offset = 0;
2400 
2401     s->legacy_address_space = address_space;
2402 
2403     vga_io_memory = vga_init_io(s, obj, &vga_ports, &vbe_ports);
2404     memory_region_add_subregion_overlap(address_space,
2405                                         isa_mem_base + 0x000a0000,
2406                                         vga_io_memory,
2407                                         1);
2408     memory_region_set_coalescing(vga_io_memory);
2409     if (init_vga_ports) {
2410         portio_list_init(&s->vga_port_list, obj, vga_ports, s, "vga");
2411         portio_list_set_flush_coalesced(&s->vga_port_list);
2412         portio_list_add(&s->vga_port_list, address_space_io, 0x3b0);
2413     }
2414     if (vbe_ports) {
2415         portio_list_init(&s->vbe_port_list, obj, vbe_ports, s, "vbe");
2416         portio_list_add(&s->vbe_port_list, address_space_io, 0x1ce);
2417     }
2418 }
2419 
2420 void vga_init_vbe(VGACommonState *s, Object *obj, MemoryRegion *system_memory)
2421 {
2422     /* With pc-0.12 and below we map both the PCI BAR and the fixed VBE region,
2423      * so use an alias to avoid double-mapping the same region.
2424      */
2425     memory_region_init_alias(&s->vram_vbe, obj, "vram.vbe",
2426                              &s->vram, 0, memory_region_size(&s->vram));
2427     /* XXX: use optimized standard vga accesses */
2428     memory_region_add_subregion(system_memory,
2429                                 VBE_DISPI_LFB_PHYSICAL_ADDRESS,
2430                                 &s->vram_vbe);
2431     s->vbe_mapped = 1;
2432 }
2433