Bare metal VGA: implement "make cursor invisible" escape sequence

This commit is contained in:
tkchia 2022-09-09 22:36:45 +00:00
parent c3208eb9d5
commit 5886678ad7
3 changed files with 28 additions and 9 deletions

View file

@ -93,7 +93,7 @@ static wchar_t *Wcs(struct Tty *tty)
void _StartTty(struct Tty *tty, unsigned short yn, unsigned short xn, void _StartTty(struct Tty *tty, unsigned short yn, unsigned short xn,
unsigned short starty, unsigned short startx, unsigned short starty, unsigned short startx,
void *vccs, wchar_t *wcs) { unsigned char chr_ht, void *vccs, wchar_t *wcs) {
struct VgaTextCharCell *ccs = vccs; struct VgaTextCharCell *ccs = vccs;
memset(tty, 0, sizeof(struct Tty)); memset(tty, 0, sizeof(struct Tty));
SetYn(tty, yn); SetYn(tty, yn);
@ -103,8 +103,11 @@ void _StartTty(struct Tty *tty, unsigned short yn, unsigned short xn,
starty = yn - 1; starty = yn - 1;
if (startx >= xn) if (startx >= xn)
startx = xn - 1; startx = xn - 1;
if (chr_ht > 32)
chr_ht = 32;
tty->y = starty; tty->y = starty;
tty->x = startx; tty->x = startx;
tty->chr_ht = chr_ht;
if (SetWcs(tty, wcs)) { if (SetWcs(tty, wcs)) {
size_t n = (size_t)yn * xn, i; size_t n = (size_t)yn * xn, i;
for (i = 0; i < n; ++i) for (i = 0; i < n; ++i)
@ -1081,10 +1084,17 @@ static void TtyEscAppend(struct Tty *tty, char c) {
} }
static void TtyUpdateHwCursor(struct Tty *tty) { static void TtyUpdateHwCursor(struct Tty *tty) {
unsigned char start = tty->chr_ht - 2, end = tty->chr_ht - 1;
unsigned short pos = tty->y * Xn(tty) + tty->x; unsigned short pos = tty->y * Xn(tty) + tty->x;
outb(CRTPORT, 0x0e); if ((tty->conf & kTtyNocursor))
start |= 1 << 5;
outb(CRTPORT, 0x0A);
outb(CRTPORT + 1, start);
outb(CRTPORT, 0x0B);
outb(CRTPORT + 1, end);
outb(CRTPORT, 0x0E);
outb(CRTPORT + 1, (unsigned char)(pos >> 8)); outb(CRTPORT + 1, (unsigned char)(pos >> 8));
outb(CRTPORT, 0x0f); outb(CRTPORT, 0x0F);
outb(CRTPORT + 1, (unsigned char)pos); outb(CRTPORT + 1, (unsigned char)pos);
} }

View file

@ -109,7 +109,7 @@ struct Tty {
uint32_t u8; uint32_t u8;
uint32_t n8; uint32_t n8;
uint32_t pr; uint32_t pr;
uint8_t fg, bg; uint8_t fg, bg, chr_ht;
uint32_t conf; uint32_t conf;
unsigned short savey, savex; unsigned short savey, savex;
struct VgaTextCharCell *ccs; struct VgaTextCharCell *ccs;
@ -134,7 +134,8 @@ struct Tty {
}; };
void _StartTty(struct Tty *, unsigned short, unsigned short, void _StartTty(struct Tty *, unsigned short, unsigned short,
unsigned short, unsigned short, void *, wchar_t *); unsigned short, unsigned short, unsigned char,
void *, wchar_t *);
ssize_t _TtyRead(struct Tty *, void *, size_t); ssize_t _TtyRead(struct Tty *, void *, size_t);
ssize_t _TtyWrite(struct Tty *, const void *, size_t); ssize_t _TtyWrite(struct Tty *, const void *, size_t);
ssize_t _TtyWriteInput(struct Tty *, const void *, size_t); ssize_t _TtyWriteInput(struct Tty *, const void *, size_t);

View file

@ -58,15 +58,23 @@ ssize_t sys_writev_vga(struct Fd *fd, const struct iovec *iov, int iovlen) {
__attribute__((__constructor__)) static textstartup void _vga_init(void) { __attribute__((__constructor__)) static textstartup void _vga_init(void) {
void * const vid_buf = (void *)(BANE + 0xb8000ull); void * const vid_buf = (void *)(BANE + 0xb8000ull);
/* Get the initial cursor position from the BIOS data area. */ /*
* Get the initial cursor position from the BIOS data area. Also get
* the height (in scan lines) of each character; this is used to set the
* cursor shape.
*/
typedef struct { typedef struct {
unsigned char col, row; unsigned char col, row;
} bios_curs_pos_t; } bios_curs_pos_t;
bios_curs_pos_t pos = *(bios_curs_pos_t *)(BANE + 0x0450ull); bios_curs_pos_t pos = *(bios_curs_pos_t *)(BANE + 0x0450ull);
uint8_t chr_ht = *(uint8_t *)(BANE + 0x0485ull),
chr_ht_hi = *(uint8_t *)(BANE + 0x0486ull);
if (chr_ht_hi != 0 || chr_ht > 32)
chr_ht = 32;
/* /*
* Initialize our tty structure from the current screen contents & current * Initialize our tty structure from the current screen contents, current
* cursor position. * cursor position, & character height.
*/ */
_StartTty(&vga_tty, VGA_TTY_HEIGHT, VGA_TTY_WIDTH, pos.row, pos.col, _StartTty(&vga_tty, VGA_TTY_HEIGHT, VGA_TTY_WIDTH, pos.row, pos.col,
vid_buf, vga_wcs); chr_ht, vid_buf, vga_wcs);
} }