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.
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
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;
}
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);
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;
}
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;
#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
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
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);
}
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));
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);