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