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);
|
||||||
export_offsetof(struct mman, e820_end);
|
export_offsetof(struct mman, e820_end);
|
||||||
export_offsetof(struct mman, bad_idt);
|
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);
|
__normalize_e820(mm);
|
||||||
__invert_memory(mm, pml4t);
|
__invert_memory(mm, pml4t);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,26 @@ struct mman {
|
||||||
unsigned char pc_drive_last_head; /* 0x1d21 */
|
unsigned char pc_drive_last_head; /* 0x1d21 */
|
||||||
unsigned char pc_drive; /* 0x1d22 */
|
unsigned char pc_drive; /* 0x1d22 */
|
||||||
char bad_idt[6]; /* 0x1d23 */
|
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_
|
COSMOPOLITAN_C_END_
|
||||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
#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_ */
|
#endif /* COSMOPOLITAN_LIBC_RUNTIME_MMAN_H_ */
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
│ OTHER DEALINGS IN THE SOFTWARE. │
|
│ OTHER DEALINGS IN THE SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
|
#include "libc/runtime/mman.internal.h"
|
||||||
#include "libc/vga/vga.internal.h"
|
#include "libc/vga/vga.internal.h"
|
||||||
|
|
||||||
// Code snippet for initializing the VGA video mode for bare metal.
|
// 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
|
mov $0x0500,%ax # just make sure we are on display
|
||||||
# page 0
|
# page 0
|
||||||
2: int $0x10 # otherwise, change the video mode
|
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
|
mov $0x1003,%ax # enable/disable VGA text blinking
|
||||||
#ifdef VGA_USE_BLINK
|
#ifdef VGA_USE_BLINK
|
||||||
mov $1,%bx
|
mov $1,%bx
|
||||||
|
|
|
@ -2,21 +2,11 @@
|
||||||
#define COSMOPOLITAN_LIBC_VGA_VGA_INTERNAL_H_
|
#define COSMOPOLITAN_LIBC_VGA_VGA_INTERNAL_H_
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* VGA_TTY_HEIGHT, VGA_TTY_WIDTH, VGA_USE_WCS, & VGA_PERSNICKETY_STATUS are
|
* VGA_USE_WCS, VGA_USE_BLINK, & VGA_PERSNICKETY_STATUS are configuration
|
||||||
* configuration knobs which can potentially be used to tweak the features
|
* knobs which can potentially be used to tweak the features to be compiled
|
||||||
* to be compiled into our VGA teletypewriter support.
|
* 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
|
* 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
|
* Unicode characters "underlying" the 8-bit (or 9-bit) characters that are
|
||||||
|
@ -114,12 +104,7 @@ struct VgaTextCharCell {
|
||||||
|
|
||||||
struct Tty {
|
struct Tty {
|
||||||
unsigned short y, x;
|
unsigned short y, x;
|
||||||
#ifndef VGA_TTY_HEIGHT
|
unsigned short yn, xn;
|
||||||
unsigned short yn;
|
|
||||||
#endif
|
|
||||||
#ifndef VGA_TTY_WIDTH
|
|
||||||
unsigned short xn;
|
|
||||||
#endif
|
|
||||||
uint32_t u8;
|
uint32_t u8;
|
||||||
uint32_t n8;
|
uint32_t n8;
|
||||||
uint32_t pr;
|
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) {
|
__attribute__((__constructor__)) static textstartup void _vga_init(void) {
|
||||||
if (IsMetal()) {
|
if (IsMetal()) {
|
||||||
struct mman *mm = (struct mman *)(BANE + 0x0500);
|
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
|
* 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
|
* 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)
|
if (chr_ht_hi != 0 || chr_ht > 32)
|
||||||
chr_ht = 32;
|
chr_ht = 32;
|
||||||
/* Make sure the video buffer is mapped into virtual memory. */
|
/* Make sure the video buffer is mapped into virtual memory. */
|
||||||
__invert_memory_area(mm, __get_pml4t(), (uint64_t)vid_buf,
|
__invert_memory_area(mm, __get_pml4t(), (uint64_t)vid_buf, vid_buf_sz,
|
||||||
2 * VGA_TTY_HEIGHT * VGA_TTY_WIDTH, PAGE_RW);
|
PAGE_RW);
|
||||||
/*
|
/*
|
||||||
* Initialize our tty structure from the current screen contents,
|
* Initialize our tty structure from the current screen contents,
|
||||||
* current cursor position, & character height.
|
* current cursor position, & character height.
|
||||||
*/
|
*/
|
||||||
_StartTty(&_vga_tty, VGA_TTY_HEIGHT, VGA_TTY_WIDTH, pos.row, pos.col,
|
_StartTty(&_vga_tty, height, width, pos.row, pos.col, chr_ht,
|
||||||
chr_ht, vid_buf, vga_wcs);
|
vid_buf, vga_wcs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue