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