Main Page | Modules | File List | File Members

console.c

00001 /* ndk - [ console.c ]
00002  *
00003  * Contains the minimal ammount of code necessary
00004  * to have console output for the kernel.
00005  *
00006  * (c)2002 dcipher / neuraldk
00007  *           www.neuraldk.org
00008  */
00009 
00010 #include "console.h"
00011 
00012 /* The video memory address. */
00013 #define COLOUR_VIDEO    0xB8000
00014 #define MONO_VIDEO      0xB0000
00015 
00016 /* The number of lines and columns */
00017 long consoleCols   = 80;
00018 long consoleLines  = 24;
00019 /* precalculate some commonly used equations */
00020 long consoleBytesPerLine = 80 * 2;
00021 long consoleTotalBytes   = 4000;
00022 /* The attribute of an character. */
00023 char consoleAttrib = 15;
00024 
00025 /* position of cursor */
00026 static int consoleXPos, consoleYPos;
00027 
00028 /* location of video memory. */
00029 static volatile unsigned char *consoleAddr;
00030 
00031 void (*consoleOut)(const char *format, ...);
00032 
00033 void consoleInit(void) {
00034   consoleClear();
00035   consoleOut = (void (*)(const char *, ...))printf;
00036   return;
00037 }
00038 
00039 /* Clear the screen and initialize VIDEO, XPOS and YPOS. */
00040 void consoleClear (void) {
00041   int i;
00042 
00043   // check for mono adaptor?
00044   consoleAddr = (unsigned char *) COLOUR_VIDEO;
00045 
00046   for (i = 0; i < consoleCols * consoleLines * 2; i++)
00047     *(consoleAddr + i) = 0;
00048 
00049   consoleXPos = 0;
00050   consoleYPos = 0;
00051 }
00052 
00053 /* Convert the integer D to a string and save the string in BUF. If
00054    BASE is equal to 'd', interpret that D is decimal, and if BASE is
00055    equal to 'x', interpret that D is hexadecimal. */
00056 static void itoa (char *buf, int base, int d, signed int length) {
00057   char *p = buf;
00058   char *p1, *p2;
00059   unsigned long ud = d;
00060   int divisor = 10;
00061 
00062   /* If %d is specified and D is minus, put `-' in the head. */
00063   if (base == 'd' && d < 0) {
00064     *p++ = '-';
00065     buf++;
00066     ud = -d;
00067   } else if (base == 'x')
00068     divisor = 16;
00069 
00070   /* Divide UD by DIVISOR until UD == 0. */
00071   do {
00072     int remainder = ud % divisor;
00073 
00074     *p++ = (remainder < 10) ? remainder + '0' : remainder + 'a' - 10;
00075     length--;
00076   } while (ud /= divisor);
00077 
00078   while(length > 0) {
00079     *p++ = '0';
00080     length--;
00081   }
00082 
00083   /* Terminate BUF. */
00084   *p = 0;
00085 
00086   /* Reverse BUF. */
00087   p1 = buf;
00088   p2 = p - 1;
00089   while (p1 < p2) {
00090     char tmp = *p1;
00091     *p1 = *p2;
00092     *p2 = tmp;
00093     p1++;
00094     p2--;
00095   }
00096 }
00097 
00098 /* Put the character C on the screen. */
00099 static void putchar (int c) {
00100   if (c == '\n' || c == '\r') {
00101   newline:
00102     consoleXPos = 0;
00103     consoleYPos++;
00104     if(consoleYPos >= consoleLines) {
00105       consoleYPos = consoleLines;
00106       // scroll up a line
00107       memcpy(consoleAddr,
00108              consoleAddr + consoleBytesPerLine,
00109              consoleTotalBytes - consoleBytesPerLine );
00110       // clear the last line
00111       memset(consoleAddr + consoleTotalBytes - consoleBytesPerLine,
00112              0,
00113              consoleBytesPerLine);
00114     }
00115     return;
00116   } else if (c == '\t') {
00117     consoleXPos += (8 - (consoleXPos & 7));
00118     return;
00119   }
00120 
00121   *(consoleAddr + (consoleXPos + consoleYPos * consoleCols) * 2)     = c & 0xFF;
00122   *(consoleAddr + (consoleXPos + consoleYPos * consoleCols) * 2 + 1) = consoleAttrib;
00123 
00124   consoleXPos++;
00125   if (consoleXPos >= consoleCols)
00126     goto newline;
00127 }
00128 
00129 /* Format a string and print it on the screen, just like the libc
00130    function printf. */
00131 void printf (const char *format, ...) {
00132   char **arg = (char **) &format;
00133   int c;
00134   char buf[20];
00135   int length;
00136 
00137   arg++;
00138 
00139   while ((c = *format++) != 0) {
00140     length = 0;
00141     if (c != '%')
00142       putchar (c);
00143     else {
00144       char *p;
00145 
00146       c = *format++;
00147       while(c >= '0' && c <= '9') {
00148         length *= 10;
00149         length += c - '0';
00150         c = *format++;
00151       }
00152       switch (c) {
00153         case 'd':
00154         case 'u':
00155         case 'x':
00156           itoa (buf, c, *((int *) arg++), length);
00157           p = buf;
00158           goto string;
00159           break;
00160 
00161         case 's':
00162           p = *arg++;
00163           if (! p)
00164             p = "(null)";
00165 
00166         string:
00167           while (*p)
00168           putchar (*p++);
00169           break;
00170 
00171         default:
00172           putchar (*((int *) arg++));
00173           break;
00174       }
00175     }
00176   }
00177 }

Generated on Sun Nov 21 18:26:11 2004 for ndk by doxygen 1.3.2