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