aboutsummaryrefslogtreecommitdiffstats
path: root/vgasrc
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2014-10-30 12:09:19 -0400
committerKevin O'Connor <kevin@koconnor.net>2014-11-12 12:17:57 -0500
commit6fed307251e2590e9a999af64cf29ff739b034f9 (patch)
tree64662671047950c5a918be236deaddae1cef6fb8 /vgasrc
parent09ae7f1b59a18f3b051cc0934efcd09d70fa6171 (diff)
downloadseabios-6fed307251e2590e9a999af64cf29ff739b034f9.tar.gz
seabios-6fed307251e2590e9a999af64cf29ff739b034f9.tar.xz
seabios-6fed307251e2590e9a999af64cf29ff739b034f9.zip
vgabios: Support emulating text mode attributes while in graphics mode
Add support for simple text mode attribute emulation while in graphics mode. This improves text highlighting and background color on some boot-loaders. Enable it only for CBVGA vgabios and only when a text mode is requested. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Diffstat (limited to 'vgasrc')
-rw-r--r--vgasrc/Kconfig6
-rw-r--r--vgasrc/cbvga.c10
-rw-r--r--vgasrc/vbe.c5
-rw-r--r--vgasrc/vgabios.h10
-rw-r--r--vgasrc/vgafb.c26
5 files changed, 47 insertions, 10 deletions
diff --git a/vgasrc/Kconfig b/vgasrc/Kconfig
index 951240c..400e8da 100644
--- a/vgasrc/Kconfig
+++ b/vgasrc/Kconfig
@@ -50,6 +50,7 @@ menu "VGA ROM"
config VGA_COREBOOT
depends on COREBOOT
bool "coreboot linear framebuffer"
+ select VGA_EMULATE_TEXT
help
Build support for a vgabios wrapper around video
devices initialized using coreboot native vga init.
@@ -83,6 +84,11 @@ menu "VGA ROM"
config VGA_STDVGA_PORTS
bool
+ config VGA_EMULATE_TEXT
+ bool
+ help
+ Support emulating text mode features when only a
+ framebuffer is available.
config VGA_ALLOCATE_EXTRA_STACK
depends on BUILD_VGABIOS
diff --git a/vgasrc/cbvga.c b/vgasrc/cbvga.c
index a9c6d3a..3acc839 100644
--- a/vgasrc/cbvga.c
+++ b/vgasrc/cbvga.c
@@ -14,12 +14,15 @@
static int CBmode VAR16;
static struct vgamode_s CBmodeinfo VAR16;
+static struct vgamode_s CBemulinfo VAR16;
static u32 CBlinelength VAR16;
struct vgamode_s *cbvga_find_mode(int mode)
{
if (mode == GET_GLOBAL(CBmode))
return &CBmodeinfo;
+ if (mode == 0x03)
+ return &CBemulinfo;
return NULL;
}
@@ -92,6 +95,8 @@ cbvga_save_restore(int cmd, u16 seg, void *data)
int
cbvga_set_mode(struct vgamode_s *vmode_g, int flags)
{
+ MASK_BDA_EXT(flags, BF_EMULATE_TEXT
+ , (vmode_g == &CBemulinfo) ? BF_EMULATE_TEXT : 0);
if (!(flags & MF_NOCLEARMEM)) {
if (GET_GLOBAL(CBmodeinfo.memmodel) == MM_TEXT) {
memset16_far(SEG_CTEXT, (void*)0, 0x0720, 80*25*2);
@@ -181,9 +186,8 @@ cbvga_setup(void)
SET_VGA(CBmodeinfo.depth, bpp);
SET_VGA(CBmodeinfo.cwidth, 8);
SET_VGA(CBmodeinfo.cheight, 16);
-
- // Setup BDA and clear screen.
- vga_set_mode(GET_GLOBAL(CBmode), 0);
+ memcpy_far(get_global_seg(), &CBemulinfo
+ , get_global_seg(), &CBmodeinfo, sizeof(CBemulinfo));
return 0;
}
diff --git a/vgasrc/vbe.c b/vgasrc/vbe.c
index e2aeced..af3d0cc 100644
--- a/vgasrc/vbe.c
+++ b/vgasrc/vbe.c
@@ -381,9 +381,8 @@ vbe_104f10(struct bregs *regs)
case 0x00:
regs->bx = 0x0f30;
break;
- case 0x01: ;
- u8 flags = GET_BDA_EXT(flags);
- SET_BDA_EXT(flags, (flags & ~BF_PM_MASK) | (regs->bh & BF_PM_MASK));
+ case 0x01:
+ MASK_BDA_EXT(flags, BF_PM_MASK, regs->bh & BF_PM_MASK);
break;
case 0x02:
regs->bh = GET_BDA_EXT(flags) & BF_PM_MASK;
diff --git a/vgasrc/vgabios.h b/vgasrc/vgabios.h
index d06ebb4..344b3d9 100644
--- a/vgasrc/vgabios.h
+++ b/vgasrc/vgabios.h
@@ -1,6 +1,7 @@
#ifndef __VGABIOS_H
#define __VGABIOS_H
+#include "config.h" // CONFIG_VGA_EMULATE_TEXT
#include "types.h" // u8
#include "farptr.h" // struct segoff_s
#include "std/vga.h" // struct video_param_s
@@ -70,12 +71,19 @@ struct vga_bda_s {
u16 vgamode_offset;
} PACKED;
-#define BF_PM_MASK 0x0f
+#define BF_PM_MASK 0x0f
+#define BF_EMULATE_TEXT 0x10
#define GET_BDA_EXT(var) \
GET_FARVAR(SEG_BDA, ((struct vga_bda_s *)VGA_CUSTOM_BDA)->var)
#define SET_BDA_EXT(var, val) \
SET_FARVAR(SEG_BDA, ((struct vga_bda_s *)VGA_CUSTOM_BDA)->var, (val))
+#define MASK_BDA_EXT(var, off, on) \
+ SET_BDA_EXT(var, (GET_BDA_EXT(var) & ~(off)) | (on))
+
+static inline int vga_emulate_text(void) {
+ return CONFIG_VGA_EMULATE_TEXT && GET_BDA_EXT(flags) & BF_EMULATE_TEXT;
+}
// Debug settings
#define DEBUG_VGA_POST 1
diff --git a/vgasrc/vgafb.c b/vgasrc/vgafb.c
index bb27660..e6a4a4c 100644
--- a/vgasrc/vgafb.c
+++ b/vgasrc/vgafb.c
@@ -380,6 +380,8 @@ gfx_clear_chars(struct vgamode_s *vmode_g, struct cursorpos dest
op.y = dest.y * cheight;
op.ylen = clearsize.y * cheight;
op.pixels[0] = ca.attr;
+ if (vga_emulate_text())
+ op.pixels[0] = ca.attr >> 4;
op.op = GO_MEMSET;
handle_gfx_op(&op);
}
@@ -414,7 +416,25 @@ gfx_write_char(struct vgamode_s *vmode_g
op.x = cp.x * 8;
int cheight = GET_BDA(char_height);
op.y = cp.y * cheight;
- int usexor = ca.attr & 0x80 && GET_GLOBAL(vmode_g->depth) < 8;
+ u8 fgattr = ca.attr, bgattr = 0x00;
+ int usexor = 0;
+ if (vga_emulate_text()) {
+ if (ca.use_attr) {
+ bgattr = fgattr >> 4;
+ fgattr = fgattr & 0x0f;
+ } else {
+ // Read bottom right pixel of the cell to guess bg color
+ op.op = GO_READ8;
+ op.y += cheight-1;
+ handle_gfx_op(&op);
+ op.y -= cheight-1;
+ bgattr = op.pixels[7];
+ fgattr = bgattr ^ 0x7;
+ }
+ } else if (fgattr & 0x80 && GET_GLOBAL(vmode_g->depth) < 8) {
+ usexor = 1;
+ fgattr &= 0x7f;
+ }
int i;
for (i = 0; i < cheight; i++, op.y++) {
u8 fontline = GET_FARVAR(font.seg, *(u8*)(font.offset+i));
@@ -423,11 +443,11 @@ gfx_write_char(struct vgamode_s *vmode_g
handle_gfx_op(&op);
int j;
for (j = 0; j < 8; j++)
- op.pixels[j] ^= (fontline & (0x80>>j)) ? (ca.attr & 0x7f) : 0x00;
+ op.pixels[j] ^= (fontline & (0x80>>j)) ? fgattr : 0x00;
} else {
int j;
for (j = 0; j < 8; j++)
- op.pixels[j] = (fontline & (0x80>>j)) ? ca.attr : 0x00;
+ op.pixels[j] = (fontline & (0x80>>j)) ? fgattr : bgattr;
}
op.op = GO_WRITE8;
handle_gfx_op(&op);