|
Mark McLoughlin |
910c5e |
From 8ad63a93a482d5c3354b97463633394456a157d5 Mon Sep 17 00:00:00 2001
|
|
Mark McLoughlin |
910c5e |
From: Avi Kivity <avi@redhat.com>
|
|
Mark McLoughlin |
910c5e |
Date: Thu, 2 Apr 2009 22:17:50 +0300
|
|
Mark McLoughlin |
910c5e |
Subject: [PATCH 1/1] kvm: qemu: Fix display breakage when resizing the screen
|
|
Mark McLoughlin |
910c5e |
|
|
Mark McLoughlin |
910c5e |
When the vga resolution changes, a new display surface is not allocated
|
|
Mark McLoughlin |
910c5e |
immediately; instead that is deferred until the next update. However,
|
|
Mark McLoughlin |
910c5e |
if we're running without a display client attached, that won't happen
|
|
Mark McLoughlin |
910c5e |
and the next bitblt is likely to cause a segfault by overflowing the
|
|
Mark McLoughlin |
910c5e |
display surface.
|
|
Mark McLoughlin |
910c5e |
|
|
Mark McLoughlin |
910c5e |
Fix by reallocating the display immediately when the resolution changes.
|
|
Mark McLoughlin |
910c5e |
|
|
Mark McLoughlin |
910c5e |
Signed-off-by: Avi Kivity <avi@redhat.com>
|
|
Mark McLoughlin |
910c5e |
---
|
|
Mark McLoughlin |
910c5e |
qemu/hw/cirrus_vga.c | 10 ++-
|
|
Mark McLoughlin |
910c5e |
qemu/hw/vga.c | 205 +++++++++++++++++++++++++++++--------------------
|
|
Mark McLoughlin |
910c5e |
qemu/hw/vga_int.h | 4 +
|
|
Mark McLoughlin |
910c5e |
3 files changed, 134 insertions(+), 85 deletions(-)
|
|
Mark McLoughlin |
910c5e |
|
|
Mark McLoughlin |
910c5e |
diff --git a/qemu/hw/cirrus_vga.c b/qemu/hw/cirrus_vga.c
|
|
Mark McLoughlin |
910c5e |
index 0ab0f14..7bd0482 100644
|
|
Mark McLoughlin |
910c5e |
--- a/qemu/hw/cirrus_vga.c
|
|
Mark McLoughlin |
910c5e |
+++ b/qemu/hw/cirrus_vga.c
|
|
Mark McLoughlin |
910c5e |
@@ -1399,6 +1399,8 @@ cirrus_hook_write_sr(CirrusVGAState * s, unsigned reg_index, int reg_value)
|
|
Mark McLoughlin |
910c5e |
break;
|
|
Mark McLoughlin |
910c5e |
}
|
|
Mark McLoughlin |
910c5e |
|
|
Mark McLoughlin |
910c5e |
+ vga_update_resolution((VGAState *)s);
|
|
Mark McLoughlin |
910c5e |
+
|
|
Mark McLoughlin |
910c5e |
return CIRRUS_HOOK_HANDLED;
|
|
Mark McLoughlin |
910c5e |
}
|
|
Mark McLoughlin |
910c5e |
|
|
Mark McLoughlin |
910c5e |
@@ -1426,6 +1428,7 @@ static void cirrus_write_hidden_dac(CirrusVGAState * s, int reg_value)
|
|
Mark McLoughlin |
910c5e |
#endif
|
|
Mark McLoughlin |
910c5e |
}
|
|
Mark McLoughlin |
910c5e |
s->cirrus_hidden_dac_lockindex = 0;
|
|
Mark McLoughlin |
910c5e |
+ vga_update_resolution((VGAState *)s);
|
|
Mark McLoughlin |
910c5e |
}
|
|
Mark McLoughlin |
910c5e |
|
|
Mark McLoughlin |
910c5e |
/***************************************
|
|
Mark McLoughlin |
910c5e |
@@ -1712,6 +1715,8 @@ cirrus_hook_write_cr(CirrusVGAState * s, unsigned reg_index, int reg_value)
|
|
Mark McLoughlin |
910c5e |
break;
|
|
Mark McLoughlin |
910c5e |
}
|
|
Mark McLoughlin |
910c5e |
|
|
Mark McLoughlin |
910c5e |
+ vga_update_resolution((VGAState *)s);
|
|
Mark McLoughlin |
910c5e |
+
|
|
Mark McLoughlin |
910c5e |
return CIRRUS_HOOK_HANDLED;
|
|
Mark McLoughlin |
910c5e |
}
|
|
Mark McLoughlin |
910c5e |
|
|
Mark McLoughlin |
910c5e |
@@ -2839,6 +2844,7 @@ static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
|
|
Mark McLoughlin |
910c5e |
if (s->ar_flip_flop == 0) {
|
|
Mark McLoughlin |
910c5e |
val &= 0x3f;
|
|
Mark McLoughlin |
910c5e |
s->ar_index = val;
|
|
Mark McLoughlin |
910c5e |
+ vga_update_resolution((VGAState *)s);
|
|
Mark McLoughlin |
910c5e |
} else {
|
|
Mark McLoughlin |
910c5e |
index = s->ar_index & 0x1f;
|
|
Mark McLoughlin |
910c5e |
switch (index) {
|
|
Mark McLoughlin |
910c5e |
@@ -2932,6 +2938,7 @@ static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
|
|
Mark McLoughlin |
910c5e |
/* can always write bit 4 of CR7 */
|
|
Mark McLoughlin |
910c5e |
if (s->cr_index == 7)
|
|
Mark McLoughlin |
910c5e |
s->cr[7] = (s->cr[7] & ~0x10) | (val & 0x10);
|
|
Mark McLoughlin |
910c5e |
+ vga_update_resolution((VGAState *)s);
|
|
Mark McLoughlin |
910c5e |
return;
|
|
Mark McLoughlin |
910c5e |
}
|
|
Mark McLoughlin |
910c5e |
switch (s->cr_index) {
|
|
Mark McLoughlin |
910c5e |
@@ -3166,7 +3173,8 @@ static int cirrus_vga_load(QEMUFile *f, void *opaque, int version_id)
|
|
Mark McLoughlin |
910c5e |
|
|
Mark McLoughlin |
910c5e |
cirrus_update_memory_access(s);
|
|
Mark McLoughlin |
910c5e |
/* force refresh */
|
|
Mark McLoughlin |
910c5e |
- s->graphic_mode = -1;
|
|
Mark McLoughlin |
910c5e |
+ vga_update_resolution((VGAState *)s);
|
|
Mark McLoughlin |
910c5e |
+ s->want_full_update = 1;
|
|
Mark McLoughlin |
910c5e |
cirrus_update_bank_ptr(s, 0);
|
|
Mark McLoughlin |
910c5e |
cirrus_update_bank_ptr(s, 1);
|
|
Mark McLoughlin |
910c5e |
return 0;
|
|
Mark McLoughlin |
910c5e |
diff --git a/qemu/hw/vga.c b/qemu/hw/vga.c
|
|
Mark McLoughlin |
910c5e |
index d4fddf9..9a950d3 100644
|
|
Mark McLoughlin |
910c5e |
--- a/qemu/hw/vga.c
|
|
Mark McLoughlin |
910c5e |
+++ b/qemu/hw/vga.c
|
|
Mark McLoughlin |
910c5e |
@@ -37,6 +37,10 @@
|
|
Mark McLoughlin |
910c5e |
|
|
Mark McLoughlin |
910c5e |
//#define DEBUG_BOCHS_VBE
|
|
Mark McLoughlin |
910c5e |
|
|
Mark McLoughlin |
910c5e |
+#define GMODE_TEXT 0
|
|
Mark McLoughlin |
910c5e |
+#define GMODE_GRAPH 1
|
|
Mark McLoughlin |
910c5e |
+#define GMODE_BLANK 2
|
|
Mark McLoughlin |
910c5e |
+
|
|
Mark McLoughlin |
910c5e |
/* force some bits to zero */
|
|
Mark McLoughlin |
910c5e |
const uint8_t sr_mask[8] = {
|
|
Mark McLoughlin |
910c5e |
(uint8_t)~0xfc,
|
|
Mark McLoughlin |
910c5e |
@@ -394,6 +398,7 @@ static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
|
|
Mark McLoughlin |
910c5e |
if (s->ar_flip_flop == 0) {
|
|
Mark McLoughlin |
910c5e |
val &= 0x3f;
|
|
Mark McLoughlin |
910c5e |
s->ar_index = val;
|
|
Mark McLoughlin |
910c5e |
+ vga_update_resolution(s);
|
|
Mark McLoughlin |
910c5e |
} else {
|
|
Mark McLoughlin |
910c5e |
index = s->ar_index & 0x1f;
|
|
Mark McLoughlin |
910c5e |
switch(index) {
|
|
Mark McLoughlin |
910c5e |
@@ -434,6 +439,7 @@ static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
|
|
Mark McLoughlin |
910c5e |
#endif
|
|
Mark McLoughlin |
910c5e |
s->sr[s->sr_index] = val & sr_mask[s->sr_index];
|
|
Mark McLoughlin |
910c5e |
if (s->sr_index == 1) s->update_retrace_info(s);
|
|
Mark McLoughlin |
910c5e |
+ vga_update_resolution(s);
|
|
Mark McLoughlin |
910c5e |
break;
|
|
Mark McLoughlin |
910c5e |
case 0x3c7:
|
|
Mark McLoughlin |
910c5e |
s->dac_read_index = val;
|
|
Mark McLoughlin |
910c5e |
@@ -461,6 +467,7 @@ static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
|
|
Mark McLoughlin |
910c5e |
printf("vga: write GR%x = 0x%02x\n", s->gr_index, val);
|
|
Mark McLoughlin |
910c5e |
#endif
|
|
Mark McLoughlin |
910c5e |
s->gr[s->gr_index] = val & gr_mask[s->gr_index];
|
|
Mark McLoughlin |
910c5e |
+ vga_update_resolution(s);
|
|
Mark McLoughlin |
910c5e |
break;
|
|
Mark McLoughlin |
910c5e |
case 0x3b4:
|
|
Mark McLoughlin |
910c5e |
case 0x3d4:
|
|
Mark McLoughlin |
910c5e |
@@ -476,6 +483,7 @@ static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
|
|
Mark McLoughlin |
910c5e |
/* can always write bit 4 of CR7 */
|
|
Mark McLoughlin |
910c5e |
if (s->cr_index == 7)
|
|
Mark McLoughlin |
910c5e |
s->cr[7] = (s->cr[7] & ~0x10) | (val & 0x10);
|
|
Mark McLoughlin |
910c5e |
+ vga_update_resolution(s);
|
|
Mark McLoughlin |
910c5e |
return;
|
|
Mark McLoughlin |
910c5e |
}
|
|
Mark McLoughlin |
910c5e |
switch(s->cr_index) {
|
|
Mark McLoughlin |
910c5e |
@@ -503,6 +511,7 @@ static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
|
|
Mark McLoughlin |
910c5e |
s->update_retrace_info(s);
|
|
Mark McLoughlin |
910c5e |
break;
|
|
Mark McLoughlin |
910c5e |
}
|
|
Mark McLoughlin |
910c5e |
+ vga_update_resolution(s);
|
|
Mark McLoughlin |
910c5e |
break;
|
|
Mark McLoughlin |
910c5e |
case 0x3ba:
|
|
Mark McLoughlin |
910c5e |
case 0x3da:
|
|
Mark McLoughlin |
910c5e |
@@ -582,11 +591,13 @@ static void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
|
|
Mark McLoughlin |
910c5e |
if ((val <= VBE_DISPI_MAX_XRES) && ((val & 7) == 0)) {
|
|
Mark McLoughlin |
910c5e |
s->vbe_regs[s->vbe_index] = val;
|
|
Mark McLoughlin |
910c5e |
}
|
|
Mark McLoughlin |
910c5e |
+ vga_update_resolution(s);
|
|
Mark McLoughlin |
910c5e |
break;
|
|
Mark McLoughlin |
910c5e |
case VBE_DISPI_INDEX_YRES:
|
|
Mark McLoughlin |
910c5e |
if (val <= VBE_DISPI_MAX_YRES) {
|
|
Mark McLoughlin |
910c5e |
s->vbe_regs[s->vbe_index] = val;
|
|
Mark McLoughlin |
910c5e |
}
|
|
Mark McLoughlin |
910c5e |
+ vga_update_resolution(s);
|
|
Mark McLoughlin |
910c5e |
break;
|
|
Mark McLoughlin |
910c5e |
case VBE_DISPI_INDEX_BPP:
|
|
Mark McLoughlin |
910c5e |
if (val == 0)
|
|
Mark McLoughlin |
910c5e |
@@ -595,6 +606,7 @@ static void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
|
|
Mark McLoughlin |
910c5e |
val == 16 || val == 24 || val == 32) {
|
|
Mark McLoughlin |
910c5e |
s->vbe_regs[s->vbe_index] = val;
|
|
Mark McLoughlin |
910c5e |
}
|
|
Mark McLoughlin |
910c5e |
+ vga_update_resolution(s);
|
|
Mark McLoughlin |
910c5e |
break;
|
|
Mark McLoughlin |
910c5e |
case VBE_DISPI_INDEX_BANK:
|
|
Mark McLoughlin |
910c5e |
if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
|
|
Mark McLoughlin |
910c5e |
@@ -663,6 +675,7 @@ static void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
|
|
Mark McLoughlin |
910c5e |
}
|
|
Mark McLoughlin |
910c5e |
s->dac_8bit = (val & VBE_DISPI_8BIT_DAC) > 0;
|
|
Mark McLoughlin |
910c5e |
s->vbe_regs[s->vbe_index] = val;
|
|
Mark McLoughlin |
910c5e |
+ vga_update_resolution(s);
|
|
Mark McLoughlin |
910c5e |
break;
|
|
Mark McLoughlin |
910c5e |
case VBE_DISPI_INDEX_VIRT_WIDTH:
|
|
Mark McLoughlin |
910c5e |
{
|
|
Mark McLoughlin |
910c5e |
@@ -683,6 +696,7 @@ static void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
|
|
Mark McLoughlin |
910c5e |
s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] = h;
|
|
Mark McLoughlin |
910c5e |
s->vbe_line_offset = line_offset;
|
|
Mark McLoughlin |
910c5e |
}
|
|
Mark McLoughlin |
910c5e |
+ vga_update_resolution(s);
|
|
Mark McLoughlin |
910c5e |
break;
|
|
Mark McLoughlin |
910c5e |
case VBE_DISPI_INDEX_X_OFFSET:
|
|
Mark McLoughlin |
910c5e |
case VBE_DISPI_INDEX_Y_OFFSET:
|
|
Mark McLoughlin |
910c5e |
@@ -697,6 +711,7 @@ static void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
|
|
Mark McLoughlin |
910c5e |
s->vbe_start_addr += x * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
|
|
Mark McLoughlin |
910c5e |
s->vbe_start_addr >>= 2;
|
|
Mark McLoughlin |
910c5e |
}
|
|
Mark McLoughlin |
910c5e |
+ vga_update_resolution(s);
|
|
Mark McLoughlin |
910c5e |
break;
|
|
Mark McLoughlin |
910c5e |
default:
|
|
Mark McLoughlin |
910c5e |
break;
|
|
Mark McLoughlin |
910c5e |
@@ -1300,7 +1315,6 @@ static void vga_draw_text(VGAState *s, int full_update)
|
|
Mark McLoughlin |
910c5e |
s->plane_updated = 0;
|
|
Mark McLoughlin |
910c5e |
full_update = 1;
|
|
Mark McLoughlin |
910c5e |
}
|
|
Mark McLoughlin |
910c5e |
- full_update |= update_basic_params(s);
|
|
Mark McLoughlin |
910c5e |
|
|
Mark McLoughlin |
910c5e |
line_offset = s->line_offset;
|
|
Mark McLoughlin |
910c5e |
s1 = s->vram_ptr + (s->start_addr * 4);
|
|
Mark McLoughlin |
910c5e |
@@ -1312,18 +1326,6 @@ static void vga_draw_text(VGAState *s, int full_update)
|
|
Mark McLoughlin |
910c5e |
return;
|
|
Mark McLoughlin |
910c5e |
}
|
|
Mark McLoughlin |
910c5e |
|
|
Mark McLoughlin |
910c5e |
- if (width != s->last_width || height != s->last_height ||
|
|
Mark McLoughlin |
910c5e |
- cw != s->last_cw || cheight != s->last_ch || s->last_depth) {
|
|
Mark McLoughlin |
910c5e |
- s->last_scr_width = width * cw;
|
|
Mark McLoughlin |
910c5e |
- s->last_scr_height = height * cheight;
|
|
Mark McLoughlin |
910c5e |
- qemu_console_resize(s->ds, s->last_scr_width, s->last_scr_height);
|
|
Mark McLoughlin |
910c5e |
- s->last_depth = 0;
|
|
Mark McLoughlin |
910c5e |
- s->last_width = width;
|
|
Mark McLoughlin |
910c5e |
- s->last_height = height;
|
|
Mark McLoughlin |
910c5e |
- s->last_ch = cheight;
|
|
Mark McLoughlin |
910c5e |
- s->last_cw = cw;
|
|
Mark McLoughlin |
910c5e |
- full_update = 1;
|
|
Mark McLoughlin |
910c5e |
- }
|
|
Mark McLoughlin |
910c5e |
s->rgb_to_pixel =
|
|
Mark McLoughlin |
910c5e |
rgb_to_pixel_dup_table[get_depth_index(s->ds)];
|
|
Mark McLoughlin |
910c5e |
full_update |= update_palette16(s);
|
|
Mark McLoughlin |
910c5e |
@@ -1580,40 +1582,20 @@ static void vga_sync_dirty_bitmap(VGAState *s)
|
|
Mark McLoughlin |
910c5e |
vga_dirty_log_start(s);
|
|
Mark McLoughlin |
910c5e |
}
|
|
Mark McLoughlin |
910c5e |
|
|
Mark McLoughlin |
910c5e |
-/*
|
|
Mark McLoughlin |
910c5e |
- * graphic modes
|
|
Mark McLoughlin |
910c5e |
- */
|
|
Mark McLoughlin |
910c5e |
-static void vga_draw_graphic(VGAState *s, int full_update)
|
|
Mark McLoughlin |
910c5e |
+static void vga_update_resolution_graphics(VGAState *s)
|
|
Mark McLoughlin |
910c5e |
{
|
|
Mark McLoughlin |
910c5e |
- int y1, y, update, linesize, y_start, double_scan, mask, depth;
|
|
Mark McLoughlin |
910c5e |
- int width, height, shift_control, line_offset, bwidth, bits;
|
|
Mark McLoughlin |
910c5e |
+ int depth = s->get_bpp(s);
|
|
Mark McLoughlin |
910c5e |
+ int width, height, shift_control, double_scan;
|
|
Mark McLoughlin |
910c5e |
int disp_width, multi_scan, multi_run;
|
|
Mark McLoughlin |
910c5e |
- uint8_t *d;
|
|
Mark McLoughlin |
910c5e |
- uint32_t v, addr1, addr;
|
|
Mark McLoughlin |
910c5e |
- long page0, page1, page_min, page_max;
|
|
Mark McLoughlin |
910c5e |
- vga_draw_line_func *vga_draw_line;
|
|
Mark McLoughlin |
910c5e |
-
|
|
Mark McLoughlin |
910c5e |
- full_update |= update_basic_params(s);
|
|
Mark McLoughlin |
910c5e |
-
|
|
Mark McLoughlin |
910c5e |
- if (!full_update)
|
|
Mark McLoughlin |
910c5e |
- vga_sync_dirty_bitmap(s);
|
|
Mark McLoughlin |
910c5e |
|
|
Mark McLoughlin |
910c5e |
s->get_resolution(s, &width, &height);
|
|
Mark McLoughlin |
910c5e |
- disp_width = width;
|
|
Mark McLoughlin |
910c5e |
|
|
Mark McLoughlin |
910c5e |
shift_control = (s->gr[0x05] >> 5) & 3;
|
|
Mark McLoughlin |
910c5e |
double_scan = (s->cr[0x09] >> 7);
|
|
Mark McLoughlin |
910c5e |
- if (shift_control != 1) {
|
|
Mark McLoughlin |
910c5e |
- multi_scan = (((s->cr[0x09] & 0x1f) + 1) << double_scan) - 1;
|
|
Mark McLoughlin |
910c5e |
- } else {
|
|
Mark McLoughlin |
910c5e |
- /* in CGA modes, multi_scan is ignored */
|
|
Mark McLoughlin |
910c5e |
- /* XXX: is it correct ? */
|
|
Mark McLoughlin |
910c5e |
- multi_scan = double_scan;
|
|
Mark McLoughlin |
910c5e |
- }
|
|
Mark McLoughlin |
910c5e |
- multi_run = multi_scan;
|
|
Mark McLoughlin |
910c5e |
+
|
|
Mark McLoughlin |
910c5e |
if (shift_control != s->shift_control ||
|
|
Mark McLoughlin |
910c5e |
double_scan != s->double_scan) {
|
|
Mark McLoughlin |
910c5e |
- full_update = 1;
|
|
Mark McLoughlin |
910c5e |
+ s->want_full_update = 1;
|
|
Mark McLoughlin |
910c5e |
s->shift_control = shift_control;
|
|
Mark McLoughlin |
910c5e |
s->double_scan = double_scan;
|
|
Mark McLoughlin |
910c5e |
}
|
|
Mark McLoughlin |
910c5e |
@@ -1627,12 +1609,25 @@ static void vga_draw_graphic(VGAState *s, int full_update)
|
|
Mark McLoughlin |
910c5e |
disp_width <<= 1;
|
|
Mark McLoughlin |
910c5e |
}
|
|
Mark McLoughlin |
910c5e |
}
|
|
Mark McLoughlin |
910c5e |
+ disp_width = width;
|
|
Mark McLoughlin |
910c5e |
+
|
|
Mark McLoughlin |
910c5e |
+ if (shift_control != 1) {
|
|
Mark McLoughlin |
910c5e |
+ multi_scan = (((s->cr[0x09] & 0x1f) + 1) << double_scan) - 1;
|
|
Mark McLoughlin |
910c5e |
+ } else {
|
|
Mark McLoughlin |
910c5e |
+ /* in CGA modes, multi_scan is ignored */
|
|
Mark McLoughlin |
910c5e |
+ /* XXX: is it correct ? */
|
|
Mark McLoughlin |
910c5e |
+ multi_scan = double_scan;
|
|
Mark McLoughlin |
910c5e |
+ }
|
|
Mark McLoughlin |
910c5e |
+
|
|
Mark McLoughlin |
910c5e |
+ multi_run = multi_scan;
|
|
Mark McLoughlin |
910c5e |
|
|
Mark McLoughlin |
910c5e |
- depth = s->get_bpp(s);
|
|
Mark McLoughlin |
910c5e |
if (s->line_offset != s->last_line_offset ||
|
|
Mark McLoughlin |
910c5e |
disp_width != s->last_width ||
|
|
Mark McLoughlin |
910c5e |
height != s->last_height ||
|
|
Mark McLoughlin |
910c5e |
- s->last_depth != depth) {
|
|
Mark McLoughlin |
910c5e |
+ s->last_depth != depth ||
|
|
Mark McLoughlin |
910c5e |
+ s->multi_run != multi_run ||
|
|
Mark McLoughlin |
910c5e |
+ s->multi_scan != multi_scan ||
|
|
Mark McLoughlin |
910c5e |
+ s->want_full_update) {
|
|
Mark McLoughlin |
910c5e |
#if defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
|
|
Mark McLoughlin |
910c5e |
if (depth == 16 || depth == 32) {
|
|
Mark McLoughlin |
910c5e |
#else
|
|
Mark McLoughlin |
910c5e |
@@ -1659,8 +1654,74 @@ static void vga_draw_graphic(VGAState *s, int full_update)
|
|
Mark McLoughlin |
910c5e |
s->last_height = height;
|
|
Mark McLoughlin |
910c5e |
s->last_line_offset = s->line_offset;
|
|
Mark McLoughlin |
910c5e |
s->last_depth = depth;
|
|
Mark McLoughlin |
910c5e |
- full_update = 1;
|
|
Mark McLoughlin |
910c5e |
- } else if (is_graphic_console() && is_buffer_shared(s->ds->surface) &&
|
|
Mark McLoughlin |
910c5e |
+ s->multi_run = multi_run;
|
|
Mark McLoughlin |
910c5e |
+ s->multi_scan = multi_scan;
|
|
Mark McLoughlin |
910c5e |
+ s->want_full_update = 1;
|
|
Mark McLoughlin |
910c5e |
+ }
|
|
Mark McLoughlin |
910c5e |
+}
|
|
Mark McLoughlin |
910c5e |
+
|
|
Mark McLoughlin |
910c5e |
+static void vga_update_resolution_text(VGAState *s)
|
|
Mark McLoughlin |
910c5e |
+{
|
|
Mark McLoughlin |
910c5e |
+ int width, height, cw, cheight;
|
|
Mark McLoughlin |
910c5e |
+
|
|
Mark McLoughlin |
910c5e |
+ vga_get_text_resolution(s, &width, &height, &cw, &cheight);
|
|
Mark McLoughlin |
910c5e |
+ if (width != s->last_width || height != s->last_height ||
|
|
Mark McLoughlin |
910c5e |
+ cw != s->last_cw || cheight != s->last_ch || s->last_depth) {
|
|
Mark McLoughlin |
910c5e |
+ s->last_scr_width = width * cw;
|
|
Mark McLoughlin |
910c5e |
+ s->last_scr_height = height * cheight;
|
|
Mark McLoughlin |
910c5e |
+ qemu_console_resize(s->ds, s->last_scr_width, s->last_scr_height);
|
|
Mark McLoughlin |
910c5e |
+ s->last_depth = 0;
|
|
Mark McLoughlin |
910c5e |
+ s->last_width = width;
|
|
Mark McLoughlin |
910c5e |
+ s->last_height = height;
|
|
Mark McLoughlin |
910c5e |
+ s->last_ch = cheight;
|
|
Mark McLoughlin |
910c5e |
+ s->last_cw = cw;
|
|
Mark McLoughlin |
910c5e |
+ s->want_full_update = 1;
|
|
Mark McLoughlin |
910c5e |
+ }
|
|
Mark McLoughlin |
910c5e |
+}
|
|
Mark McLoughlin |
910c5e |
+
|
|
Mark McLoughlin |
910c5e |
+void vga_update_resolution(VGAState *s)
|
|
Mark McLoughlin |
910c5e |
+{
|
|
Mark McLoughlin |
910c5e |
+ int graphic_mode;
|
|
Mark McLoughlin |
910c5e |
+
|
|
Mark McLoughlin |
910c5e |
+ if (!(s->ar_index & 0x20)) {
|
|
Mark McLoughlin |
910c5e |
+ graphic_mode = GMODE_BLANK;
|
|
Mark McLoughlin |
910c5e |
+ } else {
|
|
Mark McLoughlin |
910c5e |
+ graphic_mode = s->gr[6] & 1;
|
|
Mark McLoughlin |
910c5e |
+ }
|
|
Mark McLoughlin |
910c5e |
+ if (graphic_mode != s->graphic_mode) {
|
|
Mark McLoughlin |
910c5e |
+ s->graphic_mode = graphic_mode;
|
|
Mark McLoughlin |
910c5e |
+ s->want_full_update = 1;
|
|
Mark McLoughlin |
910c5e |
+ }
|
|
Mark McLoughlin |
910c5e |
+ s->want_full_update |= update_basic_params(s);
|
|
Mark McLoughlin |
910c5e |
+ switch (graphic_mode) {
|
|
Mark McLoughlin |
910c5e |
+ case GMODE_TEXT:
|
|
Mark McLoughlin |
910c5e |
+ vga_update_resolution_text(s);
|
|
Mark McLoughlin |
910c5e |
+ break;
|
|
Mark McLoughlin |
910c5e |
+ case GMODE_GRAPH:
|
|
Mark McLoughlin |
910c5e |
+ vga_update_resolution_graphics(s);
|
|
Mark McLoughlin |
910c5e |
+ break;
|
|
Mark McLoughlin |
910c5e |
+ }
|
|
Mark McLoughlin |
910c5e |
+}
|
|
Mark McLoughlin |
910c5e |
+
|
|
Mark McLoughlin |
910c5e |
+/*
|
|
Mark McLoughlin |
910c5e |
+ * graphic modes
|
|
Mark McLoughlin |
910c5e |
+ */
|
|
Mark McLoughlin |
910c5e |
+static void vga_draw_graphic(VGAState *s, int full_update)
|
|
Mark McLoughlin |
910c5e |
+{
|
|
Mark McLoughlin |
910c5e |
+ int y1, y, update, linesize, y_start, mask;
|
|
Mark McLoughlin |
910c5e |
+ int width, height, line_offset, bwidth, bits;
|
|
Mark McLoughlin |
910c5e |
+ int multi_run;
|
|
Mark McLoughlin |
910c5e |
+ uint8_t *d;
|
|
Mark McLoughlin |
910c5e |
+ uint32_t v, addr1, addr;
|
|
Mark McLoughlin |
910c5e |
+ long page0, page1, page_min, page_max;
|
|
Mark McLoughlin |
910c5e |
+ vga_draw_line_func *vga_draw_line;
|
|
Mark McLoughlin |
910c5e |
+
|
|
Mark McLoughlin |
910c5e |
+ if (!full_update)
|
|
Mark McLoughlin |
910c5e |
+ vga_sync_dirty_bitmap(s);
|
|
Mark McLoughlin |
910c5e |
+
|
|
Mark McLoughlin |
910c5e |
+ s->get_resolution(s, &width, &height);
|
|
Mark McLoughlin |
910c5e |
+ multi_run = s->multi_run;
|
|
Mark McLoughlin |
910c5e |
+ if (is_graphic_console() && is_buffer_shared(s->ds->surface) &&
|
|
Mark McLoughlin |
910c5e |
(full_update || s->ds->surface->data != s->vram_ptr + (s->start_addr * 4))) {
|
|
Mark McLoughlin |
910c5e |
s->ds->surface->data = s->vram_ptr + (s->start_addr * 4);
|
|
Mark McLoughlin |
910c5e |
dpy_setdata(s->ds);
|
|
Mark McLoughlin |
910c5e |
@@ -1669,7 +1730,7 @@ static void vga_draw_graphic(VGAState *s, int full_update)
|
|
Mark McLoughlin |
910c5e |
s->rgb_to_pixel =
|
|
Mark McLoughlin |
910c5e |
rgb_to_pixel_dup_table[get_depth_index(s->ds)];
|
|
Mark McLoughlin |
910c5e |
|
|
Mark McLoughlin |
910c5e |
- if (shift_control == 0) {
|
|
Mark McLoughlin |
910c5e |
+ if (s->shift_control == 0) {
|
|
Mark McLoughlin |
910c5e |
full_update |= update_palette16(s);
|
|
Mark McLoughlin |
910c5e |
if (s->sr[0x01] & 8) {
|
|
Mark McLoughlin |
910c5e |
v = VGA_DRAW_LINE4D2;
|
|
Mark McLoughlin |
910c5e |
@@ -1677,7 +1738,7 @@ static void vga_draw_graphic(VGAState *s, int full_update)
|
|
Mark McLoughlin |
910c5e |
v = VGA_DRAW_LINE4;
|
|
Mark McLoughlin |
910c5e |
}
|
|
Mark McLoughlin |
910c5e |
bits = 4;
|
|
Mark McLoughlin |
910c5e |
- } else if (shift_control == 1) {
|
|
Mark McLoughlin |
910c5e |
+ } else if (s->shift_control == 1) {
|
|
Mark McLoughlin |
910c5e |
full_update |= update_palette16(s);
|
|
Mark McLoughlin |
910c5e |
if (s->sr[0x01] & 8) {
|
|
Mark McLoughlin |
910c5e |
v = VGA_DRAW_LINE2D2;
|
|
Mark McLoughlin |
910c5e |
@@ -1773,7 +1834,7 @@ static void vga_draw_graphic(VGAState *s, int full_update)
|
|
Mark McLoughlin |
910c5e |
if (y_start >= 0) {
|
|
Mark McLoughlin |
910c5e |
/* flush to display */
|
|
Mark McLoughlin |
910c5e |
dpy_update(s->ds, 0, y_start,
|
|
Mark McLoughlin |
910c5e |
- disp_width, y - y_start);
|
|
Mark McLoughlin |
910c5e |
+ s->last_width, y - y_start);
|
|
Mark McLoughlin |
910c5e |
y_start = -1;
|
|
Mark McLoughlin |
910c5e |
}
|
|
Mark McLoughlin |
910c5e |
}
|
|
Mark McLoughlin |
910c5e |
@@ -1782,7 +1843,7 @@ static void vga_draw_graphic(VGAState *s, int full_update)
|
|
Mark McLoughlin |
910c5e |
if ((y1 & mask) == mask)
|
|
Mark McLoughlin |
910c5e |
addr1 += line_offset;
|
|
Mark McLoughlin |
910c5e |
y1++;
|
|
Mark McLoughlin |
910c5e |
- multi_run = multi_scan;
|
|
Mark McLoughlin |
910c5e |
+ multi_run = s->multi_scan;
|
|
Mark McLoughlin |
910c5e |
} else {
|
|
Mark McLoughlin |
910c5e |
multi_run--;
|
|
Mark McLoughlin |
910c5e |
}
|
|
Mark McLoughlin |
910c5e |
@@ -1794,7 +1855,7 @@ static void vga_draw_graphic(VGAState *s, int full_update)
|
|
Mark McLoughlin |
910c5e |
if (y_start >= 0) {
|
|
Mark McLoughlin |
910c5e |
/* flush to display */
|
|
Mark McLoughlin |
910c5e |
dpy_update(s->ds, 0, y_start,
|
|
Mark McLoughlin |
910c5e |
- disp_width, y - y_start);
|
|
Mark McLoughlin |
910c5e |
+ s->last_width, y - y_start);
|
|
Mark McLoughlin |
910c5e |
}
|
|
Mark McLoughlin |
910c5e |
/* reset modified pages */
|
|
Mark McLoughlin |
910c5e |
if (page_max != -1) {
|
|
Mark McLoughlin |
910c5e |
@@ -1831,29 +1892,17 @@ static void vga_draw_blank(VGAState *s, int full_update)
|
|
Mark McLoughlin |
910c5e |
s->last_scr_width, s->last_scr_height);
|
|
Mark McLoughlin |
910c5e |
}
|
|
Mark McLoughlin |
910c5e |
|
|
Mark McLoughlin |
910c5e |
-#define GMODE_TEXT 0
|
|
Mark McLoughlin |
910c5e |
-#define GMODE_GRAPH 1
|
|
Mark McLoughlin |
910c5e |
-#define GMODE_BLANK 2
|
|
Mark McLoughlin |
910c5e |
-
|
|
Mark McLoughlin |
910c5e |
static void vga_update_display(void *opaque)
|
|
Mark McLoughlin |
910c5e |
{
|
|
Mark McLoughlin |
910c5e |
VGAState *s = (VGAState *)opaque;
|
|
Mark McLoughlin |
910c5e |
- int full_update, graphic_mode;
|
|
Mark McLoughlin |
910c5e |
+ int full_update;
|
|
Mark McLoughlin |
910c5e |
|
|
Mark McLoughlin |
910c5e |
if (ds_get_bits_per_pixel(s->ds) == 0) {
|
|
Mark McLoughlin |
910c5e |
/* nothing to do */
|
|
Mark McLoughlin |
910c5e |
} else {
|
|
Mark McLoughlin |
910c5e |
- full_update = 0;
|
|
Mark McLoughlin |
910c5e |
- if (!(s->ar_index & 0x20)) {
|
|
Mark McLoughlin |
910c5e |
- graphic_mode = GMODE_BLANK;
|
|
Mark McLoughlin |
910c5e |
- } else {
|
|
Mark McLoughlin |
910c5e |
- graphic_mode = s->gr[6] & 1;
|
|
Mark McLoughlin |
910c5e |
- }
|
|
Mark McLoughlin |
910c5e |
- if (graphic_mode != s->graphic_mode) {
|
|
Mark McLoughlin |
910c5e |
- s->graphic_mode = graphic_mode;
|
|
Mark McLoughlin |
910c5e |
- full_update = 1;
|
|
Mark McLoughlin |
910c5e |
- }
|
|
Mark McLoughlin |
910c5e |
- switch(graphic_mode) {
|
|
Mark McLoughlin |
910c5e |
+ full_update = s->want_full_update;
|
|
Mark McLoughlin |
910c5e |
+ s->want_full_update = 0;
|
|
Mark McLoughlin |
910c5e |
+ switch(s->graphic_mode) {
|
|
Mark McLoughlin |
910c5e |
case GMODE_TEXT:
|
|
Mark McLoughlin |
910c5e |
vga_draw_text(s, full_update);
|
|
Mark McLoughlin |
910c5e |
break;
|
|
Mark McLoughlin |
910c5e |
@@ -1876,8 +1925,8 @@ static void vga_invalidate_display(void *opaque)
|
|
Mark McLoughlin |
910c5e |
{
|
|
Mark McLoughlin |
910c5e |
VGAState *s = (VGAState *)opaque;
|
|
Mark McLoughlin |
910c5e |
|
|
Mark McLoughlin |
910c5e |
- s->last_width = -1;
|
|
Mark McLoughlin |
910c5e |
- s->last_height = -1;
|
|
Mark McLoughlin |
910c5e |
+ vga_update_resolution(s);
|
|
Mark McLoughlin |
910c5e |
+ s->want_full_update = 1;
|
|
Mark McLoughlin |
910c5e |
}
|
|
Mark McLoughlin |
910c5e |
|
|
Mark McLoughlin |
910c5e |
void vga_reset(void *opaque)
|
|
Mark McLoughlin |
910c5e |
@@ -1921,7 +1970,6 @@ void vga_reset(void *opaque)
|
|
Mark McLoughlin |
910c5e |
s->vbe_bank_mask = (s->vram_size >> 16) - 1;
|
|
Mark McLoughlin |
910c5e |
#endif
|
|
Mark McLoughlin |
910c5e |
memset(s->font_offsets, '\0', sizeof(s->font_offsets));
|
|
Mark McLoughlin |
910c5e |
- s->graphic_mode = -1; /* force full update */
|
|
Mark McLoughlin |
910c5e |
s->shift_control = 0;
|
|
Mark McLoughlin |
910c5e |
s->double_scan = 0;
|
|
Mark McLoughlin |
910c5e |
s->line_offset = 0;
|
|
Mark McLoughlin |
910c5e |
@@ -1947,6 +1995,7 @@ void vga_reset(void *opaque)
|
|
Mark McLoughlin |
910c5e |
memset(&s->retrace_info, 0, sizeof (s->retrace_info));
|
|
Mark McLoughlin |
910c5e |
break;
|
|
Mark McLoughlin |
910c5e |
}
|
|
Mark McLoughlin |
910c5e |
+ vga_update_resolution(s);
|
|
Mark McLoughlin |
910c5e |
}
|
|
Mark McLoughlin |
910c5e |
|
|
Mark McLoughlin |
910c5e |
#define TEXTMODE_X(x) ((x) % width)
|
|
Mark McLoughlin |
910c5e |
@@ -1965,24 +2014,9 @@ static void vga_update_text(void *opaque, console_ch_t *chardata)
|
|
Mark McLoughlin |
910c5e |
char msg_buffer[80];
|
|
Mark McLoughlin |
910c5e |
int full_update = 0;
|
|
Mark McLoughlin |
910c5e |
|
|
Mark McLoughlin |
910c5e |
- if (!(s->ar_index & 0x20)) {
|
|
Mark McLoughlin |
910c5e |
- graphic_mode = GMODE_BLANK;
|
|
Mark McLoughlin |
910c5e |
- } else {
|
|
Mark McLoughlin |
910c5e |
- graphic_mode = s->gr[6] & 1;
|
|
Mark McLoughlin |
910c5e |
- }
|
|
Mark McLoughlin |
910c5e |
- if (graphic_mode != s->graphic_mode) {
|
|
Mark McLoughlin |
910c5e |
- s->graphic_mode = graphic_mode;
|
|
Mark McLoughlin |
910c5e |
- full_update = 1;
|
|
Mark McLoughlin |
910c5e |
- }
|
|
Mark McLoughlin |
910c5e |
- if (s->last_width == -1) {
|
|
Mark McLoughlin |
910c5e |
- s->last_width = 0;
|
|
Mark McLoughlin |
910c5e |
- full_update = 1;
|
|
Mark McLoughlin |
910c5e |
- }
|
|
Mark McLoughlin |
910c5e |
-
|
|
Mark McLoughlin |
910c5e |
switch (graphic_mode) {
|
|
Mark McLoughlin |
910c5e |
case GMODE_TEXT:
|
|
Mark McLoughlin |
910c5e |
/* TODO: update palette */
|
|
Mark McLoughlin |
910c5e |
- full_update |= update_basic_params(s);
|
|
Mark McLoughlin |
910c5e |
|
|
Mark McLoughlin |
910c5e |
/* total width & height */
|
|
Mark McLoughlin |
910c5e |
cheight = (s->cr[9] & 0x1f) + 1;
|
|
Mark McLoughlin |
910c5e |
@@ -2224,7 +2258,8 @@ static int vga_load(QEMUFile *f, void *opaque, int version_id)
|
|
Mark McLoughlin |
910c5e |
#endif
|
|
Mark McLoughlin |
910c5e |
|
|
Mark McLoughlin |
910c5e |
/* force refresh */
|
|
Mark McLoughlin |
910c5e |
- s->graphic_mode = -1;
|
|
Mark McLoughlin |
910c5e |
+ vga_update_resolution(s);
|
|
Mark McLoughlin |
910c5e |
+ s->want_full_update = 1;
|
|
Mark McLoughlin |
910c5e |
return 0;
|
|
Mark McLoughlin |
910c5e |
}
|
|
Mark McLoughlin |
910c5e |
|
|
Mark McLoughlin |
910c5e |
@@ -2418,7 +2453,8 @@ void vga_bios_init(VGAState *s)
|
|
Mark McLoughlin |
910c5e |
memcpy(s->palette, palette_model, 192);
|
|
Mark McLoughlin |
910c5e |
|
|
Mark McLoughlin |
910c5e |
s->bank_offset = 0;
|
|
Mark McLoughlin |
910c5e |
- s->graphic_mode = -1;
|
|
Mark McLoughlin |
910c5e |
+ vga_update_resolution(s);
|
|
Mark McLoughlin |
910c5e |
+ s->want_full_update = 1;
|
|
Mark McLoughlin |
910c5e |
|
|
Mark McLoughlin |
910c5e |
/* TODO: add vbe support if enabled */
|
|
Mark McLoughlin |
910c5e |
}
|
|
Mark McLoughlin |
910c5e |
@@ -2803,7 +2839,8 @@ static void vga_screen_dump_common(VGAState *s, const char *filename,
|
|
Mark McLoughlin |
910c5e |
ds->surface = qemu_create_displaysurface(w, h, 32, 4 * w);
|
|
Mark McLoughlin |
910c5e |
|
|
Mark McLoughlin |
910c5e |
s->ds = ds;
|
|
Mark McLoughlin |
910c5e |
- s->graphic_mode = -1;
|
|
Mark McLoughlin |
910c5e |
+ vga_update_resolution(s);
|
|
Mark McLoughlin |
910c5e |
+ s->want_full_update = 1;
|
|
Mark McLoughlin |
910c5e |
vga_update_display(s);
|
|
Mark McLoughlin |
910c5e |
|
|
Mark McLoughlin |
910c5e |
ppm_save(filename, ds->surface);
|
|
Mark McLoughlin |
910c5e |
diff --git a/qemu/hw/vga_int.h b/qemu/hw/vga_int.h
|
|
Mark McLoughlin |
910c5e |
index 8ba8a60..71ffeb5 100644
|
|
Mark McLoughlin |
910c5e |
--- a/qemu/hw/vga_int.h
|
|
Mark McLoughlin |
910c5e |
+++ b/qemu/hw/vga_int.h
|
|
Mark McLoughlin |
910c5e |
@@ -147,8 +147,11 @@ typedef void (* vga_update_retrace_info_fn)(struct VGAState *s);
|
|
Mark McLoughlin |
910c5e |
DisplayState *ds; \
|
|
Mark McLoughlin |
910c5e |
uint32_t font_offsets[2]; \
|
|
Mark McLoughlin |
910c5e |
int graphic_mode; \
|
|
Mark McLoughlin |
910c5e |
+ int want_full_update; \
|
|
Mark McLoughlin |
910c5e |
uint8_t shift_control; \
|
|
Mark McLoughlin |
910c5e |
uint8_t double_scan; \
|
|
Mark McLoughlin |
910c5e |
+ uint8_t multi_run; \
|
|
Mark McLoughlin |
910c5e |
+ uint8_t multi_scan; \
|
|
Mark McLoughlin |
910c5e |
uint32_t line_offset; \
|
|
Mark McLoughlin |
910c5e |
uint32_t line_compare; \
|
|
Mark McLoughlin |
910c5e |
uint32_t start_addr; \
|
|
Mark McLoughlin |
910c5e |
@@ -195,6 +198,7 @@ void vga_common_init(VGAState *s, uint8_t *vga_ram_base,
|
|
Mark McLoughlin |
910c5e |
ram_addr_t vga_ram_offset, int vga_ram_size);
|
|
Mark McLoughlin |
910c5e |
void vga_init(VGAState *s);
|
|
Mark McLoughlin |
910c5e |
void vga_reset(void *s);
|
|
Mark McLoughlin |
910c5e |
+void vga_update_resolution(VGAState *s);
|
|
Mark McLoughlin |
910c5e |
|
|
Mark McLoughlin |
910c5e |
void vga_dirty_log_start(VGAState *s);
|
|
Mark McLoughlin |
910c5e |
void vga_dirty_log_stop(VGAState *s);
|
|
Mark McLoughlin |
910c5e |
--
|
|
Mark McLoughlin |
910c5e |
1.6.0.6
|
|
Mark McLoughlin |
910c5e |
|