diff --git a/Kernel/Include/Lib/String.h b/Kernel/Include/Lib/String.h new file mode 100644 index 0000000..201334f --- /dev/null +++ b/Kernel/Include/Lib/String.h @@ -0,0 +1,18 @@ +#pragma once +#include +#include + +void* StringSet(BytePointer destination, ASCII value, Size count); +void* MemoryCopy(void* destination, const void* source, Size count); + +Int32 StringCompare(const ASCII* firstString, const ASCII* secondString); +Int32 StringCompareWithLimit(const ASCII* firstString, const ASCII* secondString, Size limit); + +ASCII* StringCopy(ASCII* destination, const ASCII* source); +ASCII* StringCopyWithLimit(ASCII* destination, const ASCII* source, Size limit); + +Size StringGetLength(const ASCII* string); +const ASCII* StringFindLastOccurrenceOfCharacter(const ASCII* string, ASCII separator); + +Int32 StringFormatVariadic(ASCII* string, Size size, const ASCII* format, va_list args); +Int32 StringFormat(ASCII* destination, UInt64 size, const ASCII* format, ...); \ No newline at end of file diff --git a/Kernel/Include/Lib/VAArgs.h b/Kernel/Include/Lib/VAArgs.h new file mode 100644 index 0000000..da688ef --- /dev/null +++ b/Kernel/Include/Lib/VAArgs.h @@ -0,0 +1,8 @@ +#pragma once + +typedef __builtin_va_list va_list; + +#define va_start(v, l) __builtin_va_start(v, l) +#define va_end(v) __builtin_va_end(v) +#define va_arg(v, l) __builtin_va_arg(v, l) +#define va_copy(d, s) __builtin_va_copy(d, s) \ No newline at end of file diff --git a/Kernel/Include/OS/Log.h b/Kernel/Include/OS/Log.h new file mode 100644 index 0000000..5b9d1d2 --- /dev/null +++ b/Kernel/Include/OS/Log.h @@ -0,0 +1,8 @@ +#pragma once +#include + +enum { + kOSLogBufferSize = 1024, +}; + +void OSLog(const ASCII* format, ...); \ No newline at end of file diff --git a/Kernel/Source/IO/Serial.c b/Kernel/Source/IO/Serial.c index 2a92d13..68f7ef9 100644 --- a/Kernel/Source/IO/Serial.c +++ b/Kernel/Source/IO/Serial.c @@ -4,7 +4,7 @@ Int32 IOSerialPutCharacter(ASCII character) { // TXFF -- TRansmit FIFO Full for PL011 is 5 bit of FR reg (0x18) - UInt64 uartFR = kUARTBaseAddress + 0x18; + UInt64 uartFR = kUARTBaseAddress + 0x18; while ((IOAddressRead32(uartFR) & (1 << 5)) != 0) { CPUYield(); @@ -22,4 +22,4 @@ Int32 IOSerialPutString(const ASCII* string) { } return i; -} \ No newline at end of file +} diff --git a/Kernel/Source/KernelMain.c b/Kernel/Source/KernelMain.c index 7cc4f2d..d21d0c3 100644 --- a/Kernel/Source/KernelMain.c +++ b/Kernel/Source/KernelMain.c @@ -1,6 +1,4 @@ -#include -#include +#include void KernelMain(void) { - IOSerialPutString("Meow nya!!\n"); } \ No newline at end of file diff --git a/Kernel/Source/Lib/String.c b/Kernel/Source/Lib/String.c new file mode 100644 index 0000000..5a23995 --- /dev/null +++ b/Kernel/Source/Lib/String.c @@ -0,0 +1,179 @@ +#include +#include + +static void BufferAdd(ASCII* buffer, Size bufferSize, Size* written, ASCII character) { + if (*written + 1 < bufferSize) { + buffer[*written] = character; + } + (*written)++; +} + +void* StringSet(BytePointer destination, ASCII value, Size count) { + BytePointer savedDestination = destination; + while (count--) { + *destination++ = (UInt8) value; + } + return savedDestination; +} + +void* MemoryCopy(void* destination, const void* source, Size count) { + BytePointer destinationBuffer = (BytePointer) destination; + const UInt8* sourceBuffer = (const UInt8*) source; + + while (count >= 8) { + *(UInt64*) destinationBuffer = *(const UInt64*) sourceBuffer; + destinationBuffer += 8; + sourceBuffer += 8; + count -= 8; + } + + while (count > 0) { + *destinationBuffer++ = *sourceBuffer++; + count--; + } + + return destination; +} + +Int32 StringCompare(const ASCII* firstString, const ASCII* secondString) { + while (*firstString && (*firstString == *secondString)) { + firstString++; + secondString++; + } + return *(const UInt8*) firstString - *(const UInt8*) secondString; +} + +Int32 StringCompareWithLimit(const ASCII* firstString, const ASCII* secondString, Size limit) { + while (limit > 0) { + if (*firstString != *secondString) return *(const UInt8*) firstString - *(const UInt8*) secondString; + if (*firstString == '\0') return 0; + firstString++; + secondString++; + limit--; + } + + return 0; +} + +ASCII* StringCopy(ASCII* destination, const ASCII* source) { + ASCII* saved = destination; + while (*source) *destination++ = *source++; + *destination = 0; + return saved; +} + +ASCII* StringCopyWithLimit(ASCII* destination, const ASCII* source, Size limit) { + ASCII* saved = destination; + while (*source && limit > 0) { + *destination++ = *source++; + limit--; + } + while (limit > 0) { + *destination++ = 0; + limit--; + } + return saved; +} + +Size StringGetLength(const ASCII* string) { + Size result = 0; + for (result = 0; string[result]; result++); + return result; +} + +const ASCII* StringFindLastOccurrenceOfCharacter(const ASCII* string, ASCII separator) { + const ASCII* lastSeparator = 0; + do { + if (*string == separator) lastSeparator = string; + } while (*string++); + + return lastSeparator; +} + +Int32 StringFormatVariadic(ASCII* string, Size size, const ASCII* format, va_list args) { + Size written = 0; + for (Size i = 0; format[i] != '\0'; i++) { + if (format[i] == '%') { + i++; + if (format[i] == '\0') break; + switch (format[i]) { + case 's': { + const ASCII* vaArgString = va_arg(args, const ASCII*); + if (!vaArgString) vaArgString = "(null)"; + while (*vaArgString) BufferAdd(string, size, &written, *vaArgString++); + break; + } + case 'c': { + ASCII character = (ASCII)va_arg(args, Int); + BufferAdd(string, size, &written, character); + break; + } + case 'd': { + Int64 number = va_arg(args, Int); + if (number < 0) { + BufferAdd(string, size, &written, '-'); + number = -number; + } + + UInt64 unsignedNumber = (UInt64)number; + ASCII tempBuffer[32]; + Size position = 0; + + if (unsignedNumber == 0) tempBuffer[position++] = '0'; + while (unsignedNumber > 0) { + tempBuffer[position++] = (ASCII)((unsignedNumber % 10) + '0'); + unsignedNumber /= 10; + } + + while (position > 0) BufferAdd(string, size, &written, tempBuffer[--position]); + break; + } + case 'x': + case 'X': { + UInt64 unsignedNumber = va_arg(args, UInt64); + UInt8 padding = (format[i] == 'X') ? 16 : 0; + + ASCII tempBuffer[32]; + Size position = 0; + static const ASCII kHexDigits[] = "0123456789ABCDEF"; + + if (unsignedNumber == 0 && padding == 0) tempBuffer[position++] = '0'; + while (unsignedNumber > 0) { + tempBuffer[position++] = kHexDigits[unsignedNumber % 16]; + unsignedNumber /= 16; + } + + while (position < (Size)padding) tempBuffer[position++] = '0'; + while (position > 0) BufferAdd(string, size, &written, tempBuffer[--position]); + break; + } + case '%': { + BufferAdd(string, size, &written, '%'); + break; + } + default: { + BufferAdd(string, size, &written, '%'); + BufferAdd(string, size, &written, format[i]); + break; + } + } + } else { + BufferAdd(string, size, &written, format[i]); + } + } + + if (size > 0) { + if (written < size) string[written] = '\0'; + else string[size - 1] = '\0'; + } + + return (Int32)written; +} + +Int32 StringFormat(ASCII* destination, UInt64 size, const ASCII* format, ...) { + va_list args; + va_start(args, format); + Int32 returnValue = StringFormatVariadic(destination, size, format, args); + va_end(args); + return returnValue; +} \ No newline at end of file diff --git a/Kernel/Source/OS/Log.c b/Kernel/Source/OS/Log.c new file mode 100644 index 0000000..d69be46 --- /dev/null +++ b/Kernel/Source/OS/Log.c @@ -0,0 +1,15 @@ +#include +#include +#include +#include + +void OSLog(const ASCII* format, ...) { + ASCII buffer[kOSLogBufferSize]; + + va_list args; + va_start(args, format); + StringFormatVariadic(buffer, kOSLogBufferSize, format, args); + va_end(args); + + IOSerialPutString(buffer); +} \ No newline at end of file