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