122 lines
3.4 KiB
C
122 lines
3.4 KiB
C
#include "../include/system.h"
|
|
#include "../include/gdt.h"
|
|
#include "../include/idt.h"
|
|
#include "../include/scrn.h"
|
|
#include "../include/shell.h"
|
|
|
|
unsigned char *memcpy(unsigned char *dest, const unsigned char *src, int count)
|
|
{
|
|
/* Add code here to copy 'count' bytes of data from 'src' to
|
|
* 'dest', finally return 'dest' */
|
|
const char *sp = (const char *)src;
|
|
char *dp = (char *)dest;
|
|
for(; count != 0; count--) *dp++ = *sp++;
|
|
return dest;
|
|
}
|
|
|
|
unsigned char *memset(unsigned char *dest, unsigned char val, int count)
|
|
{
|
|
/* Add code here to set 'count' bytes in 'dest' to 'val'.
|
|
* Again, return 'dest' */
|
|
char *temp = (char *)dest;
|
|
for( ; count != 0; count--) *temp++ = val;
|
|
return dest;
|
|
}
|
|
|
|
unsigned short *memsetw(unsigned short *dest, unsigned short val, int count)
|
|
{
|
|
/* Same as above, but this time, we're working with a 16-bit
|
|
* 'val' and dest pointer. Your code can be an exact copy of
|
|
* the above, provided that your local variables if any, are
|
|
* unsigned short */
|
|
unsigned short *temp = (unsigned short *)dest;
|
|
for( ; count != 0; count--) *temp++ = val;
|
|
return dest;
|
|
}
|
|
|
|
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 */
|
|
//size_t retval;
|
|
unsigned int retval;
|
|
for(retval = 0; *str != '\0'; str++) retval++;
|
|
return retval;
|
|
}
|
|
|
|
bool strcmp(char* str1, char* str2)
|
|
{
|
|
int len1 = strlen(str1);
|
|
int len2 = strlen(str2);
|
|
|
|
if(len1 != len2)
|
|
{
|
|
puts("Lengths different!\n");
|
|
return false;
|
|
}
|
|
for(int i = len1; i >= 0; i--)
|
|
{
|
|
if(str1[i] != str2[i]) return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/* 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 */
|
|
unsigned char inportb (unsigned short _port)
|
|
{
|
|
unsigned char rv;
|
|
__asm__ __volatile__ ("inb %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, unsigned char _data)
|
|
{
|
|
__asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data));
|
|
}
|
|
|
|
//extern char __BUILD_DATE;
|
|
//extern char __BUILD_NUMBER;
|
|
|
|
/* This is a very simple main() function. All it does is sit in an
|
|
* infinite loop. This will be like our 'idle' loop */
|
|
void main()
|
|
{
|
|
/* You would add commands after here */
|
|
init_video();
|
|
puts("Video initialized.\n");
|
|
gdt_install();
|
|
puts("Global Descriptor Table initialized.\n");
|
|
idt_install();
|
|
puts("Interrupt Descriptor Table initialized.\n");
|
|
isrs_install();
|
|
puts("Interrupt Service Routines installed.\n");
|
|
irq_install();
|
|
__asm__ __volatile__ ("sti");
|
|
puts("Interrupt Requests now allowed.\n");
|
|
//timer_install();
|
|
//puts("Installed Timer.\n");
|
|
kb_install();
|
|
puts("Keyboard installed.\n");
|
|
puts("SDOS version 0.0.0.1 initialized.\n");
|
|
run_shell();
|
|
//puts(&__BUILD_DATE);
|
|
//puts(&__BUILD_NUMBER);
|
|
//puts("Divide by zero check:\n");
|
|
//puts(5 / 0);
|
|
/* ...and leave this loop in. There is an endless loop in
|
|
* 'start.asm' also, if you accidentally delete this next line */
|
|
for (;;);
|
|
}
|
|
|
|
void idle()
|
|
{
|
|
__asm__ __volatile__ ("hlt");
|
|
} |