POK(kernelpart)
cons.c
Go to the documentation of this file.
1 /*
2  * POK header
3  *
4  * The following file is a part of the POK project. Any modification should
5  * made according to the POK licence. You CANNOT use this file or a part of
6  * this file is this part of a file for your own project
7  *
8  * For more information on the POK licence, please see our LICENCE FILE
9  *
10  * Please follow the coding guidelines described in doc/CODING_GUIDELINES
11  *
12  * Copyright (c) 2007-2009 POK team
13  *
14  * Created by julien on Thu Jan 15 23:34:13 2009
15  */
16 
17 
18 #include <errno.h>
19 
20 #include <arch/x86/ioports.h>
21 #include <libc.h>
22 #include <core/debug.h>
23 #include <core/cons.h>
24 
25 #include "cons.h"
26 
27 #if defined (POK_NEEDS_DEBUG) || defined (POK_NEEDS_CONSOLE) || defined (POK_NEEDS_INSTRUMENTATION) || defined (POK_NEEDS_COVERAGE_INFOS)
28 
29 static const int screen_w = 80;
30 static const int screen_h = 25;
31 static const int tab_size = 8;
32 static char *const vga_base = (char *)0xb8000;
33 struct s_cons g_cons;
34 
35 #if defined (POK_NEEDS_DEBUG) || defined (POK_NEEDS_INSTRUMENTATION) || defined (POK_NEEDS_COVERAGE_INFOS)
36 #define COM1 0x3F8
37 
38 int is_transmit_empty() {
39  return inb(COM1 + 5) & 0x20;
40 }
41 
42 void write_serial(char a) {
43  while (is_transmit_empty() == 0);
44 
45  outb(COM1,a);
46 }
47 #endif
48 
49 
50 
51 void pok_cons_print_char (const char c)
52 {
53 #ifdef POK_NEEDS_CONSOLE
54  char* ptr;
55  static struct s_cons local_curs; /* Local copy of the curent cursor position */
56  int i;
57 #endif
58 
59 #if defined (POK_NEEDS_DEBUG) || defined (POK_NEEDS_INSTRUMENTATION) || defined (POK_NEEDS_COVERAGE_INFOS)
60  write_serial (c);
61 #endif
62 
63 #ifdef POK_NEEDS_CONSOLE
64  local_curs = g_cons;
65 
66  if (c == '\r')
67  {
68  local_curs.col = 0;
69  }
70 
71  if (c == '\n')
72  {
73  local_curs.col = 0;
74  ++local_curs.row;
75  }
76 
77  if (c == '\t')
78  {
79  local_curs.col += tab_size - local_curs.col % tab_size;
80  }
81 
82  if (c != '\r' && c != '\n' && c != '\t')
83  {
84  ptr = vga_base + 2 * screen_w * local_curs.row + 2 * local_curs.col++;
85  *ptr = c;
86  ++ptr;
87  *ptr = local_curs.cur_attr;
88  }
89 
90  if (local_curs.col >= screen_w)
91  {
92  local_curs.col = 0;
93  ++local_curs.row;
94  }
95 
96  if (local_curs.row >= screen_h)
97  {
98  memcpy (vga_base, vga_base + 2 * screen_w, (screen_h - 1) * screen_w * 2);
99  for (i = 0; i < screen_w; ++i)
100  {
101  *(vga_base + 2 * screen_w * (screen_h - 1) + 2 * i) = 0;
102  *(vga_base + 2 * screen_w * (screen_h - 1) + 2 * i + 1) = local_curs.cur_attr;
103  }
104  local_curs.row = screen_h - 1;
105  }
106 
107  // Reset the global cursor to the new position
108  g_cons = local_curs;
109 #endif
110 }
111 
112 void pok_cons_attr (uint8_t attr)
113 {
114  g_cons.cur_attr = attr;
115 }
116 
117 void pok_cons_clear (void)
118 {
119  int i;
120  int j;
121  char *ptr;
122  static struct s_cons local_curs; /* local copy of the current cursor position */
123 
124  ptr = vga_base;
125  local_curs = g_cons;
126 
127  for (i = 0 ; i < screen_h ; ++i)
128  {
129  for (j = 0 ; j < screen_w ; ++j)
130  {
131  *ptr = 0;
132  ++ptr;
133  *ptr = g_cons.cur_attr;
134  ++ptr;
135  }
136  }
137 
138  local_curs.row = 0;
139  local_curs.col = 0;
140 
141  g_cons = local_curs; /* reset the global cursor to the new position */
142 }
143 
144 
145 pok_bool_t pok_cons_write (const char *s, size_t length)
146 {
147  int res;
148  size_t i;
149 
150  res = 0;
151  i = 0;
152 
153  while (i < length)
154  {
155  if ((const unsigned char)s[i] == CONS_ESCAPE)
156  {
157  ++i;
158  switch (s[i])
159  {
160  case CONS_CLEAR:
161  pok_cons_clear();
162  break;
163  case CONS_COLOR:
164  ++i;
165  pok_cons_attr((const unsigned char)s[i]);
166  break;
167  case CONS_SETY:
168  ++i;
169  g_cons.row = (const unsigned char)s[i] % screen_h;
170  break;
171  case CONS_SETX:
172  ++i;
173  g_cons.col = (const unsigned char)s[i] % screen_w;
174  break;
175  default:
176  pok_cons_print_char(s[i]);
177  ++res;
178  }
179  }
180  else
181  {
182  pok_cons_print_char(s[i]);
183  ++res;
184  }
185  ++i;
186  }
187  return res;
188 }
189 
190 #ifdef POK_NEEDS_CONSOLE
191 void pok_cons_disable_cursor (void)
192 {
193  char tmp;
194  int base_port;
195 
196  if (inb(0x3cc) & 0x01)
197  {
198  base_port = 0x3d4;
199  }
200  else
201  {
202  base_port = 0x3b4;
203  }
204 
205  tmp = inb (base_port);
206  outb (base_port, 0x0a);
207  outb (base_port + 1, inb (base_port + 1) | 0x20);
208  outb (base_port, tmp);
209 }
210 #endif
211 
212 int pok_cons_init (void)
213 {
214 #ifdef POK_NEEDS_CONSOLE
215  g_cons.cur_attr = CONS_FRONT (CONS_WHITE) | CONS_BACK (CONS_BLACK);
216  pok_cons_clear ();
217  pok_cons_disable_cursor ();
218  pok_print_init (pok_cons_print_char, pok_cons_attr);
219 #endif
220 
221 #if defined (POK_NEEDS_DEBUG) || defined (POK_NEEDS_INSTRUMENTATION) || defined (POK_NEEDS_COVERAGE_INFOS)
222  /* To be fixed : init serial */
223  outb(COM1 + 1, 0x00); // Disable all interrupts
224  outb(COM1 + 3, 0x80); // Enable DLAB (set baud rate divisor)
225  outb(COM1 + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud
226  outb(COM1 + 1, 0x00); // (hi byte)
227  outb(COM1 + 3, 0x03); // 8 bits, no parity, one stop bit
228  outb(COM1 + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold
229  outb(COM1 + 4, 0x0B); // IRQs enabled, RTS/DSR set
230 #endif
231 
232  return 0;
233 }
234 #else
235 int pok_cons_init (void)
236 {
237  return 0;
238 }
239 #endif
240 
241