86 lines
1.7 KiB
C
86 lines
1.7 KiB
C
#include <grub/text_fb_info.h>
|
|
#include "vga.h"
|
|
#include "ports.h"
|
|
#include <string.h>
|
|
#include <stddef.h>
|
|
#define xy_to_indx(x,y) ((x+(y*width))*2)
|
|
static char* screen;
|
|
static int width;
|
|
static int height;
|
|
static int x;
|
|
static int y;
|
|
static vga_colors fg_color;
|
|
static vga_colors bg_color;
|
|
static char* scroll_buf[0xfa0];
|
|
|
|
|
|
static void set_char(int x,int y,char c) {
|
|
screen[xy_to_indx(x,y)]=c;
|
|
screen[xy_to_indx(x,y)+1]=(bg_color<<4)|fg_color;
|
|
}
|
|
|
|
void vga_clear() {
|
|
for (int y=0;y<height;y++) {
|
|
for (int x=0;x<width;x++) {
|
|
set_char(x,y,' ');
|
|
}
|
|
}
|
|
}
|
|
|
|
static void set_cursor(int x,int y) {
|
|
int pos=(x+(y*width));
|
|
port_byte_out(0x3D4,0xF);
|
|
port_byte_out(0x3D5,pos&0xFF);
|
|
port_byte_out(0x3D4,0xE);
|
|
port_byte_out(0x3D5,(pos&0xFF00)>>8);
|
|
}
|
|
|
|
void vga_init(text_fb_info framebuffer_info) {
|
|
x=0;
|
|
y=0;
|
|
fg_color=VGA_WHITE;
|
|
bg_color=VGA_BLACK;
|
|
screen=framebuffer_info.address;
|
|
width=framebuffer_info.width;
|
|
height=framebuffer_info.height;
|
|
port_byte_out(0x3D4,0xA);
|
|
port_byte_out(0x3D5,(port_byte_in(0x3D5)&0xC0)|14);
|
|
port_byte_out(0x3D4,0xB);
|
|
port_byte_out(0x3D5,(port_byte_in(0x3D5)&0xE0)|15);
|
|
set_cursor(0,0);
|
|
vga_clear();
|
|
}
|
|
|
|
void vga_write_string(const char* string) {
|
|
for (size_t i=0;i<strlen(string);i++) {
|
|
char c=string[i];
|
|
if (c=='\n') {
|
|
x=0;
|
|
y++;
|
|
} else {
|
|
set_char(x,y,c);
|
|
x++;
|
|
}
|
|
if (x==width) {
|
|
x=0;
|
|
y++;
|
|
}
|
|
if (y==height) {
|
|
x=0;
|
|
y=24;
|
|
memcpy(scroll_buf,&screen[xy_to_indx(0,1)],xy_to_indx(0,24));
|
|
vga_clear();
|
|
memcpy(screen,scroll_buf,xy_to_indx(0,25));
|
|
}
|
|
}
|
|
set_cursor(x,y);
|
|
}
|
|
|
|
void vga_backspace() {
|
|
if (x!=0) {
|
|
x--;
|
|
set_char(x,y,' ');
|
|
set_cursor(x,y);
|
|
}
|
|
}
|