Syncboot/kernel/utils.c

201 lines
4.6 KiB
C
Raw Normal View History

/************************
*** 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 <kernel/utils.h>
#include <kernel/tty.h>
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
/*
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(;;);
}