#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(); } }