143 lines
3.0 KiB
C
143 lines
3.0 KiB
C
|
#include "vga.h"
|
||
|
#include "io.h"
|
||
|
#include "klibc.h"
|
||
|
|
||
|
static uint vgaBgColor;
|
||
|
static uint vgaColor;
|
||
|
static int line, col;
|
||
|
|
||
|
int initVGA(uint bgColor, uint color)
|
||
|
{
|
||
|
vgaBgColor = bgColor;
|
||
|
vgaColor = color;
|
||
|
clearScreen(bgColor);
|
||
|
line = 0;
|
||
|
col = 0;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
void clearScreen(uint bgColor)
|
||
|
{
|
||
|
volatile short *vga = (short *)VGA_ADDR;
|
||
|
long int colorAttr = bgColor << 12;
|
||
|
for (int i = 0; i < VGA_WIDTH * VGA_HEIGHT; i++) {
|
||
|
vga[i] = colorAttr;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void printInt(int integer)
|
||
|
{
|
||
|
char num[sizeof(int) *
|
||
|
3]; // int max is 2^(sizeof(int)*8) which is (2^3)^(sizeof(int)*8/3) =
|
||
|
// 8^(sizeof(int)*8/3) ~ 10^(sizeof(int)*8/3)
|
||
|
int i = 0, k = 0;
|
||
|
if (integer < 0) {
|
||
|
printChar('-');
|
||
|
}
|
||
|
while (integer != 0) {
|
||
|
int digit = integer % 10;
|
||
|
num[i++] = (digit > 0) ? digit : -digit;
|
||
|
integer = integer / 10;
|
||
|
}
|
||
|
for (k = i - 1; k >= 0; k--) {
|
||
|
printChar(num[k] + '0');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void printIntDetails(int integer, uint color, uint bgColor, int startX, int startY)
|
||
|
{
|
||
|
char num[sizeof(int) *
|
||
|
3]; // int max is 2^(sizeof(int)*8) which is (2^3)^(sizeof(int)*8/3) =
|
||
|
// 8^(sizeof(int)*8/3) ~ 10^(sizeof(int)*8/3)
|
||
|
int x = startX;
|
||
|
int i = 0, k = 0;
|
||
|
if (integer < 0) {
|
||
|
printCharDetails('-', color, bgColor, x++, startY);
|
||
|
}
|
||
|
while (integer != 0) {
|
||
|
int digit = integer % 10;
|
||
|
num[i++] = (digit > 0) ? digit : -digit;
|
||
|
integer = integer / 10;
|
||
|
}
|
||
|
for (k = i - 1; k >= 0; k--) {
|
||
|
printCharDetails(num[k] + '0', color, bgColor, x++, startY);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void printCharDetails(const char str, uint color, uint bgColor, int startX, int startY)
|
||
|
{
|
||
|
volatile short *vga = (short *)VGA_ADDR;
|
||
|
long int colorAttr = (bgColor << 4 | (color & 0x0f)) << 8;
|
||
|
vga[VGA_WIDTH * startY + startX] = colorAttr | str;
|
||
|
}
|
||
|
|
||
|
void vgaScrollUp(void)
|
||
|
{
|
||
|
long int colorAttr = vgaBgColor << 12;
|
||
|
volatile short *vga = (short *)VGA_ADDR;
|
||
|
for (int i = 1; i < VGA_HEIGHT - 2;
|
||
|
i++) { // last line is status line. Do not scroll it
|
||
|
memcpy((void *)&vga[VGA_WIDTH * (i - 1)], (void *)&vga[VGA_WIDTH * i],
|
||
|
VGA_WIDTH * sizeof(short));
|
||
|
}
|
||
|
for (int i = 0; i < VGA_WIDTH; i++) {
|
||
|
vga[(VGA_HEIGHT - 2) * VGA_WIDTH + i] = colorAttr;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void printString(const char *str)
|
||
|
{
|
||
|
while (*str) {
|
||
|
printChar(*(str++));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void printChar(const char str)
|
||
|
{
|
||
|
if (str == '\n') {
|
||
|
line++;
|
||
|
col = 0;
|
||
|
if (line >= VGA_HEIGHT - 1) {
|
||
|
vgaScrollUp();
|
||
|
line--;
|
||
|
}
|
||
|
}
|
||
|
else if(str == '\r')
|
||
|
{
|
||
|
col = 0;
|
||
|
}
|
||
|
else if(str == '\b')
|
||
|
{
|
||
|
col--;
|
||
|
if (col < 0) {
|
||
|
col = VGA_WIDTH - 1;
|
||
|
line--;
|
||
|
}
|
||
|
printCharDetails(' ', vgaColor, vgaBgColor, col, line);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
printCharDetails(str, vgaColor, vgaBgColor, col++, line);
|
||
|
if (col == VGA_WIDTH) {
|
||
|
col = 0;
|
||
|
line++;
|
||
|
}
|
||
|
if (line >= VGA_HEIGHT - 1) {
|
||
|
vgaScrollUp();
|
||
|
line--;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void printStringDetails(const char *str, uint color, uint bgColor, int startX, int startY)
|
||
|
{
|
||
|
volatile short *vga = (short *)VGA_ADDR;
|
||
|
int i = 0;
|
||
|
long int colorAttr = (bgColor << 4 | (color & 0x0f)) << 8;
|
||
|
while (*str) {
|
||
|
vga[VGA_WIDTH * startY + startX + i] = colorAttr | *str;
|
||
|
str++;
|
||
|
i++;
|
||
|
}
|
||
|
}
|