about summary refs log blame commit diff stats
path: root/tools/iso/kernel.soso/common.c
blob: 446f21a2e91ee962846afa43476a5e13afb8c7e8 (plain) (tree)
1
2
3
4
5
6
7
8






                                           
                                     


                                                              
                                      


                                                              
                        




                                                          
                         





                                                           
                                                         







                                         
                                                  





                                           
                                                      





















                                   
                                                        













                                                          
                                                

                     

                                                 





                         
                                                                                         





                     


                                                             








                                                     

                                           







                       

                                                  










                                                                                                                                              
                                                        
                             

                                                     


                               
                          

                           
              






                             
                                           








                                     
                             





                  
                                              
              

                          







                     
               











                                            
                     

                   
                                          





                                          
                                        





                         
                               



                   
                           


                     
        











                                                                         
                     







                       
                                                                        




                        
                                  

                                    
              


                          
                        







































                                                                  
                                                    











                                            
                                       





                              
              








                                         
                               




                                  
                                                                






                                                     
                                                                  


                                                       
                                                                    






                                                             
                  





                                                         
                      






                                                           
                            






                                                     
                             




                                                   

                                 


                           
#include "common.h"
#include "screen.h"
#include "ttydriver.h"

static BOOL gInterruptsWereEnabled = FALSE;

// Write a byte out to the specified port.
void outb(uint16 port, uint8 value) {
    asm volatile ("outb %1, %0" : : "dN" (port), "a" (value));
}

void outw(uint16 port, uint16 value) {
    asm volatile ("outw %1, %0" : : "dN" (port), "a" (value));
}

uint8 inb(uint16 port) {
    uint8 ret;
    asm volatile("inb %1, %0" : "=a" (ret) : "dN" (port));
    return ret;
}

uint16 inw(uint16 port) {
    uint16 ret;
    asm volatile ("inw %1, %0" : "=a" (ret) : "dN" (port));
    return ret;
}

// Copy len bytes from src to dest.
void* memcpy(uint8 *dest, const uint8 *src, uint32 len) {
    const uint8 *sp = (const uint8 *)src;
    uint8 *dp = (uint8 *)dest;
    for(; len != 0; len--) *dp++ = *sp++;

    return dest;
}

// Write len copies of val into dest.
void* memset(uint8 *dest, uint8 val, uint32 len) {
    uint8 *temp = (uint8 *)dest;
    for ( ; len != 0; len--) *temp++ = val;

    return dest;
}

void* memmove(void* dest, const void* src, uint32 n) {
    uint8* _dest;
    uint8* _src;

    if ( dest < src ) {
        _dest = ( uint8* )dest;
        _src = ( uint8* )src;

        while ( n-- ) {
            *_dest++ = *_src++;
        }
    } else {
        _dest = ( uint8* )dest + n;
        _src = ( uint8* )src + n;

        while ( n-- ) {
            *--_dest = *--_src;
        }
    }

    return dest;
}

int memcmp( const void* p1, const void* p2, uint32 c ) {
    const uint8* su1, *su2;
    int8 res = 0;

    for ( su1 = p1, su2 = p2; 0 < c; ++su1, ++su2, c-- ) {
        if ( ( res = *su1 - *su2 ) != 0 ) {
            break;
        }
    }

    return res;
}

// Compare two strings. Should return -1 if 
// str1 < str2, 0 if they are equal or 1 otherwise.
int strcmp(const char *str1, const char *str2) {
      int i = 0;
      int failed = 0;
      while(str1[i] != '\0' && str2[i] != '\0') {
          if(str1[i] != str2[i]) {
              failed = 1;
              break;
          }
          i++;
      }

      if ((str1[i] == '\0' && str2[i] != '\0') || (str1[i] != '\0' && str2[i] == '\0')) {
          failed = 1;
      }
  
      return failed;
}

int strncmp(const char *str1, const char *str2, int length) {
    for (int i = 0; i < length; ++i) {
        if (str1[i] != str2[i]) {
            return str1[i] - str2[i];
        }
    }

    return 0;
}

// Copy the NULL-terminated string src into dest, and
// return dest.
char *strcpy(char *dest, const char *src) {
    do {
      *dest++ = *src++;
    }
    while (*src != 0);
    *dest = '\0';

    return dest;
}

char *strcpyNonNull(char *dest, const char *src) {
    do {
      *dest++ = *src++;
    }
    while (*src != 0);

    return dest;
}

//Copies the first num characters of source to destination. If the end of the source C string is found before num characters have been copied,
//destination is padded with zeros until a total of num characters have been written to it.
//No null-character is implicitly appended at the end of destination if source is longer than num.
//Thus, in this case, destination shall not be considered a null terminated C string.
char *strncpy(char *dest, const char *src, uint32 num) {
    BOOL sourceEnded = FALSE;
    for (uint32 i = 0; i < num; ++i) {
        if (sourceEnded == FALSE && src[i] == '\0') {
            sourceEnded = TRUE;
        }

        if (sourceEnded) {
            dest[i] = '\0';
        }
        else {
            dest[i] = src[i];
        }
    }

    return dest;
}

