aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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);