2023-06-13 09:45:04 +03:00
|
|
|
#include "vga.h"
|
|
|
|
#define VGA_WIDTH 80
|
|
|
|
#define VGA_HEIGHT 25
|
|
|
|
#define VGA_MEM_ADDR 0xb8000
|
|
|
|
#define CURSOR_HOME (VGA_HEIGHT-1)*VGA_WIDTH
|
|
|
|
#define CURSOR_CHR 177;
|
|
|
|
|
|
|
|
unsigned int cursor_loc = CURSOR_HOME;
|
|
|
|
unsigned char fgcolor;
|
|
|
|
unsigned char bgcolor;
|
2023-06-14 05:21:38 +03:00
|
|
|
unsigned short blank;
|
2023-06-13 09:45:04 +03:00
|
|
|
|
|
|
|
static unsigned char vga_entry_color(enum vga_color fg, enum vga_color bg) {
|
|
|
|
return fg | bg << 4;
|
|
|
|
}
|
|
|
|
unsigned short vga_blank_entry() {
|
|
|
|
return vga_entry_color(fgcolor, bgcolor) << 8;
|
|
|
|
}
|
|
|
|
void draw_cursor(void) {
|
|
|
|
*((unsigned char *)VGA_MEM_ADDR + cursor_loc * 2) = CURSOR_CHR;
|
|
|
|
*((unsigned char *)VGA_MEM_ADDR+1 + cursor_loc * 2) = vga_entry_color(fgcolor, bgcolor);
|
|
|
|
}
|
|
|
|
|
|
|
|
void vga_set_color(enum vga_color fg, enum vga_color bg) {
|
|
|
|
fgcolor = fg;
|
|
|
|
bgcolor = bg;
|
|
|
|
}
|
|
|
|
void vga_init(enum vga_color fg, enum vga_color bg) {
|
|
|
|
vga_set_color(fg, bg);
|
2023-06-14 05:21:38 +03:00
|
|
|
blank = vga_blank_entry();
|
2023-06-13 09:45:04 +03:00
|
|
|
cls();
|
|
|
|
}
|
|
|
|
void cls(void) {
|
|
|
|
int i;
|
|
|
|
for (i=0; i<VGA_HEIGHT*VGA_WIDTH;i++) {
|
|
|
|
*((unsigned short *) VGA_MEM_ADDR+i) = blank;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void scroll(void) {
|
|
|
|
int y;
|
|
|
|
int x;
|
|
|
|
*((unsigned short *) VGA_MEM_ADDR+cursor_loc) = blank;
|
|
|
|
for (y=0;y<VGA_HEIGHT;y++) {
|
|
|
|
for (x = 0;x<VGA_WIDTH;x++) {
|
|
|
|
*((unsigned short *) VGA_MEM_ADDR+y*VGA_WIDTH+x) = *((unsigned short *) VGA_MEM_ADDR+(y+1)*VGA_WIDTH+x);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (x=0;x<VGA_WIDTH;x++) {
|
|
|
|
*((unsigned short *) VGA_MEM_ADDR+CURSOR_HOME+x) = blank;
|
|
|
|
}
|
|
|
|
cursor_loc = CURSOR_HOME;
|
|
|
|
draw_cursor();
|
|
|
|
}
|
|
|
|
void putchar(unsigned char chr) {
|
|
|
|
if (chr == '\n') {
|
|
|
|
scroll();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
*((unsigned char *) VGA_MEM_ADDR+cursor_loc * 2) = chr;
|
|
|
|
*((unsigned char *) VGA_MEM_ADDR+1+cursor_loc * 2) = vga_entry_color(fgcolor, bgcolor);
|
|
|
|
cursor_loc++;
|
|
|
|
if (cursor_loc >= VGA_HEIGHT*VGA_WIDTH) {
|
|
|
|
scroll();
|
|
|
|
}
|
|
|
|
draw_cursor();
|
|
|
|
}
|
|
|
|
|
|
|
|
void vga_write(const char* text) {
|
|
|
|
int i = 0;
|
|
|
|
while(text[i]) {
|
|
|
|
putchar(text[i]);
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void vga_write_color( const char* text, enum vga_color fg, enum vga_color bg) {
|
|
|
|
unsigned char prevfg = fgcolor;
|
|
|
|
unsigned char prevbg = bgcolor;
|
|
|
|
vga_set_color(fg, bg);
|
|
|
|
vga_write(text);
|
|
|
|
fgcolor = prevfg;
|
|
|
|
bgcolor = prevbg;
|
|
|
|
}
|
|
|
|
void vga_write_line(const char* text) {
|
|
|
|
if (cursor_loc != CURSOR_HOME) {
|
|
|
|
scroll();
|
|
|
|
}
|
|
|
|
vga_write(text);
|
|
|
|
scroll();
|
|
|
|
}
|
|
|
|
void vga_write_line_color(const char* text, enum vga_color fg, enum vga_color bg) {
|
|
|
|
unsigned char prevfg = fgcolor;
|
|
|
|
unsigned char prevbg = bgcolor;
|
|
|
|
vga_set_color(fg, bg);
|
|
|
|
vga_write_line(text);
|
|
|
|
fgcolor = prevfg;
|
|
|
|
bgcolor = prevbg;
|
|
|
|
}
|