char* strcat(char *dest, const char *src) {
    size_t i,j;
    for (i = 0; dest[i] != '\0'; i++)
        ;
    for (j = 0; src[j] != '\0'; j++)
        dest[i+j] = src[j];
    dest[i+j] = '\0';
    return dest;
}

int strlen(const char *src) {
    int i = 0;
    while (*src++)
        i++;
    return i;
}

int strFirstIndexOf(const char *src, char c) {
    int i = 0;
    while (src[i]) {
        if (src[i] == c) {
            return i;
        }
        i++;
    }

    return -1;
}

uint32 rand() {
    static uint32 x = 123456789;
    static uint32 y = 362436069;
    static uint32 z = 521288629;
    static uint32 w = 88675123;

    uint32 t;

    t = x ^ (x << 11);
    x = y; y = z; z = w;
    return w = w ^ (w >> 19) ^ t ^ (t >> 8);
}

int atoi(char *str) {
    int result = 0;

    for (int i = 0; str[i] != '\0'; ++i) {
        result = result*10 + str[i] - '0';
    }

    return result;
}

void itoa (char *buf, int base, int d) {
    char *p = buf;
    char *p1, *p2;
    unsigned long ud = d;
    int divisor = 10;


    if (base == 'd' && d < 0) {
        *p++ = '-';
        buf++;
        ud = -d;
    }
    else if (base == 'x') {
        divisor = 16;
    }

    do {
        int remainder = ud % divisor;

        *p++ = (remainder < 10) ? remainder + '0' : remainder + 'A' - 10;
    }
    while (ud /= divisor);


    *p = 0;

    //Reverse BUF.
    p1 = buf;
    p2 = p - 1;
    while (p1 < p2) {
        char tmp = *p1;
        *p1 = *p2;
        *p2 = tmp;
        p1++;
        p2--;
    }
}

int sprintf_va(char* buffer, const char *format, __builtin_va_list vl) {
    char c;
    char buf[20];

    int bufferIndex = 0;

    while ((c = *format++) != 0) {
        if (c != '%')
          buffer[bufferIndex++] = c;
        else {
            char *p;

            c = *format++;
            switch (c) {
              case 'x':
                 buf[0] = '0';
                 buf[1] = 'x';
                 //itoa (buf + 2, c, *((int *) arg++));
                 itoa (buf + 2, c, __builtin_va_arg(vl, int));
                 p = buf;
                 goto string;
                 break;
              case 'd':
              case 'u':
                //itoa (buf, c, *((int *) arg++));
                itoa (buf, c, __builtin_va_arg(vl, int));
                p = buf;
                goto string;
                break;

              case 's':
                //p = *arg++;
                p = __builtin_va_arg(vl, char*);
                if (! p)
                  p = "(null)";

              string:
                while (*p)
                  buffer[bufferIndex++] = (*p++);
                break;

              default:
                //buffer[bufferIndex++] = (*((int *) arg++));
                buffer[bufferIndex++] = __builtin_va_arg(vl, int);
                break;
              }
          }
      }

    buffer[bufferIndex] = '\0';

    return bufferIndex;
}

int sprintf(char* buffer, const char *format, ...) {
    int result = 0;

    __builtin_va_list vl;
    __builtin_va_start(vl, format);

    result = sprintf_va(buffer, format, vl);

    __builtin_va_end(vl);

    return result;
}

void printkf(const char *format, ...) {
    char buffer[1024];
    buffer[0] = 'k';
    buffer[1] = ':';
    buffer[2] = 0;

    Tty* tty = getActiveTTY();
    if (tty) {
        __builtin_va_list vl;
        __builtin_va_start(vl, format);

        sprintf_va(buffer+2, format, vl);

        __builtin_va_end(vl);

        Tty_PutText(tty, buffer);

        if (tty->flushScreen) {
            tty->flushScreen(tty);
        }
    }
}

void panic(const char *message, const char *file, uint32 line) {
    disableInterrupts();

    printkf("PANIC:%s:%d:%s\n", file, line, message);

    halt();
}

void warning(const char *message, const char *file, uint32 line) {
    printkf("WARNING:%s:%d:%s\n", file, line, message);
}

void panic_assert(const char *file, uint32 line, const char *desc) {
    disableInterrupts();

    printkf("ASSERTION-FAILED:%s:%d:%s\n", file, line, desc);

    halt();
}

uint32 readEsp() {
    uint32 stack_pointer;
    asm volatile("mov %%esp, %0" : "=r" (stack_pointer));

    return stack_pointer;
}

uint32 getCpuFlags() {
    uint32 eflags = 0;

    asm("pushfl; pop %%eax; mov %%eax, %0": "=m"(eflags):);

    return eflags;
}

BOOL isInterruptsEnabled() {
    uint32 eflags = getCpuFlags();

    uint32 interruptFlag = 0x200; //9th flag

    return (eflags & interruptFlag) == interruptFlag;
}

void beginCriticalSection() {
    gInterruptsWereEnabled = isInterruptsEnabled();

    disableInterrupts();
}

void endCriticalSection() {
    if (gInterruptsWereEnabled) {
        enableInterrupts();
    }
}