kbd: use a better get_key method
[thunix.git] / kernel / console.c
blobd47607d13c1c7f28aab7a599e277a4dbe1902790
1 /**
2 * thunix/kernel/console.c
3 *
4 * The implemention of console write and something about console.
6 * Aleaxander (C) 2007-2008
7 *
8 * Aleaxander@gmail.com
12 #include <console.h>
13 #include <string.h>
14 #include <asm/io.h>
15 #include <asm/system.h>
16 #include <keyboard.h>
18 static unsigned long video_num_columns;
19 static unsigned long video_size_row;
20 static unsigned long video_size_all;
21 static unsigned long video_num_lines;
22 static unsigned long video_mem_start;
23 static unsigned long video_mem_end;
24 static unsigned long origin;
25 static unsigned long scr_end;
26 static unsigned long pos;
27 static unsigned long x,y;
28 static unsigned long top,bottom;
29 //static unsigned char attr = 0x07;
30 //static unsigned char space = 0x20;
31 static unsigned short video_port_reg;
32 static unsigned short video_port_val;
33 static unsigned short video_erase_char;
35 static void sysbeep(void);
37 static inline void gotoxy(unsigned int new_x, unsigned int new_y)
39 if (new_x > video_num_columns || new_y >= video_num_lines)
40 return ;
41 x = new_x;
42 y = new_y;
43 pos = origin + y*video_size_row + (x << 1);
44 /* pos = origin + (y<<8) + (y<<6) +(x<<1); */
47 static inline void set_origin(void)
49 cli();
50 outb_p(12,video_port_reg);
51 outb_p(0xff&((origin-video_mem_start)>>9),video_port_val);
52 outb_p(13,video_port_reg);
53 outb_p(0xff&((origin-video_mem_start)>>1),video_port_val);
54 sti();
57 void cls(void)
59 int i = 0;
60 unsigned char c=' ';
62 for (; i < video_size_all/2; i++ ) {
63 con_write((char *)&c, 1);
66 /* goto the begining of the screen after the cls operation */
67 gotoxy(0,0);
73 static void scrup(void)
75 if (!top && bottom == video_num_lines) {
76 origin += video_size_row;
77 pos += video_size_row;
78 scr_end += video_size_row;
79 if (scr_end > video_mem_end) {
80 memcpy((void *)video_mem_start, (const void *)origin, (video_num_lines - 1) * video_size_row);
81 scr_end -= origin-video_mem_start;
82 pos -= origin-video_mem_start;
83 origin = video_mem_start;
86 /* erase the list line */
87 memset_word((void *)(scr_end - video_size_row), video_erase_char, video_num_columns);
88 set_origin();
90 } else {
91 __asm__("cld\n\t"
92 "rep\n\t"
93 "movsl\n\t"
94 "movl video_num_columns,%%ecx\n\t"
95 "rep\n\t"
96 "stosw"
97 ::"a" (video_erase_char),
98 "c" ((bottom-top-1)*video_num_columns>>1),
99 "D" (origin+video_size_row*top),
100 "S" (origin+video_size_row*(top+1)));
104 static void scrdown(void)
106 __asm__("std\n\t"
107 "rep\n\t"
108 "movsl\n\t"
109 "addl $2,%%edi\n\t"
110 "movl video_num_columns,%%ecx\n\t"
111 "rep\n\t"
112 "stosw"
113 ::"a" (video_erase_char),
114 "c" ((bottom-top-1)*video_num_columns>>1),
115 "D" (origin+video_size_row*bottom-4),
116 "S" (origin+video_size_row*(bottom-1)-4)
121 static void lf(void)
123 if (y + 1 < bottom) {
124 y ++;
125 pos = pos + video_size_row;
126 return;
128 scrup();
131 static void ri(void)
133 if (y > top) {
134 y --;
135 pos -= video_size_row;
136 return;
138 scrdown();
141 static void cr(void)
143 pos -= x << 1;
144 x = 0;
147 static void del(void)
149 if (x) {
150 pos -= 2;
151 x --;
152 *(unsigned short *) pos = video_erase_char;
156 static void insert_char(void)
158 int i = x;
159 unsigned short tmp, old = video_erase_char;
160 unsigned short * p = (unsigned short *)pos;
162 while (i++ < video_num_columns) {
163 tmp = *p;
164 *p = old;
165 old = tmp;
166 p ++;
170 static void insert_line(void)
172 int oldtop, oldbottom;
173 oldtop = top;
174 oldbottom = bottom;
175 top = y;
176 bottom = video_num_lines;
177 scrdown();
178 top = oldtop;
179 bottom = oldbottom;
182 static void delete_char(void)
184 int i;
185 unsigned short *p = (unsigned short *) pos;
187 if (x >= video_num_columns)
188 return;
189 i = x;
191 while (++i < video_num_columns) {
192 *p = *(p+1);
193 p++;
195 *p = video_erase_char;
198 static void delete_line(void)
200 int oldtop, oldbottom;
202 oldtop = top;
203 oldbottom = bottom;
204 top = y;
205 bottom = video_num_lines;
206 scrup();
207 top = oldtop;
208 bottom = oldbottom;
212 static int saved_x = 0;
213 static int saved_y = 0;
215 static void save_cur(void)
217 saved_x = x;
218 saved_y = y;
221 static void restore_cur(void)
223 gotoxy(saved_x, saved_y);
226 void get_cursor(int *new_x, int *new_y)
228 *new_x = x;
229 *new_y = y;
232 void set_cursor(void)
234 cli();
235 outb_p(14, video_port_reg);
236 outb_p(0xff & ((pos - video_mem_start)>>9), video_port_val);
237 outb_p(15, video_port_reg);
238 outb_p(0xff & ((pos - video_mem_start)>>1), video_port_val);
239 sti();
242 void con_init(void)
244 /* We have seen os goes there ! */
245 extern void keyboard_interrupt(void);
247 video_num_columns = ORIG_VIDEO_COLS;
248 video_size_row = video_num_columns * 2;
249 video_num_lines = ORIG_VIDEO_LINES;
250 video_size_all = video_size_row * video_num_lines;
251 video_erase_char = 0x0720;
253 video_mem_start = 0xb8000;
254 video_mem_end = 0xba000;
255 video_port_reg = 0x3d4;
256 video_port_val = 0x3d5;
258 origin = video_mem_start;
259 scr_end = video_mem_start + video_num_lines * video_size_row;
260 top = 0;
261 bottom = video_num_lines;
263 gotoxy(ORIG_X, ORIG_Y);
264 set_cursor();
265 cls();
266 gotoxy(ORIG_X, ORIG_Y);
267 set_cursor();
271 * Something else need do here
272 * say, keyboard interrupt and so on
277 void con_write(char *buf, int nr)
279 unsigned char c;
280 while (nr-- > 0) {
281 c = *buf++;
282 switch (c) {
283 case 10: case 11: case 12:
284 cr();
285 lf();
286 set_cursor();
287 break;
288 case 13:
289 cr();
290 lf();
291 set_cursor();
292 break;
294 case 127:
295 del();
296 break;
298 case 8: /* '\b' */
299 if (x){
300 x--;
301 pos-=2;
302 *(unsigned short*)pos = video_erase_char;
304 break;
306 case 9:/* TAB */
307 c = 8 - (x&7);
308 x += c;
309 pos += c << 1;
310 if (x > video_num_columns) {
311 x -=video_num_columns;
312 pos -=video_size_row;
313 lf();
315 break;
316 case 7:
317 sysbeep();
318 break;
320 /* special key handled here */
321 case 0xE0: /* HOME */
322 x = 0;
323 gotoxy (x, y);
324 break;
326 case 0xE1: /* END */
327 x = video_num_columns - 1;
328 gotoxy (x, y);
329 break;
331 case 0xE2: /* UP */
332 if (y == 0) {
333 scrdown();
334 y = 0;
335 } else
336 y --;
338 gotoxy (x, y);
339 break;
341 case 0xE3: /* DN */
342 if ( y == video_num_lines) {
343 scrup();
344 y = video_num_lines;
345 } else
346 y ++;
347 gotoxy (x, y);
348 break;
350 case 0xE4: /* LeFt */
351 if (x == 0) {
352 x = video_num_columns;
353 y --;
354 } else
355 x --;
356 gotoxy (x, y);
357 break;
359 case 0xE5: /* RighT */
360 if (x == video_num_columns) {
361 x = 0;
362 y ++;
363 } else
364 x +=1;
365 gotoxy (x, y);
366 break;
368 case 0xE6: /* PGUP */
369 break;
370 case 0xE7: /* PGDN */
371 break;
372 case 0xE8: /* INS */
373 break;
374 case 0xE9: /* DEL */
375 break;
376 default:
377 if (x >= video_num_columns) {
378 x -= video_num_columns;
379 pos -= video_size_row;
380 lf();
383 *(unsigned char *)pos ++ = c;
384 *(unsigned char *)pos ++ = 0x02;
385 x++;
386 break;
389 set_cursor();
394 static void sysbeep(void)
396 /* not yet */
400 void wait_key_press()
402 /* Ignore the input, just wait a key press */
403 get_key();
406 char getchar(void)
408 return get_key();
412 int putchar(int c)
414 con_write((char *)&c, 1);
415 return 1;
420 * Following functions shoud be in lib dir but not created yet,
421 * so be here now.
423 int puts(char *s)
425 return printk("%s",s);