diff options
author | Kevin O'Connor <kevin@koconnor.net> | 2014-10-30 12:09:19 -0400 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2014-11-12 12:17:57 -0500 |
commit | 6fed307251e2590e9a999af64cf29ff739b034f9 (patch) | |
tree | 64662671047950c5a918be236deaddae1cef6fb8 /vgasrc | |
parent | 09ae7f1b59a18f3b051cc0934efcd09d70fa6171 (diff) | |
download | seabios-6fed307251e2590e9a999af64cf29ff739b034f9.tar.gz |
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/Kconfig | 6 | ||||
-rw-r--r-- | vgasrc/cbvga.c | 10 | ||||
-rw-r--r-- | vgasrc/vbe.c | 5 | ||||
-rw-r--r-- | vgasrc/vgabios.h | 10 | ||||
-rw-r--r-- | vgasrc/vgafb.c | 26 |
5 files changed, 47 insertions, 10 deletions
diff --git a/vgasrc/Kconfig b/vgasrc/Kconfig index 951240cb..400e8da6 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 a9c6d3a7..3acc8398 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 e2aeced9..af3d0ccb 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 d06ebb4c..344b3d9e 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 bb27660f..e6a4a4c7 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); |