From: "Alex Bennée" <alex.bennee@linaro.org>
To: marcandre.lureau@redhat.com
Cc: qemu-devel@nongnu.org, Gerd Hoffmann <kraxel@redhat.com>
Subject: Re: [PATCH] vga: implement text mode character blink
Date: Tue, 23 Jun 2026 11:54:12 +0100 [thread overview]
Message-ID: <87fr2dmsrv.fsf@draig.linaro.org> (raw)
In-Reply-To: <20260525081944.1494798-1-marcandre.lureau@redhat.com> (marcandre lureau's message of "Mon, 25 May 2026 12:19:44 +0400")
marcandre.lureau@redhat.com writes:
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
>
> When bit 3 of the VGA Attribute Mode Control register is set, attribute
> bit 7 switches from selecting bright background colors to enabling
> character blink.
>
> Implement this by tracking a separate blink phase timer that toggles
> every 32 frames (matching real VGA hardware frame counter bit 5 @60hz),
> and rendering blinking characters by replacing their foreground with
> background during the off phase.
>
> As with cursor, no VMState migration of the fields, as they are
> transient display-side states.
>
> Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/1585
I don't think this resolves all of 1585 because I think its asking for
the other text mode features as well.
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> hw/display/vga_int.h | 2 ++
> hw/display/vga.c | 24 +++++++++++++++++++++---
> 2 files changed, 23 insertions(+), 3 deletions(-)
>
> diff --git a/hw/display/vga_int.h b/hw/display/vga_int.h
> index 747b5cc6cf8..5664317ecd6 100644
> --- a/hw/display/vga_int.h
> +++ b/hw/display/vga_int.h
> @@ -130,6 +130,8 @@ typedef struct VGACommonState {
> uint8_t cursor_start, cursor_end;
> bool cursor_visible_phase;
> int64_t cursor_blink_time;
> + bool blink_visible_phase;
> + int64_t blink_time;
> uint32_t cursor_offset;
> const GraphicHwOps *hw_ops;
> bool full_update_text;
> diff --git a/hw/display/vga.c b/hw/display/vga.c
> index 0ac4bf37310..ea01a889f20 100644
> --- a/hw/display/vga.c
> +++ b/hw/display/vga.c
> @@ -45,8 +45,10 @@
>
> bool have_vga = true;
>
> -/* 16 state changes per vertical frame @60 Hz */
> +/* frame counter bit 4: cursor blink toggles every 16 frames @60 Hz */
> #define VGA_TEXT_CURSOR_PERIOD_MS (1000 * 2 * 16 / 60)
> +/* frame counter bit 5: character blink toggles every 32 frames @60 Hz */
> +#define VGA_TEXT_BLINK_PERIOD_MS (1000 * 2 * 32 / 60)
>
> /* Address mask for non-VESA modes. */
> #define VGA_VRAM_SIZE (256 * KiB)
> @@ -1286,6 +1288,13 @@ static void vga_draw_text(VGACommonState *s, int full_update)
> s->cursor_blink_time = now + VGA_TEXT_CURSOR_PERIOD_MS / 2;
> s->cursor_visible_phase = !s->cursor_visible_phase;
> }
> + if (now >= s->blink_time) {
> + s->blink_time = now + VGA_TEXT_BLINK_PERIOD_MS / 2;
> + s->blink_visible_phase = !s->blink_visible_phase;
> + if (s->ar[VGA_ATC_MODE] & 0x08) {
> + full_update = 1;
> + }
> + }
You should update the comment above vga_draw_text and remove "flashing"
as unimplemented.
>
> dest = surface_data(surface);
> linesize = surface_stride(surface);
> @@ -1317,8 +1326,17 @@ static void vga_draw_text(VGACommonState *s, int full_update)
> #endif
> font_ptr = font_base[(cattr >> 3) & 1];
> font_ptr += 32 * 4 * ch;
> - bgcol = palette[cattr >> 4];
> - fgcol = palette[cattr & 0x0f];
> + if (s->ar[VGA_ATC_MODE] & 0x08) {
> + bgcol = palette[(cattr >> 4) & 0x07];
> + if ((cattr & 0x80) && !s->blink_visible_phase) {
> + fgcol = bgcol;
> + } else {
> + fgcol = palette[cattr & 0x0f];
> + }
> + } else {
> + bgcol = palette[cattr >> 4];
> + fgcol = palette[cattr & 0x0f];
> + }
> if (cw == 16) {
> vga_draw_glyph16(d1, linesize,
> font_ptr, cheight, fgcol, bgcol);
--
Alex Bennée
Virtualisation Tech Lead @ Linaro
prev parent reply other threads:[~2026-06-23 10:55 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-25 8:19 [PATCH] vga: implement text mode character blink marcandre.lureau
2026-06-23 10:10 ` Gerd Hoffmann
2026-06-23 10:54 ` Alex Bennée [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87fr2dmsrv.fsf@draig.linaro.org \
--to=alex.bennee@linaro.org \
--cc=kraxel@redhat.com \
--cc=marcandre.lureau@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.