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