[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 1/1] vga: honor blink attribute in text modes
From: |
Michael Slade |
Subject: |
[Qemu-devel] [PATCH 1/1] vga: honor blink attribute in text modes |
Date: |
Sun, 26 Aug 2018 18:59:56 +1000 |
Signed-off-by: Michael Slade <address@hidden>
---
hw/display/vga.c | 50 +++++++++++++++++++++++++++++++++-----------
hw/display/vga_int.h | 2 ++
2 files changed, 40 insertions(+), 12 deletions(-)
diff --git a/hw/display/vga.c b/hw/display/vga.c
index 72181330b8..03d9181d58 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -36,8 +36,10 @@
//#define DEBUG_VGA_MEM
//#define DEBUG_VGA_REG
-/* 16 state changes per vertical frame @60 Hz */
+/* state change per 16 frames @60 Hz */
#define VGA_TEXT_CURSOR_PERIOD_MS (1000 * 2 * 16 / 60)
+/* state change per 32 frames @60 Hz */
+#define VGA_TEXT_BLINK_PERIOD_MS (1000 * 2 * 32 / 60)
/*
* Video Graphics Array (VGA)
@@ -1165,6 +1167,7 @@ static void vga_get_text_resolution(VGACommonState *s,
int *pwidth, int *pheight
*pcheight = cheight;
}
+
/*
* Text mode update
* Missing:
@@ -1185,6 +1188,8 @@ static void vga_draw_text(VGACommonState *s, int
full_update)
uint32_t *palette;
uint32_t *ch_attr_ptr;
int64_t now = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
+ bool cursor_blink = 0;
+ bool attr_blink = 0;
/* compute font data address (in plane 2) */
v = sr(s, VGA_SEQ_CHARACTER_MAP);
@@ -1266,6 +1271,13 @@ static void vga_draw_text(VGACommonState *s, int
full_update)
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;
+ cursor_blink = 1;
+ }
+ bool blink_active = s->ar[VGA_ATC_MODE] & 0x08;
+ if (now >= s->attr_blink_time) {
+ s->attr_blink_time = now + VGA_TEXT_BLINK_PERIOD_MS / 2;
+ s->attr_blink_visible_phase = !s->attr_blink_visible_phase;
+ attr_blink = blink_active;
}
dest = surface_data(surface);
@@ -1283,23 +1295,36 @@ static void vga_draw_text(VGACommonState *s, int
full_update)
break;
}
ch_attr = *(uint16_t *)src;
- if (full_update || ch_attr != *ch_attr_ptr || src == cursor_ptr) {
+#ifdef HOST_WORDS_BIGENDIAN
+ ch = ch_attr >> 8;
+ cattr = ch_attr & 0xff;
+#else
+ ch = ch_attr & 0xff;
+ cattr = ch_attr >> 8;
+#endif
+
+ if (
+ full_update ||
+ ch_attr != *ch_attr_ptr ||
+ (src == cursor_ptr && cursor_blink) ||
+ (attr_blink && (cattr & 0x80))
+ ) {
if (cx < cx_min)
cx_min = cx;
if (cx > cx_max)
cx_max = cx;
*ch_attr_ptr = ch_attr;
-#ifdef HOST_WORDS_BIGENDIAN
- ch = ch_attr >> 8;
- cattr = ch_attr & 0xff;
-#else
- ch = ch_attr & 0xff;
- cattr = ch_attr >> 8;
-#endif
font_ptr = font_base[(cattr >> 3) & 1];
font_ptr += 32 * 4 * ch;
- bgcol = palette[cattr >> 4];
- fgcol = palette[cattr & 0x0f];
+ if (blink_active) {
+ bgcol = palette[(cattr >> 4) & 7];
+ fgcol = (!(cattr & 0x80) || s->attr_blink_visible_phase) ?
+ palette[cattr & 0x0f] :
+ bgcol;
+ } else {
+ bgcol = palette[cattr >> 4];
+ fgcol = palette[cattr & 0x0f];
+ }
if (cw == 16) {
vga_draw_glyph16(d1, linesize,
font_ptr, cheight, fgcol, bgcol);
@@ -1756,7 +1781,8 @@ static void vga_update_display(void *opaque)
}
if (graphic_mode != s->graphic_mode) {
s->graphic_mode = graphic_mode;
- s->cursor_blink_time = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
+ s->cursor_blink_time = s->attr_blink_time =
+ qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
full_update = 1;
}
switch(graphic_mode) {
diff --git a/hw/display/vga_int.h b/hw/display/vga_int.h
index fe23b81442..775b3e7aa9 100644
--- a/hw/display/vga_int.h
+++ b/hw/display/vga_int.h
@@ -157,7 +157,9 @@ typedef struct VGACommonState {
bool force_shadow;
uint8_t cursor_start, cursor_end;
bool cursor_visible_phase;
+ bool attr_blink_visible_phase;
int64_t cursor_blink_time;
+ int64_t attr_blink_time;
uint32_t cursor_offset;
const GraphicHwOps *hw_ops;
bool full_update_text;
--
2.17.1
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Qemu-devel] [PATCH 1/1] vga: honor blink attribute in text modes,
Michael Slade <=