From 55b8af325061bbe3b6e589a968a05207c94d825f Mon Sep 17 00:00:00 2001 From: tkchia Date: Thu, 15 Sep 2022 05:44:22 +0000 Subject: [PATCH] Bare metal VGA: fix mapping of ECMA-48 colors to VGA colors See https://github.com/jart/cosmopolitan/pull/613#issuecomment-1247490693 --- libc/vga/tty.c | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/libc/vga/tty.c b/libc/vga/tty.c index 722bd3fab..b15e027eb 100644 --- a/libc/vga/tty.c +++ b/libc/vga/tty.c @@ -605,6 +605,36 @@ static void TtyCsiN(struct Tty *tty) { } } +/** + * Map the given ECMA-48 / VT100 SGR color code to a color code for a VGA + * character attribute. More precisely, map + * + * red──┐ + * green─┐│ + * blue┐││ + * intensity│││ + * ││││ + * 3210 + * + * to + * + * blue──┐ + * green─┐│ + * red┐││ + * intensity│││ + * ││││ + * 3210 + */ +static uint8_t TtyMapEcma48Color(uint8_t color) +{ + switch (color & 0b101) { + case 0b100: + case 0b001: + color ^= 0b101; + } + return color; +} + /** * Map the given (R, G, B) triplet to one of the 16 basic foreground colors * or one of the 16 background colors. @@ -765,7 +795,7 @@ static void TtySelectGraphicsRendition(struct Tty *tty) { code[0] += 8; /* fallthrough */ case 30 ... 37: - tty->fg = code[0] - 30; + tty->fg = TtyMapEcma48Color(code[0] - 30); tty->pr |= kTtyFg; tty->pr &= ~kTtyTrue; break; @@ -774,7 +804,7 @@ static void TtySelectGraphicsRendition(struct Tty *tty) { code[0] += 8; /* fallthrough */ case 40 ... 47: - tty->bg = code[0] - 40; + tty->bg = TtyMapEcma48Color(code[0] - 40); tty->pr |= kTtyBg; tty->pr &= ~kTtyTrue; break;