This source file includes following definitions.
- gotoxy
 
- __set_origin
 
- scrollback
 
- scrollfront
 
- set_origin
 
- hide_cursor
 
- set_cursor
 
- scrup
 
- scrdown
 
- lf
 
- ri
 
- cr
 
- bs
 
- del
 
- csi_J
 
- csi_K
 
- csi_X
 
- update_attr
 
- default_attr
 
- csi_m
 
- respond_string
 
- cursor_report
 
- mouse_report
 
- status_report
 
- respond_ID
 
- invert_screen
 
- set_mode
 
- setterm_command
 
- insert_char
 
- insert_line
 
- delete_char
 
- delete_line
 
- csi_at
 
- csi_L
 
- csi_P
 
- csi_M
 
- save_cur
 
- restore_cur
 
- reset_terminal
 
- con_stop
 
- con_start
 
- con_write
 
- con_write_room
 
- con_chars_in_buffer
 
- poke_blanked_console
 
- memsetw
 
- console_print
 
- con_throttle
 
- con_unthrottle
 
- con_init
 
- kbdsave
 
- get_scrmem
 
- set_scrmem
 
- blank_screen
 
- unblank_screen
 
- update_screen
 
- do_screendump
 
- con_open
 
- highlight
 
- highlight_pointer
 
- inword
 
- sel_loadlut
 
- atedge
 
- limit
 
- mouse_reporting
 
- set_selection
 
- paste_selection
 
- clear_selection
 
- set_get_font
 
- con_set_font
 
- con_get_font
 
- con_set_trans
 
