Bare metal VGA: enable bright background colors, disable blinking (#603)

Co-authored-by: tkchia <tkchia-cosmo@gmx.com>
This commit is contained in:
tkchia 2022-09-09 19:35:16 +08:00 committed by GitHub
parent f68151c010
commit 1db76c288e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 64 additions and 9 deletions

View file

@ -263,8 +263,10 @@ static uint8_t TtyGetVgaAttr(struct Tty *tty)
uint8_t attr = tty->fg | tty->bg << 4; uint8_t attr = tty->fg | tty->bg << 4;
if ((tty->pr & kTtyBold) != 0) if ((tty->pr & kTtyBold) != 0)
attr |= 0x08; attr |= 0x08;
#ifdef VGA_USE_BLINK
if ((tty->pr & kTtyBlink) != 0) if ((tty->pr & kTtyBlink) != 0)
attr |= 0x80; attr |= 0x80;
#endif
return attr; return attr;
} }
@ -637,14 +639,25 @@ static void TtyCsiN(struct Tty *tty) {
/** /**
* Map the given (R, G, B) triplet to one of the 16 basic foreground colors * Map the given (R, G, B) triplet to one of the 16 basic foreground colors
* or one of the 8 background colors. * or one of the 8 (or 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 * @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, bool as_fg)
{ {
uint8_t hue = 0; uint8_t hue = 0;
if (as_fg) { #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); uint8_t max = MAX(MAX(r, g), b);
if (r > max / 2) if (r > max / 2)
hue |= 4; hue |= 4;
@ -656,13 +669,6 @@ static uint8_t TtyMapTrueColor(uint8_t r, uint8_t g, uint8_t b, bool as_fg)
hue = 8; hue = 8;
else if (max > 0xaa) else if (max > 0xaa)
hue |= 8; hue |= 8;
} else {
if (r >= 128)
hue |= 4;
if (g >= 128)
hue |= 2;
if (b >= 128)
hue |= 1;
} }
return hue; return hue;
} }
@ -816,6 +822,13 @@ static void TtySelectGraphicsRendition(struct Tty *tty) {
break; break;
case 100 ... 107: case 100 ... 107:
code[0] -= 100 - 40; 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 */ /* fallthrough */
case 40 ... 47: case 40 ... 47:
tty->bg = code[0] - 40; tty->bg = code[0] - 40;

View file

@ -25,6 +25,7 @@
OTHER DEALINGS IN THE SOFTWARE. OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include "libc/macros.internal.h" #include "libc/macros.internal.h"
#include "libc/vga/vga.internal.h"
// Code snippet for initializing the VGA video mode for bare metal. // Code snippet for initializing the VGA video mode for bare metal.
// //
@ -57,6 +58,13 @@
mov $0x0500,%ax # just make sure we are on display mov $0x0500,%ax # just make sure we are on display
# page 0 # page 0
2: int $0x10 # otherwise, change the video mode 2: int $0x10 # otherwise, change the video mode
mov $0x1003,%ax # enable/disable VGA text blinking
#ifdef VGA_USE_BLINK
mov $1,%bx
#else
xor %bx,%bx
#endif
int $0x10
.previous .previous
.code64 .code64
.section .rodata,"a",@progbits .section .rodata,"a",@progbits

View file

@ -26,6 +26,40 @@
* @see lkml.kernel.org/lkml/204888.1529277815@turing-police.cc.vt.edu/T/ * @see lkml.kernel.org/lkml/204888.1529277815@turing-police.cc.vt.edu/T/
*/ */
#undef VGA_USE_WCS #undef VGA_USE_WCS
/**
* The VGA hardware can be configured via the IBM BIOS, or via port I/O
* to either support blinking characters, or support the use of bright
* background colors, but not both. There is a hardware setting that
* controls whether the attribute byte for each plotted character is
* interpreted as
*
* foreground
* foreground intensity
* background
* blinking
*
* 76543210
*
* or as
*
* foreground
* foreground intensity
* background
* background intensity
*
* 76543210
*
* (NOTE: QEMU 6.2.0 does not emulate the VGA blinking feature. However,
* VirtualBox 6.1 does.)
*
* If VGA_USE_BLINK is defined, our VGA code will use the former mode, &
* will support blinking characters. If VGA_USE_BLINK is undefined, the
* VGA code will instead implement bright background colors.
*
* @see Ralf Brown's Interrupt List, int 0x10, ax = 0x1003
* (https://www.delorie.com/djgpp/doc/rbinter/id/22/1.html)
*/
#undef VGA_USE_BLINK
#define kTtyFg 0x0001 #define kTtyFg 0x0001
#define kTtyBg 0x0002 #define kTtyBg 0x0002