From: Kevin O'Connor Date: Sat, 30 Nov 2013 15:52:45 +0000 (-0500) Subject: vgabios: Support custom fonts in vga framebuffer text writing. X-Git-Tag: rel-1.7.4~21 X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=1f31f00e9672f555025ce3d2878d93fe001de55b;p=seabios.git vgabios: Support custom fonts in vga framebuffer text writing. Obtain the font data from int 0x43 and int 0x1f, and obtain the font height from the BDA. This enables application overrides for the font data. This patch also unifies the variable naming between the planar/CGA/linear character writing functions and uses the same names that the screen scrolling functions use. This patch also optimizes the inner loop of the CGA font writing to reduce overall stack usage. Signed-off-by: Kevin O'Connor --- diff --git a/vgasrc/vgafb.c b/vgasrc/vgafb.c index 815d54b..2efaab5 100644 --- a/vgasrc/vgafb.c +++ b/vgasrc/vgafb.c @@ -43,7 +43,7 @@ static void scroll_pl4(struct vgamode_s *vmode_g, int nblines, int attr , struct cursorpos ul, struct cursorpos lr) { - int cheight = GET_GLOBAL(vmode_g->cheight); + int cheight = GET_BDA(char_height); int cwidth = 1; int stride = GET_BDA(video_cols) * cwidth; void *src_far, *dest_far; @@ -79,7 +79,7 @@ static void scroll_cga(struct vgamode_s *vmode_g, int nblines, int attr , struct cursorpos ul, struct cursorpos lr) { - int cheight = GET_GLOBAL(vmode_g->cheight) / 2; + int cheight = GET_BDA(char_height) / 2; int cwidth = GET_GLOBAL(vmode_g->depth); int stride = GET_BDA(video_cols) * cwidth; void *src_far, *dest_far; @@ -117,7 +117,7 @@ static void scroll_lin(struct vgamode_s *vmode_g, int nblines, int attr , struct cursorpos ul, struct cursorpos lr) { - int cheight = 8; + int cheight = GET_BDA(char_height); int cwidth = 8; int stride = GET_BDA(video_cols) * cwidth; void *src_far, *dest_far; @@ -206,6 +206,21 @@ vgafb_scroll(int nblines, int attr, struct cursorpos ul, struct cursorpos lr) * Read/write characters to screen ****************************************************************/ +static struct segoff_s +get_font_data(u8 c) +{ + int char_height = GET_BDA(char_height); + struct segoff_s font; + if (char_height == 8 && c >= 128) { + font = GET_IVT(0x1f); + c -= 128; + } else { + font = GET_IVT(0x43); + } + font.offset += c * char_height; + return font; +} + static void write_gfx_char_pl4(struct vgamode_s *vmode_g , struct cursorpos cp, struct carattr ca) @@ -214,28 +229,20 @@ write_gfx_char_pl4(struct vgamode_s *vmode_g if (cp.x >= nbcols) return; - u8 cheight = GET_GLOBAL(vmode_g->cheight); - u8 *fdata_g; - switch (cheight) { - case 14: - fdata_g = vgafont14; - break; - case 16: - fdata_g = vgafont16; - break; - default: - fdata_g = vgafont8; - } - u16 addr = cp.x + cp.y * cheight * nbcols; - u16 src = ca.car * cheight; + struct segoff_s font = get_font_data(ca.car); + int cheight = GET_BDA(char_height); + int cwidth = 1; + int stride = nbcols * cwidth; + int addr = cp.y * cheight * stride + cp.x * cwidth; int i; for (i=0; i<4; i++) { stdvga_planar4_plane(i); u8 colors = ((ca.attr & (1<= nbcols) return; - u8 *fdata_g = vgafont8; - u8 bpp = GET_GLOBAL(vmode_g->depth); - u16 addr = (cp.x * bpp) + cp.y * 320; - u16 src = ca.car * 8; - u8 i; - for (i = 0; i < 8; i++) { - u8 *dest_far = (void*)(addr + (i >> 1) * 80); + struct segoff_s font = get_font_data(ca.car); + int cheight = GET_BDA(char_height) / 2; + int cwidth = GET_GLOBAL(vmode_g->depth); + int stride = nbcols * cwidth; + int addr = cp.y * cheight * stride + cp.x * cwidth; + int i; + for (i = 0; i < cheight*2; i++) { + u8 *dest_far = (void*)(addr + (i >> 1) * stride); if (i & 1) dest_far += 0x2000; - if (bpp == 1) { + u8 fontline = GET_FARVAR(font.seg, *(u8*)(font.offset+i)); + if (cwidth == 1) { u8 colors = (ca.attr & 0x01) ? 0xff : 0x00; - u8 pixels = colors & GET_GLOBAL(fdata_g[src + i]); + u8 pixels = colors & fontline; if (ca.attr & 0x80) pixels ^= GET_FARVAR(SEG_GRAPH, *dest_far); SET_FARVAR(SEG_CTEXT, *dest_far, pixels); } else { - u16 pixels = 0; - u8 fontline = GET_GLOBAL(fdata_g[src + i]); - int j; - for (j = 0; j < 8; j++) - if (fontline & (1<= nbcols) return; - u8 *fdata_g = vgafont8; - u16 addr = cp.x * 8 + cp.y * nbcols * 64; - u16 src = ca.car * 8; - u8 i; - for (i = 0; i < 8; i++) { - u8 *dest_far = (void*)(addr + i * nbcols * 8); - u8 fontline = GET_GLOBAL(fdata_g[src + i]); - u8 j; + struct segoff_s font = get_font_data(ca.car); + int cheight = GET_BDA(char_height); + int cwidth = 8; + int stride = nbcols * cwidth; + int addr = cp.y * cheight * stride + cp.x * cwidth; + int i; + for (i = 0; i < cheight; i++) { + u8 *dest_far = (void*)(addr + i * stride); + u8 fontline = GET_FARVAR(font.seg, *(u8*)(font.offset+i)); + int j; for (j = 0; j < 8; j++) { u8 pixel = (fontline & (0x80>>j)) ? ca.attr : 0x00; SET_FARVAR(SEG_GRAPH, dest_far[j], pixel); @@ -310,16 +321,16 @@ static void write_text_char(struct vgamode_s *vmode_g , struct cursorpos cp, struct carattr ca) { - // Compute the address - u16 nbcols = GET_BDA(video_cols); - void *address_far = (void*)(GET_BDA(video_pagesize) * cp.page - + (cp.x + cp.y * nbcols) * 2); - + int cheight = 1; + int cwidth = 2; + int stride = GET_BDA(video_cols) * cwidth; + int addr = cp.y * cheight * stride + cp.x * cwidth; + void *dest_far = (void*)(GET_BDA(video_pagesize) * cp.page + addr); if (ca.use_attr) { u16 dummy = (ca.attr << 8) | ca.car; - SET_FARVAR(GET_GLOBAL(vmode_g->sstart), *(u16*)address_far, dummy); + SET_FARVAR(GET_GLOBAL(vmode_g->sstart), *(u16*)dest_far, dummy); } else { - SET_FARVAR(GET_GLOBAL(vmode_g->sstart), *(u8*)address_far, ca.car); + SET_FARVAR(GET_GLOBAL(vmode_g->sstart), *(u8*)dest_far, ca.car); } } @@ -366,10 +377,12 @@ vgafb_read_char(struct cursorpos cp) } // Compute the address - u16 nbcols = GET_BDA(video_cols); - u16 *address_far = (void*)(GET_BDA(video_pagesize) * cp.page - + (cp.x + cp.y * nbcols) * 2); - u16 v = GET_FARVAR(GET_GLOBAL(vmode_g->sstart), *address_far); + int cheight = 1; + int cwidth = 2; + int stride = GET_BDA(video_cols) * cwidth; + int addr = cp.y * cheight * stride + cp.x * cwidth; + u16 *src_far = (void*)(GET_BDA(video_pagesize) * cp.page + addr); + u16 v = GET_FARVAR(GET_GLOBAL(vmode_g->sstart), *src_far); struct carattr ca = {v, v>>8, 0}; return ca;