root/kernel/chr_drv/console.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. gotoxy
  2. set_origin
  3. scrup
  4. scrdown
  5. lf
  6. ri
  7. cr
  8. del
  9. csi_J
  10. csi_K
  11. csi_m
  12. set_cursor
  13. respond
  14. insert_char
  15. insert_line
  16. delete_char
  17. delete_line
  18. csi_at
  19. csi_L
  20. csi_P
  21. csi_M
  22. save_cur
  23. restore_cur
  24. con_write
  25. con_init
  26. sysbeepstop
  27. sysbeep

   1 /*
   2  *  linux/kernel/console.c
   3  *
   4  *  (C) 1991  Linus Torvalds
   5  */
   6 
   7 /*
   8  *      console.c
   9  *
  10  * This module implements the console io functions
  11  *      'void con_init(void)'
  12  *      'void con_write(struct tty_queue * queue)'
  13  * Hopefully this will be a rather complete VT102 implementation.
  14  *
  15  * Beeping thanks to John T Kohl.
  16  */
  17 
  18 /*
  19  *  NOTE!!! We sometimes disable and enable interrupts for a short while
  20  * (to put a word in video IO), but this will work even for keyboard
  21  * interrupts. We know interrupts aren't enabled when getting a keyboard
  22  * interrupt, as we use trap-gates. Hopefully all is well.
  23  */
  24 
  25 /*
  26  * Code to check for different video-cards mostly by Galen Hunt,
  27  * <g-hunt@ee.utah.edu>
  28  */
  29 
  30 #include <linux/sched.h>
  31 #include <linux/tty.h>
  32 #include <asm/io.h>
  33 #include <asm/system.h>
  34 
  35 /*
  36  * These are set up by the setup-routine at boot-time:
  37  */
  38 
  39 #define ORIG_X                  (*(unsigned char *)0x90000)
  40 #define ORIG_Y                  (*(unsigned char *)0x90001)
  41 #define ORIG_VIDEO_PAGE         (*(unsigned short *)0x90004)
  42 #define ORIG_VIDEO_MODE         ((*(unsigned short *)0x90006) & 0xff)
  43 #define ORIG_VIDEO_COLS         (((*(unsigned short *)0x90006) & 0xff00) >> 8)
  44 #define ORIG_VIDEO_LINES        (25)
  45 #define ORIG_VIDEO_EGA_AX       (*(unsigned short *)0x90008)
  46 #define ORIG_VIDEO_EGA_BX       (*(unsigned short *)0x9000a)
  47 #define ORIG_VIDEO_EGA_CX       (*(unsigned short *)0x9000c)
  48 
  49 #define VIDEO_TYPE_MDA          0x10    /* Monochrome Text Display      */
  50 #define VIDEO_TYPE_CGA          0x11    /* CGA Display                  */
  51 #define VIDEO_TYPE_EGAM         0x20    /* EGA/VGA in Monochrome Mode   */
  52 #define VIDEO_TYPE_EGAC         0x21    /* EGA/VGA in Color Mode        */
  53 
  54 #define NPAR 16
  55 
  56 extern void keyboard_interrupt(void);
  57 
  58 static unsigned char    video_type;             /* Type of display being used   */
  59 static unsigned long    video_num_columns;      /* Number of text columns       */
  60 static unsigned long    video_size_row;         /* Bytes per row                */
  61 static unsigned long    video_num_lines;        /* Number of test lines         */
  62 static unsigned char    video_page;             /* Initial video page           */
  63 static unsigned long    video_mem_start;        /* Start of video RAM           */
  64 static unsigned long    video_mem_end;          /* End of video RAM (sort of)   */
  65 static unsigned short   video_port_reg;         /* Video register select port   */
  66 static unsigned short   video_port_val;         /* Video register value port    */
  67 static unsigned short   video_erase_char;       /* Char+Attrib to erase with    */
  68 
  69 static unsigned long    origin;         /* Used for EGA/VGA fast scroll */
  70 static unsigned long    scr_end;        /* Used for EGA/VGA fast scroll */
  71 static unsigned long    pos;
  72 static unsigned long    x,y;
  73 static unsigned long    top,bottom;
  74 static unsigned long    state=0;
  75 static unsigned long    npar,par[NPAR];
  76 static unsigned long    ques=0;
  77 static unsigned char    attr=0x07;
  78 
  79 static void sysbeep(void);
  80 
  81 /*
  82  * this is what the terminal answers to a ESC-Z or csi0c
  83  * query (= vt100 response).
  84  */
  85 #define RESPONSE "\033[?1;2c"
  86 
  87 /* NOTE! gotoxy thinks x==video_num_columns is ok */
  88 static inline void gotoxy(unsigned int new_x,unsigned int new_y)
     /* [previous][next][first][last][top][bottom][index][help] */
  89 {
  90         if (new_x > video_num_columns || new_y >= video_num_lines)
  91                 return;
  92         x=new_x;
  93         y=new_y;
  94         pos=origin + y*video_size_row + (x<<1);
  95 }
  96 
  97 static inline void set_origin(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  98 {
  99         cli();
 100         outb_p(12, video_port_reg);
 101         outb_p(0xff&((origin-video_mem_start)>>9), video_port_val);
 102         outb_p(13, video_port_reg);
 103         outb_p(0xff&((origin-video_mem_start)>>1), video_port_val);
 104         sti();
 105 }
 106 
 107 static void scrup(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 108 {
 109         if (video_type == VIDEO_TYPE_EGAC || video_type == VIDEO_TYPE_EGAM)
 110         {
 111                 if (!top && bottom == video_num_lines) {
 112                         origin += video_size_row;
 113                         pos += video_size_row;
 114                         scr_end += video_size_row;
 115                         if (scr_end > video_mem_end) {
 116                                 __asm__("cld\n\t"
 117                                         "rep\n\t"
 118                                         "movsl\n\t"
 119                                         "movl _video_num_columns,%1\n\t"
 120                                         "rep\n\t"
 121                                         "stosw"
 122                                         ::"a" (video_erase_char),
 123                                         "c" ((video_num_lines-1)*video_num_columns>>1),
 124                                         "D" (video_mem_start),
 125                                         "S" (origin)
 126                                         :"cx","di","si");
 127                                 scr_end -= origin-video_mem_start;
 128                                 pos -= origin-video_mem_start;
 129                                 origin = video_mem_start;
 130                         } else {
 131                                 __asm__("cld\n\t"
 132                                         "rep\n\t"
 133                                         "stosw"
 134                                         ::"a" (video_erase_char),
 135                                         "c" (video_num_columns),
 136                                         "D" (scr_end-video_size_row)
 137                                         :"cx","di");
 138                         }
 139                         set_origin();
 140                 } else {
 141                         __asm__("cld\n\t"
 142                                 "rep\n\t"
 143                                 "movsl\n\t"
 144                                 "movl _video_num_columns,%%ecx\n\t"
 145                                 "rep\n\t"
 146                                 "stosw"
 147                                 ::"a" (video_erase_char),
 148                                 "c" ((bottom-top-1)*video_num_columns>>1),
 149                                 "D" (origin+video_size_row*top),
 150                                 "S" (origin+video_size_row*(top+1))
 151                                 :"cx","di","si");
 152                 }
 153         }
 154         else            /* Not EGA/VGA */
 155         {
 156                 __asm__("cld\n\t"
 157                         "rep\n\t"
 158                         "movsl\n\t"
 159                         "movl _video_num_columns,%%ecx\n\t"
 160                         "rep\n\t"
 161                         "stosw"
 162                         ::"a" (video_erase_char),
 163                         "c" ((bottom-top-1)*video_num_columns>>1),
 164                         "D" (origin+video_size_row*top),
 165                         "S" (origin+video_size_row*(top+1))
 166                         :"cx","di","si");
 167         }
 168 }
 169 
 170 static void scrdown(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 171 {
 172         if (video_type == VIDEO_TYPE_EGAC || video_type == VIDEO_TYPE_EGAM)
 173         {
 174                 __asm__("std\n\t"
 175                         "rep\n\t"
 176                         "movsl\n\t"
 177                         "addl $2,%%edi\n\t"     /* %edi has been decremented by 4 */
 178                         "movl _video_num_columns,%%ecx\n\t"
 179                         "rep\n\t"
 180                         "stosw"
 181                         ::"a" (video_erase_char),
 182                         "c" ((bottom-top-1)*video_num_columns>>1),
 183                         "D" (origin+video_size_row*bottom-4),
 184                         "S" (origin+video_size_row*(bottom-1)-4)
 185                         :"ax","cx","di","si");
 186         }
 187         else            /* Not EGA/VGA */
 188         {
 189                 __asm__("std\n\t"
 190                         "rep\n\t"
 191                         "movsl\n\t"
 192                         "addl $2,%%edi\n\t"     /* %edi has been decremented by 4 */
 193                         "movl _video_num_columns,%%ecx\n\t"
 194                         "rep\n\t"
 195                         "stosw"
 196                         ::"a" (video_erase_char),
 197                         "c" ((bottom-top-1)*video_num_columns>>1),
 198                         "D" (origin+video_size_row*bottom-4),
 199                         "S" (origin+video_size_row*(bottom-1)-4)
 200                         :"ax","cx","di","si");
 201         }
 202 }
 203 
 204 static void lf(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 205 {
 206         if (y+1<bottom) {
 207                 y++;
 208                 pos += video_size_row;
 209                 return;
 210         }
 211         scrup();
 212 }
 213 
 214 static void ri(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 215 {
 216         if (y>top) {
 217                 y--;
 218                 pos -= video_size_row;
 219                 return;
 220         }
 221         scrdown();
 222 }
 223 
 224 static void cr(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 225 {
 226         pos -= x<<1;
 227         x=0;
 228 }
 229 
 230 static void del(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 231 {
 232         if (x) {
 233                 pos -= 2;
 234                 x--;
 235                 *(unsigned short *)pos = video_erase_char;
 236         }
 237 }
 238 
 239 static void csi_J(int par)
     /* [previous][next][first][last][top][bottom][index][help] */
 240 {
 241         long count __asm__("cx");
 242         long start __asm__("di");
 243 
 244         switch (par) {
 245                 case 0: /* erase from cursor to end of display */
 246                         count = (scr_end-pos)>>1;
 247                         start = pos;
 248                         break;
 249                 case 1: /* erase from start to cursor */
 250                         count = (pos-origin)>>1;
 251                         start = origin;
 252                         break;
 253                 case 2: /* erase whole display */
 254                         count = video_num_columns * video_num_lines;
 255                         start = origin;
 256                         break;
 257                 default:
 258                         return;
 259         }
 260         __asm__("cld\n\t"
 261                 "rep\n\t"
 262                 "stosw\n\t"
 263                 ::"c" (count),
 264                 "D" (start),"a" (video_erase_char)
 265                 :"cx","di");
 266 }
 267 
 268 static void csi_K(int par)
     /* [previous][next][first][last][top][bottom][index][help] */
 269 {
 270         long count __asm__("cx");
 271         long start __asm__("di");
 272 
 273         switch (par) {
 274                 case 0: /* erase from cursor to end of line */
 275                         if (x>=video_num_columns)
 276                                 return;
 277                         count = video_num_columns-x;
 278                         start = pos;
 279                         break;
 280                 case 1: /* erase from start of line to cursor */
 281                         start = pos - (x<<1);
 282                         count = (x<video_num_columns)?x:video_num_columns;
 283                         break;
 284                 case 2: /* erase whole line */
 285                         start = pos - (x<<1);
 286                         count = video_num_columns;
 287                         break;
 288                 default:
 289                         return;
 290         }
 291         __asm__("cld\n\t"
 292                 "rep\n\t"
 293                 "stosw\n\t"
 294                 ::"c" (count),
 295                 "D" (start),"a" (video_erase_char)
 296                 :"cx","di");
 297 }
 298 
 299 void csi_m(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 300 {
 301         int i;
 302 
 303         for (i=0;i<=npar;i++)
 304                 switch (par[i]) {
 305                         case 0:attr=0x07;break;
 306                         case 1:attr=0x0f;break;
 307                         case 4:attr=0x0f;break;
 308                         case 7:attr=0x70;break;
 309                         case 27:attr=0x07;break;
 310                 }
 311 }
 312 
 313 static inline void set_cursor(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 314 {
 315         cli();
 316         outb_p(14, video_port_reg);
 317         outb_p(0xff&((pos-video_mem_start)>>9), video_port_val);
 318         outb_p(15, video_port_reg);
 319         outb_p(0xff&((pos-video_mem_start)>>1), video_port_val);
 320         sti();
 321 }
 322 
 323 static void respond(struct tty_struct * tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 324 {
 325         char * p = RESPONSE;
 326 
 327         cli();
 328         while (*p) {
 329                 PUTCH(*p,tty->read_q);
 330                 p++;
 331         }
 332         sti();
 333         copy_to_cooked(tty);
 334 }
 335 
 336 static void insert_char(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 337 {
 338         int i=x;
 339         unsigned short tmp, old = video_erase_char;
 340         unsigned short * p = (unsigned short *) pos;
 341 
 342         while (i++<video_num_columns) {
 343                 tmp=*p;
 344                 *p=old;
 345                 old=tmp;
 346                 p++;
 347         }
 348 }
 349 
 350 static void insert_line(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 351 {
 352         int oldtop,oldbottom;
 353 
 354         oldtop=top;
 355         oldbottom=bottom;
 356         top=y;
 357         bottom = video_num_lines;
 358         scrdown();
 359         top=oldtop;
 360         bottom=oldbottom;
 361 }
 362 
 363 static void delete_char(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 364 {
 365         int i;
 366         unsigned short * p = (unsigned short *) pos;
 367 
 368         if (x>=video_num_columns)
 369                 return;
 370         i = x;
 371         while (++i < video_num_columns) {
 372                 *p = *(p+1);
 373                 p++;
 374         }
 375         *p = video_erase_char;
 376 }
 377 
 378 static void delete_line(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 379 {
 380         int oldtop,oldbottom;
 381 
 382         oldtop=top;
 383         oldbottom=bottom;
 384         top=y;
 385         bottom = video_num_lines;
 386         scrup();
 387         top=oldtop;
 388         bottom=oldbottom;
 389 }
 390 
 391 static void csi_at(unsigned int nr)
     /* [previous][next][first][last][top][bottom][index][help] */
 392 {
 393         if (nr > video_num_columns)
 394                 nr = video_num_columns;
 395         else if (!nr)
 396                 nr = 1;
 397         while (nr--)
 398                 insert_char();
 399 }
 400 
 401 static void csi_L(unsigned int nr)
     /* [previous][next][first][last][top][bottom][index][help] */
 402 {
 403         if (nr > video_num_lines)
 404                 nr = video_num_lines;
 405         else if (!nr)
 406                 nr = 1;
 407         while (nr--)
 408                 insert_line();
 409 }
 410 
 411 static void csi_P(unsigned int nr)
     /* [previous][next][first][last][top][bottom][index][help] */
 412 {
 413         if (nr > video_num_columns)
 414                 nr = video_num_columns;
 415         else if (!nr)
 416                 nr = 1;
 417         while (nr--)
 418                 delete_char();
 419 }
 420 
 421 static void csi_M(unsigned int nr)
     /* [previous][next][first][last][top][bottom][index][help] */
 422 {
 423         if (nr > video_num_lines)
 424                 nr = video_num_lines;
 425         else if (!nr)
 426                 nr=1;
 427         while (nr--)
 428                 delete_line();
 429 }
 430 
 431 static int saved_x=0;
 432 static int saved_y=0;
 433 
 434 static void save_cur(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 435 {
 436         saved_x=x;
 437         saved_y=y;
 438 }
 439 
 440 static void restore_cur(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 441 {
 442         gotoxy(saved_x, saved_y);
 443 }
 444 
 445 void con_write(struct tty_struct * tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 446 {
 447         int nr;
 448         char c;
 449 
 450         nr = CHARS(tty->write_q);
 451         while (nr--) {
 452                 GETCH(tty->write_q,c);
 453                 switch(state) {
 454                         case 0:
 455                                 if (c>31 && c<127) {
 456                                         if (x>=video_num_columns) {
 457                                                 x -= video_num_columns;
 458                                                 pos -= video_size_row;
 459                                                 lf();
 460                                         }
 461                                         __asm__("movb _attr,%%ah\n\t"
 462                                                 "movw %%ax,%1\n\t"
 463                                                 ::"a" (c),"m" (*(short *)pos)
 464                                                 :"ax");
 465                                         pos += 2;
 466                                         x++;
 467                                 } else if (c==27)
 468                                         state=1;
 469                                 else if (c==10 || c==11 || c==12)
 470                                         lf();
 471                                 else if (c==13)
 472                                         cr();
 473                                 else if (c==ERASE_CHAR(tty))
 474                                         del();
 475                                 else if (c==8) {
 476                                         if (x) {
 477                                                 x--;
 478                                                 pos -= 2;
 479                                         }
 480                                 } else if (c==9) {
 481                                         c=8-(x&7);
 482                                         x += c;
 483                                         pos += c<<1;
 484                                         if (x>video_num_columns) {
 485                                                 x -= video_num_columns;
 486                                                 pos -= video_size_row;
 487                                                 lf();
 488                                         }
 489                                         c=9;
 490                                 } else if (c==7)
 491                                         sysbeep();
 492                                 break;
 493                         case 1:
 494                                 state=0;
 495                                 if (c=='[')
 496                                         state=2;
 497                                 else if (c=='E')
 498                                         gotoxy(0,y+1);
 499                                 else if (c=='M')
 500                                         ri();
 501                                 else if (c=='D')
 502                                         lf();
 503                                 else if (c=='Z')
 504                                         respond(tty);
 505                                 else if (x=='7')
 506                                         save_cur();
 507                                 else if (x=='8')
 508                                         restore_cur();
 509                                 break;
 510                         case 2:
 511                                 for(npar=0;npar<NPAR;npar++)
 512                                         par[npar]=0;
 513                                 npar=0;
 514                                 state=3;
 515                                 if (ques=(c=='?'))
 516                                         break;
 517                         case 3:
 518                                 if (c==';' && npar<NPAR-1) {
 519                                         npar++;
 520                                         break;
 521                                 } else if (c>='0' && c<='9') {
 522                                         par[npar]=10*par[npar]+c-'0';
 523                                         break;
 524                                 } else state=4;
 525                         case 4:
 526                                 state=0;
 527                                 switch(c) {
 528                                         case 'G': case '`':
 529                                                 if (par[0]) par[0]--;
 530                                                 gotoxy(par[0],y);
 531                                                 break;
 532                                         case 'A':
 533                                                 if (!par[0]) par[0]++;
 534                                                 gotoxy(x,y-par[0]);
 535                                                 break;
 536                                         case 'B': case 'e':
 537                                                 if (!par[0]) par[0]++;
 538                                                 gotoxy(x,y+par[0]);
 539                                                 break;
 540                                         case 'C': case 'a':
 541                                                 if (!par[0]) par[0]++;
 542                                                 gotoxy(x+par[0],y);
 543                                                 break;
 544                                         case 'D':
 545                                                 if (!par[0]) par[0]++;
 546                                                 gotoxy(x-par[0],y);
 547                                                 break;
 548                                         case 'E':
 549                                                 if (!par[0]) par[0]++;
 550                                                 gotoxy(0,y+par[0]);
 551                                                 break;
 552                                         case 'F':
 553                                                 if (!par[0]) par[0]++;
 554                                                 gotoxy(0,y-par[0]);
 555                                                 break;
 556                                         case 'd':
 557                                                 if (par[0]) par[0]--;
 558                                                 gotoxy(x,par[0]);
 559                                                 break;
 560                                         case 'H': case 'f':
 561                                                 if (par[0]) par[0]--;
 562                                                 if (par[1]) par[1]--;
 563                                                 gotoxy(par[1],par[0]);
 564                                                 break;
 565                                         case 'J':
 566                                                 csi_J(par[0]);
 567                                                 break;
 568                                         case 'K':
 569                                                 csi_K(par[0]);
 570                                                 break;
 571                                         case 'L':
 572                                                 csi_L(par[0]);
 573                                                 break;
 574                                         case 'M':
 575                                                 csi_M(par[0]);
 576                                                 break;
 577                                         case 'P':
 578                                                 csi_P(par[0]);
 579                                                 break;
 580                                         case '@':
 581                                                 csi_at(par[0]);
 582                                                 break;
 583                                         case 'm':
 584                                                 csi_m();
 585                                                 break;
 586                                         case 'r':
 587                                                 if (par[0]) par[0]--;
 588                                                 if (!par[1]) par[1] = video_num_lines;
 589                                                 if (par[0] < par[1] &&
 590                                                     par[1] <= video_num_lines) {
 591                                                         top=par[0];
 592                                                         bottom=par[1];
 593                                                 }
 594                                                 break;
 595                                         case 's':
 596                                                 save_cur();
 597                                                 break;
 598                                         case 'u':
 599                                                 restore_cur();
 600                                                 break;
 601                                 }
 602                 }
 603         }
 604         set_cursor();
 605 }
 606 
 607 /*
 608  *  void con_init(void);
 609  *
 610  * This routine initalizes console interrupts, and does nothing
 611  * else. If you want the screen to clear, call tty_write with
 612  * the appropriate escape-sequece.
 613  *
 614  * Reads the information preserved by setup.s to determine the current display
 615  * type and sets everything accordingly.
 616  */
 617 void con_init(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 618 {
 619         register unsigned char a;
 620         char *display_desc = "????";
 621         char *display_ptr;
 622 
 623         video_num_columns = ORIG_VIDEO_COLS;
 624         video_size_row = video_num_columns * 2;
 625         video_num_lines = ORIG_VIDEO_LINES;
 626         video_page = ORIG_VIDEO_PAGE;
 627         video_erase_char = 0x0720;
 628         
 629         if (ORIG_VIDEO_MODE == 7)                       /* Is this a monochrome display? */
 630         {
 631                 video_mem_start = 0xb0000;
 632                 video_port_reg = 0x3b4;
 633                 video_port_val = 0x3b5;
 634                 if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10)
 635                 {
 636                         video_type = VIDEO_TYPE_EGAM;
 637                         video_mem_end = 0xb8000;
 638                         display_desc = "EGAm";
 639                 }
 640                 else
 641                 {
 642                         video_type = VIDEO_TYPE_MDA;
 643                         video_mem_end   = 0xb2000;
 644                         display_desc = "*MDA";
 645                 }
 646         }
 647         else                                                            /* If not, it is color. */
 648         {
 649                 video_mem_start = 0xb8000;
 650                 video_port_reg  = 0x3d4;
 651                 video_port_val  = 0x3d5;
 652                 if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10)
 653                 {
 654                         video_type = VIDEO_TYPE_EGAC;
 655                         video_mem_end = 0xbc000;
 656                         display_desc = "EGAc";
 657                 }
 658                 else
 659                 {
 660                         video_type = VIDEO_TYPE_CGA;
 661                         video_mem_end = 0xba000;
 662                         display_desc = "*CGA";
 663                 }
 664         }
 665 
 666         /* Let the user known what kind of display driver we are using */
 667         
 668         display_ptr = ((char *)video_mem_start) + video_size_row - 8;
 669         while (*display_desc)
 670         {
 671                 *display_ptr++ = *display_desc++;
 672                 display_ptr++;
 673         }
 674         
 675         /* Initialize the variables used for scrolling (mostly EGA/VGA) */
 676         
 677         origin  = video_mem_start;
 678         scr_end = video_mem_start + video_num_lines * video_size_row;
 679         top     = 0;
 680         bottom  = video_num_lines;
 681 
 682         gotoxy(ORIG_X,ORIG_Y);
 683         set_trap_gate(0x21,&keyboard_interrupt);
 684         outb_p(inb_p(0x21)&0xfd,0x21);
 685         a=inb_p(0x61);
 686         outb_p(a|0x80,0x61);
 687         outb(a,0x61);
 688 }
 689 /* from bsd-net-2: */
 690 
 691 void sysbeepstop(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 692 {
 693         /* disable counter 2 */
 694         outb(inb_p(0x61)&0xFC, 0x61);
 695 }
 696 
 697 int beepcount = 0;
 698 
 699 static void sysbeep(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 700 {
 701         /* enable counter 2 */
 702         outb_p(inb_p(0x61)|3, 0x61);
 703         /* set command for counter 2, 2 byte write */
 704         outb_p(0xB6, 0x43);
 705         /* send 0x637 for 750 HZ */
 706         outb_p(0x37, 0x42);
 707         outb(0x06, 0x42);
 708         /* 1/8 second */
 709         beepcount = HZ/8;       
 710 }

/* [previous][next][first][last][top][bottom][index][help] */