diff --git a/libc/intrin/mman.greg.c b/libc/intrin/mman.greg.c index c9f54e3e7..b8f87c165 100644 --- a/libc/intrin/mman.greg.c +++ b/libc/intrin/mman.greg.c @@ -163,6 +163,12 @@ noasan textreal void __setup_mman(struct mman *mm, uint64_t *pml4t) { export_offsetof(struct mman, e820); export_offsetof(struct mman, e820_end); export_offsetof(struct mman, bad_idt); + export_offsetof(struct mman, pc_video_type); + export_offsetof(struct mman, pc_video_stride); + export_offsetof(struct mman, pc_video_width); + export_offsetof(struct mman, pc_video_height); + export_offsetof(struct mman, pc_video_framebuffer); + export_offsetof(struct mman, pc_video_framebuffer_size); __normalize_e820(mm); __invert_memory(mm, pml4t); } diff --git a/libc/runtime/mman.internal.h b/libc/runtime/mman.internal.h index 5a9e2b642..0af3bb84e 100644 --- a/libc/runtime/mman.internal.h +++ b/libc/runtime/mman.internal.h @@ -18,8 +18,26 @@ struct mman { unsigned char pc_drive_last_head; /* 0x1d21 */ unsigned char pc_drive; /* 0x1d22 */ char bad_idt[6]; /* 0x1d23 */ + unsigned char pc_video_type; /* 0x1d29 */ + unsigned short pc_video_stride; /* 0x1d2a — line width, including any + invisible "pixels" — in + bytes (NOTE) */ + unsigned short pc_video_width; /* 0x1d2c — width in chars. (text) + or pixels (graphics) */ + unsigned short pc_video_height; /* 0x1d2e — height in chars. (text) + or pixels (graphics) */ + uint32_t pc_video_framebuffer; /* 0x1d30 */ + uint32_t pc_video_framebuffer_size; /* 0x1d34 */ }; COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ + +/* Values for mman::pc_video_type. TODO: implement graphics modes. */ +#define PC_VIDEO_TEXT 0 +#define PC_VIDEO_BGR565 1 +#define PC_VIDEO_BGR555 2 +#define PC_VIDEO_BGRX8888 3 +#define PC_VIDEO_RGBX8888 4 + #endif /* COSMOPOLITAN_LIBC_RUNTIME_MMAN_H_ */ diff --git a/libc/vga/rlinit-vga.S b/libc/vga/rlinit-vga.S index 7e332a5d7..914b2a4fa 100644 --- a/libc/vga/rlinit-vga.S +++ b/libc/vga/rlinit-vga.S @@ -25,6 +25,7 @@ │ OTHER DEALINGS IN THE SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" +#include "libc/runtime/mman.internal.h" #include "libc/vga/vga.internal.h" // Code snippet for initializing the VGA video mode for bare metal. @@ -58,6 +59,13 @@ mov $0x0500,%ax # just make sure we are on display # page 0 2: int $0x10 # otherwise, change the video mode + .set mm,0x0500 # note down video mode parameters + movb $PC_VIDEO_TEXT,mm+"struct mman::pc_video_type" + movw $160,mm+"struct mman::pc_video_stride" + movw $80,mm+"struct mman::pc_video_width" + movw $25,mm+"struct mman::pc_video_height" + movl $0xb8000,mm+"struct mman::pc_video_framebuffer" + movl $0x8000,mm+"struct mman::pc_video_framebuffer_size" mov $0x1003,%ax # enable/disable VGA text blinking #ifdef VGA_USE_BLINK mov $1,%bx diff --git a/libc/vga/vga.internal.h b/libc/vga/vga.internal.h index 2d4e06e9f..ca19d1508 100644 --- a/libc/vga/vga.internal.h +++ b/libc/vga/vga.internal.h @@ -2,21 +2,11 @@ #define COSMOPOLITAN_LIBC_VGA_VGA_INTERNAL_H_ /* - * VGA_TTY_HEIGHT, VGA_TTY_WIDTH, VGA_USE_WCS, & VGA_PERSNICKETY_STATUS are - * configuration knobs which can potentially be used to tweak the features - * to be compiled into our VGA teletypewriter support. + * VGA_USE_WCS, VGA_USE_BLINK, & VGA_PERSNICKETY_STATUS are configuration + * knobs which can potentially be used to tweak the features to be compiled + * into our VGA teletypewriter support. */ -/** - * Height of the video screen, in character units. Undefine if the height - * may vary at runtime. - */ -#define VGA_TTY_HEIGHT 25 -/** - * Width of the video screen, in character units. Undefine if the width may - * vary at runtime. - */ -#define VGA_TTY_WIDTH 80 /** * If VGA_USE_WCS is defined, the tty code can maintain an array of the * Unicode characters "underlying" the 8-bit (or 9-bit) characters that are @@ -114,12 +104,7 @@ struct VgaTextCharCell { struct Tty { unsigned short y, x; -#ifndef VGA_TTY_HEIGHT - unsigned short yn; -#endif -#ifndef VGA_TTY_WIDTH - unsigned short xn; -#endif + unsigned short yn, xn; uint32_t u8; uint32_t n8; uint32_t pr; diff --git a/libc/vga/writev-vga.c b/libc/vga/writev-vga.c index 0bb14c9fc..4eb6650c2 100644 --- a/libc/vga/writev-vga.c +++ b/libc/vga/writev-vga.c @@ -61,7 +61,9 @@ ssize_t sys_writev_vga(struct Fd *fd, const struct iovec *iov, int iovlen) { __attribute__((__constructor__)) static textstartup void _vga_init(void) { if (IsMetal()) { struct mman *mm = (struct mman *)(BANE + 0x0500); - void * const vid_buf = (void *)(BANE + 0xb8000ull); + unsigned short height = mm->pc_video_height, width = mm->pc_video_width; + void * vid_buf = (void *)(BANE + mm->pc_video_framebuffer); + 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 @@ -76,13 +78,13 @@ __attribute__((__constructor__)) static textstartup void _vga_init(void) { if (chr_ht_hi != 0 || chr_ht > 32) chr_ht = 32; /* Make sure the video buffer is mapped into virtual memory. */ - __invert_memory_area(mm, __get_pml4t(), (uint64_t)vid_buf, - 2 * VGA_TTY_HEIGHT * VGA_TTY_WIDTH, PAGE_RW); + __invert_memory_area(mm, __get_pml4t(), (uint64_t)vid_buf, vid_buf_sz, + PAGE_RW); /* * 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, - chr_ht, vid_buf, vga_wcs); + _StartTty(&_vga_tty, height, width, pos.row, pos.col, chr_ht, + vid_buf, vga_wcs); } }