diff --git a/libc/intrin/mman.greg.c b/libc/intrin/mman.greg.c index b8f87c165..2dad09c1f 100644 --- a/libc/intrin/mman.greg.c +++ b/libc/intrin/mman.greg.c @@ -169,6 +169,8 @@ noasan textreal void __setup_mman(struct mman *mm, uint64_t *pml4t) { export_offsetof(struct mman, pc_video_height); export_offsetof(struct mman, pc_video_framebuffer); export_offsetof(struct mman, pc_video_framebuffer_size); + export_offsetof(struct mman, pc_video_curs_info); + export_offsetof(struct mman, pc_video_char_height); __normalize_e820(mm); __invert_memory(mm, pml4t); } diff --git a/libc/runtime/mman.internal.h b/libc/runtime/mman.internal.h index 9f96ed695..2488a4ac2 100644 --- a/libc/runtime/mman.internal.h +++ b/libc/runtime/mman.internal.h @@ -29,6 +29,12 @@ struct mman { uint64_t pc_video_framebuffer; /* 0x1d30 — physical address of video frame buffer */ uint64_t pc_video_framebuffer_size; /* 0x1d38 */ + struct { /* 0x1d40 — starting cursor pos. */ + unsigned short y, x; + } pc_video_curs_info; + unsigned short pc_video_char_height; /* 0x1d44 — character height (useful + for setting cursor shape + in text mode) */ }; COSMOPOLITAN_C_END_ diff --git a/libc/vga/rlinit-vga.S b/libc/vga/rlinit-vga.S index ed74f4fe3..6d4962bec 100644 --- a/libc/vga/rlinit-vga.S +++ b/libc/vga/rlinit-vga.S @@ -78,7 +78,13 @@ xor %bx,%bx #endif int $0x10 -9: +9: mov 0x0450,%dx # note down cursor position + movzbw %dh,%ax + mov %ax,mm+"struct mman::pc_video_curs_info" + mov %dl,%al + mov %ax,mm+"struct mman::pc_video_curs_info"+2 + mov 0x0486,%ax # ...& character height + mov %ax,mm+"struct mman::pc_video_char_height" .previous .code64 .section .rodata,"a",@progbits diff --git a/libc/vga/vga-init.c b/libc/vga/vga-init.c index 347c6e826..2434c7a33 100644 --- a/libc/vga/vga-init.c +++ b/libc/vga/vga-init.c @@ -40,21 +40,15 @@ __attribute__((__constructor__)) static textstartup void _vga_init(void) { uint64_t vid_buf_phy = mm->pc_video_framebuffer; void *vid_buf = (void *)(BANE + vid_buf_phy); size_t vid_buf_sz = mm->pc_video_framebuffer_size; - /* - * 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, chr_ht_hi, chr_wid; + unsigned short starty = mm->pc_video_curs_info.y, + startx = mm->pc_video_curs_info.x; + uint8_t chr_ht, chr_wid; if (vid_type == PC_VIDEO_TEXT) { - chr_ht = *(uint8_t *)(BANE + 0x0485ull), - chr_ht_hi = *(uint8_t *)(BANE + 0x0486ull); - if (chr_ht_hi != 0 || chr_ht > 32 || chr_ht < 2) + unsigned short chr_ht_val = mm->pc_video_char_height; + if (chr_ht_val > 32 || chr_ht_val < 2) chr_ht = VGA_ASSUME_CHAR_HEIGHT_PX; + else + chr_ht = chr_ht_val; } else chr_ht = VGA_ASSUME_CHAR_HEIGHT_PX; chr_wid = VGA_ASSUME_CHAR_WIDTH_PX; @@ -64,7 +58,7 @@ __attribute__((__constructor__)) static textstartup void _vga_init(void) { * Initialize our tty structure from the current screen geometry, * screen contents, cursor position, & character dimensions. */ - _StartTty(&_vga_tty, vid_type, height, width, stride, pos.row, pos.col, + _StartTty(&_vga_tty, vid_type, height, width, stride, starty, startx, chr_ht, chr_wid, vid_buf, false); } }