forked from PoliEcho-holding-org/kern
144 lines
2.7 KiB
C
144 lines
2.7 KiB
C
#include "stdarg.h"
|
|
#include "stdint.h"
|
|
#include "string.h"
|
|
#include "stdio.h"
|
|
#include "port.h"
|
|
|
|
static uint32_t xpos;
|
|
static uint32_t ypos;
|
|
static uint8_t attr;
|
|
|
|
void setAttr(uint8_t newattr) { attr = newattr; }
|
|
|
|
void setCursor(uint32_t row, uint32_t col) {
|
|
xpos = col;
|
|
ypos = row;
|
|
updateCursor();
|
|
}
|
|
|
|
void updateCursor() {
|
|
uint16_t pos = xpos + ypos * COLS;
|
|
|
|
outb(0x3d4, 0x0f);
|
|
outb(0x3d5, pos & 0xff);
|
|
outb(0x3d4, 0x0e);
|
|
outb(0x3d5, (pos >> 8) & 0xff);
|
|
}
|
|
|
|
void hideCursor() {
|
|
outb(0x3d4, 0x0a);
|
|
outb(0x3d5, 0x20);
|
|
}
|
|
|
|
void showCursor() {
|
|
uint8_t start = 0;
|
|
uint8_t end = 15;
|
|
|
|
outb(0x3d4, 0x0a);
|
|
outb(0x3d5, (inb(0x3d5) & 0xc0) | start);
|
|
outb(0x3d4, 0x0b);
|
|
outb(0x3d5, (inb(0x3d5) & 0xe0) | end);
|
|
}
|
|
|
|
void cls() {
|
|
uint8_t* vidmem = (uint8_t*)VIDMEM;
|
|
|
|
for (size_t i = 0; i < ROWS * COLS; i++) {
|
|
vidmem[i * 2] = 0;
|
|
vidmem[i * 2 + 1] = attr;
|
|
}
|
|
|
|
xpos = 0;
|
|
ypos = 0;
|
|
updateCursor();
|
|
}
|
|
|
|
void putat(uint32_t row, uint32_t col, int c) {
|
|
uint8_t* vidmem = (uint8_t*)VIDMEM;
|
|
vidmem[(col + row * COLS) * 2] = c & 0xFF;
|
|
vidmem[(col + row * COLS) * 2 + 1] = attr;
|
|
}
|
|
|
|
void newline() {
|
|
xpos = 0;
|
|
ypos++;
|
|
if (ypos >= ROWS) ypos = 0;
|
|
updateCursor();
|
|
}
|
|
|
|
void putc(int c) {
|
|
putat(ypos, xpos, c);
|
|
xpos++;
|
|
if (xpos >= COLS) newline();
|
|
updateCursor();
|
|
}
|
|
|
|
void puts(char* s) {
|
|
while (*s != '\0') {
|
|
if (*s == '\n' || *s == '\r') {
|
|
newline();
|
|
s++;
|
|
} else putc(*s++);
|
|
}
|
|
}
|
|
|
|
int vsnprintf(void* buf, size_t len, char* fmt, va_list args) {
|
|
char* str = (char*)buf;
|
|
size_t pos = 0;
|
|
|
|
while (*fmt != '\0') {
|
|
if (*fmt != '%') {
|
|
if (pos < len - 1) str[pos++] = *fmt++;
|
|
continue;
|
|
}
|
|
|
|
fmt++;
|
|
char pad = ' ';
|
|
int width = 0;
|
|
|
|
if (*fmt == '0') pad = '0';
|
|
while (*fmt >= '0' && *fmt <= '9') {
|
|
width *= 10;
|
|
width += *fmt++ - '0';
|
|
}
|
|
|
|
// DO NOT TALK ABOUT THIS ABOMINATION
|
|
char* s;
|
|
switch (*fmt++) {
|
|
case 'd': s = itoa(va_arg(args, int), 10); goto string;
|
|
case 'x': s = itoa(va_arg(args, int), 16); goto string;
|
|
case 's': s = va_arg(args, char*); goto string;
|
|
case 'c': if (pos < len - 1) str[pos++] = va_arg(args, char); break;
|
|
case '%': if (pos < len - 1) str[pos++] = '%'; break;
|
|
default:
|
|
if (pos < len - 1) str[pos++] = '%';
|
|
if (pos < len - 1) str[pos++] = *(fmt - 1);
|
|
break;
|
|
string:
|
|
width -= strlen(s) - 1;
|
|
if (width < 0) width = 0;
|
|
while (width-- && pos < len - 1) str[pos++] = pad;
|
|
while (*s && pos < len - 1) str[pos++] = *s++;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (len > 0) {
|
|
if (pos < len) str[pos++] = '\0';
|
|
else str[len - 1] = '\0'; // Shouldn't be able to be reached, but who knows
|
|
}
|
|
|
|
return pos;
|
|
}
|
|
|
|
int printf(char* fmt, ...) {
|
|
va_list args;
|
|
va_start(args, fmt);
|
|
char buf[256];
|
|
int ret = vsnprintf(buf, 256, fmt, args);
|
|
va_end(args);
|
|
puts(buf);
|
|
return ret;
|
|
}
|
|
|