diff --git a/lib/printf.c b/lib/printf.c new file mode 100644 index 0000000..4a0efcb --- /dev/null +++ b/lib/printf.c @@ -0,0 +1,183 @@ +#include +#include +#include +#include + +#include + +void printwc(const char* str, uint8_t color) +{ + uint8_t c = terminal_getcolor(); + terminal_setcolor(color); + printf(str); + terminal_setcolor(c); +} + +void printd(const char* str) +{ + terminal_debug_writestring(str); +} + +void printdc(const char* str, uint8_t color) +{ + uint8_t c = terminal_getcolor(); + terminal_setcolor(color); + printd(str); + terminal_setcolor(c); +} + +void printf(const char* format, ...) { + va_list args; + va_start(args, format); + + for (size_t i = 0; format[i] != '\0'; ++i) { + if (format[i] == '%' && format[i + 1] != '\0') { + ++i; + + // Parse width (only supports zero-padding like %04x) + int width = 0; + if (format[i] == '0') { + ++i; + while (format[i] >= '0' && format[i] <= '9') { + width = width * 10 + (format[i] - '0'); + ++i; + } + } + + switch (format[i]) { + case 's': { + const char* str = va_arg(args, const char*); + terminal_writestring(str ? str : "(null)"); + break; + } + case 'c': { + char c = (char) va_arg(args, int); + terminal_putchar(c); + break; + } + case 'd': + case 'i': { + int32_t val = va_arg(args, int32_t); + print_int(val); + break; + } + case 'u': { + uint32_t val = va_arg(args, uint32_t); + print_uint(val); + break; + } + case 'x': { + uint32_t val = va_arg(args, uint32_t); + print_hex(val, width, false); + break; + } + case 'X': { + uint32_t val = va_arg(args, uint32_t); + print_hex(val, width, true); + break; + } + case 'p': { + void* ptr = va_arg(args, void*); + terminal_writestring("0x"); + print_hex((uint32_t)(uintptr_t)ptr, 8, true); // assumes 32-bit pointer + break; + } + case 'f': + case 'F': { + double val = va_arg(args, double); // double is promoted from float + print_double(val, 2); // 2 decimal places + break; + } + case '%': { + terminal_putchar('%'); + break; + } + default: { + terminal_putchar('%'); + terminal_putchar(format[i]); + break; + } + } + } else { + terminal_putchar(format[i]); + } + } + + va_end(args); +} + +void print_double(double value, int precision) +{ + // Handle the integer part + int32_t integer_part = (int32_t)value; + double fractional_part = value - integer_part; + + // Print the integer part + print_int(integer_part); + + // Print the decimal point + terminal_putchar('.'); + + // Print the fractional part (scaled up) + fractional_part *= 1; + for (int i = 0; i < precision; i++) { + fractional_part *= 10; + } + + int32_t frac_int = (int32_t)fractional_part; + print_int(frac_int); +} + +void print_uint(uint32_t value) { + char buffer[11]; // Enough for 32-bit unsigned int + int i = 0; + + do { + buffer[i++] = '0' + (value % 10); + value /= 10; + } while (value > 0); + + while (i--) { + terminal_putchar(buffer[i]); + } +} + +void print_int(int32_t value) { + char buffer[12]; // Enough for 32-bit signed int (-2147483648) + int i = 0; + uint32_t u; + + if (value < 0) { + terminal_putchar('-'); + u = (uint32_t)(-value); + } else { + u = (uint32_t)value; + } + + // Convert to string in reverse + do { + buffer[i++] = '0' + (u % 10); + u /= 10; + } while (u > 0); + + // Print in correct order + while (i--) { + terminal_putchar(buffer[i]); + } +} + +void print_hex(uint32_t value, int width, bool uppercase) +{ + const char* hex_chars = uppercase ? "0123456789ABCDEF" : "0123456789abcdef"; + char buffer[9]; // 8 hex digits max for 32-bit + int i = 0; + + do { + buffer[i++] = hex_chars[value & 0xF]; + value >>= 4; + } while (value || i < width); // ensure at least 'width' digits + + while (i--) { + terminal_putchar(buffer[i]); + } +} diff --git a/lib/processes.c b/lib/processes.c new file mode 100644 index 0000000..a84eafb --- /dev/null +++ b/lib/processes.c @@ -0,0 +1,5 @@ +#include + +#include + + diff --git a/lib/string.c b/lib/string.c new file mode 100644 index 0000000..47660be --- /dev/null +++ b/lib/string.c @@ -0,0 +1,160 @@ +#include + +#include + +extern int16_t sse_initialized; + +size_t strlen(const char* str) +{ + size_t len = 0; + while (str[len]) len++; + return len; +} + +size_t strcmp(const char *s1, const char *s2) +{ + int32_t i = 0; + + while ((s1[i] == s2[i])) + { + if (s2[i++] == 0) + { + return 0; + } + } + return 1; +} + +int32_t strncmp(const char *s1, const char *s2, size_t n) +{ + while (n--) + { + unsigned char c1 = (unsigned char)*s1++; + unsigned char c2 = (unsigned char)*s2++; + if (c1 != c2) + { + return c1 - c2; + } + if (c1 == '\0') + { + break; + } + } + return 0; +} + + +size_t strcpy(char *dst, const char *src) +{ + int32_t i = 0; + while ((*dst++ = *src++) != 0) + i++; + return i; +} + +char *strncpy(char *dest, const char *src, uint32_t n) +{ + if (sse_initialized > 0) + { + return sse2_strncpy(dest, src, n); + } + + uint32_t i = 0; + for (; i < n && src[i]; ++i) + dest[i] = src[i]; + + for (; i < n; ++i) + dest[i] = '\0'; + + return dest; +} + +void strcat(char *dest, const char *src) +{ + char *end = (char *)dest + strlen(dest); + memcpy((void *)end, (void *)src, strlen(src)); + end = end + strlen(src); + *end = '\0'; +} + +void *memset(void *dst, char c, uint32_t n) +{ + char *temp = dst; + for (; n != 0; n--) *temp++ = c; + return dst; +} + +void *memcpy(void *dst, const void *src, uint32_t n) +{ + if (sse_initialized > 0) + { + return sse2_memcpy(dst, src, n); + } + + char *ret = dst; + char *p = dst; + const char *q = src; + while (n--) + *p++ = *q++; + return ret; +} + +int32_t memcmp(uint8_t *s1, uint8_t *s2, uint32_t n) +{ + while (n--) + { + if (*s1 != *s2) + return 0; + s1++; + s2++; + } + return 1; +} + +void* memclr(const void * const m_start, const size_t m_count) +{ + if (sse_initialized > 0) + { + return memclr_sse2(m_start, m_count); + } + + return memset(m_start, '\0', (uint32_t)m_count); +} + +int32_t isspace(char c) +{ + return c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r'; +} + +int32_t isalpha(char c) +{ + return (((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z'))); +} + +int32_t ischar(int32_t c) +{ + return ((c >= 32) && (c <= 126)); +} + +char upper(char c) +{ + if ((c >= 'a') && (c <= 'z')) + return (c - 32); + return c; +} + +char toupper(char c) +{ + if ((c >= 'a') && (c <= 'z')) + { + return (c - 32); + } + return c; +} + +char lower(char c) +{ + if ((c >= 'A') && (c <= 'Z')) + return (c + 32); + return c; +} diff --git a/lib/syscall.c b/lib/syscall.c new file mode 100644 index 0000000..49f6d35 --- /dev/null +++ b/lib/syscall.c @@ -0,0 +1,4 @@ +#include + + +#include