libk.c

Go to the documentation of this file.
00001 /* libk.c */
00002 
00003 /* Aca van todas las funciones que inician la llamada al sistema. Usadas, por ejemplo, por INIT */
00004 
00005 #include "routix/system.h"
00006 #include "routix/time.h"
00007 #include "routix/paging.h"
00008 #include "routix/task.h"
00009 #include "sys/syscalls.h"
00010 #include "routix/syscalls.h"
00011 #include <routix/kstdio.h>
00012 
00013 #include <stdarg.h>
00014 
00015 // Constantes
00016 #define HEXADECIMAL 16
00017 
00018 // Macros
00019 #define PRINTn(num,base,padding) (printn_all(num,base,padding,0));
00020 
00021 
00022 int exec (char *);
00023 char getascii_video (char c);
00024 void printn( unsigned int num, int base);
00025 void printn_all( unsigned int num, int base, unsigned int padding,unsigned int anidamiento);
00026 
00027 
00028 
00029 int execve (char *tarea, char **argv, char **envp)
00030 {
00031         int retorno;
00032     _syscall3(SYS_PROCESS | SYS_EXECVE, retorno, tarea, argv, envp);
00033 
00034     return retorno;
00035 }       
00036 
00037 
00038 void kprintf ( char *string, ...)
00039 {
00040  char *p=string;
00041  char *d;
00042  char car;
00043 
00044  unsigned int i;
00045  long long int lli;
00046  int padding;
00047         
00048  va_list argumentos;
00049 
00050  va_start(argumentos, string );
00051 
00052  for ( p=string; *p ; p++ ) {
00053   if ( *p != '%' ) {
00054    putchar(*p);
00055    continue;
00056   }
00057   
00058         switch (*++p) {
00059 
00060                 case 'c':
00061             car=va_arg(argumentos, int);     
00062             putchar( (char) car);
00063             break;
00064 
00065           case 'x':
00066             i = va_arg(argumentos, unsigned int );
00067             printn(i,16);
00068             break;
00069 
00070 
00071                 case 'd':
00072            i = va_arg(argumentos, int);
00073                  if (i > (0xffffffff/2) ) {
00074                         putchar('-');
00075                         printn(~i+1,10);
00076                         break;
00077                  }
00078              printn(i,10);
00079              break;
00080 
00081           case 'u':
00082             i = va_arg(argumentos, unsigned int);
00083             printn(i,10);
00084             break;
00085                  
00086                 case 'o':
00087            i = va_arg(argumentos, unsigned int);
00088      printn(i,8);
00089      break; 
00090 
00091                 case 's':
00092                   d = va_arg(argumentos, char *);
00093                   puts(d);
00094             break;
00095 
00096         
00097                 // Tenemos el caso de querer imprimir un long long (8 bytes = 64bits)
00098                 // para ello tenemos que pensar que dado un número, por ej.:
00099                 //      2217 = 0x08A9 = 100010101001
00100                 // supongamos a modo de análisis que tenemos que imprimir estos 2 bytes y
00101                 // que nuestra capacidad de manejo (en registros) es de 1 byte.
00102                 //      El MSB= 0x08 = 8
00103                 //      y       LSB=0xA9        = 169
00104                 // mientras que deberíamos leer:
00105                 //      MSB = 22 = 0x16 
00106                 //      LSB = 17 = 0x11
00107                 //
00108                 //      MSB = 0x08 --> 0x16 => dif = 0x16 - 0x08 = 0x0e
00109                 //      LSB = 0xa9 --> 0x11     => dif = 0x11 - 0xa9 = neg 
00110                 // 
00111                 // Otro ejemplo:
00112                 //      3598 = 0x0E0E = 111000001110
00113                 //
00114                 //      MSB = 0x0E --> 0x35     => dif = 0x35 - 0x0e = 0x27
00115                 //      LSB = 0x0E --> 0x98     => dif = 0x98 - 0x0e = 0x8a
00116                 // 
00117                 // Por ahora no encuentro una forma sencilla de imprimir números long long
00118                 // en decimal, realizamos la implementación en hexa.
00119                 // 
00120                 case 'l':
00121 
00122                         if ( *++p != 'l' )
00123                                 break;
00124 
00125                         switch ( *++p ) {
00126 
00127                                 case 'x':
00128                                         lli = va_arg(argumentos, long long int);
00129                 
00130                                         // Si los 4 bytes más significativos no son nulos el debemos agregar
00131                                         // ceros en el menos significativo
00132                                         if ( lli>>32 )
00133                                                 padding=8;
00134 
00135                                         // Si los 4 bytes más significativos son nulos no importa el padding, 
00136                                         // pero lo colocamos en 1 para que cuando sea 0 imprima por lo menos
00137                                         // ese caracter 
00138                                         else
00139                                                 padding=1;
00140                                                 
00141                                         PRINTn( (unsigned int) (lli>>32), HEXADECIMAL, 0);
00142                                         PRINTn( (unsigned int) lli, HEXADECIMAL, padding);
00143                                         break;
00144 
00145                         }
00146                         
00147                         break;
00148              
00149              
00150 
00151                 default:
00152                         putchar(*p);
00153                         break;
00154 
00155   }
00156         
00157  }
00158   
00159  va_end(argumentos);
00160 }
00161 
00162 void printn( unsigned int num, int base)
00163 {
00164  unsigned int div;
00165  if ( (div=num/base) ) printn(div,base);
00166  putchar( getascii_video(num%base) );
00167 }
00168 
00169 
00170 char getascii_video ( char c )
00171 {
00172  char valor = '0' + c;
00173 
00174  if ( valor > '9' ) valor += 7;
00175  return valor;
00176 }
00177 
00179 inline unsigned int get_vector_elements (char **p)
00180 {
00181         unsigned long i;
00182         for ( ; *(p+i) ; i++);
00183         return i;
00184 }
00185 
00186 /* Permite imprimir un entero con padding
00187  *
00188  * function printn_all(numero, base, padding, anidamiento)
00189  *
00190  * division = numero/base;
00191  * resto                = numero%base;
00192  *
00193  * * Con resto levantamos el último dígito, ya que la división puede ser
00194  * * nula, ej.: 7/16 = 0 pero 7%16 = 7
00195  * if ( division || resto ) {
00196  *      printn_all(division,base,padding,anidamiento+1)
00197  *      imprimir el caracter numero%base;
00198  * }
00199  *
00200  * else {
00201  *      while( padding-- > anidamiento )
00202  *              imprimir el caracter '0'
00203  * }
00204  *
00205  */ 
00206 void printn_all( unsigned int num, int base, unsigned int padding,unsigned int anidamiento)
00207 {
00208         unsigned int div;
00209  
00210         if ( (div=num/base) || (num%base) ) {
00211                 printn_all(div,base, padding, anidamiento+1 );
00212                 putchar( getascii_video(num%base) );
00213          }
00214 
00215         else {
00216 
00217                 while ( padding-- >anidamiento)
00218                         putchar( getascii_video(0) );
00219         }
00220 
00221 }
00222 
00223 

Generated on Sun May 30 18:38:35 2004 for Routix OS by doxygen 1.3.6