168 lines
4.8 KiB
C
168 lines
4.8 KiB
C
![]() |
/*
|
||
|
File: utils.C
|
||
|
|
||
|
Author: R. Bettati
|
||
|
Department of Computer Science
|
||
|
Texas A&M University
|
||
|
|
||
|
Date : 09/02/12
|
||
|
|
||
|
*/
|
||
|
|
||
|
/* Some of the code comes from Brandon Friesens OS Tutorial:
|
||
|
* bkerndev - Bran's Kernel Development Tutorial
|
||
|
* By: Brandon F. (friesenb@gmail.com)
|
||
|
* Desc: Interrupt Descriptor Table management
|
||
|
*
|
||
|
* Notes: No warranty expressed or implied. Use at own risk. */
|
||
|
|
||
|
|
||
|
/*--------------------------------------------------------------------------*/
|
||
|
/* DEFINES */
|
||
|
/*--------------------------------------------------------------------------*/
|
||
|
|
||
|
/* -- (none ) -- */
|
||
|
|
||
|
/*--------------------------------------------------------------------------*/
|
||
|
/* INCLUDES */
|
||
|
/*--------------------------------------------------------------------------*/
|
||
|
|
||
|
#include "utils.H"
|
||
|
|
||
|
/*--------------------------------------------------------------------------*/
|
||
|
/* DATA STRUCTURES */
|
||
|
/*--------------------------------------------------------------------------*/
|
||
|
|
||
|
/* -- (none) -- */
|
||
|
|
||
|
/*--------------------------------------------------------------------------*/
|
||
|
/* CONSTANTS */
|
||
|
/*--------------------------------------------------------------------------*/
|
||
|
|
||
|
/* -- (none) -- */
|
||
|
|
||
|
/*--------------------------------------------------------------------------*/
|
||
|
/* ABORT (USED e.g. IN _ASSERT() */
|
||
|
/*--------------------------------------------------------------------------*/
|
||
|
|
||
|
void abort() {
|
||
|
for(;;);
|
||
|
}
|
||
|
|
||
|
/*--------------------------------------------------------------------------*/
|
||
|
/* MEMORY OPERATIONS */
|
||
|
/*--------------------------------------------------------------------------*/
|
||
|
|
||
|
void *memcpy(void *dest, const void *src, int count)
|
||
|
{
|
||
|
const char *sp = (const char *)src;
|
||
|
char *dp = (char *)dest;
|
||
|
for(; count != 0; count--) *dp++ = *sp++;
|
||
|
return dest;
|
||
|
}
|
||
|
|
||
|
void *memset(void *dest, char val, int count)
|
||
|
{
|
||
|
char *temp = (char *)dest;
|
||
|
for( ; count != 0; count--) *temp++ = val;
|
||
|
return dest;
|
||
|
}
|
||
|
|
||
|
unsigned short *memsetw(unsigned short *dest, unsigned short val, int count)
|
||
|
{
|
||
|
unsigned short *temp = (unsigned short *)dest;
|
||
|
for( ; count != 0; count--) *temp++ = val;
|
||
|
return dest;
|
||
|
}
|
||
|
|
||
|
/*--------------------------------------------------------------------------*/
|
||
|
/* STRING OPERATIONS */
|
||
|
/*--------------------------------------------------------------------------*/
|
||
|
|
||
|
|
||
|
int strlen(const char *_str) {
|
||
|
/* This loops through character array 'str', returning how
|
||
|
* many characters it needs to check before it finds a 0.
|
||
|
* In simple words, it returns the length in bytes of a string */
|
||
|
int len = 0;
|
||
|
while (*_str != 0) {
|
||
|
_str++;
|
||
|
len++;
|
||
|
}
|
||
|
return len;
|
||
|
}
|
||
|
void strcpy(char* _dst, char* _src) {
|
||
|
while (*_src != 0) {
|
||
|
*_dst = *_src;
|
||
|
_dst++;
|
||
|
_src++;
|
||
|
}
|
||
|
*_dst = 0; // put terminating 0 at end.
|
||
|
}
|
||
|
|
||
|
void int2str(int _num, char * _str) {
|
||
|
/* -- THIS IMPLEMENTATION IS ONE PRETTY BAD HACK. */
|
||
|
int i;
|
||
|
char temp[11];
|
||
|
|
||
|
temp[0] = '\0';
|
||
|
for(i = 1; i <= 10; i++) {
|
||
|
temp[i] = _num % 10 + '0';
|
||
|
_num /= 10;
|
||
|
}
|
||
|
for(i = 10; temp[i] == '0'; i--);
|
||
|
if( i == 0 )
|
||
|
i++;
|
||
|
while( i >= 0 )
|
||
|
*_str++ = temp[i--];
|
||
|
}
|
||
|
|
||
|
|
||
|
void uint2str(unsigned int _num, char * _str) {
|
||
|
/* -- THIS IS A BAD HACK AS WELL. */
|
||
|
int i;
|
||
|
char temp[11];
|
||
|
|
||
|
temp[0] = '\0';
|
||
|
for(i = 1; i <= 10; i++) {
|
||
|
temp[i] = _num % 10 + '0';
|
||
|
_num /= 10;
|
||
|
}
|
||
|
for(i = 10; temp[i] == '0'; i--);
|
||
|
if( i == 0 )
|
||
|
i++;
|
||
|
while( i >= 0 )
|
||
|
*_str++ = temp[i--];
|
||
|
}
|
||
|
|
||
|
/*--------------------------------------------------------------------------*/
|
||
|
/* POERT I/O OPERATIONS */
|
||
|
/*--------------------------------------------------------------------------*/
|
||
|
|
||
|
/* We will use this later on for reading from the I/O ports to get data
|
||
|
* from devices such as the keyboard. We are using what is called
|
||
|
* 'inline assembly' in these routines to actually do the work */
|
||
|
char inportb (unsigned short _port) {
|
||
|
unsigned char rv;
|
||
|
__asm__ __volatile__ ("inb %1, %0" : "=a" (rv) : "dN" (_port));
|
||
|
return rv;
|
||
|
}
|
||
|
|
||
|
unsigned short inportw (unsigned short _port) {
|
||
|
unsigned short rv;
|
||
|
__asm__ __volatile__ ("inw %1, %0" : "=a" (rv) : "dN" (_port));
|
||
|
return rv;
|
||
|
}
|
||
|
|
||
|
/* We will use this to write to I/O ports to send bytes to devices. This
|
||
|
* will be used in the next tutorial for changing the textmode cursor
|
||
|
* position. Again, we use some inline assembly for the stuff that simply
|
||
|
* cannot be done in C */
|
||
|
void outportb (unsigned short _port, char _data) {
|
||
|
__asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data));
|
||
|
}
|
||
|
|
||
|
void outportw (unsigned short _port, unsigned short _data) {
|
||
|
__asm__ __volatile__ ("outw %1, %0" : : "dN" (_port), "a" (_data));
|
||
|
}
|