- con_get_trans
 
   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 
  34 
  35 
  36 
  37 
  38 
  39 
  40 
  41 
  42 
  43 #define CAN_LOAD_EGA_FONTS    
  44 
  45 
  46 
  47 
  48 
  49 
  50 
  51 
  52 #include <linux/sched.h>
  53 #include <linux/timer.h>
  54 #include <linux/interrupt.h>
  55 #include <linux/tty.h>
  56 #include <linux/tty_flip.h>
  57 #include <linux/config.h>
  58 #include <linux/kernel.h>
  59 #include <linux/string.h>
  60 #include <linux/errno.h>
  61 #include <linux/kd.h>
  62 #include <linux/major.h>
  63 
  64 #include <asm/io.h>
  65 #include <asm/system.h>
  66 #include <asm/segment.h>
  67 #include <asm/bitops.h>
  68 
  69 #include "kbd_kern.h"
  70 #include "vt_kern.h"
  71 
  72 #ifndef MIN
  73 #define MIN(a,b)        ((a) < (b) ? (a) : (b))
  74 #endif
  75 
  76 struct tty_driver console_driver;
  77 static int console_refcount;
  78 static struct tty_struct *console_table[NR_CONSOLES];
  79 static struct termios *console_termios[NR_CONSOLES];
  80 static struct termios *console_termios_locked[NR_CONSOLES];
  81 
  82 #ifdef CONFIG_SELECTION
  83 #include <linux/ctype.h>
  84 
  85 
  86 int set_selection(const int arg, struct tty_struct *tty);
  87 int paste_selection(struct tty_struct *tty);
  88 static void clear_selection(void);
  89 static void highlight_pointer(const int currcons, const int where);
  90 
  91 
  92 #define SEL_BUFFER_SIZE 4096
  93 static int sel_cons;
  94 static int sel_start = -1;
  95 static int sel_end;
  96 static char sel_buffer[SEL_BUFFER_SIZE] = { '\0' };
  97 #endif 
  98 
  99 #define NPAR 16
 100 
 101 extern void vt_init(void);
 102 extern void register_console(void (*proc)(const char *));
 103 extern void compute_shiftstate(void);
 104 
 105 unsigned long   video_num_columns;              
 106 unsigned long   video_num_lines;                
 107 
 108 static unsigned char    video_type;             
 109 static unsigned long    video_mem_base;         
 110 static unsigned long    video_mem_term;         
 111 static unsigned long    video_size_row;         
 112 static unsigned char    video_page;             
 113 static unsigned short   video_port_reg;         
 114 static unsigned short   video_port_val;         
 115 static int can_do_color = 0;
 116 static int printable = 0;
 117 
 118 static struct {
 119         unsigned short  vc_video_erase_char;    
 120         unsigned char   vc_attr;                
 121         unsigned char   vc_def_color;           
 122         unsigned char   vc_color;               
 123         unsigned char   vc_s_color;             
 124         unsigned char   vc_ulcolor;             
 125         unsigned char   vc_halfcolor;           
 126         unsigned long   vc_origin;              
 127         unsigned long   vc_scr_end;             
 128         unsigned long   vc_pos;
 129         unsigned long   vc_x,vc_y;
 130         unsigned long   vc_top,vc_bottom;
 131         unsigned long   vc_state;
 132         unsigned long   vc_npar,vc_par[NPAR];
 133         unsigned long   vc_video_mem_start;     
 134         unsigned long   vc_video_mem_end;       
 135         unsigned long   vc_saved_x;
 136         unsigned long   vc_saved_y;
 137         
 138         unsigned long   vc_charset      : 1;    
 139         unsigned long   vc_s_charset    : 1;    
 140         unsigned long   vc_disp_ctrl    : 1;    
 141         unsigned long   vc_toggle_meta  : 1;    
 142         unsigned long   vc_decscnm      : 1;    
 143         unsigned long   vc_decom        : 1;    
 144         unsigned long   vc_decawm       : 1;    
 145         unsigned long   vc_deccm        : 1;    
 146         unsigned long   vc_decim        : 1;    
 147         
 148         unsigned long   vc_intensity    : 2;    
 149         unsigned long   vc_underline    : 1;
 150         unsigned long   vc_blink        : 1;
 151         unsigned long   vc_reverse      : 1;
 152         unsigned long   vc_s_intensity  : 2;    
 153         unsigned long   vc_s_underline  : 1;
 154         unsigned long   vc_s_blink      : 1;
 155         unsigned long   vc_s_reverse    : 1;
 156         
 157         unsigned long   vc_ques         : 1;
 158         unsigned long   vc_need_wrap    : 1;
 159         unsigned long   vc_report_mouse : 2;
 160         unsigned long   vc_tab_stop[5];         
 161         unsigned char * vc_translate;
 162         unsigned char * vc_G0_charset;
 163         unsigned char * vc_G1_charset;
 164         unsigned char * vc_saved_G0;
 165         unsigned char * vc_saved_G1;
 166         
 167 } vc_cons [NR_CONSOLES];
 168 
 169 unsigned short *vc_scrbuf[NR_CONSOLES];
 170 static unsigned short * vc_scrmembuf;
 171 static int console_blanked = 0;
 172 
 173 #define origin          (vc_cons[currcons].vc_origin)
 174 #define scr_end         (vc_cons[currcons].vc_scr_end)
 175 #define pos             (vc_cons[currcons].vc_pos)
 176 #define top             (vc_cons[currcons].vc_top)
 177 #define bottom          (vc_cons[currcons].vc_bottom)
 178 #define x               (vc_cons[currcons].vc_x)
 179 #define y               (vc_cons[currcons].vc_y)
 180 #define vc_state                (vc_cons[currcons].vc_state)
 181 #define npar            (vc_cons[currcons].vc_npar)
 182 #define par             (vc_cons[currcons].vc_par)
 183 #define ques            (vc_cons[currcons].vc_ques)
 184 #define attr            (vc_cons[currcons].vc_attr)
 185 #define saved_x         (vc_cons[currcons].vc_saved_x)
 186 #define saved_y         (vc_cons[currcons].vc_saved_y)
 187 #define translate       (vc_cons[currcons].vc_translate)
 188 #define G0_charset      (vc_cons[currcons].vc_G0_charset)
 189 #define G1_charset      (vc_cons[currcons].vc_G1_charset)
 190 #define saved_G0        (vc_cons[currcons].vc_saved_G0)
 191 #define saved_G1        (vc_cons[currcons].vc_saved_G1)
 192 #define video_mem_start (vc_cons[currcons].vc_video_mem_start)
 193 #define video_mem_end   (vc_cons[currcons].vc_video_mem_end)
 194 #define video_erase_char (vc_cons[currcons].vc_video_erase_char)        
 195 #define disp_ctrl       (vc_cons[currcons].vc_disp_ctrl)
 196 #define toggle_meta     (vc_cons[currcons].vc_toggle_meta)
 197 #define decscnm         (vc_cons[currcons].vc_decscnm)
 198 #define decom           (vc_cons[currcons].vc_decom)
 199 #define decawm          (vc_cons[currcons].vc_decawm)
 200 #define deccm           (vc_cons[currcons].vc_deccm)
 201 #define decim           (vc_cons[currcons].vc_decim)
 202 #define need_wrap       (vc_cons[currcons].vc_need_wrap)
 203 #define report_mouse    (vc_cons[currcons].vc_report_mouse)
 204 #define color           (vc_cons[currcons].vc_color)
 205 #define s_color         (vc_cons[currcons].vc_s_color)
 206 #define def_color       (vc_cons[currcons].vc_def_color)
 207 #define foreground      (color & 0x0f)
 208 #define background      (color & 0xf0)
 209 #define charset         (vc_cons[currcons].vc_charset)
 210 #define s_charset       (vc_cons[currcons].vc_s_charset)
 211 #define intensity       (vc_cons[currcons].vc_intensity)
 212 #define underline       (vc_cons[currcons].vc_underline)
 213 #define blink           (vc_cons[currcons].vc_blink)
 214 #define reverse         (vc_cons[currcons].vc_reverse)
 215 #define s_intensity     (vc_cons[currcons].vc_s_intensity)
 216 #define s_underline     (vc_cons[currcons].vc_s_underline)
 217 #define s_blink         (vc_cons[currcons].vc_s_blink)
 218 #define s_reverse       (vc_cons[currcons].vc_s_reverse)
 219 #define ulcolor         (vc_cons[currcons].vc_ulcolor)
 220 #define halfcolor       (vc_cons[currcons].vc_halfcolor)
 221 #define tab_stop        (vc_cons[currcons].vc_tab_stop)
 222 #define vcmode          (vt_cons[currcons].vc_mode)
 223 #define vtmode          (vt_cons[currcons].vt_mode)
 224 #define vtpid           (vt_cons[currcons].vt_pid)
 225 #define vtnewvt         (vt_cons[currcons].vt_newvt)
 226 
 227 #define set_kbd(x) set_vc_kbd_mode(kbd_table+currcons,x)
 228 #define clr_kbd(x) clr_vc_kbd_mode(kbd_table+currcons,x)
 229 #define is_kbd(x) vc_kbd_mode(kbd_table+currcons,x)
 230 
 231 #define decarm          VC_REPEAT
 232 #define decckm          VC_CKMODE
 233 #define kbdapplic       VC_APPLIC
 234 #define kbdraw          VC_RAW
 235 #define lnm             VC_CRLF
 236 
 237 int blankinterval = 10*60*HZ;
 238 static int screen_size = 0;
 239 
 240 
 241 
 242 
 243 #define VT100ID "\033[?1;2c"
 244 #define VT102ID "\033[?6c"
 245 
 246 static unsigned char * translations[] = {
 247 
 248 (unsigned char *)
 249         "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
 250         "\0\0\0\0\0\0\0\0\0\0\376\0\0\0\0\0"
 251         " !\"#$%&'()*+,-./0123456789:;<=>?"
 252         "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
 253         "`abcdefghijklmnopqrstuvwxyz{|}~\0"
 254         "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
 255         "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
 256         "\377\255\233\234\376\235\174\025\376\376\246\256\252\055\376\376"
 257         "\370\361\375\376\376\346\024\371\376\376\247\257\254\253\376\250"
 258         "\376\376\376\376\216\217\222\200\376\220\376\376\376\376\376\376"
 259         "\376\245\376\376\376\376\231\376\350\376\376\376\232\376\376\341"
 260         "\205\240\203\376\204\206\221\207\212\202\210\211\215\241\214\213"
 261         "\376\244\225\242\223\376\224\366\355\227\243\226\201\376\376\230",
 262 
 263 (unsigned char *)
 264         "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
 265         "\0\0\0\0\0\0\0\0\0\0\376\0\0\0\0\0"
 266         " !\"#$%&'()*+,-./0123456789:;<=>?"
 267         "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^ "
 268         "\004\261\007\007\007\007\370\361\007\007\331\277\332\300\305\304"
 269         "\304\304\137\137\303\264\301\302\263\363\362\343\330\234\007\0"
 270         "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
 271         "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
 272         "\377\255\233\234\376\235\174\025\376\376\246\256\252\055\376\376"
 273         "\370\361\375\376\376\346\024\371\376\376\247\257\254\253\376\250"
 274         "\376\376\376\376\216\217\222\200\376\220\376\376\376\376\376\376"
 275         "\376\245\376\376\376\376\231\376\376\376\376\376\232\376\376\341"
 276         "\205\240\203\376\204\206\221\207\212\202\210\211\215\241\214\213"
 277         "\376\244\225\242\223\376\224\366\376\227\243\226\201\376\376\230",
 278 
 279 (unsigned char *)
 280         "\000\001\002\003\004\005\006\007\000\011\000\013\000\000\000\000"
 281         "\020\021\022\023\024\025\026\027\030\031\032\000\034\035\036\037"
 282         "\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057"
 283         "\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077"
 284         "\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117"
 285         "\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137"
 286         "\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157"
 287         "\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177"
 288         "\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217"
 289         "\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237"
 290         "\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257"
 291         "\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277"
 292         "\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317"
 293         "\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337"
 294         "\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357"
 295         "\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377",
 296  
 297 (unsigned char *)
 298         "\000\001\002\003\004\005\006\007\010\011\000\013\000\000\016\017"
 299         "\020\021\022\023\024\025\026\027\030\031\032\000\034\035\036\037"
 300         "\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057"
 301         "\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077"
 302         "\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117"
 303         "\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137"
 304         "\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157"
 305         "\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177"
 306         "\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217"
 307         "\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237"
 308         "\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257"
 309         "\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277"
 310         "\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317"
 311         "\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337"
 312         "\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357"
 313         "\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377"
 314 };
 315 
 316 #define NORM_TRANS (translations[0])
 317 #define GRAF_TRANS (translations[1])
 318 #define NULL_TRANS (translations[2])
 319 #define USER_TRANS (translations[3])
 320 
 321 static unsigned char color_table[] = { 0, 4, 2, 6, 1, 5, 3, 7,
 322                                        8,12,10,14, 9,13,11,15 };
 323 
 324 
 325 
 326 
 327 
 328 
 329 static void gotoxy(int currcons, int new_x, int new_y)
     
 330 {
 331         int max_y;
 332 
 333         if (new_x < 0)
 334                 x = 0;
 335         else
 336                 if (new_x >= video_num_columns)
 337                         x = video_num_columns - 1;
 338                 else
 339                         x = new_x;
 340         if (decom) {
 341                 new_y += top;
 342                 max_y = bottom;
 343         } else
 344                 max_y = video_num_lines;
 345         if (new_y < 0)
 346                 y = 0;
 347         else
 348                 if (new_y >= max_y)
 349                         y = max_y - 1;
 350                 else
 351                         y = new_y;
 352         pos = origin + y*video_size_row + (x<<1);
 353         need_wrap = 0;
 354 }
 355 
 356 
 357 
 358 
 359 static unsigned short __real_origin;
 360 static unsigned short __origin;
 361 
 362 static inline void __set_origin(unsigned short offset)
     
 363 {
 364         unsigned long flags;
 365 #ifdef CONFIG_SELECTION
 366         clear_selection();
 367 #endif 
 368         save_flags(flags); cli();
 369         __origin = offset;
 370         outb_p(12, video_port_reg);
 371         outb_p(offset >> 8, video_port_val);
 372         outb_p(13, video_port_reg);
 373         outb_p(offset, video_port_val);
 374         restore_flags(flags);
 375 }
 376 
 377 void scrollback(int lines)
     
 378 {
 379         if (!lines)
 380                 lines = video_num_lines/2;
 381         lines *= video_num_columns;
 382         lines = __origin - lines;
 383         if (lines < 0)
 384                 lines = 0;
 385         __set_origin(lines);
 386 }
 387 
 388 void scrollfront(int lines)
     
 389 {
 390         if (!lines)
 391                 lines = video_num_lines/2;
 392         lines *= video_num_columns;
 393         lines = __origin + lines;
 394         if (lines > __real_origin)
 395                 lines = __real_origin;
 396         __set_origin(lines);
 397 }
 398 
 399 static void set_origin(int currcons)
     
 400 {
 401         if (video_type != VIDEO_TYPE_EGAC && video_type != VIDEO_TYPE_EGAM)
 402                 return;
 403         if (currcons != fg_console || console_blanked || vcmode == KD_GRAPHICS)
 404                 return;
 405         __real_origin = (origin-video_mem_base) >> 1;
 406         __set_origin(__real_origin);
 407 }
 408 
 409 
 410 
 411 
 412 static inline void hide_cursor(void)
     
 413 {
 414   
 415 
 416 
 417         outb_p(14, video_port_reg);
 418         outb_p(0xff&((video_mem_term-video_mem_base)>>9), video_port_val);
 419         outb_p(15, video_port_reg);
 420         outb_p(0xff&((video_mem_term-video_mem_base)>>1), video_port_val);
 421 }
 422 
 423 static inline void set_cursor(int currcons)
     
 424 {
 425         unsigned long flags;
 426 
 427         if (currcons != fg_console || console_blanked || vcmode == KD_GRAPHICS)
 428                 return;
 429         if (__real_origin != __origin)
 430                 set_origin(__real_origin);
 431         save_flags(flags); cli();
 432         if (deccm) {
 433                 outb_p(14, video_port_reg);
 434                 outb_p(0xff&((pos-video_mem_base)>>9), video_port_val);
 435                 outb_p(15, video_port_reg);
 436                 outb_p(0xff&((pos-video_mem_base)>>1), video_port_val);
 437         } else
 438                 hide_cursor();
 439         restore_flags(flags);
 440 }
 441 
 442 static void scrup(int currcons, unsigned int t, unsigned int b)
     
 443 {
 444         int hardscroll = 1;
 445 
 446         if (b > video_num_lines || t >= b)
 447                 return;
 448         if (video_type != VIDEO_TYPE_EGAC && video_type != VIDEO_TYPE_EGAM)
 449                 hardscroll = 0;
 450         else if (t || b != video_num_lines)
 451                 hardscroll = 0;
 452         if (hardscroll) {
 453                 origin += video_size_row;
 454                 pos += video_size_row;
 455                 scr_end += video_size_row;
 456                 if (scr_end > video_mem_end) {
 457                         __asm__("cld\n\t"
 458                                 "rep\n\t"
 459                                 "movsl\n\t"
 460                                 "movl _video_num_columns,%1\n\t"
 461                                 "rep\n\t"
 462                                 "stosw"
 463                                 : 
 464                                 :"a" (video_erase_char),
 465                                 "c" ((video_num_lines-1)*video_num_columns>>1),
 466                                 "D" (video_mem_start),
 467                                 "S" (origin)
 468                                 :"cx","di","si");
 469                         scr_end -= origin-video_mem_start;
 470                         pos -= origin-video_mem_start;
 471                         origin = video_mem_start;
 472                 } else {
 473                         __asm__("cld\n\t"
 474                                 "rep\n\t"
 475                                 "stosw"
 476                                 : 
 477                                 :"a" (video_erase_char),
 478                                 "c" (video_num_columns),
 479                                 "D" (scr_end-video_size_row)
 480                                 :"cx","di");
 481                 }
 482                 set_origin(currcons);
 483         } else {
 484                 __asm__("cld\n\t"
 485                         "rep\n\t"
 486                         "movsl\n\t"
 487                         "movl _video_num_columns,%%ecx\n\t"
 488                         "rep\n\t"
 489                         "stosw"
 490                         : 
 491                         :"a" (video_erase_char),
 492                         "c" ((b-t-1)*video_num_columns>>1),
 493                         "D" (origin+video_size_row*t),
 494                         "S" (origin+video_size_row*(t+1))
 495                         :"cx","di","si");
 496         }
 497 }
 498 
 499 static void scrdown(int currcons, unsigned int t, unsigned int b)
     
 500 {
 501         if (b > video_num_lines || t >= b)
 502                 return;
 503         __asm__("std\n\t"
 504                 "rep\n\t"
 505                 "movsl\n\t"
 506                 "addl $2,%%edi\n\t"     
 507                 "movl _video_num_columns,%%ecx\n\t"
 508                 "rep\n\t"
 509                 "stosw\n\t"
 510                 "cld"
 511                 : 
 512                 :"a" (video_erase_char),
 513                 "c" ((b-t-1)*video_num_columns>>1),
 514                 "D" (origin+video_size_row*b-4),
 515                 "S" (origin+video_size_row*(b-1)-4)
 516                 :"ax","cx","di","si");
 517 }
 518 
 519 static void lf(int currcons)
     
 520 {
 521         if (y+1<bottom) {
 522                 y++;
 523                 pos += video_size_row;
 524                 return;
 525         } else 
 526                 scrup(currcons,top,bottom);
 527         need_wrap = 0;
 528 }
 529 
 530 static void ri(int currcons)
     
 531 {
 532         if (y>top) {
 533                 y--;
 534                 pos -= video_size_row;
 535                 return;
 536         } else
 537                 scrdown(currcons,top,bottom);
 538         need_wrap = 0;
 539 }
 540 
 541 static inline void cr(int currcons)
     
 542 {
 543         pos -= x<<1;
 544         need_wrap = x = 0;
 545 }
 546 
 547 static inline void bs(int currcons)
     
 548 {
 549         if (x) {
 550                 pos -= 2;
 551                 x--;
 552                 need_wrap = 0;
 553         }
 554 }
 555 
 556 static inline void del(int currcons)
     
 557 {
 558 #if 0
 559         if (x) {
 560                 if (!need_wrap) {    
 561                         pos -= 2;
 562                         x--;
 563                 }
 564                 *(unsigned short *)pos = video_erase_char;
 565                 need_wrap = 0;
 566         }
 567 #endif
 568 }
 569 
 570 static void csi_J(int currcons, int vpar)
     
 571 {
 572         unsigned long count;
 573         unsigned long start;
 574 
 575         switch (vpar) {
 576                 case 0: 
 577                         count = (scr_end-pos)>>1;
 578                         start = pos;
 579                         break;
 580                 case 1: 
 581                         count = ((pos-origin)>>1)+1;
 582                         start = origin;
 583                         break;
 584                 case 2: 
 585                         count = video_num_columns * video_num_lines;
 586                         start = origin;
 587                         break;
 588                 default:
 589                         return;
 590         }
 591         __asm__("cld\n\t"
 592                 "rep\n\t"
 593                 "stosw\n\t"
 594                 : 
 595                 :"c" (count),
 596                 "D" (start),"a" (video_erase_char)
 597                 :"cx","di");
 598         need_wrap = 0;
 599 }
 600 
 601 static void csi_K(int currcons, int vpar)
     
 602 {
 603         long count;
 604         long start;
 605 
 606         switch (vpar) {
 607                 case 0: 
 608                         count = video_num_columns-x;
 609                         start = pos;
 610                         break;
 611                 case 1: 
 612                         start = pos - (x<<1);
 613                         count = x+1;
 614                         break;
 615                 case 2: 
 616                         start = pos - (x<<1);
 617                         count = video_num_columns;
 618                         break;
 619                 default:
 620                         return;
 621         }
 622         __asm__("cld\n\t"
 623                 "rep\n\t"
 624                 "stosw\n\t"
 625                 : 
 626                 :"c" (count),
 627                 "D" (start),"a" (video_erase_char)
 628                 :"cx","di");
 629         need_wrap = 0;
 630 }
 631 
 632 static void csi_X(int currcons, int vpar)
     
 633 {
 634         long count;
 635         long start;
 636 
 637         if (!vpar)
 638                 vpar++;
 639 
 640         start=pos;
 641         count=(vpar > video_num_columns-x) ? (video_num_columns-x) : vpar;
 642 
 643         __asm__("cld\n\t"
 644                 "rep\n\t"
 645                 "stosw\n\t"
 646                 : 
 647                 :"c" (count),
 648                 "D" (start),"a" (video_erase_char)
 649                 :"cx","di");
 650         need_wrap = 0;
 651 }
 652 
 653 
 654 
 655 
 656 static void update_attr(int currcons)
     
 657 {
 658         attr = color;
 659         if (can_do_color) {
 660                 if (underline)
 661                         attr = (attr & 0xf0) | ulcolor;
 662                 else if (intensity == 0)
 663                         attr = (attr & 0xf0) | halfcolor;
 664         }
 665         if (reverse ^ decscnm)
 666                 attr = (attr & 0x88) | (((attr >> 4) | (attr << 4)) & 0x77);
 667         if (blink)
 668                 attr ^= 0x80;
 669         if (intensity == 2)
 670                 attr ^= 0x08;
 671         if (!can_do_color) {
 672                 if (underline)
 673                         attr = (attr & 0xf8) | 0x01;
 674                 else if (intensity == 0)
 675                         attr = (attr & 0xf0) | 0x08;
 676         }
 677         if (decscnm)
 678                 video_erase_char = (((color & 0x88) | (((color >> 4) | (color << 4)) & 0x77)) << 8) | ' ';
 679         else
 680                 video_erase_char = (color << 8) | ' ';
 681 }
 682 
 683 static void default_attr(int currcons)
     
 684 {
 685         intensity = 1;
 686         underline = 0;
 687         reverse = 0;
 688         blink = 0;
 689         color = def_color;
 690 }
 691 
 692 static void csi_m(int currcons)
     
 693 {
 694         int i;
 695 
 696         for (i=0;i<=npar;i++)
 697                 switch (par[i]) {
 698                         case 0: 
 699                                 default_attr(currcons);
 700                                 break;
 701                         case 1:
 702                                 intensity = 2;
 703                                 break;
 704                         case 2:
 705                                 intensity = 0;
 706                                 break;
 707                         case 4:
 708                                 underline = 1;
 709                                 break;
 710                         case 5:
 711                                 blink = 1;
 712                                 break;
 713                         case 7:
 714                                 reverse = 1;
 715                                 break;
 716                         case 10: 
 717 
 718 
 719 
 720 
 721                                 translate = (charset == 0
 722                                                 ? G0_charset
 723                                                 : G1_charset);
 724                                 disp_ctrl = 0;
 725                                 toggle_meta = 0;
 726                                 break;
 727                         case 11: 
 728 
 729 
 730 
 731                                 translate = NULL_TRANS;
 732                                 disp_ctrl = 1;
 733                                 toggle_meta = 0;
 734                                 break;
 735                         case 12: 
 736 
 737 
 738 
 739                                 translate = NULL_TRANS;
 740                                 disp_ctrl = 1;
 741                                 toggle_meta = 1;
 742                                 break;
 743                         case 21:
 744                         case 22:
 745                                 intensity = 1;
 746                                 break;
 747                         case 24:
 748                                 underline = 0;
 749                                 break;
 750                         case 25:
 751                                 blink = 0;
 752                                 break;
 753                         case 27:
 754                                 reverse = 0;
 755                                 break;
 756                         case 38: 
 757 
 758 
 759 
 760 
 761                                 color = (def_color & 0x0f) | background;
 762                                 underline = 1;
 763                                 break;
 764                         case 39: 
 765 
 766 
 767 
 768 
 769                                 color = (def_color & 0x0f) | background;
 770                                 underline = 0;
 771                                 break;
 772                         case 49:
 773                                 color = (def_color & 0xf0) | foreground;
 774                                 break;
 775                         default:
 776                                 if (par[i] >= 30 && par[i] <= 37)
 777                                         color = color_table[par[i]-30]
 778                                                 | background; 
 779                                 else if (par[i] >= 40 && par[i] <= 47)
 780                                         color = (color_table[par[i]-40]<<4)
 781                                                 | foreground;
 782                                 break;
 783                 }
 784         update_attr(currcons);
 785 }
 786 
 787 static void respond_string(char * p, struct tty_struct * tty)
     
 788 {
 789         while (*p) {
 790                 tty_insert_flip_char(tty, *p, 0);
 791                 p++;
 792         }
 793         tty_schedule_flip(tty);
 794 }
 795 
 796 static void cursor_report(int currcons, struct tty_struct * tty)
     
 797 {
 798         char buf[40];
 799 
 800         sprintf(buf, "\033[%ld;%ldR", y + (decom ? top+1 : 1), x+1);
 801         respond_string(buf, tty);
 802 }
 803 
 804 static void mouse_report(int currcons, struct tty_struct * tty,
     
 805                          int butt, int mrx, int mry)
 806 {
 807         char buf[8];
 808 
 809         sprintf(buf, "\033[M%c%c%c", (char)(' ' + butt), (char)('!' + mrx),
 810                 (char)('!' + mry));
 811         respond_string(buf, tty);
 812 }
 813 
 814 static inline void status_report(int currcons, struct tty_struct * tty)
     
 815 {
 816         respond_string("\033[0n", tty); 
 817 }
 818 
 819 static inline void respond_ID(int currcons, struct tty_struct * tty)
     
 820 {
 821         respond_string(VT102ID, tty);
 822 }
 823 
 824 static void invert_screen(int currcons) {
     
 825         unsigned char *p;
 826 
 827         if (can_do_color)
 828                 for (p = (unsigned char *)origin+1; p < (unsigned char *)scr_end; p+=2)
 829                         *p = (*p & 0x88) | (((*p >> 4) | (*p << 4)) & 0x77);
 830         else
 831                 for (p = (unsigned char *)origin+1; p < (unsigned char *)scr_end; p+=2)
 832                         *p ^= *p & 0x07 == 1 ? 0x70 : 0x77;
 833 }
 834 
 835 static void set_mode(int currcons, int on_off)
     
 836 {
 837         int i;
 838 
 839         for (i=0; i<=npar; i++)
 840                 if (ques) switch(par[i]) {      
 841                         case 1:                 
 842                                 if (on_off)
 843                                         set_kbd(decckm);
 844                                 else
 845                                         clr_kbd(decckm);
 846                                 break;
 847                         case 3: 
 848                                 csi_J(currcons,2);
 849                                 gotoxy(currcons,0,0);
 850                                 break;
 851                         case 5:                 
 852                                 if (decscnm != on_off) {
 853                                         decscnm = on_off;
 854                                         invert_screen(currcons);
 855                                         update_attr(currcons);
 856                                 }
 857                                 break;
 858                         case 6:                 
 859                                 decom = on_off;
 860                                 gotoxy(currcons,0,0);
 861                                 break;
 862                         case 7:                 
 863                                 decawm = on_off;
 864                                 break;
 865                         case 8:                 
 866                                 if (on_off)
 867                                         set_kbd(decarm);
 868                                 else
 869                                         clr_kbd(decarm);
 870                                 break;
 871                         case 9:
 872                                 report_mouse = on_off ? 1 : 0;
 873                                 break;
 874                         case 25:                
 875                                 deccm = on_off;
 876                                 set_cursor(currcons);
 877                                 break;
 878                         case 1000:
 879                                 report_mouse = on_off ? 2 : 0;
 880                                 break;
 881                 } else switch(par[i]) {         
 882                         case 4:                 
 883                                 decim = on_off;
 884                                 break;
 885                         case 20:                
 886                                 if (on_off)
 887                                         set_kbd(lnm);
 888                                 else
 889                                         clr_kbd(lnm);
 890                                 break;
 891                 }
 892 }
 893 
 894 static void setterm_command(int currcons)
     
 895 {
 896         switch(par[0]) {
 897                 case 1: 
 898                         if (can_do_color && par[1] < 16) {
 899                                 ulcolor = color_table[par[1]];
 900                                 if (underline)
 901                                         update_attr(currcons);
 902                         }
 903                         break;
 904                 case 2: 
 905                         if (can_do_color && par[1] < 16) {
 906                                 halfcolor = color_table[par[1]];
 907                                 if (intensity == 0)
 908                                         update_attr(currcons);
 909                         }
 910                         break;
 911                 case 8: 
 912                         def_color = attr;
 913                         default_attr(currcons);
 914                         update_attr(currcons);
 915                         break;
 916                 case 9: 
 917                         blankinterval = ((par[1] < 60) ? par[1] : 60) * 60 * HZ;
 918                         break;
 919         }
 920 }
 921 
 922 static void insert_char(int currcons)
     
 923 {
 924         unsigned int i = x;
 925         unsigned short tmp, old = video_erase_char;
 926         unsigned short * p = (unsigned short *) pos;
 927 
 928         while (i++ < video_num_columns) {
 929                 tmp = *p;
 930                 *p = old;
 931                 old = tmp;
 932                 p++;
 933         }
 934         need_wrap = 0;
 935 }
 936 
 937 static void insert_line(int currcons)
     
 938 {
 939         scrdown(currcons,y,bottom);
 940         need_wrap = 0;
 941 }
 942 
 943 static void delete_char(int currcons)
     
 944 {
 945         unsigned int i = x;
 946         unsigned short * p = (unsigned short *) pos;
 947 
 948         while (++i < video_num_columns) {
 949                 *p = *(p+1);
 950                 p++;
 951         }
 952         *p = video_erase_char;
 953         need_wrap = 0;
 954 }
 955 
 956 static void delete_line(int currcons)
     
 957 {
 958         scrup(currcons,y,bottom);
 959         need_wrap = 0;
 960 }
 961 
 962 static void csi_at(int currcons, unsigned int nr)
     
 963 {
 964         if (nr > video_num_columns)
 965                 nr = video_num_columns;
 966         else if (!nr)
 967                 nr = 1;
 968         while (nr--)
 969                 insert_char(currcons);
 970 }
 971 
 972 static void csi_L(int currcons, unsigned int nr)
     
 973 {
 974         if (nr > video_num_lines)
 975                 nr = video_num_lines;
 976         else if (!nr)
 977                 nr = 1;
 978         while (nr--)
 979                 insert_line(currcons);
 980 }
 981 
 982 static void csi_P(int currcons, unsigned int nr)
     
 983 {
 984         if (nr > video_num_columns)
 985                 nr = video_num_columns;
 986         else if (!nr)
 987                 nr = 1;
 988         while (nr--)
 989                 delete_char(currcons);
 990 }
 991 
 992 static void csi_M(int currcons, unsigned int nr)
     
 993 {
 994         if (nr > video_num_lines)
 995                 nr = video_num_lines;
 996         else if (!nr)
 997                 nr=1;
 998         while (nr--)
 999                 delete_line(currcons);
1000 }
1001 
1002 static void save_cur(int currcons)
     
