2018-07-20 15:41:58 +02:00
|
|
|
#include "vga.h"
|
|
|
|
#include "io.h"
|
|
|
|
#include "klibc.h"
|
|
|
|
|
|
|
|
static uint vgaBgColor;
|
|
|
|
static uint vgaColor;
|
|
|
|
static int line, col;
|
|
|
|
|
2018-11-08 22:08:27 +01:00
|
|
|
int VGASetup(uint bgColor, uint color)
|
2018-07-20 15:41:58 +02:00
|
|
|
{
|
|
|
|
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;
|
2018-11-07 17:38:28 +01:00
|
|
|
for (int i = 1; i < VGA_HEIGHT - 1;
|
2018-07-20 15:41:58 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-06 22:28:45 +02:00
|
|
|
void vprintf(const char *format, va_list ap)
|
|
|
|
{
|
|
|
|
int i = 0;
|
|
|
|
while (format[i] != '\0') {
|
|
|
|
switch (format[i]) {
|
|
|
|
case '%':
|
|
|
|
switch (format[i + 1]) {
|
|
|
|
case 'i':
|
|
|
|
case 'd': {
|
|
|
|
int d = va_arg(ap, int);
|
|
|
|
printInt(d);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 'c': {
|
|
|
|
int c = va_arg(ap, int);
|
|
|
|
printChar((char)c);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 's': {
|
|
|
|
char *str = va_arg(ap, char *);
|
|
|
|
if(!str)
|
|
|
|
str = "[NULL STR]";
|
|
|
|
printString(str);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case '%':
|
|
|
|
printChar('%');
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
i++;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
printChar(format[i]);
|
|
|
|
}
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void printf(const char *format, ...){
|
|
|
|
va_list ap;
|
|
|
|
va_start(ap, format);
|
|
|
|
vprintf(format, ap);
|
|
|
|
va_end(ap);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-07-20 15:41:58 +02:00
|
|
|
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++;
|
|
|
|
}
|
|
|
|
}
|