From nobody Sat Dec 21 11:55:26 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of seabios.org designates 78.46.105.101 as permitted sender) client-ip=78.46.105.101; envelope-from=seabios-bounces@seabios.org; helo=coreboot.org; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of seabios.org designates 78.46.105.101 as permitted sender) smtp.mailfrom=seabios-bounces@seabios.org Return-Path: Received: from coreboot.org (coreboot.org [78.46.105.101]) by mx.zohomail.com with SMTPS id 1710135188709154.34624796864034; Sun, 10 Mar 2024 22:33:08 -0700 (PDT) Received: from authenticated-user (PRIMARY_HOSTNAME [PUBLIC_IP]) by coreboot.org (Postfix) with ESMTPA id 69DDC21CCB; Mon, 11 Mar 2024 05:33:03 +0000 (UTC) Received: from authenticated-user (PRIMARY_HOSTNAME [PUBLIC_IP]) by coreboot.org (Postfix) with ESMTP id B3F7E2193D for ; Mon, 11 Mar 2024 05:32:45 +0000 (UTC) Received: from authenticated-user (PRIMARY_HOSTNAME [PUBLIC_IP]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) (Authenticated sender: daniel@drv.nu) by oak.drv.nu (Postfix) with ESMTPSA id DA2D7103045; Sun, 10 Mar 2024 22:32:43 -0700 (PDT) From: Daniel Verkamp To: seabios@seabios.org Date: Sun, 10 Mar 2024 22:32:39 -0700 Message-ID: <20240311053239.866790-1-daniel@drv.nu> MIME-Version: 1.0 X-Spam-Level: ** Message-ID-Hash: 5ZJGBHNSSNVTXPBXWNB23EUPBD6U64XC X-Message-ID-Hash: 5ZJGBHNSSNVTXPBXWNB23EUPBD6U64XC X-MailFrom: daniel@drv.nu X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-seabios.seabios.org-0; header-match-seabios.seabios.org-1; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.6b1 Precedence: list Subject: [SeaBIOS] [PATCH] vbe: implement function 09h (get/set palette data) List-Id: SeaBIOS mailing list Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Content-Transfer-Encoding: quoted-printable Authentication-Results: coreboot.org; auth=pass smtp.auth=mailman@coreboot.org smtp.mailfrom=seabios-bounces@seabios.org X-Spamd-Bar: / X-ZM-MESSAGEID: 1710135189868100001 Content-Type: text/plain; charset="utf-8" Since the VBE mode attributes indicate that all modes are not VGA compatible, applications must use VBE function 09h to manipulate the palette rather than directly accessing the VGA registers. This implementation uses the standard VGA registers for all hardware, which may not be appropriate; I only verified qemu -device VGA. Without this patch, the get/set palette function returns an error code, so programs that use 8-bit indexed color modes fail. For example, Quake (DOS) printed "Error: Unable to load VESA palette" and exited when trying to set a SVGA mode like 640x480, but with the patch it succeeds. This fixes qemu issue #251 and #1862. Signed-off-by: Daniel Verkamp --- src/std/vbe.h | 7 +++++++ vgasrc/stdvga.h | 3 +++ vgasrc/stdvgaio.c | 30 ++++++++++++++++++++++++++++++ vgasrc/vbe.c | 42 ++++++++++++++++++++++++++++++++++++++++++ vgasrc/vgahw.h | 8 ++++++++ 5 files changed, 90 insertions(+) diff --git a/src/std/vbe.h b/src/std/vbe.h index fe96f5ec..fddaa4fd 100644 --- a/src/std/vbe.h +++ b/src/std/vbe.h @@ -88,6 +88,13 @@ struct vbe_crtc_info { u8 reserved[40]; } PACKED; =20 +struct vbe_palette_entry { + u8 blue; + u8 green; + u8 red; + u8 align; +} PACKED; + /* VBE Return Status Info */ /* AL */ #define VBE_RETURN_STATUS_SUPPORTED 0x4F diff --git a/vgasrc/stdvga.h b/vgasrc/stdvga.h index 4184c600..af10fd78 100644 --- a/vgasrc/stdvga.h +++ b/vgasrc/stdvga.h @@ -74,6 +74,9 @@ int stdvga_get_displaystart(struct vgamode_s *vmode_g); int stdvga_set_displaystart(struct vgamode_s *vmode_g, int val); int stdvga_get_dacformat(struct vgamode_s *vmode_g); int stdvga_set_dacformat(struct vgamode_s *vmode_g, int val); +struct vbe_palette_entry; +int stdvga_set_palette_colors(u16 seg, struct vbe_palette_entry *pal_far, = u8 start, int count); +int stdvga_get_palette_colors(u16 seg, struct vbe_palette_entry *pal_far, = u8 start, int count); int stdvga_save_restore(int cmd, u16 seg, void *data); void stdvga_enable_video_addressing(u8 disable); int stdvga_setup(void); diff --git a/vgasrc/stdvgaio.c b/vgasrc/stdvgaio.c index 77fcecdf..ec22c4a1 100644 --- a/vgasrc/stdvgaio.c +++ b/vgasrc/stdvgaio.c @@ -6,6 +6,7 @@ =20 #include "farptr.h" // GET_FARVAR #include "stdvga.h" // VGAREG_PEL_MASK +#include "std/vbe.h" // vbe_palette_entry #include "vgautil.h" // stdvga_pelmask_read #include "x86.h" // inb =20 @@ -184,3 +185,32 @@ stdvga_dac_write(u16 seg, u8 *data_far, u8 start, int = count) count--; } } + +int +stdvga_set_palette_colors(u16 seg, struct vbe_palette_entry *pal_far, u8 s= tart, int count) +{ + outb(start, VGAREG_DAC_WRITE_ADDRESS); + while (count) { + outb(GET_FARVAR(seg, pal_far->red), VGAREG_DAC_DATA); + outb(GET_FARVAR(seg, pal_far->green), VGAREG_DAC_DATA); + outb(GET_FARVAR(seg, pal_far->blue), VGAREG_DAC_DATA); + pal_far++; + count--; + } + return 0; +} + +int +stdvga_get_palette_colors(u16 seg, struct vbe_palette_entry *pal_far, u8 s= tart, int count) +{ + outb(start, VGAREG_DAC_READ_ADDRESS); + while (count) { + SET_FARVAR(seg, pal_far->red, inb(VGAREG_DAC_DATA)); + SET_FARVAR(seg, pal_far->green, inb(VGAREG_DAC_DATA)); + SET_FARVAR(seg, pal_far->blue, inb(VGAREG_DAC_DATA)); + SET_FARVAR(seg, pal_far->align, 0); + pal_far++; + count--; + } + return 0; +} diff --git a/vgasrc/vbe.c b/vgasrc/vbe.c index 91abc9ab..0ac88805 100644 --- a/vgasrc/vbe.c +++ b/vgasrc/vbe.c @@ -376,6 +376,47 @@ fail: regs->ax =3D 0x014f; } =20 +static void +vbe_104f09(struct bregs *regs) +{ + struct vgamode_s *vmode_g =3D get_current_mode(); + if (! vmode_g) + goto fail; + u8 memmodel =3D GET_GLOBAL(vmode_g->memmodel); + u8 depth =3D GET_GLOBAL(vmode_g->depth); + if (memmodel =3D=3D MM_DIRECT || memmodel =3D=3D MM_YUV || depth > 8) { + regs->ax =3D 0x034f; + return; + } + if (regs->dh) + goto fail; + u8 start =3D regs->dl; + int count =3D regs->cx; + int max_colors =3D 1 << depth; + if (start + count > max_colors) + goto fail; + u16 seg =3D regs->es; + struct vbe_palette_entry *pal =3D (void*)(regs->di+0); + int ret; + switch (regs->bl) { + case 0x80: + case 0x00: + ret =3D vgahw_set_palette_colors(seg, pal, start, count); + break; + case 0x01: + ret =3D vgahw_get_palette_colors(seg, pal, start, count); + break; + default: + goto fail; + } + if (ret < 0) + goto fail; + regs->ax =3D 0x004f; + return; +fail: + regs->ax =3D 0x014f; +} + static void vbe_104f0a(struct bregs *regs) { @@ -456,6 +497,7 @@ handle_104f(struct bregs *regs) case 0x06: vbe_104f06(regs); break; case 0x07: vbe_104f07(regs); break; case 0x08: vbe_104f08(regs); break; + case 0x09: vbe_104f09(regs); break; case 0x0a: vbe_104f0a(regs); break; case 0x10: vbe_104f10(regs); break; case 0x15: vbe_104f15(regs); break; diff --git a/vgasrc/vgahw.h b/vgasrc/vgahw.h index 8b64660e..684530d6 100644 --- a/vgasrc/vgahw.h +++ b/vgasrc/vgahw.h @@ -141,6 +141,14 @@ static inline int vgahw_set_dacformat(struct vgamode_s= *vmode_g, int val) { return stdvga_set_dacformat(vmode_g, val); } =20 +static inline int vgahw_set_palette_colors(u16 seg, struct vbe_palette_ent= ry *pal_far, u8 start, int count) { + return stdvga_set_palette_colors(seg, pal_far, start, count); +} + +static inline int vgahw_get_palette_colors(u16 seg, struct vbe_palette_ent= ry *pal_far, u8 start, int count) { + return stdvga_get_palette_colors(seg, pal_far, start, count); +} + static inline int vgahw_save_restore(int cmd, u16 seg, void *data) { if (CONFIG_VGA_CIRRUS) return clext_save_restore(cmd, seg, data); --=20 2.43.0 _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org