1003 {
1004         saved_x         = x;
1005         saved_y         = y;
1006         s_intensity     = intensity;
1007         s_underline     = underline;
1008         s_blink         = blink;
1009         s_reverse       = reverse;
1010         s_charset       = charset;
1011         s_color         = color;
1012         saved_G0        = G0_charset;
1013         saved_G1        = G1_charset;
1014 }
1015 
1016 static void restore_cur(int currcons)
     
1017 {
1018         gotoxy(currcons,saved_x,saved_y);
1019         intensity       = s_intensity;
1020         underline       = s_underline;
1021         blink           = s_blink;
1022         reverse         = s_reverse;
1023         charset         = s_charset;
1024         color           = s_color;
1025         G0_charset      = saved_G0;
1026         G1_charset      = saved_G1;
1027         translate       = charset ? G1_charset : G0_charset;
1028         update_attr(currcons);
1029         need_wrap = 0;
1030 }
1031 
1032 enum { ESnormal, ESesc, ESsquare, ESgetpars, ESgotpars, ESfunckey, 
1033         EShash, ESsetG0, ESsetG1, ESignore };
1034 
1035 static void reset_terminal(int currcons, int do_clear)
     
1036 {
1037         top             = 0;
1038         bottom          = video_num_lines;
1039         vc_state                = ESnormal;
1040         ques            = 0;
1041         translate       = NORM_TRANS;
1042         G0_charset      = NORM_TRANS;
1043         G1_charset      = GRAF_TRANS;
1044         charset         = 0;
1045         need_wrap       = 0;
1046         report_mouse    = 0;
1047 
1048         disp_ctrl       = 0;
1049         toggle_meta     = 0;
1050 
1051         decscnm         = 0;
1052         decom           = 0;
1053         decawm          = 1;
1054         deccm           = 1;
1055         decim           = 0;
1056 
1057         set_kbd(decarm);
1058         clr_kbd(decckm);
1059         clr_kbd(kbdapplic);
1060         clr_kbd(lnm);
1061         kbd_table[currcons].lockstate = 0;
1062         kbd_table[currcons].ledstate = kbd_table[currcons].default_ledstate;
1063         set_leds();
1064 
1065         default_attr(currcons);
1066         update_attr(currcons);
1067 
1068         tab_stop[0]     = 0x01010100;
1069         tab_stop[1]     =
1070         tab_stop[2]     =
1071         tab_stop[3]     =
1072         tab_stop[4]     = 0x01010101;
1073 
1074         if (do_clear) {
1075                 gotoxy(currcons,0,0);
1076                 csi_J(currcons,2);
1077                 save_cur(currcons);
1078         }
1079 }
1080 
1081 
1082 
1083 
1084 static void con_stop(struct tty_struct *tty)
     
