From 26712247add19a54d4671f2c0e50234905c2c608 Mon Sep 17 00:00:00 2001 From: tkchia Date: Sat, 10 Sep 2022 06:18:43 +0000 Subject: [PATCH] Bare metal VGA: simplify treatment of background color codes --- libc/vga/tty.c | 76 +++++++++++++++++++++++--------------------------- 1 file changed, 35 insertions(+), 41 deletions(-) diff --git a/libc/vga/tty.c b/libc/vga/tty.c index 84bac011f..3094c9db6 100644 --- a/libc/vga/tty.c +++ b/libc/vga/tty.c @@ -261,15 +261,29 @@ static void TtySetCodepage(struct Tty *tty, char id) { } } +/** + * Map the currently active foreground & background colors & terminal + * configuration to a VGA text character attribute byte. + * + * @see VGA_USE_BLINK macro (libc/vga/vga.internal.h) + * @see drivers/tty/vt/vt.c in Linux 5.9.14 source code + */ static uint8_t TtyGetVgaAttr(struct Tty *tty) { uint8_t attr = tty->fg | tty->bg << 4; - if ((tty->pr & kTtyBold) != 0) - attr |= 0x08; #ifdef VGA_USE_BLINK + /* + * If blinking is enabled, we can only have the 8 dark background color + * codes (0 to 7). Simply map any bright background color (8 to 15) to + * its corresponding dark color, & call it a day. This is a bit more + * simplistic than what Linux does, but should be enough. + */ + attr &= ~0x80; if ((tty->pr & kTtyBlink) != 0) attr |= 0x80; #endif + if ((tty->pr & kTtyBold) != 0) + attr |= 0x08; return attr; } @@ -642,37 +656,23 @@ static void TtyCsiN(struct Tty *tty) { /** * Map the given (R, G, B) triplet to one of the 16 basic foreground colors - * or one of the 8 (or 16) background colors. + * or one of the 16 background colors. * - * @see VGA_USE_BLINK macro (libc/vga/vga.internal.h) * @see drivers/tty/vt/vt.c in Linux 5.9.14 source code */ -static uint8_t TtyMapTrueColor(uint8_t r, uint8_t g, uint8_t b, bool as_fg) +static uint8_t TtyMapTrueColor(uint8_t r, uint8_t g, uint8_t b) { - uint8_t hue = 0; -#ifdef VGA_USE_BLINK - if (!as_fg) { - if (r >= 128) - hue |= 4; - if (g >= 128) - hue |= 2; - if (b >= 128) - hue |= 1; - } else -#endif - { - uint8_t max = MAX(MAX(r, g), b); - if (r > max / 2) - hue |= 4; - if (g > max / 2) - hue |= 2; - if (b > max / 2) - hue |= 1; - if (hue == 7 && max <= 0x55) - hue = 8; - else if (max > 0xaa) - hue |= 8; - } + uint8_t hue = 0, max = MAX(MAX(r, g), b); + if (r > max / 2) + hue |= 4; + if (g > max / 2) + hue |= 2; + if (b > max / 2) + hue |= 1; + if (hue == 7 && max <= 0x55) + hue = 8; + else if (max > 0xaa) + hue |= 8; return hue; } @@ -682,7 +682,7 @@ static uint8_t TtyMapTrueColor(uint8_t r, uint8_t g, uint8_t b, bool as_fg) * * @see drivers/tty/vt/vt.c in Linux 5.9.14 source code */ -static uint8_t TtyMapXtermColor(uint8_t color, bool as_fg) +static uint8_t TtyMapXtermColor(uint8_t color) { uint8_t r, g, b; if (color < 8) { @@ -702,7 +702,7 @@ static uint8_t TtyMapXtermColor(uint8_t color, bool as_fg) r = color * 0x55 / 2; } else r = g = b = (unsigned)color * 10 - 2312; - return TtyMapTrueColor(r, g, b, as_fg); + return TtyMapTrueColor(r, g, b); } static void TtySelectGraphicsRendition(struct Tty *tty) { @@ -825,13 +825,7 @@ static void TtySelectGraphicsRendition(struct Tty *tty) { break; case 100 ... 107: code[0] -= 100 - 40; -#ifndef VGA_USE_BLINK - /* - * If blinking is not enabled in VGA text mode, then we can - * use bright background colors. - */ code[0] += 8; -#endif /* fallthrough */ case 40 ... 47: tty->bg = code[0] - 40; @@ -858,7 +852,7 @@ static void TtySelectGraphicsRendition(struct Tty *tty) { if (++code[3] == 3) { code[3] = 0; t = kSgr; - tty->fg = TtyMapTrueColor(code[0], code[1], code[2], true); + tty->fg = TtyMapTrueColor(code[0], code[1], code[2]); tty->pr |= kTtyFg; tty->pr |= kTtyTrue; } @@ -867,20 +861,20 @@ static void TtySelectGraphicsRendition(struct Tty *tty) { if (++code[3] == 3) { code[3] = 0; t = kSgr; - tty->bg = TtyMapTrueColor(code[0], code[1], code[2], false); + tty->bg = TtyMapTrueColor(code[0], code[1], code[2]); tty->pr |= kTtyBg; tty->pr |= kTtyTrue; } break; case kSgrFgXterm: t = kSgr; - tty->fg = TtyMapXtermColor(code[0], true); + tty->fg = TtyMapXtermColor(code[0]); tty->pr |= kTtyFg; tty->pr &= ~kTtyTrue; break; case kSgrBgXterm: t = kSgr; - tty->bg = TtyMapXtermColor(code[0], false); + tty->bg = TtyMapXtermColor(code[0]); tty->pr |= kTtyBg; tty->pr &= ~kTtyTrue; break;