misc: changes from a long time ago
This commit is contained in:
126
arch/x86_64/vga.c
Normal file
126
arch/x86_64/vga.c
Normal file
@@ -0,0 +1,126 @@
|
||||
#include <arch/irq.h>
|
||||
#include <arch/ports.h>
|
||||
#include <arch/serial.h>
|
||||
#include <mango/libc/stdio.h>
|
||||
#include <mango/machine/vm.h>
|
||||
#include <mango/printk.h>
|
||||
|
||||
struct vga_console {
|
||||
uint16_t *vga_framebuffer;
|
||||
unsigned int vga_cursor_x, vga_cursor_y;
|
||||
unsigned int vga_screen_width, vga_screen_height;
|
||||
uint8_t vga_attrib;
|
||||
};
|
||||
|
||||
static struct vga_console vga_con = {
|
||||
.vga_attrib = 0x0F,
|
||||
.vga_screen_width = 80,
|
||||
.vga_screen_height = 25,
|
||||
.vga_framebuffer = (uint16_t *)0xffffffff800b8000,
|
||||
};
|
||||
|
||||
static void vga_console_clear(struct vga_console *con)
|
||||
{
|
||||
size_t len = con->vga_screen_width * con->vga_screen_height;
|
||||
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
con->vga_framebuffer[i] = (uint16_t)con->vga_attrib << 8;
|
||||
}
|
||||
|
||||
con->vga_cursor_x = 0;
|
||||
con->vga_cursor_y = 0;
|
||||
}
|
||||
|
||||
static void vga_console_show_cursor(struct vga_console *con)
|
||||
{
|
||||
size_t start = 0, end = 15;
|
||||
|
||||
outportb(0x3D4, 0x0A);
|
||||
outportb(0x3D5, (inportb(0x3D5) & 0xC0) | start);
|
||||
|
||||
outportb(0x3D4, 0x0B);
|
||||
outportb(0x3D5, (inportb(0x3D5) & 0xE0) | end);
|
||||
}
|
||||
|
||||
static void vga_console_update_cursor(struct vga_console *con)
|
||||
{
|
||||
uint16_t pos
|
||||
= con->vga_cursor_y * con->vga_screen_width + con->vga_cursor_x;
|
||||
|
||||
outportb(0x3D4, 0x0F);
|
||||
outportb(0x3D5, (uint8_t)(pos & 0xFF));
|
||||
outportb(0x3D4, 0x0E);
|
||||
outportb(0x3D5, (uint8_t)((pos >> 8) & 0xFF));
|
||||
}
|
||||
|
||||
static void vga_console_scroll(struct vga_console *con)
|
||||
{
|
||||
uint16_t *src = &con->vga_framebuffer[con->vga_screen_width];
|
||||
uint16_t *dest = &con->vga_framebuffer[0];
|
||||
size_t len = (con->vga_screen_height - 1) * con->vga_screen_width
|
||||
* sizeof *con->vga_framebuffer;
|
||||
|
||||
memcpy(dest, src, len);
|
||||
|
||||
dest = &con->vga_framebuffer
|
||||
[(con->vga_screen_height - 1) * con->vga_screen_width];
|
||||
len = con->vga_screen_width;
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
dest[i] = (uint16_t)con->vga_attrib << 8;
|
||||
}
|
||||
|
||||
con->vga_cursor_x = 0;
|
||||
con->vga_cursor_y = con->vga_screen_height - 1;
|
||||
}
|
||||
|
||||
static void vga_console_putc(struct vga_console *con, char c)
|
||||
{
|
||||
switch (c) {
|
||||
case '\n':
|
||||
con->vga_cursor_x = 0;
|
||||
con->vga_cursor_y++;
|
||||
break;
|
||||
case '\r':
|
||||
con->vga_cursor_x = 0;
|
||||
break;
|
||||
default:
|
||||
con->vga_framebuffer
|
||||
[con->vga_cursor_y * con->vga_screen_width
|
||||
+ con->vga_cursor_x]
|
||||
= ((uint16_t)con->vga_attrib << 8) | c;
|
||||
con->vga_cursor_x++;
|
||||
break;
|
||||
}
|
||||
|
||||
if (con->vga_cursor_x >= con->vga_screen_width) {
|
||||
con->vga_cursor_x = 0;
|
||||
con->vga_cursor_y++;
|
||||
}
|
||||
|
||||
if (con->vga_cursor_y >= con->vga_screen_height) {
|
||||
vga_console_scroll(con);
|
||||
}
|
||||
}
|
||||
|
||||
static void vgacon_write(struct console *con, const char *s, unsigned int len)
|
||||
{
|
||||
for (unsigned int i = 0; i < len; i++) {
|
||||
vga_console_putc(&vga_con, s[i]);
|
||||
}
|
||||
|
||||
vga_console_update_cursor(&vga_con);
|
||||
}
|
||||
|
||||
static struct console vgacon = {
|
||||
.c_name = "vgacon",
|
||||
.c_flags = CON_BOOT,
|
||||
.c_write = vgacon_write,
|
||||
.c_lock = SPIN_LOCK_INIT,
|
||||
};
|
||||
|
||||
void vgacon_init(void)
|
||||
{
|
||||
vga_console_clear(&vga_con);
|
||||
vga_console_show_cursor(&vga_con);
|
||||
console_register(&vgacon);
|
||||
}
|
||||
Reference in New Issue
Block a user