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