Add VGA code to vga_drv

This commit is contained in:
pjht 2019-08-31 11:04:30 -05:00
parent 58711735b2
commit 4771173c6c
6 changed files with 170 additions and 1 deletions

View File

@ -1,3 +1,9 @@
int main() {
#include <grub/text_fb_info.h>
int main() {
text_fb_info info;
info.address=map_phys((void*)0xB8000,10);
info.width=80;
info.height=25;
vga_init(info);
}

31
vga_drv/ports.c Normal file
View File

@ -0,0 +1,31 @@
#include <stdint.h>
uint8_t port_byte_in(uint16_t port) {
uint8_t result;
asm("in %%dx, %%al":"=a"(result):"d"(port));
return result;
}
void port_byte_out(uint16_t port,uint8_t data) {
asm("out %%al, %%dx":: "a"(data),"d"(port));
}
uint16_t port_word_in(uint16_t port) {
uint16_t result;
asm("in %%dx, %%ax":"=a"(result):"d"(port));
return result;
}
void port_word_out(uint16_t port,uint16_t data) {
asm("out %%ax, %%dx":: "a" (data), "d" (port));
}
uint32_t port_long_in(uint16_t port) {
uint32_t result;
asm("inl %%dx, %%eax":"=a"(result):"d"(port));
return result;
}
void port_long_out(uint16_t port,uint32_t data) {
asm("outl %%eax, %%dx":: "a" (data), "d" (port));
}

12
vga_drv/ports.h Normal file
View File

@ -0,0 +1,12 @@
#ifndef PORTS_H
#define PORTS_H
#include <stdint.h>
uint8_t port_byte_in(uint16_t port);
void port_byte_out(uint16_t port,uint8_t data);
uint16_t port_word_in(uint16_t port);
void port_word_out(uint16_t port,uint16_t data);
uint32_t port_long_in(uint16_t port);
void port_long_out(uint16_t port,uint32_t data);
#endif

91
vga_drv/vga.c Normal file
View File

@ -0,0 +1,91 @@
#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++;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-value"
for (int i=0;i<67108864;i++) {
1+1;
}
#pragma GCC diagnostic pop
} 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);
}
}

29
vga_drv/vga.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef vga_H
#define vga_H
typedef enum {
VGA_BLACK=0,
VGA_BLUE=1,
VGA_GREEN=2,
VGA_CYAN=3,
VGA_RED=4,
VGA_PURPLE=5,
VGA_BROWN=6,
VGA_GRAY=7,
VGA_DARK_GRAY=8,
VGA_LIGHT_BLUE=9,
VGA_LIGHT_GREEN=10,
VGA_LIGHT_CYAN=11,
VGA_LIGHT_RED=12,
VGA_LIGHT_PURPLE=13,
VGA_YELLOW=14,
VGA_WHITE=15
} vga_colors;
void vga_init();
void vga_write_string(const char *string);
void vga_clear();
void vga_backspace();
#endif

Binary file not shown.