提交 799e709b 编写于 作者: A aliguori

Revert r6989

There is a much more elegant fix that will follow up after this commit.
Signed-off-by: NAnthony Liguori <aliguori@us.ibm.com>



git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@7025 c046a42c-6fe2-441c-8c8c-71466251a162
上级 3e00b3f5
...@@ -1392,8 +1392,6 @@ cirrus_hook_write_sr(CirrusVGAState * s, unsigned reg_index, int reg_value) ...@@ -1392,8 +1392,6 @@ cirrus_hook_write_sr(CirrusVGAState * s, unsigned reg_index, int reg_value)
break; break;
} }
vga_update_resolution((VGAState *)s);
return CIRRUS_HOOK_HANDLED; return CIRRUS_HOOK_HANDLED;
} }
...@@ -1421,7 +1419,6 @@ static void cirrus_write_hidden_dac(CirrusVGAState * s, int reg_value) ...@@ -1421,7 +1419,6 @@ static void cirrus_write_hidden_dac(CirrusVGAState * s, int reg_value)
#endif #endif
} }
s->cirrus_hidden_dac_lockindex = 0; s->cirrus_hidden_dac_lockindex = 0;
vga_update_resolution((VGAState *)s);
} }
/*************************************** /***************************************
...@@ -1708,8 +1705,6 @@ cirrus_hook_write_cr(CirrusVGAState * s, unsigned reg_index, int reg_value) ...@@ -1708,8 +1705,6 @@ cirrus_hook_write_cr(CirrusVGAState * s, unsigned reg_index, int reg_value)
break; break;
} }
vga_update_resolution((VGAState *)s);
return CIRRUS_HOOK_HANDLED; return CIRRUS_HOOK_HANDLED;
} }
...@@ -2835,7 +2830,6 @@ static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val) ...@@ -2835,7 +2830,6 @@ static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
if (s->ar_flip_flop == 0) { if (s->ar_flip_flop == 0) {
val &= 0x3f; val &= 0x3f;
s->ar_index = val; s->ar_index = val;
vga_update_resolution((VGAState *)s);
} else { } else {
index = s->ar_index & 0x1f; index = s->ar_index & 0x1f;
switch (index) { switch (index) {
...@@ -2929,7 +2923,6 @@ static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val) ...@@ -2929,7 +2923,6 @@ static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
/* can always write bit 4 of CR7 */ /* can always write bit 4 of CR7 */
if (s->cr_index == 7) if (s->cr_index == 7)
s->cr[7] = (s->cr[7] & ~0x10) | (val & 0x10); s->cr[7] = (s->cr[7] & ~0x10) | (val & 0x10);
vga_update_resolution((VGAState *)s);
return; return;
} }
switch (s->cr_index) { switch (s->cr_index) {
...@@ -2958,7 +2951,6 @@ static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val) ...@@ -2958,7 +2951,6 @@ static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
s->update_retrace_info((VGAState *) s); s->update_retrace_info((VGAState *) s);
break; break;
} }
vga_update_resolution((VGAState *)s);
break; break;
case 0x3ba: case 0x3ba:
case 0x3da: case 0x3da:
...@@ -3165,8 +3157,7 @@ static int cirrus_vga_load(QEMUFile *f, void *opaque, int version_id) ...@@ -3165,8 +3157,7 @@ static int cirrus_vga_load(QEMUFile *f, void *opaque, int version_id)
cirrus_update_memory_access(s); cirrus_update_memory_access(s);
/* force refresh */ /* force refresh */
vga_update_resolution((VGAState *)s); s->graphic_mode = -1;
s->want_full_update = 1;
cirrus_update_bank_ptr(s, 0); cirrus_update_bank_ptr(s, 0);
cirrus_update_bank_ptr(s, 1); cirrus_update_bank_ptr(s, 1);
return 0; return 0;
......
...@@ -36,10 +36,6 @@ ...@@ -36,10 +36,6 @@
//#define DEBUG_BOCHS_VBE //#define DEBUG_BOCHS_VBE
#define GMODE_TEXT 0
#define GMODE_GRAPH 1
#define GMODE_BLANK 2
/* force some bits to zero */ /* force some bits to zero */
const uint8_t sr_mask[8] = { const uint8_t sr_mask[8] = {
0x03, 0x03,
...@@ -397,7 +393,6 @@ static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val) ...@@ -397,7 +393,6 @@ static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
if (s->ar_flip_flop == 0) { if (s->ar_flip_flop == 0) {
val &= 0x3f; val &= 0x3f;
s->ar_index = val; s->ar_index = val;
vga_update_resolution(s);
} else { } else {
index = s->ar_index & 0x1f; index = s->ar_index & 0x1f;
switch(index) { switch(index) {
...@@ -438,7 +433,6 @@ static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val) ...@@ -438,7 +433,6 @@ static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
#endif #endif
s->sr[s->sr_index] = val & sr_mask[s->sr_index]; s->sr[s->sr_index] = val & sr_mask[s->sr_index];
if (s->sr_index == 1) s->update_retrace_info(s); if (s->sr_index == 1) s->update_retrace_info(s);
vga_update_resolution(s);
break; break;
case 0x3c7: case 0x3c7:
s->dac_read_index = val; s->dac_read_index = val;
...@@ -466,7 +460,6 @@ static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val) ...@@ -466,7 +460,6 @@ static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
printf("vga: write GR%x = 0x%02x\n", s->gr_index, val); printf("vga: write GR%x = 0x%02x\n", s->gr_index, val);
#endif #endif
s->gr[s->gr_index] = val & gr_mask[s->gr_index]; s->gr[s->gr_index] = val & gr_mask[s->gr_index];
vga_update_resolution(s);
break; break;
case 0x3b4: case 0x3b4:
case 0x3d4: case 0x3d4:
...@@ -482,7 +475,6 @@ static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val) ...@@ -482,7 +475,6 @@ static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
/* can always write bit 4 of CR7 */ /* can always write bit 4 of CR7 */
if (s->cr_index == 7) if (s->cr_index == 7)
s->cr[7] = (s->cr[7] & ~0x10) | (val & 0x10); s->cr[7] = (s->cr[7] & ~0x10) | (val & 0x10);
vga_update_resolution(s);
return; return;
} }
switch(s->cr_index) { switch(s->cr_index) {
...@@ -510,7 +502,6 @@ static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val) ...@@ -510,7 +502,6 @@ static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
s->update_retrace_info(s); s->update_retrace_info(s);
break; break;
} }
vga_update_resolution(s);
break; break;
case 0x3ba: case 0x3ba:
case 0x3da: case 0x3da:
...@@ -590,13 +581,11 @@ static void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val) ...@@ -590,13 +581,11 @@ static void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
if ((val <= VBE_DISPI_MAX_XRES) && ((val & 7) == 0)) { if ((val <= VBE_DISPI_MAX_XRES) && ((val & 7) == 0)) {
s->vbe_regs[s->vbe_index] = val; s->vbe_regs[s->vbe_index] = val;
} }
vga_update_resolution(s);
break; break;
case VBE_DISPI_INDEX_YRES: case VBE_DISPI_INDEX_YRES:
if (val <= VBE_DISPI_MAX_YRES) { if (val <= VBE_DISPI_MAX_YRES) {
s->vbe_regs[s->vbe_index] = val; s->vbe_regs[s->vbe_index] = val;
} }
vga_update_resolution(s);
break; break;
case VBE_DISPI_INDEX_BPP: case VBE_DISPI_INDEX_BPP:
if (val == 0) if (val == 0)
...@@ -605,7 +594,6 @@ static void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val) ...@@ -605,7 +594,6 @@ static void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
val == 16 || val == 24 || val == 32) { val == 16 || val == 24 || val == 32) {
s->vbe_regs[s->vbe_index] = val; s->vbe_regs[s->vbe_index] = val;
} }
vga_update_resolution(s);
break; break;
case VBE_DISPI_INDEX_BANK: case VBE_DISPI_INDEX_BANK:
if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) { if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
...@@ -674,7 +662,6 @@ static void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val) ...@@ -674,7 +662,6 @@ static void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
} }
s->dac_8bit = (val & VBE_DISPI_8BIT_DAC) > 0; s->dac_8bit = (val & VBE_DISPI_8BIT_DAC) > 0;
s->vbe_regs[s->vbe_index] = val; s->vbe_regs[s->vbe_index] = val;
vga_update_resolution(s);
break; break;
case VBE_DISPI_INDEX_VIRT_WIDTH: case VBE_DISPI_INDEX_VIRT_WIDTH:
{ {
...@@ -695,7 +682,6 @@ static void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val) ...@@ -695,7 +682,6 @@ static void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] = h; s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] = h;
s->vbe_line_offset = line_offset; s->vbe_line_offset = line_offset;
} }
vga_update_resolution(s);
break; break;
case VBE_DISPI_INDEX_X_OFFSET: case VBE_DISPI_INDEX_X_OFFSET:
case VBE_DISPI_INDEX_Y_OFFSET: case VBE_DISPI_INDEX_Y_OFFSET:
...@@ -710,7 +696,6 @@ static void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val) ...@@ -710,7 +696,6 @@ static void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
s->vbe_start_addr += x * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3); s->vbe_start_addr += x * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
s->vbe_start_addr >>= 2; s->vbe_start_addr >>= 2;
} }
vga_update_resolution(s);
break; break;
default: default:
break; break;
...@@ -1317,6 +1302,7 @@ static void vga_draw_text(VGAState *s, int full_update) ...@@ -1317,6 +1302,7 @@ static void vga_draw_text(VGAState *s, int full_update)
s->plane_updated = 0; s->plane_updated = 0;
full_update = 1; full_update = 1;
} }
full_update |= update_basic_params(s);
line_offset = s->line_offset; line_offset = s->line_offset;
s1 = s->vram_ptr + (s->start_addr * 4); s1 = s->vram_ptr + (s->start_addr * 4);
...@@ -1328,6 +1314,18 @@ static void vga_draw_text(VGAState *s, int full_update) ...@@ -1328,6 +1314,18 @@ static void vga_draw_text(VGAState *s, int full_update)
return; return;
} }
if (width != s->last_width || height != s->last_height ||
cw != s->last_cw || cheight != s->last_ch || s->last_depth) {
s->last_scr_width = width * cw;
s->last_scr_height = height * cheight;
qemu_console_resize(s->ds, s->last_scr_width, s->last_scr_height);
s->last_depth = 0;
s->last_width = width;
s->last_height = height;
s->last_ch = cheight;
s->last_cw = cw;
full_update = 1;
}
s->rgb_to_pixel = s->rgb_to_pixel =
rgb_to_pixel_dup_table[get_depth_index(s->ds)]; rgb_to_pixel_dup_table[get_depth_index(s->ds)];
full_update |= update_palette16(s); full_update |= update_palette16(s);
...@@ -1584,21 +1582,39 @@ static void vga_sync_dirty_bitmap(VGAState *s) ...@@ -1584,21 +1582,39 @@ static void vga_sync_dirty_bitmap(VGAState *s)
vga_dirty_log_start(s); vga_dirty_log_start(s);
} }
static void vga_update_resolution_graphics(VGAState *s) /*
* graphic modes
*/
static void vga_draw_graphic(VGAState *s, int full_update)
{ {
int depth = s->get_bpp(s); int y1, y, update, page_min, page_max, linesize, y_start, double_scan, mask, depth;
int width, height, shift_control, double_scan; int width, height, shift_control, line_offset, page0, page1, bwidth, bits;
int disp_width, multi_scan, multi_run; int disp_width, multi_scan, multi_run;
uint8_t *d;
uint32_t v, addr1, addr;
vga_draw_line_func *vga_draw_line;
full_update |= update_basic_params(s);
if (!full_update)
vga_sync_dirty_bitmap(s);
s->get_resolution(s, &width, &height); s->get_resolution(s, &width, &height);
disp_width = width; disp_width = width;
shift_control = (s->gr[0x05] >> 5) & 3; shift_control = (s->gr[0x05] >> 5) & 3;
double_scan = (s->cr[0x09] >> 7); double_scan = (s->cr[0x09] >> 7);
if (shift_control != 1) {
multi_scan = (((s->cr[0x09] & 0x1f) + 1) << double_scan) - 1;
} else {
/* in CGA modes, multi_scan is ignored */
/* XXX: is it correct ? */
multi_scan = double_scan;
}
multi_run = multi_scan;
if (shift_control != s->shift_control || if (shift_control != s->shift_control ||
double_scan != s->double_scan) { double_scan != s->double_scan) {
s->want_full_update = 1; full_update = 1;
s->shift_control = shift_control; s->shift_control = shift_control;
s->double_scan = double_scan; s->double_scan = double_scan;
} }
...@@ -1612,28 +1628,12 @@ static void vga_update_resolution_graphics(VGAState *s) ...@@ -1612,28 +1628,12 @@ static void vga_update_resolution_graphics(VGAState *s)
disp_width <<= 1; disp_width <<= 1;
} }
} }
disp_width = width;
if (shift_control != 1) {
multi_scan = (((s->cr[0x09] & 0x1f) + 1) << double_scan) - 1;
} else {
/* in CGA modes, multi_scan is ignored */
/* XXX: is it correct ? */
multi_scan = double_scan;
}
multi_run = multi_scan;
depth = s->get_bpp(s);
if (s->line_offset != s->last_line_offset || if (s->line_offset != s->last_line_offset ||
disp_width != s->last_width || disp_width != s->last_width ||
height != s->last_height || height != s->last_height ||
s->last_depth != depth || s->last_depth != depth) {
s->multi_run != multi_run ||
s->multi_scan != multi_scan ||
s->want_full_update) {
if (s->ds->surface->pf.depth == 0) {
goto dont_touch_display_surface;
}
#if defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN) #if defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
if (depth == 16 || depth == 32) { if (depth == 16 || depth == 32) {
#else #else
...@@ -1650,91 +1650,14 @@ static void vga_update_resolution_graphics(VGAState *s) ...@@ -1650,91 +1650,14 @@ static void vga_update_resolution_graphics(VGAState *s)
} else { } else {
qemu_console_resize(s->ds, disp_width, height); qemu_console_resize(s->ds, disp_width, height);
} }
dont_touch_display_surface:
s->last_scr_width = disp_width; s->last_scr_width = disp_width;
s->last_scr_height = height; s->last_scr_height = height;
s->last_width = disp_width; s->last_width = disp_width;
s->last_height = height; s->last_height = height;
s->last_line_offset = s->line_offset; s->last_line_offset = s->line_offset;
s->last_depth = depth; s->last_depth = depth;
s->multi_run = multi_run; full_update = 1;
s->multi_scan = multi_scan; } else if (is_buffer_shared(s->ds->surface) &&
s->want_full_update = 1;
}
}
static void vga_update_resolution_text(VGAState *s)
{
int width, height, cw, cheight;
vga_get_text_resolution(s, &width, &height, &cw, &cheight);
if (width != s->last_width || height != s->last_height ||
cw != s->last_cw || cheight != s->last_ch || s->last_depth) {
s->last_scr_width = width * cw;
s->last_scr_height = height * cheight;
if (s->ds->surface->pf.depth != 0) {
qemu_console_resize(s->ds, s->last_scr_width, s->last_scr_height);
} else {
/*
* curses expects width and height to be in character cell
* dimensions, not pixels.
*/
s->ds->surface->width = width;
s->ds->surface->height = height;
dpy_resize(s->ds);
}
s->last_depth = 0;
s->last_width = width;
s->last_height = height;
s->last_ch = cheight;
s->last_cw = cw;
s->want_full_update = 1;
}
}
void vga_update_resolution(VGAState *s)
{
int graphic_mode;
if (!(s->ar_index & 0x20)) {
graphic_mode = GMODE_BLANK;
} else {
graphic_mode = s->gr[6] & 1;
}
if (graphic_mode != s->graphic_mode) {
s->graphic_mode = graphic_mode;
s->want_full_update = 1;
}
s->want_full_update |= update_basic_params(s);
switch (graphic_mode) {
case GMODE_TEXT:
vga_update_resolution_text(s);
break;
case GMODE_GRAPH:
vga_update_resolution_graphics(s);
break;
}
}
/*
* graphic modes
*/
static void vga_draw_graphic(VGAState *s, int full_update)
{
int y1, y, update, linesize, y_start, mask;
int width, height, line_offset, bwidth, bits;
int multi_run;
uint8_t *d;
uint32_t v, addr1, addr;
long page0, page1, page_min, page_max;
vga_draw_line_func *vga_draw_line;
if (!full_update)
vga_sync_dirty_bitmap(s);
s->get_resolution(s, &width, &height);
multi_run = s->multi_run;
if (is_buffer_shared(s->ds->surface) &&
(full_update || s->ds->surface->data != s->vram_ptr + (s->start_addr * 4))) { (full_update || s->ds->surface->data != s->vram_ptr + (s->start_addr * 4))) {
s->ds->surface->data = s->vram_ptr + (s->start_addr * 4); s->ds->surface->data = s->vram_ptr + (s->start_addr * 4);
dpy_setdata(s->ds); dpy_setdata(s->ds);
...@@ -1743,7 +1666,7 @@ static void vga_draw_graphic(VGAState *s, int full_update) ...@@ -1743,7 +1666,7 @@ static void vga_draw_graphic(VGAState *s, int full_update)
s->rgb_to_pixel = s->rgb_to_pixel =
rgb_to_pixel_dup_table[get_depth_index(s->ds)]; rgb_to_pixel_dup_table[get_depth_index(s->ds)];
if (s->shift_control == 0) { if (shift_control == 0) {
full_update |= update_palette16(s); full_update |= update_palette16(s);
if (s->sr[0x01] & 8) { if (s->sr[0x01] & 8) {
v = VGA_DRAW_LINE4D2; v = VGA_DRAW_LINE4D2;
...@@ -1751,7 +1674,7 @@ static void vga_draw_graphic(VGAState *s, int full_update) ...@@ -1751,7 +1674,7 @@ static void vga_draw_graphic(VGAState *s, int full_update)
v = VGA_DRAW_LINE4; v = VGA_DRAW_LINE4;
} }
bits = 4; bits = 4;
} else if (s->shift_control == 1) { } else if (shift_control == 1) {
full_update |= update_palette16(s); full_update |= update_palette16(s);
if (s->sr[0x01] & 8) { if (s->sr[0x01] & 8) {
v = VGA_DRAW_LINE2D2; v = VGA_DRAW_LINE2D2;
...@@ -1847,7 +1770,7 @@ static void vga_draw_graphic(VGAState *s, int full_update) ...@@ -1847,7 +1770,7 @@ static void vga_draw_graphic(VGAState *s, int full_update)
if (y_start >= 0) { if (y_start >= 0) {
/* flush to display */ /* flush to display */
dpy_update(s->ds, 0, y_start, dpy_update(s->ds, 0, y_start,
s->last_width, y - y_start); disp_width, y - y_start);
y_start = -1; y_start = -1;
} }
} }
...@@ -1856,7 +1779,7 @@ static void vga_draw_graphic(VGAState *s, int full_update) ...@@ -1856,7 +1779,7 @@ static void vga_draw_graphic(VGAState *s, int full_update)
if ((y1 & mask) == mask) if ((y1 & mask) == mask)
addr1 += line_offset; addr1 += line_offset;
y1++; y1++;
multi_run = s->multi_scan; multi_run = multi_scan;
} else { } else {
multi_run--; multi_run--;
} }
...@@ -1868,7 +1791,7 @@ static void vga_draw_graphic(VGAState *s, int full_update) ...@@ -1868,7 +1791,7 @@ static void vga_draw_graphic(VGAState *s, int full_update)
if (y_start >= 0) { if (y_start >= 0) {
/* flush to display */ /* flush to display */
dpy_update(s->ds, 0, y_start, dpy_update(s->ds, 0, y_start,
s->last_width, y - y_start); disp_width, y - y_start);
} }
/* reset modified pages */ /* reset modified pages */
if (page_max != -1) { if (page_max != -1) {
...@@ -1905,17 +1828,29 @@ static void vga_draw_blank(VGAState *s, int full_update) ...@@ -1905,17 +1828,29 @@ static void vga_draw_blank(VGAState *s, int full_update)
s->last_scr_width, s->last_scr_height); s->last_scr_width, s->last_scr_height);
} }
#define GMODE_TEXT 0
#define GMODE_GRAPH 1
#define GMODE_BLANK 2
static void vga_update_display(void *opaque) static void vga_update_display(void *opaque)
{ {
VGAState *s = (VGAState *)opaque; VGAState *s = (VGAState *)opaque;
int full_update; int full_update, graphic_mode;
if (ds_get_bits_per_pixel(s->ds) == 0) { if (ds_get_bits_per_pixel(s->ds) == 0) {
/* nothing to do */ /* nothing to do */
} else { } else {
full_update = s->want_full_update; full_update = 0;
s->want_full_update = 0; if (!(s->ar_index & 0x20)) {
switch(s->graphic_mode) { graphic_mode = GMODE_BLANK;
} else {
graphic_mode = s->gr[6] & 1;
}
if (graphic_mode != s->graphic_mode) {
s->graphic_mode = graphic_mode;
full_update = 1;
}
switch(graphic_mode) {
case GMODE_TEXT: case GMODE_TEXT:
vga_draw_text(s, full_update); vga_draw_text(s, full_update);
break; break;
...@@ -1935,8 +1870,8 @@ static void vga_invalidate_display(void *opaque) ...@@ -1935,8 +1870,8 @@ static void vga_invalidate_display(void *opaque)
{ {
VGAState *s = (VGAState *)opaque; VGAState *s = (VGAState *)opaque;
vga_update_resolution(s); s->last_width = -1;
s->want_full_update = 1; s->last_height = -1;
} }
void vga_reset(void *opaque) void vga_reset(void *opaque)
...@@ -1980,6 +1915,7 @@ void vga_reset(void *opaque) ...@@ -1980,6 +1915,7 @@ void vga_reset(void *opaque)
s->vbe_bank_mask = (s->vram_size >> 16) - 1; s->vbe_bank_mask = (s->vram_size >> 16) - 1;
#endif #endif
memset(s->font_offsets, '\0', sizeof(s->font_offsets)); memset(s->font_offsets, '\0', sizeof(s->font_offsets));
s->graphic_mode = -1; /* force full update */
s->shift_control = 0; s->shift_control = 0;
s->double_scan = 0; s->double_scan = 0;
s->line_offset = 0; s->line_offset = 0;
...@@ -2005,7 +1941,6 @@ void vga_reset(void *opaque) ...@@ -2005,7 +1941,6 @@ void vga_reset(void *opaque)
memset(&s->retrace_info, 0, sizeof (s->retrace_info)); memset(&s->retrace_info, 0, sizeof (s->retrace_info));
break; break;
} }
vga_update_resolution(s);
} }
#define TEXTMODE_X(x) ((x) % width) #define TEXTMODE_X(x) ((x) % width)
...@@ -2017,28 +1952,50 @@ void vga_reset(void *opaque) ...@@ -2017,28 +1952,50 @@ void vga_reset(void *opaque)
static void vga_update_text(void *opaque, console_ch_t *chardata) static void vga_update_text(void *opaque, console_ch_t *chardata)
{ {
VGAState *s = (VGAState *) opaque; VGAState *s = (VGAState *) opaque;
int i, cursor_offset, cursor_visible; int graphic_mode, i, cursor_offset, cursor_visible;
int cw, cheight, width, height, size, c_min, c_max; int cw, cheight, width, height, size, c_min, c_max;
uint32_t *src; uint32_t *src;
console_ch_t *dst, val; console_ch_t *dst, val;
char msg_buffer[80]; char msg_buffer[80];
int full_update = s->want_full_update; int full_update = 0;
if (!(s->ar_index & 0x20)) {
graphic_mode = GMODE_BLANK;
} else {
graphic_mode = s->gr[6] & 1;
}
if (graphic_mode != s->graphic_mode) {
s->graphic_mode = graphic_mode;
full_update = 1;
}
if (s->last_width == -1) {
s->last_width = 0;
full_update = 1;
}
s->want_full_update = 0; switch (graphic_mode) {
switch (s->graphic_mode) {
case GMODE_TEXT: case GMODE_TEXT:
/* TODO: update palette */ /* TODO: update palette */
full_update |= update_basic_params(s);
vga_get_text_resolution(s, &width, &height, &cw, &cheight); /* total width & height */
cheight = (s->cr[9] & 0x1f) + 1;
if (s->ds->surface->width != width cw = 8;
|| s->ds->surface->height != height) { if (!(s->sr[1] & 0x01))
s->ds->surface->width = width; cw = 9;
s->ds->surface->height = height; if (s->sr[1] & 0x08)
dpy_resize(s->ds); cw = 16; /* NOTE: no 18 pixel wide */
width = (s->cr[0x01] + 1);
if (s->cr[0x06] == 100) {
/* ugly hack for CGA 160x100x16 - explain me the logic */
height = 100;
} else {
height = s->cr[0x12] |
((s->cr[0x07] & 0x02) << 7) |
((s->cr[0x07] & 0x40) << 3);
height = (height + 1) / cheight;
} }
/* total width & height */
size = (height * width); size = (height * width);
if (size > CH_ATTR_SIZE) { if (size > CH_ATTR_SIZE) {
if (!full_update) if (!full_update)
...@@ -2049,6 +2006,20 @@ static void vga_update_text(void *opaque, console_ch_t *chardata) ...@@ -2049,6 +2006,20 @@ static void vga_update_text(void *opaque, console_ch_t *chardata)
break; break;
} }
if (width != s->last_width || height != s->last_height ||
cw != s->last_cw || cheight != s->last_ch) {
s->last_scr_width = width * cw;
s->last_scr_height = height * cheight;
s->ds->surface->width = width;
s->ds->surface->height = height;
dpy_resize(s->ds);
s->last_width = width;
s->last_height = height;
s->last_ch = cheight;
s->last_cw = cw;
full_update = 1;
}
/* Update "hardware" cursor */ /* Update "hardware" cursor */
cursor_offset = ((s->cr[0x0e] << 8) | s->cr[0x0f]) - s->start_addr; cursor_offset = ((s->cr[0x0e] << 8) | s->cr[0x0f]) - s->start_addr;
if (cursor_offset != s->cursor_offset || if (cursor_offset != s->cursor_offset ||
...@@ -2247,8 +2218,7 @@ static int vga_load(QEMUFile *f, void *opaque, int version_id) ...@@ -2247,8 +2218,7 @@ static int vga_load(QEMUFile *f, void *opaque, int version_id)
#endif #endif
/* force refresh */ /* force refresh */
vga_update_resolution(s); s->graphic_mode = -1;
s->want_full_update = 1;
return 0; return 0;
} }
...@@ -2671,8 +2641,7 @@ static void vga_screen_dump_common(VGAState *s, const char *filename, ...@@ -2671,8 +2641,7 @@ static void vga_screen_dump_common(VGAState *s, const char *filename,
ds->surface = qemu_create_displaysurface(ds, w, h); ds->surface = qemu_create_displaysurface(ds, w, h);
s->ds = ds; s->ds = ds;
vga_update_resolution(s); s->graphic_mode = -1;
s->want_full_update = 1;
vga_update_display(s); vga_update_display(s);
ppm_save(filename, ds->surface); ppm_save(filename, ds->surface);
...@@ -2703,16 +2672,10 @@ static void vga_screen_dump(void *opaque, const char *filename) ...@@ -2703,16 +2672,10 @@ static void vga_screen_dump(void *opaque, const char *filename)
{ {
VGAState *s = (VGAState *)opaque; VGAState *s = (VGAState *)opaque;
switch (s->graphic_mode) { if (!(s->ar_index & 0x20))
case GMODE_TEXT:
vga_screen_dump_text(s, filename);
break;
case GMODE_GRAPH:
vga_screen_dump_graphic(s, filename);
break;
case GMODE_BLANK:
default:
vga_screen_dump_blank(s, filename); vga_screen_dump_blank(s, filename);
break; else if (s->gr[6] & 1)
} vga_screen_dump_graphic(s, filename);
else
vga_screen_dump_text(s, filename);
} }
...@@ -147,11 +147,8 @@ typedef void (* vga_update_retrace_info_fn)(struct VGAState *s); ...@@ -147,11 +147,8 @@ typedef void (* vga_update_retrace_info_fn)(struct VGAState *s);
DisplayState *ds; \ DisplayState *ds; \
uint32_t font_offsets[2]; \ uint32_t font_offsets[2]; \
int graphic_mode; \ int graphic_mode; \
int want_full_update; \
uint8_t shift_control; \ uint8_t shift_control; \
uint8_t double_scan; \ uint8_t double_scan; \
uint8_t multi_run; \
uint8_t multi_scan; \
uint32_t line_offset; \ uint32_t line_offset; \
uint32_t line_compare; \ uint32_t line_compare; \
uint32_t start_addr; \ uint32_t start_addr; \
...@@ -198,7 +195,6 @@ void vga_common_init(VGAState *s, uint8_t *vga_ram_base, ...@@ -198,7 +195,6 @@ void vga_common_init(VGAState *s, uint8_t *vga_ram_base,
ram_addr_t vga_ram_offset, int vga_ram_size); ram_addr_t vga_ram_offset, int vga_ram_size);
void vga_init(VGAState *s); void vga_init(VGAState *s);
void vga_reset(void *s); void vga_reset(void *s);
void vga_update_resolution(VGAState *s);
void vga_dirty_log_start(VGAState *s); void vga_dirty_log_start(VGAState *s);
void vga_dirty_log_stop(VGAState *s); void vga_dirty_log_stop(VGAState *s);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册