1085 {
1086         set_vc_kbd_led(kbd_table + fg_console, VC_SCROLLOCK);
1087         set_leds();
1088 }
1089 
1090 
1091 
1092 
1093 static void con_start(struct tty_struct *tty)
     
1094 {
1095         clr_vc_kbd_led(kbd_table + fg_console, VC_SCROLLOCK);
1096         set_leds();
1097 }
1098 
1099 static int con_write(struct tty_struct * tty, int from_user,
     
1100                      unsigned char *buf, int count)
1101 {
1102         int c, n = 0;
1103         unsigned int currcons;
1104         struct vt_struct *vt = tty->driver_data;
1105 
1106         currcons = vt->vc_num;
1107         if (currcons >= NR_CONSOLES) {
1108                 printk("con_write: illegal vc index (%d)\n", currcons);
1109                 return 0;
1110         }
1111 #ifdef CONFIG_SELECTION
1112         
1113         if (currcons == sel_cons)
1114                 clear_selection();
1115 #endif 
1116         disable_bh(KEYBOARD_BH);
1117         while (!tty->stopped && count) {
1118                 c = from_user ? get_fs_byte(buf) : *buf;
1119                 buf++; n++; count--;
1120                 if (vc_state == ESnormal
1121                 && (c >= 32 || (disp_ctrl && (c&0x7f) != 27))
1122                 && (toggle_meta ? translate[c|0x80] : translate[c])) {
1123                         if (toggle_meta)
1124                                 c |= 0x80;
1125                         if (need_wrap) {
1126                                 cr(currcons);
1127                                 lf(currcons);
1128                         }
1129                         if (decim)
1130                                 insert_char(currcons);
1131                         c = translate[c];
1132                         *(unsigned short *) pos = (attr << 8) + c;
1133                         if (x == video_num_columns - 1)
1134                                 need_wrap = decawm;
1135                         else {
1136                                 x++;
1137                                 pos+=2;
1138                         }
1139                         continue;
1140                 }
1141 
1142                 
1143 
1144 
1145 
1146                 switch (c) {
1147                         case 7:
1148                                 kd_mksound(0x637, HZ/8);
1149                                 continue;
1150                         case 8:
1151                                 bs(currcons);
1152                                 continue;
1153                         case 9:
1154                                 pos -= (x << 1);
1155                                 while (x < video_num_columns - 1) {
1156                                         x++;
1157                                         if (tab_stop[x >> 5] & (1 << (x & 31)))
1158                                                 break;
1159                                 }
1160                                 pos += (x << 1);
1161                                 continue;
1162                         case 10: case 11: case 12:
1163                                 lf(currcons);
1164                                 if (!is_kbd(lnm))
1165                                         continue;
1166                         case 13:
1167                                 cr(currcons);
1168                                 continue;
1169                         case 14:
1170                                 charset = 1;
1171                                 translate = G1_charset;
1172                                 continue;
1173                         case 15:
1174                                 charset = 0;
1175                                 translate = G0_charset;
1176                                 continue;
1177                         case 24: case 26:
1178                                 vc_state = ESnormal;
1179                                 continue;
1180                         case 27:
1181                                 vc_state = ESesc;
1182                                 continue;
1183                         case 127:
1184                                 del(currcons);
1185                                 continue;
1186                         case 128+27:
1187                                 vc_state = ESsquare;
1188                                 continue;
1189                 }
1190                 switch(vc_state) {
1191                         case ESesc:
1192                                 vc_state = ESnormal;
1193                                 switch (c) {
1194                                   case '[':
1195                                         vc_state = ESsquare;
1196                                         continue;
1197                                   case 'E':
1198                                         cr(currcons);
1199                                         lf(currcons);
1200                                         continue;
1201                                   case 'M':
1202                                         ri(currcons);
1203                                         continue;
1204                                   case 'D':
1205                                         lf(currcons);
1206                                         continue;
1207                                   case 'H':
1208                                         tab_stop[x >> 5] |= (1 << (x & 31));
1209                                         continue;
1210                                   case 'Z':
1211                                         respond_ID(currcons,tty);
1212                                         continue;
1213                                   case '7':
1214                                         save_cur(currcons);
1215                                         continue;
1216                                   case '8':
1217                                         restore_cur(currcons);
1218                                         continue;
1219                                   case '(':
1220                                         vc_state = ESsetG0;
1221                                         continue;
1222                                   case ')':
1223                                         vc_state = ESsetG1;
1224                                         continue;
1225                                   case '#':
1226                                         vc_state = EShash;
1227                                         continue;
1228                                   case 'c':
1229                                         reset_terminal(currcons,1);
1230                                         continue;
1231                                   case '>':  
1232                                         clr_kbd(kbdapplic);
1233                                         continue;
1234                                   case '=':  
1235                                         set_kbd(kbdapplic);
1236                                         continue;
1237                                 }       
1238                                 continue;
1239                         case ESsquare:
1240                                 for(npar = 0 ; npar < NPAR ; npar++)
1241                                         par[npar] = 0;
1242                                 npar = 0;
1243                                 vc_state = ESgetpars;
1244                                 if (c == '[') { 
1245                                         vc_state=ESfunckey;
1246                                         continue;
1247                                 }
1248                                 ques = (c=='?');
1249                                 if (ques)
1250                                         continue;
1251                         case ESgetpars:
1252                                 if (c==';' && npar<NPAR-1) {
1253                                         npar++;
1254                                         continue;
1255                                 } else if (c>='0' && c<='9') {
1256                                         par[npar] *= 10;
1257                                         par[npar] += c-'0';
1258                                         continue;
1259                                 } else vc_state=ESgotpars;
1260                         case ESgotpars:
1261                                 vc_state = ESnormal;
1262                                 switch(c) {
1263                                         case 'h':
1264                                                 set_mode(currcons,1);
1265                                                 continue;
1266                                         case 'l':
1267                                                 set_mode(currcons,0);
1268                                                 continue;
1269                                         case 'n':
1270                                                 if (!ques)
1271                                                         if (par[0] == 5)
1272                                                                 status_report(currcons,tty);
1273                                                         else if (par[0] == 6)
1274                                                                 cursor_report(currcons,tty);
1275                                                 continue;
1276                                 }
1277                                 if (ques) {
1278                                         ques = 0;
1279                                         continue;
1280                                 }
1281                                 switch(c) {
1282                                         case 'G': case '`':
1283                                                 if (par[0]) par[0]--;
1284                                                 gotoxy(currcons,par[0],y);
1285                                                 continue;
1286                                         case 'A':
1287                                                 if (!par[0]) par[0]++;
1288                                                 gotoxy(currcons,x,y-par[0]);
1289                                                 continue;
1290                                         case 'B': case 'e':
1291                                                 if (!par[0]) par[0]++;
1292                                                 gotoxy(currcons,x,y+par[0]);
1293                                                 continue;
1294                                         case 'C': case 'a':
1295                                                 if (!par[0]) par[0]++;
1296                                                 gotoxy(currcons,x+par[0],y);
1297                                                 continue;
1298                                         case 'D':
1299                                                 if (!par[0]) par[0]++;
1300                                                 gotoxy(currcons,x-par[0],y);
1301                                                 continue;
1302                                         case 'E':
1303                                                 if (!par[0]) par[0]++;
1304                                                 gotoxy(currcons,0,y+par[0]);
1305                                                 continue;
1306                                         case 'F':
1307                                                 if (!par[0]) par[0]++;
1308                                                 gotoxy(currcons,0,y-par[0]);
1309                                                 continue;
1310                                         case 'd':
1311                                                 if (par[0]) par[0]--;
1312                                                 gotoxy(currcons,x,par[0]);
1313                                                 continue;
1314                                         case 'H': case 'f':
1315                                                 if (par[0]) par[0]--;
1316                                                 if (par[1]) par[1]--;
1317                                                 gotoxy(currcons,par[1],par[0]);
1318                                                 continue;
1319                                         case 'J':
1320                                                 csi_J(currcons,par[0]);
1321                                                 continue;
1322                                         case 'K':
1323                                                 csi_K(currcons,par[0]);
1324                                                 continue;
1325                                         case 'L':
1326                                                 csi_L(currcons,par[0]);
1327                                                 continue;
1328                                         case 'M':
1329                                                 csi_M(currcons,par[0]);
1330                                                 continue;
1331                                         case 'P':
1332                                                 csi_P(currcons,par[0]);
1333                                                 continue;
1334                                         case 'c':
1335                                                 if (!par[0])
1336                                                         respond_ID(currcons,tty);
1337                                                 continue;
1338                                         case 'g':
1339                                                 if (!par[0])
1340                                                         tab_stop[x >> 5] &= ~(1 << (x & 31));
1341                                                 else if (par[0] == 3) {
1342                                                         tab_stop[0] =
1343                                                         tab_stop[1] =
1344                                                         tab_stop[2] =
1345                                                         tab_stop[3] =
1346                                                         tab_stop[4] = 0;
1347                                                 }
1348                                                 continue;
1349                                         case 'm':
1350                                                 csi_m(currcons);
1351                                                 continue;
1352                                         case 'r':
1353                                                 if (!par[0])
1354                                                         par[0]++;
1355                                                 if (!par[1])
1356                                                         par[1] = video_num_lines;
1357                                                 
1358                                                 if (par[0] < par[1] &&
1359                                                     par[1] <= video_num_lines) {
1360                                                         top=par[0]-1;
1361                                                         bottom=par[1];
1362                                                         gotoxy(currcons,0,0);
1363                                                 }
1364                                                 continue;
1365                                         case 's':
1366                                                 save_cur(currcons);
1367                                                 continue;
1368                                         case 'u':
1369                                                 restore_cur(currcons);
1370                                                 continue;
1371                                         case 'X':
1372                                                 csi_X(currcons, par[0]);
1373                                                 continue;
1374                                         case '@':
1375                                                 csi_at(currcons,par[0]);
1376                                                 continue;
1377                                         case ']': 
1378                                                 setterm_command(currcons);
1379                                                 continue;
1380                                 }
1381                                 continue;
1382                         case ESfunckey:
1383                                 vc_state = ESnormal;
1384                                 continue;
1385                         case EShash:
1386                                 vc_state = ESnormal;
1387                                 if (c == '8') {
1388                                         
1389                                         video_erase_char =
1390                                                 (video_erase_char & 0xff00) | 'E';
1391                                         csi_J(currcons, 2);
1392                                         video_erase_char =
1393                                                 (video_erase_char & 0xff00) | ' ';
1394                                 }
1395                                 continue;
1396                         case ESsetG0:
1397                                 if (c == '0')
1398                                         G0_charset = GRAF_TRANS;
1399                                 else if (c == 'B')
1400                                         G0_charset = NORM_TRANS;
1401                                 else if (c == 'U')
1402                                         G0_charset = NULL_TRANS;
1403                                 else if (c == 'K')
1404                                         G0_charset = USER_TRANS;
1405                                 if (charset == 0)
1406                                         translate = G0_charset;
1407                                 vc_state = ESnormal;
1408                                 continue;
1409                         case ESsetG1:
1410                                 if (c == '0')
1411                                         G1_charset = GRAF_TRANS;
1412                                 else if (c == 'B')
1413                                         G1_charset = NORM_TRANS;
1414                                 else if (c == 'U')
1415                                         G1_charset = NULL_TRANS;
1416                                 else if (c == 'K')
1417                                         G1_charset = USER_TRANS;
1418                                 if (charset == 1)
1419                                         translate = G1_charset;
1420                                 vc_state = ESnormal;
1421                                 continue;
1422                         default:
1423                                 vc_state = ESnormal;
1424                 }
1425         }
1426         if (vcmode != KD_GRAPHICS)
1427                 set_cursor(currcons);
1428         enable_bh(KEYBOARD_BH);
1429         return n;
1430 }
1431 
1432 static int con_write_room(struct tty_struct *tty)
     
