diff --git a/Makefile b/Makefile index 23cdfee..cb9b5cb 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ # Define the object files -OBJS = bin/boot.o bin/kernel.o bin/idt.o bin/isr.o bin/screen.o bin/utils.o bin/string.o +OBJS = bin/boot.o bin/kernel.o bin/idt.o bin/isr.o bin/screen.o bin/utils.o bin/string.o bin/stdio.o # Define the compiler and assembler -CC = gcc +CC = gcc -D__is_katauos AS = nasm # Define the compiler flags @@ -42,6 +42,9 @@ bin/utils.o: src/utils.c bin/string.o: src/string.c $(CC) $(CFLAGS) -c $< -o $@ +bin/stdio.o: src/stdio.c + $(CC) $(CFLAGS) -c $< -o $@ + clean: rm -rf bin/ rm -f $(OUTPUT) diff --git a/include/stdio.h b/include/stdio.h new file mode 100644 index 0000000..7d90f68 --- /dev/null +++ b/include/stdio.h @@ -0,0 +1,13 @@ +#ifndef STDIO_H +#define STDIO_H + +//TODO: these should be contained in newlib i guess +//but until i implement it let it be here yo +#define EOF (-1) +#define INT_MAX 2147483647 + +int printf(const char* __restrict, ...); +int putchar(int); +int puts(const char*); + +#endif diff --git a/src/isr.c b/src/isr.c index 2a56355..0fb4450 100644 --- a/src/isr.c +++ b/src/isr.c @@ -44,7 +44,7 @@ void isr_install() { void isr0() { terminal_writestring(exception_messages[0]); - asm("hlt"); + asm("hlt"); } void isr1() { diff --git a/src/kernel.c b/src/kernel.c index ae7e1b0..aaa0583 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -1,5 +1,6 @@ #include "../include/isr.h" #include "../include/screen.h" +#include "../include/stdio.h" #include "../include/utils.h" /* Check if the compiler thinks you are targeting the wrong operating system. */ @@ -16,9 +17,12 @@ void kmain() { terminal_initialize(); - terminal_writestring("KatauOS booting up\n"); + printf("KatauOS booting up\n"); isr_install(); - terminal_writestring("Kernel init sequence completed\n"); + printf("Kernel init sequence completed\n"); + + char yooo[256] = "heheh"; + printf("test string: %s\n", yooo); while(1) { diff --git a/src/stdio.c b/src/stdio.c new file mode 100644 index 0000000..35ec51f --- /dev/null +++ b/src/stdio.c @@ -0,0 +1,99 @@ +#include "../include/stdio.h" +#include +#include +#include +#include "../include/string.h" + +#ifdef __is_katauos +#include "../include/screen.h" +#endif + +int puts(const char* string) { + return printf("%s\n", string); +} + +int putchar(int ic) { +#if defined(__is_katauos) + char c = (char) ic; + terminal_write(&c, sizeof(c)); +#else + // TODO: Implement stdio and the write system call. +#endif + return ic; +} + + +static bool print(const char* data, size_t length) { + const unsigned char* bytes = (const unsigned char*) data; + for (size_t i = 0; i < length; i++) + if (putchar(bytes[i]) == EOF) + return false; + return true; +} + +int printf(const char* restrict format, ...) { + va_list parameters; + va_start(parameters, format); + + int written = 0; + + while (*format != '\0') { + size_t maxrem = INT_MAX - written; + + if (format[0] != '%' || format[1] == '%') { + if (format[0] == '%') + format++; + size_t amount = 1; + while (format[amount] && format[amount] != '%') + amount++; + if (maxrem < amount) { + // TODO: Set errno to EOVERFLOW. + return -1; + } + if (!print(format, amount)) + return -1; + format += amount; + written += amount; + continue; + } + + const char* format_begun_at = format++; + + if (*format == 'c') { + format++; + char c = (char) va_arg(parameters, int /* char promotes to int */); + if (!maxrem) { + // TODO: Set errno to EOVERFLOW. + return -1; + } + if (!print(&c, sizeof(c))) + return -1; + written++; + } else if (*format == 's') { + format++; + const char* str = va_arg(parameters, const char*); + size_t len = strlen(str); + if (maxrem < len) { + // TODO: Set errno to EOVERFLOW. + return -1; + } + if (!print(str, len)) + return -1; + written += len; + } else { + format = format_begun_at; + size_t len = strlen(format); + if (maxrem < len) { + // TODO: Set errno to EOVERFLOW. + return -1; + } + if (!print(format, len)) + return -1; + written += len; + format += len; + } + } + + va_end(parameters); + return written; +}