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