mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-08-09 11:20:30 +00:00
[metal] Read VGA info from BDA before long mode entry, not after
If using a pre-existing VGA text console, the VGA initialization code now retrieves the cursor position & character height from the BIOS data area while still in real mode — rather than reading from the BIOS data area only after entering long mode. (This should help make the code more correct, if Cosmopolitan were to support UEFI graphics output in the future. If the program were booted via UEFI, then the long mode IsMetal() code would still be activated, but the BIOS data area might not have been initialized in that case.) This change also means that there are now a few more fields in the `struct mman`.
This commit is contained in:
parent
9926ed74f1
commit
7059a7109d
4 changed files with 23 additions and 15 deletions
|
@ -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_height);
|
||||||
export_offsetof(struct mman, pc_video_framebuffer);
|
export_offsetof(struct mman, pc_video_framebuffer);
|
||||||
export_offsetof(struct mman, pc_video_framebuffer_size);
|
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);
|
__normalize_e820(mm);
|
||||||
__invert_memory(mm, pml4t);
|
__invert_memory(mm, pml4t);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,12 @@ struct mman {
|
||||||
uint64_t pc_video_framebuffer; /* 0x1d30 — physical address of
|
uint64_t pc_video_framebuffer; /* 0x1d30 — physical address of
|
||||||
video frame buffer */
|
video frame buffer */
|
||||||
uint64_t pc_video_framebuffer_size; /* 0x1d38 */
|
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_
|
COSMOPOLITAN_C_END_
|
||||||
|
|
|
@ -78,7 +78,13 @@
|
||||||
xor %bx,%bx
|
xor %bx,%bx
|
||||||
#endif
|
#endif
|
||||||
int $0x10
|
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
|
.previous
|
||||||
.code64
|
.code64
|
||||||
.section .rodata,"a",@progbits
|
.section .rodata,"a",@progbits
|
||||||
|
|
|
@ -40,21 +40,15 @@ __attribute__((__constructor__)) static textstartup void _vga_init(void) {
|
||||||
uint64_t vid_buf_phy = mm->pc_video_framebuffer;
|
uint64_t vid_buf_phy = mm->pc_video_framebuffer;
|
||||||
void *vid_buf = (void *)(BANE + vid_buf_phy);
|
void *vid_buf = (void *)(BANE + vid_buf_phy);
|
||||||
size_t vid_buf_sz = mm->pc_video_framebuffer_size;
|
size_t vid_buf_sz = mm->pc_video_framebuffer_size;
|
||||||
/*
|
unsigned short starty = mm->pc_video_curs_info.y,
|
||||||
* Get the initial cursor position from the BIOS data area. Also get
|
startx = mm->pc_video_curs_info.x;
|
||||||
* the height (in scan lines) of each character; this is used to set the
|
uint8_t chr_ht, chr_wid;
|
||||||
* 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;
|
|
||||||
if (vid_type == PC_VIDEO_TEXT) {
|
if (vid_type == PC_VIDEO_TEXT) {
|
||||||
chr_ht = *(uint8_t *)(BANE + 0x0485ull),
|
unsigned short chr_ht_val = mm->pc_video_char_height;
|
||||||
chr_ht_hi = *(uint8_t *)(BANE + 0x0486ull);
|
if (chr_ht_val > 32 || chr_ht_val < 2)
|
||||||
if (chr_ht_hi != 0 || chr_ht > 32 || chr_ht < 2)
|
|
||||||
chr_ht = VGA_ASSUME_CHAR_HEIGHT_PX;
|
chr_ht = VGA_ASSUME_CHAR_HEIGHT_PX;
|
||||||
|
else
|
||||||
|
chr_ht = chr_ht_val;
|
||||||
} else
|
} else
|
||||||
chr_ht = VGA_ASSUME_CHAR_HEIGHT_PX;
|
chr_ht = VGA_ASSUME_CHAR_HEIGHT_PX;
|
||||||
chr_wid = VGA_ASSUME_CHAR_WIDTH_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,
|
* Initialize our tty structure from the current screen geometry,
|
||||||
* screen contents, cursor position, & character dimensions.
|
* 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);
|
chr_ht, chr_wid, vid_buf, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue