Newer
Older
tree-os / src / kernel / lib / textMode / stdio.c
@lukas lukas on 2 Apr 2021 2 KB add basic tasking
#include <stdarg.h>
#include <stdint.h>
#include <lib/textMode/stdio.h>
#include <lib/ports.h>
#include <lib/textMode/cursor.h>

uint16_t* framebuffer = (uint16_t*) FRAMEBUFFER_LOCATION;
char format = 0x0F;

void putCharAtOffset(char c, uint16_t position) {
    *(framebuffer + position) = (c | format << 8);
}

void putCharAt(char c, uint8_t x, uint8_t y) {
    putCharAtOffset(c, (x + y * VIDEO_WIDTH));
}

void putCharsAt(char* string, uint8_t x, uint8_t y) {
    uint16_t position = 0;
    char c = *string;
    while (c != 0x00) {
        putCharAt(c, x + position, y);
        position++;
        c = *(string + position);
    }
}

void putChar(char c) {
    uint16_t offset = getCursorOffset();
    putCharAtOffset(c, offset);
    setCursorOffset(offset + 1);
}

void puts(char* string) {
    while (*string != 0x00) {
        putChar(*string);
        string++;
    }
}

void newLine() {
    uint16_t offset = getCursorOffset();
    uint8_t x = offset % VIDEO_WIDTH;
    uint8_t y = offset / VIDEO_WIDTH;
    x = 0;
    y++;
    if (y > VIDEO_HEIGHT) {
        // shiftUp(); : TODO
    }
    setCursorPosition(x, y);
}

char HEX_PREFIX[] = "0x";
char HEX_CHARS[] = "0123456789ABCDEF";

void putHex(uint32_t x) {
    uint8_t alreadyWriting = 0;
    puts(HEX_PREFIX);
    for (int8_t i = 7; i >= 0; i--) {
        uint8_t nibble = (x >> (i * 4)) & 0x0F;
        if (! alreadyWriting && nibble != 0x00) {
            alreadyWriting = 0x01;
        }
        if (! alreadyWriting) {
            continue;
        }
        putChar(HEX_CHARS[nibble]);
    }
}

void handleInsert(char insertType, uint32_t x) {
    if (insertType == 's') {
        puts((char*) x);
    }
    if (insertType == 'x') {
        putHex(x);
    }
}

void printf(const char* format, ...) {
    va_list valist;
    va_start(valist, format);
    for (int i = 0; format[i] != 0; i++) {
        if (format[i] == '\n') {
            newLine();
            continue;
        }
        if (format[i] == '%') {
            handleInsert(format[++i], va_arg(valist, int));
            continue;
        }
        putChar(format[i]);
    }
    va_end(valist);
}

void clearScreen() {
    setCursorOffset(0);
    for (int y = 0; y < VIDEO_HEIGHT; y++) {
        for (int x = 0; x < VIDEO_WIDTH; x++) {
            putCharAt(' ', x, y);
        }
    }
}

void setTextStyle(uint8_t style) {
    format = style;
}