2019-06-27 18:57:54 +00:00
|
|
|
/************************
|
|
|
|
*** Team Kitty, 2019 ***
|
2019-07-17 01:04:04 +00:00
|
|
|
*** Sync ***
|
2019-06-27 18:57:54 +00:00
|
|
|
***********************/
|
2019-07-17 01:04:04 +00:00
|
|
|
|
|
|
|
/* 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.
|
|
|
|
*/
|
2019-06-27 18:57:54 +00:00
|
|
|
|
2019-04-07 14:34:15 +00:00
|
|
|
#include <kernel/utils.h>
|
2019-06-27 18:57:54 +00:00
|
|
|
#include <kernel/tty.h>
|
2019-04-07 14:34:15 +00:00
|
|
|
#include <stddef.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <stdbool.h>
|
2019-04-01 11:21:00 +00:00
|
|
|
#include <stddef.h>
|
|
|
|
|
2019-06-27 18:57:54 +00:00
|
|
|
/*
|
|
|
|
Returns the length of a given string.
|
|
|
|
* @param string: String to count
|
|
|
|
*/
|
2019-04-01 11:21:00 +00:00
|
|
|
size_t strlen(const char* string) {
|
|
|
|
size_t size = 0;
|
|
|
|
while (string[size])
|
|
|
|
size++;
|
|
|
|
return size;
|
2019-04-03 08:51:46 +00:00
|
|
|
}
|
|
|
|
|
2019-06-27 18:57:54 +00:00
|
|
|
/*
|
|
|
|
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;
|
2019-04-03 08:51:46 +00:00
|
|
|
asm volatile("inb %1, %0" : "=a" (ptr) : "dN" (port));
|
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
|
2019-06-27 18:57:54 +00:00
|
|
|
/*
|
|
|
|
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) {
|
2019-04-03 08:51:46 +00:00
|
|
|
asm volatile("outb %1, %0" : : "dN" (port), "a" (data));
|
2019-04-07 12:16:53 +00:00
|
|
|
}
|
|
|
|
|
2019-06-27 18:57:54 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
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.
|
|
|
|
*/
|
2019-04-07 12:16:53 +00:00
|
|
|
void memcpy(void* dest, void* src, size_t n) {
|
|
|
|
char* src_c = (char*)src;
|
2019-06-25 21:31:26 +00:00
|
|
|
char* dest_c = (char*)dest;
|
2019-04-07 12:16:53 +00:00
|
|
|
|
|
|
|
for(size_t i = 0; i < n; i++) {
|
|
|
|
dest_c[i] = src_c[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-27 18:57:54 +00:00
|
|
|
/*
|
|
|
|
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.
|
|
|
|
*/
|
2019-04-07 12:16:53 +00:00
|
|
|
void memset(void* src, int chr, size_t n) {
|
2019-06-27 18:57:54 +00:00
|
|
|
uint8_t* ptr = src;
|
2019-04-07 12:16:53 +00:00
|
|
|
while(n--) {
|
2019-06-27 18:57:54 +00:00
|
|
|
*ptr++ = (uint8_t) chr;
|
2019-04-07 12:16:53 +00:00
|
|
|
}
|
|
|
|
}
|
2019-04-07 14:34:15 +00:00
|
|
|
|
2019-06-27 18:57:54 +00:00
|
|
|
/*
|
|
|
|
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.
|
|
|
|
*/
|
|
|
|
|
2019-04-07 14:34:15 +00:00
|
|
|
void int_to_ascii(int num, char* string) {
|
|
|
|
size_t i = 0; //Counter.
|
2019-06-27 18:57:54 +00:00
|
|
|
// TODO: Convert this to a for-loop?
|
2019-04-07 14:34:15 +00:00
|
|
|
int32_t calc = 0;
|
|
|
|
bool negative = false;
|
|
|
|
|
|
|
|
if(num == 0) {
|
|
|
|
string[0] = '0';
|
|
|
|
string[1] = '\0';
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-06-27 18:57:54 +00:00
|
|
|
// TODO: Implement this as an abs() function?
|
2019-04-07 14:34:15 +00:00
|
|
|
if(num < 0) {
|
|
|
|
num = -num;
|
2019-06-27 18:57:54 +00:00
|
|
|
string[i] = '-';
|
|
|
|
i++;
|
2019-04-07 14:34:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
while(num != 0) {
|
2019-06-27 18:57:54 +00:00
|
|
|
// 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
|
2019-04-07 14:34:15 +00:00
|
|
|
|
2019-06-27 18:57:54 +00:00
|
|
|
string[i] = calc;// Set the current position in the string
|
|
|
|
i++; // Increase for the next number.
|
2019-04-07 14:34:15 +00:00
|
|
|
}
|
|
|
|
|
2019-06-27 18:57:54 +00:00
|
|
|
// ! This code does weird things.
|
|
|
|
// It serves an unknown purpose, and should not be used, but is left here just in case.
|
|
|
|
/*
|
2019-04-07 14:34:15 +00:00
|
|
|
for(size_t j = 0; j < i/2; j++) {
|
|
|
|
calc = string[j];
|
|
|
|
string[j] = string[i-j-1];
|
|
|
|
string[j-i-1] = calc;
|
|
|
|
}
|
2019-06-27 18:57:54 +00:00
|
|
|
*/
|
2019-04-07 14:34:15 +00:00
|
|
|
}
|
|
|
|
|
2019-06-27 18:57:54 +00:00
|
|
|
/*
|
|
|
|
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.
|
|
|
|
*/
|
2019-06-25 21:31:26 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2019-06-27 18:57:54 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
Same as itoa, but for hexadecimal.
|
|
|
|
* @param num: Number to convert
|
|
|
|
* @param string: String pointer to put the converted number.
|
|
|
|
*/
|
2019-04-07 14:34:15 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-27 18:57:54 +00:00
|
|
|
/*
|
|
|
|
Converts a C-str to an empty C-str. :)
|
|
|
|
* @param string: The string to empty.
|
|
|
|
*/
|
|
|
|
|
2019-04-07 14:34:15 +00:00
|
|
|
void empty_string(char* string) {
|
|
|
|
size_t len = strlen(string);
|
|
|
|
|
|
|
|
for(size_t i = 0; i < len + 1; i++) {
|
|
|
|
string[i] = '\0';
|
|
|
|
}
|
2019-06-25 21:31:26 +00:00
|
|
|
}
|
2019-06-27 18:57:54 +00:00
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
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(;;);
|
|
|
|
|
|
|
|
}
|