diff options
Diffstat (limited to 'hw/vga.c')
-rw-r--r-- | hw/vga.c | 27 |
1 files changed, 22 insertions, 5 deletions
@@ -38,6 +38,9 @@ //#define DEBUG_BOCHS_VBE +/* 16 state changes per vertical frame @60 Hz */ +#define VGA_TEXT_CURSOR_PERIOD_MS (1000 * 2 * 16 / 60) + /* * Video Graphics Array (VGA) * @@ -1300,6 +1303,7 @@ static void vga_draw_text(VGACommonState *s, int full_update) uint32_t *ch_attr_ptr; vga_draw_glyph8_func *vga_draw_glyph8; vga_draw_glyph9_func *vga_draw_glyph9; + int64_t now = qemu_get_clock_ms(vm_clock); /* compute font data address (in plane 2) */ v = s->sr[VGA_SEQ_CHARACTER_MAP]; @@ -1370,6 +1374,10 @@ static void vga_draw_text(VGACommonState *s, int full_update) s->cursor_end = s->cr[VGA_CRTC_CURSOR_END]; } cursor_ptr = s->vram_ptr + (s->start_addr + cursor_offset) * 4; + if (now >= s->cursor_blink_time) { + s->cursor_blink_time = now + VGA_TEXT_CURSOR_PERIOD_MS / 2; + s->cursor_visible_phase = !s->cursor_visible_phase; + } depth_index = get_depth_index(s->ds); if (cw == 16) @@ -1390,7 +1398,7 @@ static void vga_draw_text(VGACommonState *s, int full_update) cx_max = -1; for(cx = 0; cx < width; cx++) { ch_attr = *(uint16_t *)src; - if (full_update || ch_attr != *ch_attr_ptr) { + if (full_update || ch_attr != *ch_attr_ptr || src == cursor_ptr) { if (cx < cx_min) cx_min = cx; if (cx > cx_max) @@ -1420,7 +1428,8 @@ static void vga_draw_text(VGACommonState *s, int full_update) font_ptr, cheight, fgcol, bgcol, dup9); } if (src == cursor_ptr && - !(s->cr[VGA_CRTC_CURSOR_START] & 0x20)) { + !(s->cr[VGA_CRTC_CURSOR_START] & 0x20) && + s->cursor_visible_phase) { int line_start, line_last, h; /* draw the cursor */ line_start = s->cr[VGA_CRTC_CURSOR_START] & 0x1f; @@ -1884,6 +1893,7 @@ static void vga_update_display(void *opaque) } if (graphic_mode != s->graphic_mode) { s->graphic_mode = graphic_mode; + s->cursor_blink_time = qemu_get_clock_ms(vm_clock); full_update = 1; } switch(graphic_mode) { @@ -2225,7 +2235,7 @@ const VMStateDescription vmstate_vga_common = { } }; -void vga_common_init(VGACommonState *s, int vga_ram_size) +void vga_common_init(VGACommonState *s) { int i, j, v, b; @@ -2252,16 +2262,23 @@ void vga_common_init(VGACommonState *s, int vga_ram_size) expand4to8[i] = v; } + /* valid range: 1 MB -> 256 MB */ + s->vram_size = 1024 * 1024; + while (s->vram_size < (s->vram_size_mb << 20) && + s->vram_size < (256 << 20)) { + s->vram_size <<= 1; + } + s->vram_size_mb = s->vram_size >> 20; + #ifdef CONFIG_BOCHS_VBE s->is_vbe_vmstate = 1; #else s->is_vbe_vmstate = 0; #endif - memory_region_init_ram(&s->vram, "vga.vram", vga_ram_size); + memory_region_init_ram(&s->vram, "vga.vram", s->vram_size); vmstate_register_ram_global(&s->vram); xen_register_framebuffer(&s->vram); s->vram_ptr = memory_region_get_ram_ptr(&s->vram); - s->vram_size = vga_ram_size; s->get_bpp = vga_get_bpp; s->get_offsets = vga_get_offsets; s->get_resolution = vga_get_resolution; |