1433 {
1434         if (tty->stopped)
1435                 return 0;
1436         return 4096;            
1437 }
1438 
1439 static int con_chars_in_buffer(struct tty_struct *tty)
     
1440 {
1441         return 0;               
1442 }
1443 
1444 void poke_blanked_console(void)
     
1445 {
1446         timer_active &= ~(1<<BLANK_TIMER);
1447         if (vt_cons[fg_console].vc_mode == KD_GRAPHICS)
1448                 return;
1449         if (console_blanked) {
1450                 timer_table[BLANK_TIMER].expires = 0;
1451                 timer_active |= 1<<BLANK_TIMER;
1452         } else if (blankinterval) {
1453                 timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
1454                 timer_active |= 1<<BLANK_TIMER;
1455         }
1456 }
1457 
1458 void * memsetw(void * s,unsigned short c,int count)
     
1459 {
1460 __asm__("cld\n\t"
1461         "rep\n\t"
1462         "stosw"
1463         : 
1464         :"a" (c),"D" (s),"c" (count)
1465         :"cx","di");
1466 return s;
1467 }
1468 
1469 void console_print(const char * b)
     
1470 {
1471         int currcons = fg_console;
1472         unsigned char c;
1473 
1474         if (!printable || currcons<0 || currcons>=NR_CONSOLES)
1475                 return;
1476         while ((c = *(b++)) != 0) {
1477                 if (c == 10 || c == 13 || need_wrap) {
1478                         if (c != 13)
1479                                 lf(currcons);
1480                         cr(currcons);
1481                         if (c == 10 || c == 13)
1482                                 continue;
1483                 }
1484                 *(unsigned short *) pos = (attr << 8) + c;
1485                 if (x == video_num_columns - 1) {
1486                         need_wrap = 1;
1487                         continue;
1488                 }
1489                 x++;
1490                 pos+=2;
1491         }
1492         set_cursor(currcons);
1493         if (vt_cons[fg_console].vc_mode == KD_GRAPHICS)
1494                 return;
1495         timer_active &= ~(1<<BLANK_TIMER);
1496         if (console_blanked) {
1497                 timer_table[BLANK_TIMER].expires = 0;
1498                 timer_active |= 1<<BLANK_TIMER;
1499         } else if (blankinterval) {
1500                 timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
1501                 timer_active |= 1<<BLANK_TIMER;
1502         }
1503 }
1504 
1505 
1506 
1507 
1508 
1509 
1510 static void con_throttle(struct tty_struct *tty)
     
