Make thunix can be run on a old bochs
[thunix.git] / kernel / console.c
blob811e2d30fd61435fce12ce452118a44d243f8c06
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);
38 static inline void gotoxy(unsigned int new_x, unsigned int new_y)
40 if (new_x > video_num_columns || new_y >= video_num_lines)
41 return ;
42 x = new_x;
43 y = new_y;
44 pos = origin + y*video_size_row + (x << 1);
45 /* pos = origin + (y<<8) + (y<<6) +(x<<1); */
48 static inline void set_origin(void)
50 cli();
51 outb_p(12,video_port_reg);
52 outb_p(0xff&((origin-video_mem_start)>>9),video_port_val);
53 outb_p(13,video_port_reg);
54 outb_p(0xff&((origin-video_mem_start)>>1),video_port_val);
55 sti();
58 void cls(void)
60 int i = 0;
61 unsigned char c=' ';
63 for (; i < video_size_all/2; i++ ) {
64 con_write((char *)&c, 1);
71 static void scrup(void)
73 if (!top && bottom == video_num_lines) {
74 origin += video_size_row;
75 pos += video_size_row;
76 scr_end += video_size_row;
77 if (scr_end > video_mem_end) {
78 __asm__("cld\n\t"
79 "rep\n\t"
80 "movsl\n\t"
81 "movl video_num_columns,%1\n\t"
82 "rep\n\t"
83 "stosw"
84 ::"a" (video_erase_char),
85 "c" ((video_num_lines-1)*video_num_columns>>1),
86 "D" (video_mem_start),
87 "S" (origin) );
88 scr_end -= origin-video_mem_start;
89 pos -= origin-video_mem_start;
90 origin = video_mem_start;
91 } else {
92 __asm__("cld\n\t"
93 "rep\n\t"
94 "stosw"
95 ::"a" (video_erase_char),
96 "c" (video_num_columns),
97 "D" (scr_end-video_size_row) );
99 set_origin();
101 } else {
102 __asm__("cld\n\t"
103 "rep\n\t"
104 "movsl\n\t"
105 "movl video_num_columns,%%ecx\n\t"
106 "rep\n\t"
107 "stosw"
108 ::"a" (video_erase_char),
109 "c" ((bottom-top-1)*video_num_columns>>1),
110 "D" (origin+video_size_row*top),
111 "S" (origin+video_size_row*(top+1)));
115 static void scrdown(void)
117 __asm__("std\n\t"
118 "rep\n\t"
119 "movsl\n\t"
120 "addl $2,%%edi\n\t"
121 "movl video_num_columns,%%ecx\n\t"
122 "rep\n\t"
123 "stosw"
124 ::"a" (video_erase_char),
125 "c" ((bottom-top-1)*video_num_columns>>1),
126 "D" (origin+video_size_row*bottom-4),
127 "S" (origin+video_size_row*(bottom-1)-4)
132 static void lf(void)
134 if (y + 1 < bottom) {
135 y ++;
136 pos = pos + video_size_row;
137 return;
139 scrup();
142 static void ri(void)
144 if (y > top) {
145 y --;
146 pos -= video_size_row;
147 return;
149 scrdown();
152 static void cr(void)
154 pos -= x << 1;
155 x = 0;
158 static void del(void)
160 if (x) {
161 pos -= 2;
162 x --;
163 *(unsigned short *) pos = video_erase_char;
167 static void insert_char(void)
169 int i = x;
170 unsigned short tmp, old = video_erase_char;
171 unsigned short * p = (unsigned short *)pos;
173 while (i++ < video_num_columns) {
174 tmp = *p;
175 *p = old;
176 old = tmp;
177 p ++;
181 static void insert_line(void)
183 int oldtop, oldbottom;
184 oldtop = top;
185 oldbottom = bottom;
186 top = y;
187 bottom = video_num_lines;
188 scrdown();
189 top = oldtop;
190 bottom = oldbottom;
193 static void delete_char(void)
195 int i;
196 unsigned short *p = (unsigned short *) pos;
198 if (x >= video_num_columns)
199 return;
200 i = x;
202 while (++i < video_num_columns) {
203 *p = *(p+1);
204 p++;
206 *p = video_erase_char;
209 static void delete_line(void)
211 int oldtop, oldbottom;
213 oldtop = top;
214 oldbottom = bottom;
215 top = y;
216 bottom = video_num_lines;
217 scrup();
218 top = oldtop;
219 bottom = oldbottom;
223 static int saved_x = 0;
224 static int saved_y = 0;
226 static void save_cur(void)
228 saved_x = x;
229 saved_y = y;
232 static void restore_cur(void)
234 gotoxy(saved_x, saved_y);
237 void get_cursor(int *new_x, int *new_y)
239 *new_x = x;
240 *new_y = y;
243 void set_cursor(void)
245 cli();
246 outb_p(14, video_port_reg);
247 outb_p(0xff & ((pos - video_mem_start)>>9), video_port_val);
248 outb_p(15, video_port_reg);
249 outb_p(0xff & ((pos - video_mem_start)>>1), video_port_val);
250 sti();
253 void con_init(void)
255 /* We have seen os goes there ! */
256 extern void keyboard_interrupt(void);
258 video_num_columns = ORIG_VIDEO_COLS;
259 video_size_row = video_num_columns * 2;
260 video_num_lines = ORIG_VIDEO_LINES;
261 video_size_all = video_size_row * video_num_lines;
262 video_erase_char = 0x0720;
264 video_mem_start = 0xb8000;
265 video_mem_end = 0xba000;
266 video_port_reg = 0x3d4;
267 video_port_val = 0x3d5;
269 origin = video_mem_start;
270 scr_end = video_mem_start + video_num_lines * video_size_row;
271 top = 0;
272 bottom = video_num_lines;
274 gotoxy(ORIG_X, ORIG_Y);
275 set_cursor();
276 cls();
277 gotoxy(ORIG_X, ORIG_Y);
278 set_cursor();
282 * Something else need do here
283 * say, keyboard interrupt and so on
288 void con_write(char *buf, int nr)
290 unsigned char c;
291 while (nr-- > 0) {
292 c = *buf++;
293 switch (c) {
294 case 10: case 11: case 12:
295 cr();
296 lf();
297 set_cursor();
298 break;
299 case 13:
300 cr();
301 lf();
302 set_cursor();
303 break;
305 case 127:
306 del();
307 break;
309 case 8: /* '\b' */
310 if (x){
311 x--;
312 pos-=2;
313 *(unsigned short*)pos = video_erase_char;
315 break;
317 case 9:/* TAB */
318 c = 8 - (x&7);
319 x += c;
320 pos += c << 1;
321 if (x > video_num_columns) {
322 x -=video_num_columns;
323 pos -=video_size_row;
324 lf();
326 break;
327 case 7:
328 sysbeep();
329 break;
331 /* special key handled here */
332 case 0xE0: /* HOME */
333 x = 0;
334 gotoxy (x, y);
335 break;
337 case 0xE1: /* END */
338 x = video_num_columns - 1;
339 gotoxy (x, y);
340 break;
342 case 0xE2: /* UP */
343 if (y == 0) {
344 scrdown();
345 y = 0;
346 } else
347 y --;
349 gotoxy (x, y);
350 break;
352 case 0xE3: /* DN */
353 if ( y == video_num_lines) {
354 scrup();
355 y = video_num_lines;
356 } else
357 y ++;
358 gotoxy (x, y);
359 break;
361 case 0xE4: /* LeFt */
362 if (x == 0) {
363 x = video_num_columns;
364 y --;
365 } else
366 x --;
367 gotoxy (x, y);
368 break;
370 case 0xE5: /* RighT */
371 if (x == video_num_columns) {
372 x = 0;
373 y ++;
374 } else
375 x +=1;
376 gotoxy (x, y);
377 break;
379 case 0xE6: /* PGUP */
380 break;
381 case 0xE7: /* PGDN */
382 break;
383 case 0xE8: /* INS */
384 break;
385 case 0xE9: /* DEL */
386 break;
387 default:
388 if (x >= video_num_columns) {
389 x -= video_num_columns;
390 pos -= video_size_row;
391 lf();
394 *(unsigned char *)pos ++ = c;
395 *(unsigned char *)pos ++ = 0x02;
396 x++;
397 break;
400 set_cursor();
405 static void sysbeep(void)
407 /* not yet */
416 * Following functions shoud be in lib dir but not created yet,
417 * so be here now.
419 extern int printk(char *fmt, ...);
420 int puts(char *s)
422 return printk("%s",s);