terminal-vga: recover vga text mode operation
This commit is contained in:
parent
72968ed85c
commit
8531fe709e
@ -11,9 +11,20 @@
|
||||
* try to move the hardware cursor off screen so it doesn't
|
||||
* interfere with the rest of the terminal and look weird.
|
||||
*/
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/sysfunc.h>
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
int x[] = {0xFF,0xFF};
|
||||
return sysfunc(TOARU_SYS_FUNC_SETVGACURSOR, (char **)x);
|
||||
int fd = open("/dev/port", O_RDWR);
|
||||
if (fd < 0) return 1;
|
||||
lseek(fd, 0x3D4, SEEK_SET);
|
||||
write(fd, (unsigned char[]){14}, 1);
|
||||
lseek(fd, 0x3D5, SEEK_SET);
|
||||
write(fd, (unsigned char[]){0xFF}, 1);
|
||||
lseek(fd, 0x3D4, SEEK_SET);
|
||||
write(fd, (unsigned char[]){15}, 1);
|
||||
lseek(fd, 0x3D5, SEEK_SET);
|
||||
write(fd, (unsigned char[]){0xFF}, 1);
|
||||
return 0;
|
||||
}
|
||||
|
@ -26,6 +26,8 @@
|
||||
|
||||
#include <wchar.h>
|
||||
|
||||
#include <kernel/video.h>
|
||||
|
||||
#include <toaru/decodeutf8.h>
|
||||
#include <toaru/kbd.h>
|
||||
#include <toaru/graphics.h>
|
||||
@ -42,8 +44,8 @@
|
||||
static int fd_master, fd_slave;
|
||||
static FILE * terminal;
|
||||
|
||||
static uint16_t term_width = 80; /* Width of the terminal (in cells) */
|
||||
static uint16_t term_height = 25; /* Height of the terminal (in cells) */
|
||||
static ssize_t term_width = 80; /* Width of the terminal (in cells) */
|
||||
static ssize_t term_height = 25; /* Height of the terminal (in cells) */
|
||||
static uint16_t csr_x = 0; /* Cursor X */
|
||||
static uint16_t csr_y = 0; /* Cursor Y */
|
||||
static term_cell_t * term_buffer = NULL; /* The terminal cell buffer */
|
||||
@ -481,7 +483,7 @@ void handle_input_s(char * c) {
|
||||
write_input_buffer(c, len);
|
||||
}
|
||||
|
||||
unsigned short * textmemptr = (unsigned short *)0xB8000;
|
||||
unsigned short * textmemptr = NULL;
|
||||
unsigned short * mirrorcopy = NULL;
|
||||
void placech(unsigned char c, int x, int y, int attr) {
|
||||
unsigned int where = y * term_width + x;
|
||||
@ -1225,6 +1227,12 @@ int main(int argc, char ** argv) {
|
||||
}
|
||||
}
|
||||
|
||||
int vga_text_fd = open("/dev/vga0", 0, 0);
|
||||
if (vga_text_fd < 0) return 1;
|
||||
ioctl(vga_text_fd, IO_VID_WIDTH, &term_width);
|
||||
ioctl(vga_text_fd, IO_VID_HEIGHT, &term_height);
|
||||
ioctl(vga_text_fd, IO_VID_ADDR, &textmemptr);
|
||||
|
||||
putenv("TERM=toaru-vga");
|
||||
|
||||
openpty(&fd_master, &fd_slave, NULL, NULL, NULL);
|
||||
@ -1247,7 +1255,7 @@ int main(int argc, char ** argv) {
|
||||
|
||||
fflush(stdin);
|
||||
|
||||
system("cursor-off"); /* Might GPF */
|
||||
system("cursor-off");
|
||||
|
||||
signal(SIGUSR2, sig_suspend_input);
|
||||
|
||||
@ -1328,7 +1336,7 @@ int main(int argc, char ** argv) {
|
||||
}
|
||||
}
|
||||
if (res[1]) {
|
||||
int r = read(kfd, buf, BUF_SIZE);
|
||||
int r = read(kfd, buf, 1);
|
||||
for (int i = 0; i < r; ++i) {
|
||||
int ret = kbd_scancode(&kbd_state, buf[i], &event);
|
||||
key_event(ret, &event);
|
||||
|
@ -241,6 +241,8 @@ size_t fbterm_write(size_t size, uint8_t *buffer) {
|
||||
}
|
||||
|
||||
void fbterm_initialize(void) {
|
||||
if (!lfb_resolution_x) return;
|
||||
|
||||
if (args_present("fbterm-scroll")) {
|
||||
fbterm_scroll = 1;
|
||||
}
|
||||
|
@ -189,7 +189,9 @@ static struct procfs_entry framebuffer_entry = {
|
||||
/* Install framebuffer device */
|
||||
static void finalize_graphics(const char * driver) {
|
||||
lfb_driver_name = driver;
|
||||
lfb_device = lfb_video_device_create();
|
||||
lfb_device->length = lfb_resolution_s * lfb_resolution_y; /* Size is framebuffer size in bytes */
|
||||
vfs_mount("/dev/fb0", lfb_device);
|
||||
|
||||
procfs_install(&framebuffer_entry);
|
||||
}
|
||||
@ -447,6 +449,53 @@ static void auto_scan_pci(uint32_t device, uint16_t v, uint16_t d, void * extra)
|
||||
}
|
||||
}
|
||||
|
||||
static fs_node_t * vga_text_device = NULL;
|
||||
|
||||
static int ioctl_vga(fs_node_t * node, unsigned long request, void * argp) {
|
||||
switch (request) {
|
||||
case IO_VID_WIDTH:
|
||||
/* Get framebuffer width */
|
||||
validate(argp);
|
||||
*((size_t *)argp) = 80;
|
||||
return 0;
|
||||
case IO_VID_HEIGHT:
|
||||
/* Get framebuffer height */
|
||||
validate(argp);
|
||||
*((size_t *)argp) = 25;
|
||||
return 0;
|
||||
case IO_VID_ADDR:
|
||||
/* Map framebuffer into userspace process */
|
||||
validate(argp);
|
||||
{
|
||||
uintptr_t vga_user_offset;
|
||||
if (*(uintptr_t*)argp == 0) {
|
||||
vga_user_offset = 0x100000000;
|
||||
} else {
|
||||
validate((void*)(*(uintptr_t*)argp));
|
||||
vga_user_offset = *(uintptr_t*)argp;
|
||||
}
|
||||
for (uintptr_t i = 0; i < 0x1000; i += 0x1000) {
|
||||
union PML * page = mmu_get_page(vga_user_offset + i, MMU_GET_MAKE);
|
||||
mmu_frame_map_address(page,MMU_FLAG_WRITABLE|MMU_FLAG_WC,((uintptr_t)(0xB8000) & 0xFFFFFFFF) + i);
|
||||
}
|
||||
*((uintptr_t *)argp) = vga_user_offset;
|
||||
}
|
||||
return 0;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static void vga_text_init(void) {
|
||||
vga_text_device = calloc(sizeof(fs_node_t), 1);
|
||||
snprintf(vga_text_device->name, 100, "vga0");
|
||||
vga_text_device->length = 0;
|
||||
vga_text_device->flags = FS_BLOCKDEVICE;
|
||||
vga_text_device->mask = 0660;
|
||||
vga_text_device->ioctl = ioctl_vga;
|
||||
vfs_mount("/dev/vga0", vga_text_device);
|
||||
}
|
||||
|
||||
static int lfb_init(const char * c) {
|
||||
char * arg = strdup(c);
|
||||
char * argv[10];
|
||||
@ -479,6 +528,10 @@ static int lfb_init(const char * c) {
|
||||
} else if (!strcmp(argv[0],"preset")) {
|
||||
/* Set by bootloader (UEFI) */
|
||||
graphics_install_preset(x,y);
|
||||
} else if (!strcmp(argv[0],"text")) {
|
||||
/* VGA text mode? TODO: We should try to detect this,
|
||||
* or limit it to things that are likely to have it... */
|
||||
vga_text_init();
|
||||
} else {
|
||||
ret_val = 1;
|
||||
}
|
||||
@ -488,9 +541,7 @@ static int lfb_init(const char * c) {
|
||||
}
|
||||
|
||||
int framebuffer_initialize(void) {
|
||||
lfb_device = lfb_video_device_create();
|
||||
lfb_init(args_present("vid") ? args_value("vid") : "auto");
|
||||
vfs_mount("/dev/fb0", lfb_device);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user