1511 {
1512 }
1513 
1514 static void con_unthrottle(struct tty_struct *tty)
     
1515 {
1516         struct vt_struct *vt = (struct vt_struct *) tty->driver_data;
1517 
1518         wake_up_interruptible(&vt->paste_wait);
1519 }
1520 
1521 
1522 
1523 
1524 
1525 
1526 
1527 
1528 
1529 
1530 
1531 long con_init(long kmem_start)
     
1532 {
1533         char *display_desc = "????";
1534         int currcons = 0;
1535         long base;
1536         int orig_x = ORIG_X;
1537         int orig_y = ORIG_Y;
1538 
1539         memset(&console_driver, 0, sizeof(struct tty_driver));
1540         console_driver.magic = TTY_DRIVER_MAGIC;
1541         console_driver.name = "tty";
1542         console_driver.name_base = 1;
1543         console_driver.major = TTY_MAJOR;
1544         console_driver.minor_start = 1;
1545         console_driver.num = NR_CONSOLES;
1546         console_driver.type = TTY_DRIVER_TYPE_CONSOLE;
1547         console_driver.init_termios = tty_std_termios;
1548         console_driver.flags = TTY_DRIVER_REAL_RAW;
1549         console_driver.refcount = &console_refcount;
1550         console_driver.table = console_table;
1551         console_driver.termios = console_termios;
1552         console_driver.termios_locked = console_termios_locked;
1553 
1554         console_driver.open = con_open;
1555         console_driver.write = con_write;
1556         console_driver.write_room = con_write_room;
1557         console_driver.chars_in_buffer = con_chars_in_buffer;
1558         console_driver.ioctl = vt_ioctl;
1559         console_driver.stop = con_stop;
1560         console_driver.start = con_start;
1561         console_driver.throttle = con_throttle;
1562         console_driver.unthrottle = con_unthrottle;
1563         
1564         if (tty_register_driver(&console_driver))
1565                 panic("Couldn't register console driver\n");
1566         
1567         vc_scrmembuf = (unsigned short *) kmem_start;
1568         video_num_columns = ORIG_VIDEO_COLS;
1569         video_size_row = video_num_columns * 2;
1570         video_num_lines = ORIG_VIDEO_LINES;
1571         video_page = ORIG_VIDEO_PAGE;
1572         screen_size = (video_num_lines * video_size_row);
1573         kmem_start += NR_CONSOLES * screen_size;
1574         timer_table[BLANK_TIMER].fn = blank_screen;
1575         timer_table[BLANK_TIMER].expires = 0;
1576         if (blankinterval) {
1577                 timer_table[BLANK_TIMER].expires = jiffies+blankinterval;
1578                 timer_active |= 1<<BLANK_TIMER;
1579         }
1580         
1581         if (ORIG_VIDEO_MODE == 7)       
1582         {
1583                 video_mem_base = 0xb0000;
1584                 video_port_reg = 0x3b4;
1585                 video_port_val = 0x3b5;
1586                 if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10)
1587                 {
1588                         video_type = VIDEO_TYPE_EGAM;
1589                         video_mem_term = 0xb8000;
1590                         display_desc = "EGA+";
1591                 }
1592                 else
1593                 {
1594                         video_type = VIDEO_TYPE_MDA;
1595                         video_mem_term = 0xb2000;
1596                         display_desc = "*MDA";
1597                 }
1598         }
1599         else                            
1600         {
1601                 can_do_color = 1;
1602                 video_mem_base = 0xb8000;
1603                 video_port_reg  = 0x3d4;
1604                 video_port_val  = 0x3d5;
1605                 if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10)
1606                 {
1607                         video_type = VIDEO_TYPE_EGAC;
1608                         video_mem_term = 0xc0000;
1609                         display_desc = "EGA+";
1610                 }
1611                 else
1612                 {
1613                         video_type = VIDEO_TYPE_CGA;
1614                         video_mem_term = 0xba000;
1615                         display_desc = "*CGA";
1616                 }
1617         }
1618         
1619         
1620 
1621         base = (long)vc_scrmembuf;
1622         for (currcons = 0; currcons<NR_CONSOLES; currcons++) {
1623                 pos = origin = video_mem_start = base;
1624                 scr_end = video_mem_end = (base += screen_size);
1625                 vc_scrbuf[currcons] = (unsigned short *) origin;
1626                 vcmode          = KD_TEXT;
1627                 vtmode.mode     = VT_AUTO;
1628                 vtmode.waitv    = 0;
1629                 vtmode.relsig   = 0;
1630                 vtmode.acqsig   = 0;
1631                 vtmode.frsig    = 0;
1632                 vtpid           = -1;
1633                 vtnewvt         = -1;
1634                 clr_kbd(kbdraw);
1635                 def_color       = 0x07;   
1636                 ulcolor         = 0x0f;   
1637                 halfcolor       = 0x08;   
1638                 vt_cons[currcons].paste_wait = 0;
1639                 reset_terminal(currcons, currcons);
1640         }
1641         currcons = fg_console = 0;
1642 
1643         video_mem_start = video_mem_base;
1644         video_mem_end = video_mem_term;
1645         origin = video_mem_start;
1646         scr_end = video_mem_start + video_num_lines * video_size_row;
1647         gotoxy(currcons,0,0);
1648         save_cur(currcons);
1649         gotoxy(currcons,orig_x,orig_y);
1650         update_screen(fg_console);
1651         printable = 1;
1652         printk("Console: %s %s %ldx%ld, %d virtual consoles\n",
1653                 can_do_color?"colour":"mono",
1654                 display_desc,
1655                 video_num_columns,video_num_lines,
1656                 NR_CONSOLES);
1657         register_console(console_print);
1658         return kmem_start;
1659 }
1660 
1661 
1662 
1663 
1664 
1665 void kbdsave(int new_console)
     
