mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-08-09 03:10:27 +00:00
Bare metal VGA: pass video mode information via struct mman
This should hopefully help us adapt the VGA console code, to work with video modes other than 80 × 25 × 16 text.
This commit is contained in:
parent
8089876c51
commit
388c4f6060
5 changed files with 43 additions and 24 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue