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