POK(kernelpart)
|
00001 /* 00002 * POK header 00003 * 00004 * The following file is a part of the POK project. Any modification should 00005 * made according to the POK licence. You CANNOT use this file or a part of 00006 * this file is this part of a file for your own project 00007 * 00008 * For more information on the POK licence, please see our LICENCE FILE 00009 * 00010 * Please follow the coding guidelines described in doc/CODING_GUIDELINES 00011 * 00012 * Copyright (c) 2007-2009 POK team 00013 * 00014 * Created by julien on Thu Jan 15 23:34:13 2009 00015 */ 00016 00017 00018 #include <errno.h> 00019 00020 #include <arch/x86/ioports.h> 00021 #include <libc.h> 00022 #include <core/debug.h> 00023 #include <core/cons.h> 00024 00025 #include "cons.h" 00026 00027 #if defined (POK_NEEDS_DEBUG) || defined (POK_NEEDS_CONSOLE) || defined (POK_NEEDS_INSTRUMENTATION) || defined (POK_NEEDS_COVERAGE_INFOS) 00028 00029 static const int screen_w = 80; 00030 static const int screen_h = 25; 00031 static const int tab_size = 8; 00032 static char *const vga_base = (char *)0xb8000; 00033 struct s_cons g_cons; 00034 00035 #if defined (POK_NEEDS_DEBUG) || defined (POK_NEEDS_INSTRUMENTATION) || defined (POK_NEEDS_COVERAGE_INFOS) 00036 #define COM1 0x3F8 00037 00038 int is_transmit_empty() { 00039 return inb(COM1 + 5) & 0x20; 00040 } 00041 00042 void write_serial(char a) { 00043 while (is_transmit_empty() == 0); 00044 00045 outb(COM1,a); 00046 } 00047 #endif 00048 00049 00050 00051 void pok_cons_print_char (const char c) 00052 { 00053 #ifdef POK_NEEDS_CONSOLE 00054 char* ptr; 00055 static struct s_cons local_curs; /* Local copy of the curent cursor position */ 00056 int i; 00057 #endif 00058 00059 #if defined (POK_NEEDS_DEBUG) || defined (POK_NEEDS_INSTRUMENTATION) || defined (POK_NEEDS_COVERAGE_INFOS) 00060 write_serial (c); 00061 #endif 00062 00063 #ifdef POK_NEEDS_CONSOLE 00064 local_curs = g_cons; 00065 00066 if (c == '\r') 00067 { 00068 local_curs.col = 0; 00069 } 00070 00071 if (c == '\n') 00072 { 00073 local_curs.col = 0; 00074 ++local_curs.row; 00075 } 00076 00077 if (c == '\t') 00078 { 00079 local_curs.col += tab_size - local_curs.col % tab_size; 00080 } 00081 00082 if (c != '\r' && c != '\n' && c != '\t') 00083 { 00084 ptr = vga_base + 2 * screen_w * local_curs.row + 2 * local_curs.col++; 00085 *ptr = c; 00086 ++ptr; 00087 *ptr = local_curs.cur_attr; 00088 } 00089 00090 if (local_curs.col >= screen_w) 00091 { 00092 local_curs.col = 0; 00093 ++local_curs.row; 00094 } 00095 00096 if (local_curs.row >= screen_h) 00097 { 00098 memcpy (vga_base, vga_base + 2 * screen_w, (screen_h - 1) * screen_w * 2); 00099 for (i = 0; i < screen_w; ++i) 00100 { 00101 *(vga_base + 2 * screen_w * (screen_h - 1) + 2 * i) = 0; 00102 *(vga_base + 2 * screen_w * (screen_h - 1) + 2 * i + 1) = local_curs.cur_attr; 00103 } 00104 local_curs.row = screen_h - 1; 00105 } 00106 00107 // Reset the global cursor to the new position 00108 g_cons = local_curs; 00109 #endif 00110 } 00111 00112 void pok_cons_attr (uint8_t attr) 00113 { 00114 g_cons.cur_attr = attr; 00115 } 00116 00117 void pok_cons_clear (void) 00118 { 00119 int i; 00120 int j; 00121 char *ptr; 00122 static struct s_cons local_curs; /* local copy of the current cursor position */ 00123 00124 ptr = vga_base; 00125 local_curs = g_cons; 00126 00127 for (i = 0 ; i < screen_h ; ++i) 00128 { 00129 for (j = 0 ; j < screen_w ; ++j) 00130 { 00131 *ptr = 0; 00132 ++ptr; 00133 *ptr = g_cons.cur_attr; 00134 ++ptr; 00135 } 00136 } 00137 00138 local_curs.row = 0; 00139 local_curs.col = 0; 00140 00141 g_cons = local_curs; /* reset the global cursor to the new position */ 00142 } 00143 00144 00145 pok_bool_t pok_cons_write (const char *s, size_t length) 00146 { 00147 int res; 00148 size_t i; 00149 00150 res = 0; 00151 i = 0; 00152 00153 while (i < length) 00154 { 00155 if ((const unsigned char)s[i] == CONS_ESCAPE) 00156 { 00157 ++i; 00158 switch (s[i]) 00159 { 00160 case CONS_CLEAR: 00161 pok_cons_clear(); 00162 break; 00163 case CONS_COLOR: 00164 ++i; 00165 pok_cons_attr((const unsigned char)s[i]); 00166 break; 00167 case CONS_SETY: 00168 ++i; 00169 g_cons.row = (const unsigned char)s[i] % screen_h; 00170 break; 00171 case CONS_SETX: 00172 ++i; 00173 g_cons.col = (const unsigned char)s[i] % screen_w; 00174 break; 00175 default: 00176 pok_cons_print_char(s[i]); 00177 ++res; 00178 } 00179 } 00180 else 00181 { 00182 pok_cons_print_char(s[i]); 00183 ++res; 00184 } 00185 ++i; 00186 } 00187 return res; 00188 } 00189 00190 #ifdef POK_NEEDS_CONSOLE 00191 void pok_cons_disable_cursor (void) 00192 { 00193 char tmp; 00194 int base_port; 00195 00196 if (inb(0x3cc) & 0x01) 00197 { 00198 base_port = 0x3d4; 00199 } 00200 else 00201 { 00202 base_port = 0x3b4; 00203 } 00204 00205 tmp = inb (base_port); 00206 outb (base_port, 0x0a); 00207 outb (base_port + 1, inb (base_port + 1) | 0x20); 00208 outb (base_port, tmp); 00209 } 00210 #endif 00211 00212 int pok_cons_init (void) 00213 { 00214 #ifdef POK_NEEDS_CONSOLE 00215 g_cons.cur_attr = CONS_FRONT (CONS_WHITE) | CONS_BACK (CONS_BLACK); 00216 pok_cons_clear (); 00217 pok_cons_disable_cursor (); 00218 pok_print_init (pok_cons_print_char, pok_cons_attr); 00219 #endif 00220 00221 #if defined (POK_NEEDS_DEBUG) || defined (POK_NEEDS_INSTRUMENTATION) || defined (POK_NEEDS_COVERAGE_INFOS) 00222 /* To be fixed : init serial */ 00223 outb(COM1 + 1, 0x00); // Disable all interrupts 00224 outb(COM1 + 3, 0x80); // Enable DLAB (set baud rate divisor) 00225 outb(COM1 + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud 00226 outb(COM1 + 1, 0x00); // (hi byte) 00227 outb(COM1 + 3, 0x03); // 8 bits, no parity, one stop bit 00228 outb(COM1 + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold 00229 outb(COM1 + 4, 0x0B); // IRQs enabled, RTS/DSR set 00230 #endif 00231 00232 return 0; 00233 } 00234 #else 00235 int pok_cons_init (void) 00236 { 00237 return 0; 00238 } 00239 #endif 00240 00241