diff --git a/kernel/kernel.c b/kernel/kernel.c index b77af8e..c0ca65c 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -1,9 +1,7 @@ -#include -#include -#include -#include +#include #include #include +#include #include #include #include @@ -24,8 +22,26 @@ #include #include #include +#include #include +/* Little teaser +#include +void mathTest() { + printf("|-4| = %d\n", abs(-4)); + printf("|-3.14| = %f\n", fabs(-3.14)); + printf("e^3 = %f\n", exp(3)); + printf("e^5 = %f\n", exp2(5)); + printf("ln(2) = %f\n", log(2)); + printf("log2(69) = %f\n", log2(69)); + printf("log10(100) = %f\n", log10(100)); + printf("sqrt(2) = %f\n", sqrt(2)); + printf("cbrt(27) = %f\n", cbrt(27)); + printf("hyp(8, 6) = %f\n", hypot(8, 6)); + printf("3^4 = %f\n", pow(3, 4)); +} +*/ + #define PROMPT "#>" // FS things @@ -45,24 +61,27 @@ void main() { maxBlocks = *(uint32_t*)PHYS_MEM_MAX_BLOCKS; usedBlocks = *(uint32_t*)PHYS_MEM_USED_BLOCKS; - // Interrupt setup - setupIdt(); - setupExceptions(); - idtSetGate(0x80, syscallHandler, USR_INT_GAME_FLAGS); // Setup Syscall handler in IDT for int 0x80 - disableIrqs(); - remapPic(); - unsetIrqMask(2); // Enable PIC 2 line - __asm__ volatile ("sti"); - - setupTimer(); - setupRtc(); - setupKeyboard(); + // Setup serial output for debugf() if (setupSerial(PORT_COM1) != 0) { printf("\x1b[1MFailed to initialize serial interface\x1b[8M\n"); } else { - serialPrint(PORT_COM1, "\x1b[H\x1b[J"); + serialPrint(PORT_COM1, "\x1b[H\x1b[J"); // Clear serialPrint(PORT_COM1, "kern. \x1b[36m(Serial console)\x1b[0m\n\n"); } + // Interrupt setup + setupIsrs(); + + // Programmable Interval Timer + registerIrq(0, timerHandler); + setPitPhase(0, 2, 1000); // 1000Hz + + // Real Time Clock + registerIrq(8, rtcHandler); + enableRtc(); + + // Keyboard + registerIrq(1, keyboardHandler); + // Setup kernel malloc variables mallocNode_t* kernelMallocListHead = 0; uint32_t kernelMallocVirtualAddr = KERNEL_MALLOC_AREA; @@ -89,16 +108,26 @@ void main() { strcpy(cwd, "/"); // Terminal setup - terminal->fg = FG_COLOR; - terminal->bg = BG_COLOR; + console->fg = FG_COLOR; + console->bg = BG_COLOR; printf("\x1b[J"); // Clear printf("kern.\n\n"); + while (1) { + printf("\x1b[6M%s \x1b[2M%s \x1b[8M", cwd, PROMPT); + char input[256]; + char* inPtr = &input[0]; + + reads(inPtr); + } +} + +int _m() { // Run Interactive Shell Program // TODO: Make it in another file while (1) { - printf("\x1b[6M\x1b[8N%s \x1b[2M%s \x1b[8M", cwd, PROMPT); + printf("\x1b[6M%s \x1b[2M%s ", cwd, PROMPT); char input[256]; char* inputPtr = input; diff --git a/libc/include/math.h b/libc/include/math.h index a434242..6b0e7db 100644 --- a/libc/include/math.h +++ b/libc/include/math.h @@ -2,15 +2,68 @@ #define _MATH_H // Constants -#define PI 3.141592653589 // Should be good enough -#define E 2.718281828459 +#define M_E 2.71828182845904523536 // e +#define M_LOG2E 1.44269504088896340736 // log_2 e +#define M_LOG10E 0.43429448190325182765 // log_10 e +#define M_LN2 0.69314718055994530941 // ln(2) +#define M_LN10 2.30258509299404568402 // ln(10) +#define M_PI 3.14159265358979323846 // pi +#define M_PI_2 1.57079632679489661923 // pi/2 +#define M_PI_4 0.78539816339744830961 // pi/4 +#define M_1_PI 0.31830988618379067153 // 1/pi +#define M_2_PI 0.63661977236758134307 // 2/pi +#define M_SQRT2 1.41421356237309504880 // sqrt(2) +#define M_SQRT1_2 0.70710678118654752440 // 1/sqrt(2) -// Macros -#define abs(x) ( (x) > 0 ? (x) : -(x) ) -#define sign(x) ( (x) == 0 ? 0 : ((x) < 0 ? -1 : 1 ) ) +// TODO: +#define NAN (__builtin_inff()) +#define INFINITY (__builtin_nanf("")) -#define floor(x) ( (int)(x) ) // C floors floats when converting to ints -#define round(x) ( (int)((x) + 0.5) ) // Normal rounding -#define ceil(x) ( (int)((x) + 1) ) // Always rounds up +// Absolute value +int abs(int n); +double fabs(double n); + +// Exponential & logarithmic +double exp(double x); +double exp2(double x); +double log(double x); +double log2(double x); +double log10(double x); +double logn(double x, double n); + +// Power +double sqrt(double x); +double cbrt(double x); +double hypot(double x, double y); +double pow(double base, double expn); + +// Trigonometric +double sin(double x); +double cos(double x); +double tan(double x); +double asin(double x); +double acos(double x); +double atan(double x); +double atan2(double y, double x); + +// Hyperbolic +double sinh(double x); +double cosh(double x); +double tanh(double x); + +// Rounding & remainder +double floor(double x); +double ceil(double x); +double round(double x); +double trunc(double x); +double fmod(double x, double y); +double modf(double x, double* iptr); + +// Error handling +double nan(const char* tagp); +double inf(); +int isfinite(double x); +int isinf(double x); +int isnan(double x); #endif diff --git a/libc/include/syscall.h b/libc/include/syscall.h index 6fddedc..af9ebe6 100644 --- a/libc/include/syscall.h +++ b/libc/include/syscall.h @@ -6,15 +6,15 @@ #define MAX_SYSCALLS 9 typedef enum { - SYS_RESERVED, - SYS_SLEEP, + SYS_EXIT, SYS_READ, SYS_WRITE, SYS_OPEN, SYS_CLOSE, + SYS_SEEK, SYS_MALLOC, SYS_FREE, - SYS_SEEK, + SYS_SLEEP, } SYSCALL_NUMBERS; typedef enum { diff --git a/libc/math/abs.c b/libc/math/abs.c new file mode 100644 index 0000000..d59322b --- /dev/null +++ b/libc/math/abs.c @@ -0,0 +1,10 @@ +#include + +int abs(int n) { + return (n < 0) ? -n : n; +} + +double fabs(double x) { + return (x < 0.0) ? -x : x; +} + diff --git a/libc/math/const.c b/libc/math/const.c new file mode 100644 index 0000000..4d19e36 --- /dev/null +++ b/libc/math/const.c @@ -0,0 +1,43 @@ +#include + +double nan(const char* tagp) { + (void)tagp; + + // Create a NaN bit pattern in IEEE 754 + uint64_t nanBits = 0x7ff8000000000000ULL; + double result; + memcpy(&result, &nanBits, sizeof(result)); + return result; +} + +double inf() { + // Create an infinity bit pattern in IEEE 754 + uint64_t infBits = 0x7ff0000000000000ULL; + double result; + memcpy(&result, &infBits, sizeof(result)); + return result; +} + +int isfinite(double x) { + uint64_t bits; + memcpy(&bits, &x, sizeof(bits)); + uint64_t exponent = (bits >> 52) & 0x7ff; + return exponent != 0x7ff; +} + +int isinf(double x) { + uint64_t bits; + memcpy(&bits, &x, sizeof(bits)); + uint64_t exponent = (bits >> 52) & 0x7ff; + uint64_t mantissa = bits & 0xfffffffffffff; + return (exponent == 0x7ff && mantissa == 0); +} + +int isnan(double x) { + uint64_t bits; + memcpy(&bits, &x, sizeof(bits)); + uint64_t exponent = (bits >> 52) & 0x7ff; + uint64_t mantissa = bits & 0xfffffffffffff; + return (exponent == 0x7ff && mantissa != 0); +} + diff --git a/libc/math/exp.c b/libc/math/exp.c new file mode 100644 index 0000000..dfb011a --- /dev/null +++ b/libc/math/exp.c @@ -0,0 +1,46 @@ +#include + +#define _EXP_TAYLOR_TERMS 10 +#define _EXP2_TAYLOR_TERMS 5 + +double exp(double x) { + if (x == 0.0) return 1.0; + if (x < 0.0) return 1.0 / exp(-x); + + double sum = 1.0; // Result + double term = 1.0; // Curent term in the series + + /* + Calculate the Taylor series: + e^x = 1 + x + x^2/2! + x^3/3! + ... + */ + for (int i = 1; i < _EXP_TAYLOR_TERMS; i++) { + term *= x / (double)i; + sum += term; + } + + return sum; +} + +double exp2(double x) { + if (x == 0.0) return 1.0; + if (x < 0.0) return 1.0 / exp2(-x); + + int n = (int)x; // Integer part + double frac = x - n;// Fractional part + + // Integer power of 2 + double result = (double)(1 << n); // 2^n is just 1 << n + + // Approximate the fractional part + double sum = 1.0; + double term = frac; + + for (int i = 1; i < _EXP2_TAYLOR_TERMS; i++) { + sum += term; + term *= frac / (i+1); + } + + return result * sum; +} + diff --git a/libc/math/htrig.c b/libc/math/htrig.c new file mode 100644 index 0000000..91e8dd9 --- /dev/null +++ b/libc/math/htrig.c @@ -0,0 +1,16 @@ +#include + +double sinh(double x) { + return (exp(x) - exp(-x)) / 2.0; +} + +double cosh(double x) { + return (exp(x) + exp(-x)) / 2.0; +} + +double tanh(double x) { + double ex = exp(x); + double emx = exp(-x); + return (ex - exp) / (ex + exp); +} + diff --git a/libc/math/log.c b/libc/math/log.c new file mode 100644 index 0000000..808aeb7 --- /dev/null +++ b/libc/math/log.c @@ -0,0 +1,35 @@ +#include + +#define _LOG_TERMS 20 + +double log(double x) { + if (x <= 0.0) return -INFINITY; + + double result = 0.0; + double term = (x - 1.0) / (x + 1.0); + double termSquared = term*term; + double numerator = term; + + for (int i = 1; i < _LOG_TERMS; i++) { + result += numerator / (double)i; + numerator *= termSquared; + } + + return 2.0 * result; +} + +double log2(double x) { + if (x <= 0.0) return -INFINITY; + return log(x) / M_LN2; +} + +double log10(double x) { + if (x <= 0.0) return -INFINITY; + return log(x) / M_LN10; +} + +double logn(double x, double n) { + if (x <= 0.0) return -INFINITY; + return log(x) / log(n); +} + diff --git a/libc/math/pow.c b/libc/math/pow.c new file mode 100644 index 0000000..db11e3a --- /dev/null +++ b/libc/math/pow.c @@ -0,0 +1,42 @@ +#include + +#define _POW_LOOP_MAX 60 + +double sqrt(double x) { + if (x < 0.0) return -NAN; + + double result = x; + double oldResult = 0.0; + + while (result != oldResult) { + oldResult = result; + result = 0.5 * (result + x/result); + } + + return result; +} + +double cbrt(double x) { + double result = x; + double oldResult = 0.0; + + while (result != oldResult) { + oldResult = result; + result = (2.0 * result + x/(result * result)) / 3.0; + } + + return result; +} + +double hypot(double x, double y) { + return sqrt(x*x + y*y); +} + +double pow(double base, double expn) { // exp is a function so we have to use expn + if (base == 0.0 && expn == 0.0) return NAN; + if (base == 0.0) return 0.0; + if (expn == 0.0) return 1.0; + + return exp(expn * log(base)); +} + diff --git a/libc/math/round.c b/libc/math/round.c new file mode 100644 index 0000000..bbda40e --- /dev/null +++ b/libc/math/round.c @@ -0,0 +1,46 @@ +#include + +double round(double x) { + double res; + __asm__ volatile ( + "fldl %1\n" // Load x to the FPU stack + "frndint\n" // Round to nearest integer + "fstpl %0" // Store result + : "=m"(res) + : "m"(x) + ); + if ((x - res) == 0.5 || (x - res) == -0.5) { + // Halfway cases: round away from zero + res += (x > 0) ? 1.0 : -1.0; + } + return res; +} + +double floor(double x) { + double res = round(x); + if (res > x) { res -= 1.0; } + return res; +} + +double ceil(double x){ + double res = round(x); + if (res < x) { res += 1.0; } + return res; +} + +double trunc(double x) { + double res = round(x); + if (x < 0 && x != res) { res -= 1.0; } + return res; +} + +double fmod(double x, double y) { + return x - y * floor(x / y); +} + +double modf(double x, double* iptr) { + double whole = trunc(x); + *iptr = whole; + return x - whole; +} + diff --git a/libc/math/trig.c b/libc/math/trig.c new file mode 100644 index 0000000..3497631 --- /dev/null +++ b/libc/math/trig.c @@ -0,0 +1,61 @@ +#include + +double sin(double x) { + double res; + __asm__ volatile ( + "fldl %1\n" // Load x to the FPU stack + "fsin\n" // Compute sin(x) + "fstpl %0" // Store result + : "=m"(res) : "m"(x) + ); + return res; +} + +double cos(double x) { + double res; + __asm__ volatile ( + "fldl %1\n" // Load x to the FPU stack + "fcos\n" // Compute cos(x) + "fstpl %0" // Store result + : "=m"(res) : "m"(x) + ); + return res; +} + + +double tan(double x) { + return sin(x) / cos(x); +} + +double asin(double x) { + return atan2(x, sqrt(1 - x*x)); +} + +double acos(double x) { + return M_PI_2 - asin(x); +} + +double atan(double x) { + double res; + __asm__ volatile ( + "fld1\n" // Load 1.0 to the FPU stack + "fldl %1\n" // Load x to the FPU stack + "fpatan\n" // Compute atan(x) + "fstpl %0" // Store result + : "=m"(res) : "m"(x) + ); + return res; +} + +double atan2(double y, double x) { + double res; + __asm__ volatile ( + "fldl %2\n" // Load x to the FPU stack + "fldl %1\n" // Load y to the FPU stack + "fpatan\n" // Compute atan2(y, x) + "fstpl %0" // Store the result + : "=m"(res) : "m"(y), "m"(x) + ); + return res; +} + diff --git a/make.defaults b/make.defaults index c0c91aa..375d5ef 100644 --- a/make.defaults +++ b/make.defaults @@ -12,8 +12,8 @@ MAKE = make # Flags CFLAGS = -Wall -Wextra -Wno-pointer-sign -Wno-pointer-arith -Wno-unused-parameter\ -Os -std=c17 -nostdinc -g -Werror\ - -ffreestanding -fno-stack-protector -fno-builtin -fno-pie\ - -m32 -mgeneral-regs-only -march=i386 + -ffreestanding -fno-stack-protector -fno-builtin -fno-pie -fcommon\ + -m32 -march=i386 LDFLAGS = -z notext -melf_i386 -nostdlib ASFLAGS = diff --git a/todo.txt b/todo.txt index 47f1b53..77c79ac 100644 --- a/todo.txt +++ b/todo.txt @@ -128,20 +128,18 @@ Legend: - [ ] Hyperbolic versions - [x] Absolute value - [ ] isOdd() 🗿 - - [ ] Exponential fn (e^x) - - [ ] Logarithm - - [ ] Power - - [ ] Square Root - - [ ] Nth Root - - [x] Floor - - [x] Round - - [x] Ceiling + - [x] Exponential fn (e^x) + - [x] Logarithm + - [x] Power + - [x] Square Root + - [ ] Floor + - [ ] Round + - [ ] Ceiling - [x] Sign - - [ ] INFINITY - - [ ] NAN + - [x] INFINITY + - [x] NAN - [x] E (eulers number) - [x] PI - - [ ] Floating point macros/functions - [ ] Filesystem - [x] Utility for filesystem building (not just an assembly file)