This source file includes following definitions.
- gotoxy
- set_origin
- scrup
- scrdown
- lf
- ri
- cr
- del
- csi_J
- csi_K
- csi_m
- set_cursor
- hide_cursor
- respond
- insert_char
- insert_line
- delete_char
- delete_line
- csi_at
- csi_L
- csi_P
- csi_M
- save_cur
- restore_cur
- con_write
- do_keyboard_interrupt
- memsetw
- con_init
- kbdsave
- get_scrmem
- set_scrmem
- blank_screen
- unblank_screen
- update_screen
- sysbeepstop
- sysbeep
- do_screendump
- console_print
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 #include <linux/sched.h>
34 #include <linux/timer.h>
35 #include <linux/tty.h>
36 #include <linux/config.h>
37 #include <linux/kernel.h>
38
39 #include <asm/io.h>
40 #include <asm/system.h>
41 #include <asm/segment.h>
42
43 #include <string.h>
44 #include <errno.h>
45
46 #define DEF_TERMIOS \
47 (struct termios) { \
48 ICRNL, \
49 OPOST | ONLCR, \
50 0, \
51 IXON | ISIG | ICANON | ECHO | ECHOCTL | ECHOKE, \
52 0, \
53 INIT_C_CC \
54 }
55
56 static void blank_screen(void);
57 static void unblank_screen(void);
58
59
60
61
62
63 #define ORIG_X (*(unsigned char *)0x90000)
64 #define ORIG_Y (*(unsigned char *)0x90001)
65 #define ORIG_VIDEO_PAGE (*(unsigned short *)0x90004)
66 #define ORIG_VIDEO_MODE ((*(unsigned short *)0x90006) & 0xff)
67 #define ORIG_VIDEO_COLS (((*(unsigned short *)0x90006) & 0xff00) >> 8)
68 #define ORIG_VIDEO_LINES ((*(unsigned short *)0x9000e) & 0xff)
69 #define ORIG_VIDEO_EGA_AX (*(unsigned short *)0x90008)
70 #define ORIG_VIDEO_EGA_BX (*(unsigned short *)0x9000a)
71 #define ORIG_VIDEO_EGA_CX (*(unsigned short *)0x9000c)
72
73 #define VIDEO_TYPE_MDA 0x10
74 #define VIDEO_TYPE_CGA 0x11
75 #define VIDEO_TYPE_EGAM 0x20
76 #define VIDEO_TYPE_EGAC 0x21
77
78 #define NPAR 16
79
80 int NR_CONSOLES = 0;
81
82 extern void keyboard_interrupt(void);
83 extern void set_leds(void);
84 extern unsigned char kapplic;
85 extern unsigned char kleds;
86 extern unsigned char kmode;
87
88 unsigned long video_num_columns;
89 unsigned long video_num_lines;
90
91 static unsigned char video_type;
92 static unsigned long video_mem_base;
93 static unsigned long video_mem_term;
94 static unsigned long video_size_row;
95 static unsigned char video_page;
96 static unsigned short video_port_reg;
97 static unsigned short video_port_val;
98 static int can_do_colour = 0;
99
100 static struct {
101 unsigned short vc_video_erase_char;
102 unsigned char vc_attr;
103 unsigned char vc_def_attr;
104 int vc_bold_attr;
105 unsigned long vc_ques;
106 unsigned long vc_state;
107 char * vc_restate;
108 unsigned long vc_checkin;
109 unsigned long vc_origin;
110 unsigned long vc_scr_end;
111 unsigned long vc_pos;
112 unsigned long vc_x,vc_y;
113 unsigned long vc_top,vc_bottom;
114 unsigned long vc_npar,vc_par[NPAR];
115 unsigned long vc_video_mem_start;
116 unsigned long vc_video_mem_end;
117 unsigned int vc_saved_x;
118 unsigned int vc_saved_y;
119 unsigned int vc_iscolor;
120 unsigned char vc_kbdapplic;
121 unsigned char vc_kbdleds;
122 unsigned char vc_kbdmode;
123 char * vc_translate;
124 } vc_cons [MAX_CONSOLES];
125
126 #define MEM_BUFFER_SIZE (2*80*50*8)
127
128 unsigned short *vc_scrbuf[MAX_CONSOLES];
129 unsigned short vc_scrmembuf[MEM_BUFFER_SIZE/2];
130 static int console_blanked = 0;
131
132 #define origin (vc_cons[currcons].vc_origin)
133 #define scr_end (vc_cons[currcons].vc_scr_end)
134 #define pos (vc_cons[currcons].vc_pos)
135 #define top (vc_cons[currcons].vc_top)
136 #define bottom (vc_cons[currcons].vc_bottom)
137 #define x (vc_cons[currcons].vc_x)
138 #define y (vc_cons[currcons].vc_y)
139 #define state (vc_cons[currcons].vc_state)
140 #define restate (vc_cons[currcons].vc_restate)
141 #define checkin (vc_cons[currcons].vc_checkin)
142 #define npar (vc_cons[currcons].vc_npar)
143 #define par (vc_cons[currcons].vc_par)
144 #define ques (vc_cons[currcons].vc_ques)
145 #define attr (vc_cons[currcons].vc_attr)
146 #define saved_x (vc_cons[currcons].vc_saved_x)
147 #define saved_y (vc_cons[currcons].vc_saved_y)
148 #define translate (vc_cons[currcons].vc_translate)
149 #define video_mem_start (vc_cons[currcons].vc_video_mem_start)
150 #define video_mem_end (vc_cons[currcons].vc_video_mem_end)
151 #define def_attr (vc_cons[currcons].vc_def_attr)
152 #define video_erase_char (vc_cons[currcons].vc_video_erase_char)
153 #define iscolor (vc_cons[currcons].vc_iscolor)
154 #define kbdapplic (vc_cons[currcons].vc_kbdapplic)
155 #define kbdmode (vc_cons[currcons].vc_kbdmode)
156 #define kbdleds (vc_cons[currcons].vc_kbdleds)
157
158 int blankinterval = 5*60*HZ;
159 static int screen_size = 0;
160
161 static void sysbeep(void);
162
163
164
165
166
167 #define RESPONSE "\033[?1;2c"
168
169 static char * translations[] = {
170
171 "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
172 "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
173 " !\"#$%&'()*+,-./0123456789:;<=>?"
174 "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
175 "`abcdefghijklmnopqrstuvwxyz{|}~\0"
176 "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
177 "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
178 "\040\255\233\234\376\235\174\025\376\376\246\256\252\055\376\376"
179 "\370\361\375\376\376\346\024\371\376\376\247\257\254\253\376\250"
180 "\376\376\376\376\216\217\222\200\376\220\376\376\376\376\376\376"
181 "\376\245\376\376\376\376\231\376\376\376\376\376\232\376\376\341"
182 "\205\240\203\376\204\206\221\207\212\202\210\211\215\241\214\213"
183 "\376\244\225\242\223\376\224\366\376\227\243\226\201\376\376\230",
184
185 "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
186 "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
187 " !\"#$%&'()*+,-./0123456789:;<=>?"
188 "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^ "
189 "\004\261\007\007\007\007\370\361\007\007\275\267\326\323\327\304"
190 "\304\304\304\304\307\266\320\322\272\363\362\343\007\234\007\0"
191 "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
192 "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
193 "\040\255\233\234\376\235\174\025\376\376\246\256\252\055\376\376"
194 "\370\361\375\376\376\346\024\371\376\376\247\257\254\253\376\250"
195 "\376\376\376\376\216\217\222\200\376\220\376\376\376\376\376\376"
196 "\376\245\376\376\376\376\231\376\376\376\376\376\232\376\376\341"
197 "\205\240\203\376\204\206\221\207\212\202\210\211\215\241\214\213"
198 "\376\244\225\242\223\376\224\366\376\227\243\226\201\376\376\230"
199 };
200
201 #define NORM_TRANS (translations[0])
202 #define GRAF_TRANS (translations[1])
203
204
205 static inline void gotoxy(int currcons, unsigned int new_x,unsigned int new_y)
206 {
207 if (new_x > video_num_columns || new_y >= video_num_lines)
208 return;
209 x = new_x;
210 y = new_y;
211 pos = origin + y*video_size_row + (x<<1);
212 }
213
214 static inline void set_origin(int currcons)
215 {
216 if (video_type != VIDEO_TYPE_EGAC && video_type != VIDEO_TYPE_EGAM)
217 return;
218 if (currcons != fg_console)
219 return;
220 cli();
221 outb_p(12, video_port_reg);
222 outb_p(0xff&((origin-video_mem_base)>>9), video_port_val);
223 outb_p(13, video_port_reg);
224 outb_p(0xff&((origin-video_mem_base)>>1), video_port_val);
225 sti();
226 }
227
228 static void scrup(int currcons, unsigned int t, unsigned int b)
229 {
230 int hardscroll = 1;
231
232 if (b > video_num_lines || t >= b)
233 return;
234 if (video_type != VIDEO_TYPE_EGAC && video_type != VIDEO_TYPE_EGAM)
235 hardscroll = 0;
236 else if (t || b != video_num_lines)
237 hardscroll = 0;
238 if (hardscroll) {
239 origin += video_size_row;
240 pos += video_size_row;
241 scr_end += video_size_row;
242 if (scr_end > video_mem_end) {
243 __asm__("cld\n\t"
244 "rep\n\t"
245 "movsl\n\t"
246 "movl _video_num_columns,%1\n\t"
247 "rep\n\t"
248 "stosw"
249 ::"a" (video_erase_char),
250 "c" ((video_num_lines-1)*video_num_columns>>1),
251 "D" (video_mem_start),
252 "S" (origin)
253 :"cx","di","si");
254 scr_end -= origin-video_mem_start;
255 pos -= origin-video_mem_start;
256 origin = video_mem_start;
257 } else {
258 __asm__("cld\n\t"
259 "rep\n\t"
260 "stosw"
261 ::"a" (video_erase_char),
262 "c" (video_num_columns),
263 "D" (scr_end-video_size_row)
264 :"cx","di");
265 }
266 set_origin(currcons);
267 } else {
268 __asm__("cld\n\t"
269 "rep\n\t"
270 "movsl\n\t"
271 "movl _video_num_columns,%%ecx\n\t"
272 "rep\n\t"
273 "stosw"
274 ::"a" (video_erase_char),
275 "c" ((b-t-1)*video_num_columns>>1),
276 "D" (origin+video_size_row*t),
277 "S" (origin+video_size_row*(t+1))
278 :"cx","di","si");
279 }
280 }
281
282 static void scrdown(int currcons, unsigned int t, unsigned int b)
283 {
284 if (b > video_num_lines || t >= b)
285 return;
286 __asm__("std\n\t"
287 "rep\n\t"
288 "movsl\n\t"
289 "addl $2,%%edi\n\t"
290 "movl _video_num_columns,%%ecx\n\t"
291 "rep\n\t"
292 "stosw\n\t"
293 "cld"
294 ::"a" (video_erase_char),
295 "c" ((b-t-1)*video_num_columns>>1),
296 "D" (origin+video_size_row*b-4),
297 "S" (origin+video_size_row*(b-1)-4)
298 :"ax","cx","di","si");
299 }
300
301 static void lf(int currcons)
302 {
303 if (y+1<bottom) {
304 y++;
305 pos += video_size_row;
306 return;
307 } else
308 scrup(currcons,top,bottom);
309 }
310
311 static void ri(int currcons)
312 {
313 if (y>top) {
314 y--;
315 pos -= video_size_row;
316 return;
317 } else
318 scrdown(currcons,top,bottom);
319 }
320
321 static void cr(int currcons)
322 {
323 pos -= x<<1;
324 x=0;
325 }
326
327 static void del(int currcons)
328 {
329 if (x) {
330 pos -= 2;
331 x--;
332 *(unsigned short *)pos = video_erase_char;
333 }
334 }
335
336 static void csi_J(int currcons, int vpar)
337 {
338 unsigned long count;
339 unsigned long start;
340
341 switch (vpar) {
342 case 0:
343 count = (scr_end-pos)>>1;
344 start = pos;
345 break;
346 case 1:
347 count = (pos-origin)>>1;
348 start = origin;
349 break;
350 case 2:
351 count = video_num_columns * video_num_lines;
352 start = origin;
353 break;
354 default:
355 return;
356 }
357 __asm__("cld\n\t"
358 "rep\n\t"
359 "stosw\n\t"
360 ::"c" (count),
361 "D" (start),"a" (video_erase_char)
362 :"cx","di");
363 }
364
365 static void csi_K(int currcons, int vpar)
366 {
367 long count;
368 long start;
369
370 switch (vpar) {
371 case 0:
372 if (x>=video_num_columns)
373 return;
374 count = video_num_columns-x;
375 start = pos;
376 break;
377 case 1:
378 start = pos - (x<<1);
379 count = (x<video_num_columns)?x:video_num_columns;
380 break;
381 case 2:
382 start = pos - (x<<1);
383 count = video_num_columns;
384 break;
385 default:
386 return;
387 }
388 __asm__("cld\n\t"
389 "rep\n\t"
390 "stosw\n\t"
391 ::"c" (count),
392 "D" (start),"a" (video_erase_char)
393 :"cx","di");
394 }
395
396 static void csi_m(int currcons )
397 {
398 int i;
399 static int conv_table[8] = { 0, 4, 2, 6, 1, 5, 3, 7 };
400
401 for (i=0;i<=npar;i++)
402 switch (par[i]) {
403 case 0: attr=def_attr;break;
404 case 1: attr=(iscolor?attr|0x08:attr|0x0f);break;
405
406 case 4:
407 if (!iscolor)
408 attr |= 0x01;
409 else
410 {
411 if (vc_cons[currcons].vc_bold_attr != -1)
412 attr = (vc_cons[currcons].vc_bold_attr&0x0f)|(0xf0&(attr));
413 else
414 { short newattr = (attr&0xf0)|(0xf&(~attr));
415 attr = ((newattr&0xf)==((attr>>4)&0xf)?
416 (attr&0xf0)|(((attr&0xf)+1)%0xf):
417 newattr);
418 }
419 }
420 break;
421 case 5: attr=attr|0x80;break;
422 case 7: attr=(attr&0x88)|((attr<<4)&0x70)|
423 ((attr>>4)&0x07);break;
424 case 22: attr=attr&0xf7;break;
425 case 24: attr=attr&0xfe;break;
426 case 25: attr=attr&0x7f;break;
427 case 27: attr=def_attr;break;
428 case 39: attr=(attr & 0xf8)|(def_attr & 0x07); break;
429 case 49: attr=(attr & 0x8f)|(def_attr & 0x70); break;
430 default:
431 if (!can_do_colour)
432 break;
433 iscolor = 1;
434 if ((par[i]>=30) && (par[i]<=37))
435 attr = (attr & 0xf8) | conv_table[par[i]-30];
436 else
437 if ((par[i]>=40) && (par[i]<=47))
438 attr = (attr & 0x8f) | (conv_table[par[i]-40]<<4);
439 else
440 break;
441 }
442 }
443
444 static inline void set_cursor(int currcons)
445 {
446 if (currcons != fg_console)
447 return;
448 cli();
449 outb_p(14, video_port_reg);
450 outb_p(0xff&((pos-video_mem_base)>>9), video_port_val);
451 outb_p(15, video_port_reg);
452 outb_p(0xff&((pos-video_mem_base)>>1), video_port_val);
453 sti();
454 }
455
456 static inline void hide_cursor(int currcons)
457 {
458 outb_p(14, video_port_reg);
459 outb_p(0xff&((scr_end-video_mem_base)>>9), video_port_val);
460 outb_p(15, video_port_reg);
461 outb_p(0xff&((scr_end-video_mem_base)>>1), video_port_val);
462 }
463
464 static void respond(int currcons, struct tty_struct * tty)
465 {
466 char * p = RESPONSE;
467
468 cli();
469 while (*p) {
470 PUTCH(*p,tty->read_q);
471 p++;
472 }
473 sti();
474 TTY_READ_FLUSH(tty);
475 }
476
477 static void insert_char(int currcons)
478 {
479 unsigned int i = x;
480 unsigned short tmp, old = video_erase_char;
481 unsigned short * p = (unsigned short *) pos;
482
483 while (i++ < video_num_columns) {
484 tmp = *p;
485 *p = old;
486 old = tmp;
487 p++;
488 }
489 }
490
491 static void insert_line(int currcons)
492 {
493 scrdown(currcons,y,bottom);
494 }
495
496 static void delete_char(int currcons)
497 {
498 unsigned int i = x;
499 unsigned short * p = (unsigned short *) pos;
500
501 if (x >= video_num_columns)
502 return;
503 while (++i < video_num_columns) {
504 *p = *(p+1);
505 p++;
506 }
507 *p = video_erase_char;
508 }
509
510 static void delete_line(int currcons)
511 {
512 scrup(currcons,y,bottom);
513 }
514
515 static void csi_at(int currcons, unsigned int nr)
516 {
517 if (nr > video_num_columns)
518 nr = video_num_columns;
519 else if (!nr)
520 nr = 1;
521 while (nr--)
522 insert_char(currcons);
523 }
524
525 static void csi_L(int currcons, unsigned int nr)
526 {
527 if (nr > video_num_lines)
528 nr = video_num_lines;
529 else if (!nr)
530 nr = 1;
531 while (nr--)
532 insert_line(currcons);
533 }
534
535 static void csi_P(int currcons, unsigned int nr)
536 {
537 if (nr > video_num_columns)
538 nr = video_num_columns;
539 else if (!nr)
540 nr = 1;
541 while (nr--)
542 delete_char(currcons);
543 }
544
545 static void csi_M(int currcons, unsigned int nr)
546 {
547 if (nr > video_num_lines)
548 nr = video_num_lines;
549 else if (!nr)
550 nr=1;
551 while (nr--)
552 delete_line(currcons);
553 }
554
555 static void save_cur(int currcons)
556 {
557 saved_x = x;
558 saved_y = y;
559 }
560
561 static void restore_cur(int currcons)
562 {
563 gotoxy(currcons, saved_x, saved_y);
564 }
565
566
567 enum { ESnormal, ESesc, ESsquare, ESgetpars, ESgotpars, ESfunckey,
568 ESsetterm, ESsetgraph, ESgraph, ESgresc, ESignore };
569
570 void con_write(struct tty_struct * tty)
571 {
572 unsigned char c;
573 unsigned int currcons;
574
575 wake_up(&tty->write_q->proc_list);
576 currcons = tty - tty_table;
577 if (currcons >= MAX_CONSOLES) {
578 printk("con_write: illegal tty\n\r");
579 return;
580 }
581 while (!EMPTY(tty->write_q)) {
582 if (tty->stopped)
583 break;
584 GETCH(tty->write_q,c);
585 if (c == 24 || c == 26)
586 state = ESnormal;
587 switch(state) {
588 case ESnormal:
589 if (translate[c]) {
590 c = translate[c];
591 while (x >= video_num_columns) {
592 x -= video_num_columns;
593 pos -= video_size_row;
594 lf(currcons);
595 }
596 *(char *) pos = c;
597 *(char *) (pos+1) = attr;
598 pos += 2;
599 x++;
600 } else if (c == 27)
601 state = ESesc;
602 else if (c == 10 || c == 11 || c == 12)
603 lf(currcons);
604 else if (c == 13)
605 cr(currcons);
606 else if (c == 127)
607 del(currcons);
608 else if (c == 8) {
609 if (x) {
610 x--;
611 pos -= 2;
612 }
613 } else if (c == 9) {
614 c = 8-(x&7);
615 x += c;
616 pos += c<<1;
617 if (x > video_num_columns) {
618 x -= video_num_columns;
619 pos -= video_size_row;
620 lf(currcons);
621 }
622 c = 9;
623 } else if (c == 7)
624 sysbeep();
625 else if (c == 14) {
626 checkin = 1;
627 translate = restate;
628 } else if (c == 15) {
629 translate = NORM_TRANS;
630 checkin = 0;
631 }
632 break;
633 case ESesc:
634 state = ESnormal;
635 switch (c) {
636 case '[':
637 state = ESsquare;
638 break;
639 case 'E':
640 gotoxy(currcons,0,y+1);
641 break;
642 case 'M':
643 ri(currcons);
644 break;
645 case 'D':
646 lf(currcons);
647 break;
648 case 'Z':
649 respond(currcons,tty);
650 break;
651 case '7':
652 save_cur(currcons);
653 break;
654 case '8':
655 restore_cur(currcons);
656 break;
657 case '(':
658 case ')':
659 state = ESsetgraph;
660 break;
661 case 'P':
662 state = ESsetterm;
663 break;
664 case '#':
665 state = -1;
666 break;
667 case 'c':
668 tty->termios = DEF_TERMIOS;
669 state = ESnormal;
670 restate = NORM_TRANS;
671 checkin = 0;
672 top = 0;
673 bottom = video_num_lines;
674 translate = NORM_TRANS;
675 case '>':
676 kbdapplic = 0;
677 if (currcons == fg_console)
678 kapplic = 0;
679 break;
680 case '=':
681 kbdapplic = 1;
682 if (currcons == fg_console)
683 kapplic = 1;
684 break;
685 }
686 break;
687 case ESsquare:
688 for(npar = 0 ; npar < NPAR ; npar++)
689 par[npar] = 0;
690 npar = 0;
691 state = ESgetpars;
692 if (c == '[') {
693 state=ESfunckey;
694 break;
695 }
696 if (ques=(c=='?'))
697 break;
698 case ESgetpars:
699 if (c==';' && npar<NPAR-1) {
700 npar++;
701 break;
702 } else if (c>='0' && c<='9') {
703 par[npar] *= 10;
704 par[npar] += c-'0';
705 break;
706 } else state=ESgotpars;
707 case ESgotpars:
708 state = ESnormal;
709 if (ques) {
710 ques = 0;
711 break;
712 }
713 switch(c) {
714 case 'G': case '`':
715 if (par[0]) par[0]--;
716 gotoxy(currcons,par[0],y);
717 break;
718 case 'A':
719 if (!par[0]) par[0]++;
720 gotoxy(currcons,x,y-par[0]);
721 break;
722 case 'B': case 'e':
723 if (!par[0]) par[0]++;
724 gotoxy(currcons,x,y+par[0]);
725 break;
726 case 'C': case 'a':
727 if (!par[0]) par[0]++;
728 gotoxy(currcons,x+par[0],y);
729 break;
730 case 'D':
731 if (!par[0]) par[0]++;
732 gotoxy(currcons,x-par[0],y);
733 break;
734 case 'E':
735 if (!par[0]) par[0]++;
736 gotoxy(currcons,0,y+par[0]);
737 break;
738 case 'F':
739 if (!par[0]) par[0]++;
740 gotoxy(currcons,0,y-par[0]);
741 break;
742 case 'd':
743 if (par[0]) par[0]--;
744 gotoxy(currcons,x,par[0]);
745 break;
746 case 'H': case 'f':
747 if (par[0]) par[0]--;
748 if (par[1]) par[1]--;
749 gotoxy(currcons,par[1],par[0]);
750 break;
751 case 'J':
752 csi_J(currcons,par[0]);
753 break;
754 case 'K':
755 csi_K(currcons,par[0]);
756 break;
757 case 'L':
758 csi_L(currcons,par[0]);
759 break;
760 case 'M':
761 csi_M(currcons,par[0]);
762 break;
763 case 'P':
764 csi_P(currcons,par[0]);
765 break;
766 case '@':
767 csi_at(currcons,par[0]);
768 break;
769 case 'm':
770 csi_m(currcons);
771 break;
772 case 'r':
773 if (par[0])
774 par[0]--;
775 if (!par[1])
776 par[1] = video_num_lines;
777 if (par[0] < par[1] &&
778 par[1] <= video_num_lines) {
779 top=par[0];
780 bottom=par[1];
781 }
782 break;
783 case 's':
784 save_cur(currcons);
785 break;
786 case 'u':
787 restore_cur(currcons);
788 break;
789 case 'l':
790 case 'b':
791 if (!((npar >= 2) &&
792 ((par[1]-13) == par[0]) &&
793 ((par[2]-17) == par[0])))
794 break;
795 if ((c=='l') && (par[0]<=60)) {
796 blankinterval = HZ*60*par[0];
797 }
798 if (c=='b')
799 vc_cons[currcons].vc_bold_attr
800 = par[0];
801 }
802 break;
803 case ESfunckey:
804 state = ESnormal;
805 break;
806 case ESsetterm:
807 state = ESnormal;
808 if (c == 'S') {
809 def_attr = attr;
810 video_erase_char = (video_erase_char&0x0ff) | (def_attr<<8);
811 } else if (c == 'L')
812 ;
813 else if (c == 'l')
814 ;
815 break;
816 case ESsetgraph:
817 if (c == '0') {
818 if (checkin)
819 translate = GRAF_TRANS;
820 restate = GRAF_TRANS;
821 } else if (c == 'B')
822 translate = restate = NORM_TRANS;
823 state = ESnormal;
824 break;
825 default:
826 state = ESnormal;
827 }
828 }
829 set_cursor(currcons);
830 timer_active &= ~(1<<BLANK_TIMER);
831 if (console_blanked) {
832 timer_table[BLANK_TIMER].expires = 0;
833 timer_active |= 1<<BLANK_TIMER;
834 } else if (blankinterval) {
835 timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
836 timer_active |= 1<<BLANK_TIMER;
837 }
838 }
839
840 void do_keyboard_interrupt(void)
841 {
842 TTY_READ_FLUSH(TTY_TABLE(0));
843 timer_active &= ~(1<<BLANK_TIMER);
844 if (console_blanked) {
845 timer_table[BLANK_TIMER].expires = 0;
846 timer_active |= 1<<BLANK_TIMER;
847 } else if (blankinterval) {
848 timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
849 timer_active |= 1<<BLANK_TIMER;
850 }
851 }
852
853 void * memsetw(void * s,unsigned short c,int count)
854 {
855 __asm__("cld\n\t"
856 "rep\n\t"
857 "stosw"
858 ::"a" (c),"D" (s),"c" (count)
859 :"cx","di");
860 return s;
861 }
862
863
864
865
866
867
868
869
870
871
872
873 void con_init(void)
874 {
875 register unsigned char a;
876 char *display_desc = "????";
877 char *display_ptr;
878 int currcons = 0;
879 long base, term;
880 long video_memory;
881 long saveterm, savebase;
882
883 video_num_columns = ORIG_VIDEO_COLS;
884 video_size_row = video_num_columns * 2;
885 video_num_lines = ORIG_VIDEO_LINES;
886 video_page = ORIG_VIDEO_PAGE;
887 video_erase_char = 0x0720;
888 timer_table[BLANK_TIMER].fn = blank_screen;
889 timer_table[BLANK_TIMER].expires = 0;
890 if (blankinterval) {
891 timer_table[BLANK_TIMER].expires = jiffies+blankinterval;
892 timer_active |= 1<<BLANK_TIMER;
893 }
894
895 if (ORIG_VIDEO_MODE == 7)
896 {
897 video_mem_base = 0xb0000;
898 video_port_reg = 0x3b4;
899 video_port_val = 0x3b5;
900 if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10)
901 {
902 video_type = VIDEO_TYPE_EGAM;
903 video_mem_term = 0xb8000;
904 display_desc = "EGAm";
905 }
906 else
907 {
908 video_type = VIDEO_TYPE_MDA;
909 video_mem_term = 0xb2000;
910 display_desc = "*MDA";
911 }
912 }
913 else
914 {
915 can_do_colour = 1;
916 video_mem_base = 0xb8000;
917 video_port_reg = 0x3d4;
918 video_port_val = 0x3d5;
919 if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10)
920 {
921 video_type = VIDEO_TYPE_EGAC;
922 video_mem_term = 0xc0000;
923 display_desc = "EGAc";
924 }
925 else
926 {
927 video_type = VIDEO_TYPE_CGA;
928 video_mem_term = 0xba000;
929 display_desc = "*CGA";
930 }
931 }
932
933
934
935 display_ptr = ((char *)video_mem_base) + video_size_row - 8;
936 while (*display_desc)
937 {
938 *display_ptr++ = *display_desc++;
939 display_ptr++;
940 }
941
942 savebase = video_mem_base;
943 saveterm = video_mem_term;
944 memsetw(vc_scrmembuf,video_erase_char,MEM_BUFFER_SIZE/2);
945 video_mem_base = (long)vc_scrmembuf;
946 video_mem_term = (long)&(vc_scrmembuf[MEM_BUFFER_SIZE/2]);
947 video_memory = video_mem_term - video_mem_base;
948 screen_size = (video_num_lines * video_size_row);
949 NR_CONSOLES = video_memory / screen_size;
950 if (NR_CONSOLES > MAX_CONSOLES)
951 NR_CONSOLES = MAX_CONSOLES;
952 if (!NR_CONSOLES)
953 NR_CONSOLES = 1;
954 video_memory = screen_size;
955
956
957
958 base = origin = video_mem_start = video_mem_base;
959 term = video_mem_end = base + video_memory;
960 scr_end = video_mem_start + screen_size;
961 top = 0;
962 bottom = video_num_lines;
963 attr = 0x07;
964 def_attr = 0x07;
965 restate = NORM_TRANS;
966 state = ESnormal;
967 checkin = 0;
968 ques = 0;
969 iscolor = 0;
970 translate = NORM_TRANS;
971 kbdleds = 2;
972 kbdmode = 0;
973 kbdapplic = 0;
974 vc_cons[0].vc_bold_attr = -1;
975
976 gotoxy(currcons,ORIG_X,ORIG_Y);
977 for (currcons = 1; currcons<NR_CONSOLES; currcons++) {
978 vc_cons[currcons] = vc_cons[0];
979 origin = video_mem_start = (base += video_memory);
980 scr_end = origin + video_num_lines * video_size_row;
981 video_mem_end = (term += video_memory);
982 gotoxy(currcons,0,0);
983 }
984 for (currcons = 0; currcons<NR_CONSOLES; currcons++)
985 vc_scrbuf[currcons] = (unsigned short *)origin;
986 currcons = 0;
987 video_mem_base = savebase;
988 video_mem_term = saveterm;
989
990 video_mem_start = video_mem_base;
991 video_mem_end = video_mem_term;
992 origin = video_mem_start;
993 scr_end = video_mem_start + video_num_lines * video_size_row;
994 top = 0;
995 bottom = video_num_lines;
996 pos=origin + y*video_size_row + (x<<1);
997 update_screen(fg_console);
998 set_trap_gate(0x21,&keyboard_interrupt);
999 outb_p(inb_p(0x21)&0xfd,0x21);
1000 a=inb_p(0x61);
1001 outb_p(a|0x80,0x61);
1002 outb_p(a,0x61);
1003 }
1004
1005 void kbdsave(int new_console)
1006 {
1007 int currcons = fg_console;
1008 kbdmode = kmode;
1009 kbdleds = kleds;
1010 kbdapplic = kapplic;
1011 currcons = new_console;
1012 kmode = (kmode & 0x3F) | (kbdmode & 0xC0);
1013 kleds = kbdleds;
1014 kapplic = kbdapplic;
1015 set_leds();
1016 }
1017
1018 static void get_scrmem(int currcons)
1019 {
1020 memcpy((void *)vc_scrbuf[fg_console],(void *)origin, screen_size);
1021 video_mem_start = (unsigned long)vc_scrbuf[fg_console];
1022 origin = video_mem_start;
1023 scr_end = video_mem_end = video_mem_start+screen_size;
1024 pos = origin + y*video_size_row + (x<<1);
1025 }
1026
1027 static void set_scrmem(int currcons)
1028 {
1029 video_mem_start = video_mem_base;
1030 video_mem_end = video_mem_term;
1031 origin = video_mem_start;
1032 scr_end = video_mem_start + screen_size;
1033 pos = origin + y*video_size_row + (x<<1);
1034 memcpy((void *)video_mem_base, (void *)vc_scrbuf[fg_console], screen_size);
1035 }
1036
1037 void blank_screen(void)
1038 {
1039 timer_table[BLANK_TIMER].fn = unblank_screen;
1040 get_scrmem(fg_console);
1041 hide_cursor(fg_console);
1042 console_blanked = 1;
1043 memsetw((void *)video_mem_base, 0x0020, video_mem_term-video_mem_base );
1044 }
1045
1046 void unblank_screen(void)
1047 {
1048 timer_table[BLANK_TIMER].fn = blank_screen;
1049 if (blankinterval) {
1050 timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
1051 timer_active |= 1<<BLANK_TIMER;
1052 }
1053 console_blanked = 0;
1054 set_scrmem(fg_console);
1055 set_origin(fg_console);
1056 set_cursor(fg_console);
1057 }
1058
1059 void update_screen(int new_console)
1060 {
1061 static int lock = 0;
1062
1063 if (new_console == fg_console || lock)
1064 return;
1065 lock = 1;
1066 kbdsave(new_console);
1067 get_scrmem(fg_console);
1068 fg_console = new_console;
1069 set_scrmem(fg_console);
1070 set_origin(fg_console);
1071 set_cursor(new_console);
1072 lock = 0;
1073 }
1074
1075
1076
1077 static void sysbeepstop(void)
1078 {
1079
1080 outb(inb_p(0x61)&0xFC, 0x61);
1081 }
1082
1083 static void sysbeep(void)
1084 {
1085
1086 outb_p(inb_p(0x61)|3, 0x61);
1087
1088 outb_p(0xB6, 0x43);
1089
1090 outb_p(0x37, 0x42);
1091 outb(0x06, 0x42);
1092
1093 timer_table[BEEP_TIMER].expires = jiffies + HZ/8;
1094 timer_table[BEEP_TIMER].fn = sysbeepstop;
1095 timer_active |= 1<<BEEP_TIMER;
1096 }
1097
1098 int do_screendump(int arg)
1099 {
1100 char *sptr, *buf = (char *)arg;
1101 int currcons, l;
1102
1103 verify_area(buf,2+video_num_columns*video_num_lines);
1104 currcons = get_fs_byte(buf+1);
1105 if ((currcons<0) || (currcons>NR_CONSOLES))
1106 return -EIO;
1107 put_fs_byte((char)(video_num_lines),buf++);
1108 put_fs_byte((char)(video_num_columns),buf++);
1109 currcons = (currcons ? currcons-1 : fg_console);
1110 sptr = (char *) origin;
1111 for (l=video_num_lines*video_num_columns; l>0 ; l--, sptr++)
1112 put_fs_byte(*sptr++,buf++);
1113 return(0);
1114 }
1115
1116 void console_print(const char * b)
1117 {
1118 int currcons = fg_console;
1119 char c;
1120
1121 if (currcons<0 || currcons>=NR_CONSOLES)
1122 currcons = 0;
1123 while (c = *(b++)) {
1124 if (c == 10) {
1125 cr(currcons);
1126 lf(currcons);
1127 continue;
1128 }
1129 if (c == 13) {
1130 cr(currcons);
1131 continue;
1132 }
1133 while (x >= video_num_columns) {
1134 x -= video_num_columns;
1135 pos -= video_size_row;
1136 lf(currcons);
1137 }
1138 *(char *) pos = c;
1139 *(char *) (pos+1) = attr;
1140 pos += 2;
1141 x++;
1142 }
1143 set_cursor(currcons);
1144 }