/************************ *** Team Kitty, 2019 *** *** Sync *** ***********************/ /* This file contains utility functions * for the kernel and OS to use. They * will be naturally optimized through * the run of development, and thus are * to be used scarcely until a more * permanent solution can be found. */ #include #include #include #include #include #include /* Returns the length of a given string. * @param string: String to count */ size_t strlen(const char* string) { size_t size = 0; while (string[size]) size++; return size; } /* Read data from a port. Effectively communicates with hardware. * @param port: The port number to read, as a hex short. */ uint8_t inb(uint16_t port) { uint8_t ptr; asm volatile("inb %1, %0" : "=a" (ptr) : "dN" (port)); return ptr; } /* Write data to a port. Effectively communicates with hardware. * @param port: The port to read * @param data: A pointer to which the data will be stored. */ void outb(uint16_t port, uint8_t data) { asm volatile("outb %1, %0" : : "dN" (port), "a" (data)); } /* Memory Copy. Required by GCC. * @param dest: The destination in memory, to which the data will be copied. * @param src: The source of the data which will be copied. * @param n: The length of the copy, in byets. */ void memcpy(void* dest, void* src, size_t n) { char* src_c = (char*)src; char* dest_c = (char*)dest; for(size_t i = 0; i < n; i++) { dest_c[i] = src_c[i]; } } /* Memory Set. Required by GCC> * @param src: The data to be overwritten. * @param chr: The byte to overwrite the source with. * @param n: How many bytes to overwrite. */ void memset(void* src, int chr, size_t n) { uint8_t* ptr = src; while(n--) { *ptr++ = (uint8_t) chr; } } /* Turns an integer into a C-str. * @note Inefficient and unsafe. * @param num: The number to convert * @param string: The string to be written into. */ void int_to_ascii(int num, char* string) { size_t i = 0; //Counter. // TODO: Convert this to a for-loop? int32_t calc = 0; bool negative = false; if(num == 0) { string[0] = '0'; string[1] = '\0'; return; } // TODO: Implement this as an abs() function? if(num < 0) { num = -num; string[i] = '-'; i++; } while(num != 0) { // Overall this looks pretty confusing. // TODO: cleanup? calc = num % 10; // Gets the lowest digit, num = num / 10; // Shifts the other digits down to prepare for the next iteration. calc += 48; // Convert the number to an ASCII value string[i] = calc;// Set the current position in the string i++; // Increase for the next number. } // ! This code does weird things. // It serves an unknown purpose, and should not be used, but is left here just in case. /* for(size_t j = 0; j < i/2; j++) { calc = string[j]; string[j] = string[i-j-1]; string[j-i-1] = calc; } */ } /* A strange version of the above function. Different way of doing the same thing? * @param num: the number to convert. Must be positive * @retval The new string. */ char* itoc(size_t num) { char* result; size_t tmp_value; do { tmp_value = num; num /= 10; *result++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" [35 + (tmp_value - num * 10)]; }while (num); return result; } /* Same as itoa, but for hexadecimal. * @param num: Number to convert * @param string: String pointer to put the converted number. */ void int_to_hex(int num, char* string) { empty_string(string); uint8_t i = 8; uint8_t temp = 0; while(i != 0) { i--; temp = num & 0xF; num = num >> 4; if(temp >= 10) { temp += 7; } temp += 48; string[i] = temp; } } /* Converts a C-str to an empty C-str. :) * @param string: The string to empty. */ void empty_string(char* string) { size_t len = strlen(string); for(size_t i = 0; i < len + 1; i++) { string[i] = '\0'; } } /* The signal that everything has gone wrong. Equivalent to a linux kernel panic and a Windows Blue Screen. TODO: Needs to be re-engineered to give as much useful information as possible. Ideally also have a visual interface, XP installer style. * @param cause: A string, telling the basic reason for the crash. */ void panic(char* cause) { term_writes("\n\n>>>> PANIC <<<<\nCaused by: "); term_writes(cause); for(;;); }