1666 {
1667 }
1668 
1669 static void get_scrmem(int currcons)
     
1670 {
1671         memcpy((void *)vc_scrbuf[currcons],(void *)origin, screen_size);
1672         video_mem_start = (unsigned long)vc_scrbuf[currcons];
1673         origin  = video_mem_start;
1674         scr_end = video_mem_end = video_mem_start+screen_size;
1675         pos = origin + y*video_size_row + (x<<1);
1676 }
1677 
1678 static void set_scrmem(int currcons)
     
1679 {
1680 #ifdef CONFIG_HGA
1681   
1682 
1683 
1684 
1685 
1686 
1687         
1688         if (video_type == VIDEO_TYPE_MDA)
1689           {
1690             if (vcmode == KD_TEXT)
1691               {
1692                 
1693                 int     i;
1694                 static char herc_txt_tbl[12] = {
1695                   0x61,0x50,0x52,0x0f,0x19,6,0x19,0x19,2,0x0d,0x0b,0x0c };
1696                 outb_p(0, 0x3bf);  
1697                 outb_p(0, 0x3b8);  
1698                 for ( i = 0 ; i < 12 ; i++ )
1699                   {
1700                     outb_p(i, 0x3b4);
1701                     outb_p(herc_txt_tbl[i], 0x3b5);
1702                   }
1703               }
1704 #define HGA_BLINKER_ON 0x20
1705 #define HGA_SCREEN_ON  8
1706             
1707             outb_p(HGA_BLINKER_ON | HGA_SCREEN_ON, 0x3b8);
1708           }
1709 #endif CONFIG_HGA
1710 
1711         video_mem_start = video_mem_base;
1712         video_mem_end = video_mem_term;
1713         origin  = video_mem_start;
1714         scr_end = video_mem_start + screen_size;
1715         pos = origin + y*video_size_row + (x<<1);
1716         memcpy((void *)video_mem_base, (void *)vc_scrbuf[fg_console], screen_size);
1717 }
1718 
1719 void blank_screen(void)
     
1720 {
1721         if (console_blanked)
1722                 return;
1723         timer_table[BLANK_TIMER].fn = unblank_screen;
1724         get_scrmem(fg_console);
1725         hide_cursor();
1726         console_blanked = 1;
1727         memsetw((void *)video_mem_base, 0x0020, video_mem_term-video_mem_base );
1728 }
1729 
1730 void unblank_screen(void)
     
1731 {
1732         if (!console_blanked)
1733                 return;
1734         timer_table[BLANK_TIMER].fn = blank_screen;
1735         if (blankinterval) {
1736                 timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
1737                 timer_active |= 1<<BLANK_TIMER;
1738         }
1739         console_blanked = 0;
1740         set_scrmem(fg_console);
1741         set_origin(fg_console);
1742         set_cursor(fg_console);
1743 }
1744 
1745 void update_screen(int new_console)
     
1746 {
1747         static int lock = 0;
1748 
1749         if (new_console == fg_console || lock)
1750                 return;
1751         lock = 1;
1752         kbdsave(new_console);
1753 #ifdef CONFIG_SELECTION
1754         highlight_pointer(fg_console,-1);
1755 #endif 
1756         get_scrmem(fg_console); 
1757         fg_console = new_console;
1758         set_scrmem(fg_console); 
1759         set_origin(fg_console);
1760         set_cursor(new_console);
1761         set_leds();
1762         compute_shiftstate();
1763         lock = 0;
1764 }
1765 
1766 int do_screendump(int arg)
     
1767 {
1768         char *sptr, *buf = (char *)arg;
1769         int currcons, l;
1770 
1771         if (!suser())
1772                 return -EPERM;
1773         l = verify_area(VERIFY_WRITE, buf,2+video_num_columns*video_num_lines);
1774         if (l)
1775                 return l;
1776         currcons = get_fs_byte(buf+1);
1777         if ((currcons<0) || (currcons>NR_CONSOLES))
1778                 return -EIO;
1779         put_fs_byte((char)(video_num_lines),buf++);     
1780         put_fs_byte((char)(video_num_columns),buf++);
1781         currcons = (currcons ? currcons-1 : fg_console);
1782         sptr = (char *) origin;
1783         for (l=video_num_lines*video_num_columns; l>0 ; l--, sptr++)
1784                 put_fs_byte(*sptr++,buf++);     
1785         return(0);
1786 }
1787 
1788 
1789 
1790 
1791 
1792 int con_open(struct tty_struct *tty, struct file * filp)
     
1793 {
1794         int     idx;
1795 
1796         idx = MINOR(tty->device) - tty->driver.minor_start;
1797         
1798         if (idx > NR_CONSOLES)
1799                 return -ENODEV;
1800         vt_cons[idx].vc_num = idx;
1801         tty->driver_data = &vt_cons[idx];
1802         
1803         if (!tty->winsize.ws_row && !tty->winsize.ws_col) {
1804                 tty->winsize.ws_row = video_num_lines;
1805                 tty->winsize.ws_col = video_num_columns;
1806         }
1807         return 0;
1808 }
1809 
1810 #ifdef CONFIG_SELECTION
1811 
1812 #define hwscroll_offset (currcons == fg_console ? ((__real_origin - __origin) << 1) : 0)
1813 
1814 
1815 static void highlight(const int currcons, const int s, const int e)
     
1816 {
1817         unsigned char *p, *p1, *p2;
1818 
1819         p1 = (unsigned char *)origin - hwscroll_offset + s + 1;
1820         p2 = (unsigned char *)origin - hwscroll_offset + e + 1;
1821         if (p1 > p2)
1822         {
1823                 p = p1;
1824                 p1 = p2;
1825                 p2 = p;
1826         }
1827         for (p = p1; p <= p2; p += 2)
1828                 *p = (*p & 0x88) | ((*p << 4) & 0x70) | ((*p >> 4) & 0x07);
1829 }
1830 
1831 
1832 static void highlight_pointer(const int currcons, const int where)
     
1833 {
1834         unsigned char *p;
1835         static char *prev=NULL;
1836 
1837         if (where==-1) 
1838         {
1839                 if (prev)
1840                 {
1841                         *prev ^= 0x77;
1842                         prev=NULL;
1843                 }
1844         }
1845         else
1846         {
1847                 p = (unsigned char *)origin - hwscroll_offset + where + 1;
1848                 *p ^= 0x77;
1849                 if (prev) *prev ^= 0x77; 
1850                 prev=p;
1851         }
1852 }
1853 
1854 
1855 
1856 
1857 
1858 static unsigned long inwordLut[4]={
1859   0x00000000, 
1860   0x03FF0000, 
1861   0x87FFFFFE, 
1862   0x07FFFFFE  
1863 };
1864 static inline int inword(const char c) {
     
1865    return ( inwordLut[(c>>5)&3] >> (c&0x1F) ) & 1;
1866 }
1867 
1868 
1869 int sel_loadlut(const int arg)
     
1870 {
1871     memcpy_fromfs(inwordLut,(unsigned long *)(arg+4),16);
1872     return 0;
1873 }
1874 
1875 
1876 static inline int atedge(const int p)
     
1877 {
1878         return (!(p % video_size_row) || !((p + 2) % video_size_row));
1879 }
1880 
1881 
1882 static inline short limit(const int v, const int l, const int u)
     
1883 {
1884         return (v < l) ? l : ((v > u) ? u : v);
1885 }
1886 
1887 
1888 int mouse_reporting(void)
     
1889 {
1890         int currcons = fg_console;
1891 
1892         return report_mouse;
1893 }
1894 
1895 
1896 int set_selection(const int arg, struct tty_struct *tty)
     
