diff --git a/libc/vga/tty.c b/libc/vga/tty.c index 76d6c7f96..84bac011f 100644 --- a/libc/vga/tty.c +++ b/libc/vga/tty.c @@ -93,7 +93,7 @@ static wchar_t *Wcs(struct Tty *tty) void _StartTty(struct Tty *tty, unsigned short yn, unsigned short xn, unsigned short starty, unsigned short startx, - void *vccs, wchar_t *wcs) { + unsigned char chr_ht, void *vccs, wchar_t *wcs) { struct VgaTextCharCell *ccs = vccs; memset(tty, 0, sizeof(struct Tty)); SetYn(tty, yn); @@ -103,8 +103,11 @@ void _StartTty(struct Tty *tty, unsigned short yn, unsigned short xn, starty = yn - 1; if (startx >= xn) startx = xn - 1; + if (chr_ht > 32) + chr_ht = 32; tty->y = starty; tty->x = startx; + tty->chr_ht = chr_ht; if (SetWcs(tty, wcs)) { size_t n = (size_t)yn * xn, 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) { + unsigned char start = tty->chr_ht - 2, end = tty->chr_ht - 1; 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, 0x0f); + outb(CRTPORT, 0x0F); outb(CRTPORT + 1, (unsigned char)pos); } diff --git a/libc/vga/vga.internal.h b/libc/vga/vga.internal.h index 134303139..fe2b8a921 100644 --- a/libc/vga/vga.internal.h +++ b/libc/vga/vga.internal.h @@ -109,7 +109,7 @@ struct Tty { uint32_t u8; uint32_t n8; uint32_t pr; - uint8_t fg, bg; + uint8_t fg, bg, chr_ht; uint32_t conf; unsigned short savey, savex; struct VgaTextCharCell *ccs; @@ -134,7 +134,8 @@ struct Tty { }; 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 _TtyWrite(struct Tty *, const void *, size_t); ssize_t _TtyWriteInput(struct Tty *, const void *, size_t); diff --git a/libc/vga/writev-vga.c b/libc/vga/writev-vga.c index 854596441..6df7f93c8 100644 --- a/libc/vga/writev-vga.c +++ b/libc/vga/writev-vga.c @@ -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) { 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 { unsigned char col, row; } bios_curs_pos_t; 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 - * cursor position. + * Initialize our tty structure from the current screen contents, current + * cursor position, & character height. */ _StartTty(&vga_tty, VGA_TTY_HEIGHT, VGA_TTY_WIDTH, pos.row, pos.col, - vid_buf, vga_wcs); + chr_ht, vid_buf, vga_wcs); }