1897 {
1898         unsigned short *args, xs, ys, xe, ye;
1899         int currcons = fg_console;
1900         int sel_mode, new_sel_start, new_sel_end, spc;
1901         char *bp, *obp, *spos;
1902         int i, ps, pe;
1903         char *off = (char *)origin - hwscroll_offset;
1904 
1905         unblank_screen();
1906         args = (unsigned short *)(arg + 1);
1907         xs = get_fs_word(args++) - 1;
1908         ys = get_fs_word(args++) - 1;
1909         xe = get_fs_word(args++) - 1;
1910         ye = get_fs_word(args++) - 1;
1911         sel_mode = get_fs_word(args);
1912 
1913         xs = limit(xs, 0, video_num_columns - 1);
1914         ys = limit(ys, 0, video_num_lines - 1);
1915         xe = limit(xe, 0, video_num_columns - 1);
1916         ye = limit(ye, 0, video_num_lines - 1);
1917         ps = ys * video_size_row + (xs << 1);
1918         pe = ye * video_size_row + (xe << 1);
1919 
1920         if (report_mouse && (sel_mode & 16)) {
1921                 mouse_report(currcons, tty, sel_mode & 15, xs, ys);
1922                 return 0;
1923         }
1924 
1925         if (ps > pe)    
1926         {
1927                 int tmp = ps;
1928                 ps = pe;
1929                 pe = tmp;
1930         }
1931 
1932         switch (sel_mode)
1933         {
1934                 case 0: 
1935                         new_sel_start = ps;
1936                         new_sel_end = pe;
1937                         break;
1938                 case 1: 
1939                         spc = isspace(*(off + ps));
1940                         for (new_sel_start = ps; ; ps -= 2)
1941                         {
1942                                 if ((spc && !isspace(*(off + ps))) ||
1943                                     (!spc && !inword(*(off + ps))))
1944                                         break;
1945                                 new_sel_start = ps;
1946                                 if (!(ps % video_size_row))
1947                                         break;
1948                         }
1949                         spc = isspace(*(off + pe));
1950                         for (new_sel_end = pe; ; pe += 2)
1951                         {
1952                                 if ((spc && !isspace(*(off + pe))) ||
1953                                     (!spc && !inword(*(off + pe))))
1954                                         break;
1955                                 new_sel_end = pe;
1956                                 if (!((pe + 2) % video_size_row))
1957                                         break;
1958                         }
1959                         break;
1960                 case 2: 
1961                         new_sel_start = ps - ps % video_size_row;
1962                         new_sel_end = pe + video_size_row
1963                                     - pe % video_size_row - 2;
1964                         break;
1965                 case 3: 
1966                         if (sel_cons != currcons)
1967                         {
1968                                 highlight_pointer(sel_cons,-1);
1969                                 clear_selection();
1970                                 sel_cons = currcons;
1971                         }
1972                         highlight_pointer(sel_cons,pe);
1973                         return 0; 
1974                 default:
1975                         return -EINVAL;
1976         }
1977         
1978         if (new_sel_end > new_sel_start &&
1979                 !atedge(new_sel_end) && isspace(*(off + new_sel_end)))
1980         {
1981                 for (pe = new_sel_end + 2; ; pe += 2)
1982                 {
1983                         if (!isspace(*(off + pe)) || atedge(pe))
1984                                 break;
1985                 }
1986                 if (isspace(*(off + pe)))
1987                         new_sel_end = pe;
1988         }
1989         if (sel_cons != currcons)
1990         {
1991                 clear_selection();
1992                 sel_cons = currcons;
1993         }
1994         if (sel_start == -1)    
1995                 highlight(sel_cons, new_sel_start, new_sel_end);
1996         else if (new_sel_start == sel_start)
1997         {
1998                 if (new_sel_end == sel_end)     
1999                         return 0;
2000                 else if (new_sel_end > sel_end) 
2001                         highlight(sel_cons, sel_end + 2, new_sel_end);
2002                 else                            
2003                         highlight(sel_cons, new_sel_end + 2, sel_end);
2004         }
2005         else if (new_sel_end == sel_end)
2006         {
2007                 if (new_sel_start < sel_start)  
2008                         highlight(sel_cons, new_sel_start, sel_start - 2);
2009                 else                            
2010                         highlight(sel_cons, sel_start, new_sel_start - 2);
2011         }
2012         else    
2013         {
2014                 clear_selection();
2015                 highlight(sel_cons, new_sel_start, new_sel_end);
2016         }
2017         sel_start = new_sel_start;
2018         sel_end = new_sel_end;
2019         obp = bp = sel_buffer;
2020         for (i = sel_start; i <= sel_end; i += 2)
2021         {
2022                 spos = (char *)off + i;
2023                 *bp++ = *spos;
2024                 if (!isspace(*spos))
2025                         obp = bp;
2026                 if (! ((i + 2) % video_size_row))
2027                 {
2028                         
2029 
2030                         if (obp != bp)
2031                         {
2032                                 bp = obp;
2033                                 *bp++ = '\r';
2034                         }
2035                         obp = bp;
2036                 }
2037                 
2038 
2039                 if (bp - sel_buffer > SEL_BUFFER_SIZE - 3)
2040                         break;
2041         }
2042         *bp = '\0';
2043         return 0;
2044 }
2045 
2046 
2047 
2048 int paste_selection(struct tty_struct *tty)
     
2049 {
2050         struct wait_queue wait = { current, NULL };
2051         char    *bp = sel_buffer;
2052         int     c, l;
2053         struct vt_struct *vt = (struct vt_struct *) tty->driver_data;
2054         
2055         if (!sel_buffer[0])
2056                 return 0;
2057         unblank_screen();
2058         c = strlen(sel_buffer);
2059         current->state = TASK_INTERRUPTIBLE;
2060         add_wait_queue(&vt->paste_wait, &wait);
2061         while (c) {
2062                 if (test_bit(TTY_THROTTLED, &tty->flags)) {
2063                         schedule();
2064                         continue;
2065                 }
2066                 l = MIN(c, tty->ldisc.receive_room(tty));
2067                 tty->ldisc.receive_buf(tty, bp, 0, l);
2068                 c -= l;
2069                 bp += l;
2070         }
2071         current->state = TASK_RUNNING;
2072         return 0;
2073 }
2074 
2075 
2076 
2077 static void clear_selection()
     
2078 {
2079         highlight_pointer(sel_cons, -1); 
2080         if (sel_start != -1)
2081         {
2082                 highlight(sel_cons, sel_start, sel_end);
2083                 sel_start = -1;
2084         }
2085 }
2086 #endif 
2087 
2088 
2089 
2090 
2091 
2092 
2093 
2094 
2095 
2096 
2097 
2098 
2099 
2100 #define colourmap ((char *)0xa0000)
2101 #define blackwmap ((char *)0xb0000)
2102 #define cmapsz 8192
2103 #define seq_port_reg (0x3c4)
2104 #define seq_port_val (0x3c5)
2105 #define gr_port_reg (0x3ce)
2106 #define gr_port_val (0x3cf)
2107 
2108 static int set_get_font(char * arg, int set)
     
2109 {
2110 #ifdef CAN_LOAD_EGA_FONTS
2111         int i;
2112         char *charmap;
2113         int beg;
2114 
2115         
2116 
2117         if (video_type == VIDEO_TYPE_EGAC) {
2118                 charmap = colourmap;
2119                 beg = 0x0e;
2120         } else if (video_type == VIDEO_TYPE_EGAM) {
2121                 charmap = blackwmap;
2122                 beg = 0x0a;
2123         } else
2124                 return -EINVAL;
2125 
2126         i = verify_area(set ? VERIFY_READ : VERIFY_WRITE, (void *)arg, cmapsz);
2127         if (i)
2128                 return i;
2129 
2130         cli();
2131         outb_p( 0x00, seq_port_reg );   
2132         outb_p( 0x01, seq_port_val );   
2133         outb_p( 0x02, seq_port_reg );
2134         outb_p( 0x04, seq_port_val );   
2135         outb_p( 0x04, seq_port_reg );
2136         outb_p( 0x07, seq_port_val );   
2137         outb_p( 0x00, seq_port_reg );
2138         outb_p( 0x03, seq_port_val );   
2139 
2140         outb_p( 0x04, gr_port_reg );    
2141         outb_p( 0x02, gr_port_val );    
2142         outb_p( 0x05, gr_port_reg );
2143         outb_p( 0x00, gr_port_val );    
2144         outb_p( 0x06, gr_port_reg );
2145         outb_p( 0x00, gr_port_val );    
2146         sti();
2147 
2148         if (set)
2149                 for (i=0; i<cmapsz ; i++)
2150                         *(charmap+i) = get_fs_byte(arg+i);
2151         else
2152                 for (i=0; i<cmapsz ; i++)
2153                         put_fs_byte(*(charmap+i), arg+i);
2154 
2155         cli();
2156         outb_p( 0x00, seq_port_reg );   
2157         outb_p( 0x01, seq_port_val );   
2158         outb_p( 0x02, seq_port_reg );
2159         outb_p( 0x03, seq_port_val );   
2160         outb_p( 0x04, seq_port_reg );
2161         outb_p( 0x03, seq_port_val );   
2162         outb_p( 0x00, seq_port_reg );
2163         outb_p( 0x03, seq_port_val );   
2164 
2165         outb_p( 0x04, gr_port_reg );    
2166         outb_p( 0x00, gr_port_val );    
2167         outb_p( 0x05, gr_port_reg );
2168         outb_p( 0x10, gr_port_val );    
2169         outb_p( 0x06, gr_port_reg );
2170         outb_p( beg, gr_port_val );     
2171         sti();
2172 
2173         return 0;
2174 #else
2175         return -EINVAL;
2176 #endif
2177 }
2178 
2179 
2180 
2181 
2182 
2183 
2184 
2185 int con_set_font (char *arg)
     
2186 {
2187         return set_get_font (arg,1);
2188 }
2189 
2190 int con_get_font (char *arg)
     
2191 {
2192         return set_get_font (arg,0);
2193 }
2194 
2195 
2196 
2197 
2198 
2199 
2200 int con_set_trans(char * arg)
     
2201 {
2202         int i;
2203 
2204         i = verify_area(VERIFY_READ, (void *)arg, E_TABSZ);
2205         if (i)
2206                 return i;
2207 
2208         for (i=0; i<E_TABSZ ; i++) USER_TRANS[i] = get_fs_byte(arg+i);
2209         USER_TRANS[012]=0;
2210         USER_TRANS[014]=0;
2211         USER_TRANS[015]=0;
2212         USER_TRANS[033]=0;
2213         return 0;
2214 }
2215 
2216 int con_get_trans(char * arg)
     
2217 {
2218         int i;
2219 
2220         i = verify_area(VERIFY_WRITE, (void *)arg, E_TABSZ);
2221         if (i)
2222                 return i;
2223 
2224         for (i=0; i<E_TABSZ ; i++) put_fs_byte(USER_TRANS[i],arg+i);
2225         return 0;
2226 }