root/arch/ppc/kernel/raw_printf.c

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

DEFINITIONS

This source file includes following definitions.
  1. _sputc
  2. _sprintk
  3. _vsprintk
  4. _printk
  5. _vprintk
  6. _cvt
  7. _disable_interrupts
  8. CRT_getc
  9. s
  10. NS16550_init
  11. c
  12. c
  13. _cnpause
  14. _disable_interrupts
  15. _printk
  16. _printk
  17. abort
  18. s
  19. _disable_interrupts
  20. printk
  21. printk
  22. s
  23. video_on
  24. CRT_init
  25. kbd
  26. scankbd
  27. kbdreset
  28. CRT_getc
  29. CRT_test
  30. _dump_buf_with_offset
  31. _dump_buf
  32. dump_buf_with_offset
  33. dump_buf

   1 #define FALSE 0
   2 #define TRUE  1
   3 #include <stdarg.h>
   4 
   5 extern void cnputc(char c);
   6 char cngetc(void);
   7 int cntstc(void);
   8 void _cnpause(void);
   9 void cnpause(void);
  10 void video_on(void);
  11 int CRT_init(void);
  12 int kbd(int noblock);
  13 int scankbd(void);
  14 static char *_sprintk_ptr;
  15 void kbdreset(void);
  16 int CRT_test(void);
  17 int CRT_putc(int , unsigned char );
  18 /*int CRT_putc(int port, u_char c)*/
  19 int CRT_getc(void);
  20 int _vprintk(   int (*putc)(), const char *fmt0, va_list ap);
  21 static _cvt(unsigned long val, char *buf, long radix, char *digits);
  22 static void cursor(void);
  23 static void initscreen(void );
  24 
  25 /*
  26  * COM1 NS16550 support
  27  */
  28 
  29 struct NS16550
  30         {
  31                 unsigned char rbr;  /* 0 */
  32                 unsigned char ier;  /* 1 */
  33                 unsigned char fcr;  /* 2 */
  34                 unsigned char lcr;  /* 3 */
  35                 unsigned char mcr;  /* 4 */
  36                 unsigned char lsr;  /* 5 */
  37                 unsigned char msr;  /* 6 */
  38                 unsigned char scr;  /* 7 */
  39         };
  40 
  41 #define thr rbr
  42 #define iir fcr
  43 #define dll rbr
  44 #define dlm ier
  45 
  46 #define LSR_DR   0x01  /* Data ready */
  47 #define LSR_OE   0x02  /* Overrun */
  48 #define LSR_PE   0x04  /* Parity error */
  49 #define LSR_FE   0x08  /* Framing error */
  50 #define LSR_BI   0x10  /* Break */
  51 #define LSR_THRE 0x20  /* Xmit holding register empty */
  52 #define LSR_TEMT 0x40  /* Xmitter empty */
  53 #define LSR_ERR  0x80  /* Error */
  54 
  55 #define COM1    0x800003F8
  56 #define COM2    0x800002F8
  57 
  58 typedef struct NS16550 *NS16550_t;
  59 
  60 const NS16550_t COM_PORTS[] = { COM1,COM2};
  61 
  62 volatile struct NS16550 *NS16550_init(int chan);
  63 void NS16550_putc(volatile struct NS16550 *com_port, unsigned char c);
  64 unsigned char NS16550_getc(volatile struct NS16550 *com_port);
  65 static _sputc(char c)
     /* [previous][next][first][last][top][bottom][index][help] */
  66 {
  67    *_sprintk_ptr++ = c;
  68    *_sprintk_ptr = '\0';
  69 }
  70 
  71 _sprintk(char *buf, char const *fmt, ...)
     /* [previous][next][first][last][top][bottom][index][help] */
  72 {
  73         int ret;
  74         va_list ap;
  75 
  76         va_start(ap, fmt);
  77         _sprintk_ptr = buf;
  78         ret = _vprintk(_sputc, fmt, ap);
  79         va_end(ap);
  80         return (ret);
  81 }
  82 
  83 _vsprintk(char *buf, char const *fmt, va_list ap)
     /* [previous][next][first][last][top][bottom][index][help] */
  84 {
  85         int ret;
  86 
  87         _sprintk_ptr = buf;
  88         ret = _vprintk(_sputc, fmt, ap);
  89         return (ret);
  90 }
  91 
  92 _printk(char const *fmt, ...)
     /* [previous][next][first][last][top][bottom][index][help] */
  93 {
  94         int ret;
  95         va_list ap;
  96 
  97         va_start(ap, fmt);
  98         ret = _vprintk(cnputc, fmt, ap);
  99         va_end(ap);
 100         return (ret);
 101 }
 102 
 103 #define is_digit(c) ((c >= '0') && (c <= '9'))
 104 
 105 int _vprintk(   int (*putc)(), const char *fmt0, va_list ap)
     /* [previous][next][first][last][top][bottom][index][help] */
 106 {
 107    char c, sign, *cp;
 108    int left_prec, right_prec, zero_fill, length, pad, pad_on_right;
 109    char buf[32];
 110    long val;
 111    while (c = *fmt0++)
 112    {
 113       if (c == '%')
 114       {
 115          c = *fmt0++;
 116          left_prec = right_prec = pad_on_right = 0;
 117          if (c == '-')
 118          {
 119             c = *fmt0++;
 120             pad_on_right++;
 121          }
 122          if (c == '0')
 123          {
 124             zero_fill = TRUE;
 125             c = *fmt0++;
 126          } else
 127          {
 128             zero_fill = FALSE;
 129          }
 130          while (is_digit(c))
 131          {
 132             left_prec = (left_prec * 10) + (c - '0');
 133             c = *fmt0++;
 134          }
 135          if (c == '.')
 136          {
 137             c = *fmt0++;
 138             zero_fill++;
 139             while (is_digit(c))
 140             {
 141                right_prec = (right_prec * 10) + (c - '0');
 142                c = *fmt0++;
 143             }
 144          } else
 145          {
 146             right_prec = left_prec;
 147          }
 148          sign = '\0';
 149          switch (c)
 150          {
 151             case 'd':
 152             case 'x':
 153             case 'X':
 154                val = va_arg(ap, long);
 155                switch (c)
 156                {
 157                   case 'd':
 158                      if (val < 0)
 159                      {
 160                         sign = '-';
 161                         val = -val;
 162                      }
 163                      length = _cvt(val, buf, 10, "0123456789");
 164                      break;
 165                   case 'x':
 166                      length = _cvt(val, buf, 16, "0123456789abcdef");
 167                      break;
 168                   case 'X':
 169                      length = _cvt(val, buf, 16, "0123456789ABCDEF");
 170                      break;
 171                }
 172                cp = buf;
 173                break;
 174             case 's':
 175                cp = va_arg(ap, char *);
 176                length = strlen(cp);
 177                break;
 178             case 'c':
 179                c = va_arg(ap, long /*char*/);
 180                (*putc)(c);
 181                continue;
 182             default:
 183                (*putc)('?');
 184          }
 185          pad = left_prec - length;
 186          if (sign != '\0')
 187          {
 188             pad--;
 189          }
 190          if (zero_fill)
 191          {
 192             c = '0';
 193             if (sign != '\0')
 194             {
 195                (*putc)(sign);
 196                sign = '\0';
 197             }
 198          } else
 199          {
 200             c = ' ';
 201          }
 202          if (!pad_on_right)
 203          {
 204             while (pad-- > 0)
 205             {
 206                (*putc)(c);
 207             }
 208          }
 209          if (sign != '\0')
 210          {
 211             (*putc)(sign);
 212          }
 213          while (length-- > 0)
 214          {
 215             (*putc)(c = *cp++);
 216             if (c == '\n')
 217             {
 218                (*putc)('\r');
 219             }
 220          }
 221          if (pad_on_right)
 222          {
 223             while (pad-- > 0)
 224             {
 225                (*putc)(c);
 226             }
 227          }
 228       } else
 229       {
 230          (*putc)(c);
 231          if (c == '\n')
 232          {
 233             (*putc)('\r');
 234          }
 235       }
 236    }
 237 }
 238 
 239 static _cvt(unsigned long val, char *buf, long radix, char *digits)
     /* [previous][next][first][last][top][bottom][index][help] */
 240 {
 241    char temp[80];
 242    char *cp = temp;
 243    int length = 0;
 244    if (val == 0)
 245    { /* Special case */
 246       *cp++ = '0';
 247    } else
 248    while (val)
 249    {
 250       *cp++ = digits[val % radix];
 251       val /= radix;
 252    }
 253    while (cp != temp)
 254    {
 255       *buf++ = *--cp;
 256       length++;
 257    }
 258    *buf = '\0';
 259    return (length);
 260 }
 261 
 262 /*
 263  * Console I/O interface
 264  */
 265 typedef const (*proc)();
 266 typedef int dev_t;
 267 
 268 #define FALSE 0
 269 #define TRUE  1
 270 
 271 #define CRT_PORT 0x3D4  /* Pick one */
 272 
 273 static int init = FALSE;
 274 static int is_crt = 0;
 275 static int port = 0;
 276 static int line_num = 0;
 277 #define MAX_LINES 24
 278 
 279 char cngetc(void)
 280 {
 281    int s = _disable_interrupts();
     /* [previous][next][first][last][top][bottom][index][help] */
 282    char c = '\0';
 283    if (port == CRT_PORT)
 284    {
 285 /*      c = CRT_getc(port);*/
 286      c = CRT_getc();
     /* [previous][next][first][last][top][bottom][index][help] */
 287    } else
 288    if (port)
 289    {
 290       c = NS16550_getc((struct NS16550 *)port);
 291    }
 292    _enable_interrupts(s);
     /* [previous][next][first][last][top][bottom][index][help] */
 293    return (c);
 294 }
 295 
 296 int cntstc(void)
 297 {
 298    return (0);
 299 }
 300 
 301 char _cn_trace[1024];
 302 char *_cnp = _cn_trace;
 303 
 304 /*
 305  * Console kernel output character routine.
 306  */
 307 void
 308 cnputc(char c)
 309 {
 310    *_cnp++ = c;
 311    if (_cnp == &_cn_trace[sizeof(_cn_trace)])
 312    {
 313       _cnp = _cn_trace;
 314    }
 315    if (!init)
 316    {
 317       if (is_crt = CRT_init())
 318       {
 319          port = CRT_PORT;
 320       } else
 321       {
 322          port =(int) NS16550_init(0);
     /* [previous][next][first][last][top][bottom][index][help] */
 323       }
 324       init = TRUE;
 325    }
 326    if (port == CRT_PORT)
 327    {
 328       CRT_putc(port, c);
     /* [previous][next][first][last][top][bottom][index][help] */
 329    } else
 330    if (port)
 331    {
 332       NS16550_putc((struct NS16550 *)port, c);
     /* [previous][next][first][last][top][bottom][index][help] */
 333    }
 334    if (c == '\n')
 335    {
 336       if (line_num >= 0) line_num++;
 337    }
 338    if (c == '\r')
 339    {
 340       if (line_num >= MAX_LINES)
 341       {
 342          line_num = 0;
 343          _cnpause();
     /* [previous][next][first][last][top][bottom][index][help] */
 344       }
 345    }
 346 }
 347 
 348 void _cnpause(void)
 349 {
 350    int c;
 351    int s = _disable_interrupts();
     /* [previous][next][first][last][top][bottom][index][help] */
 352    _printk("-- More? ");
     /* [previous][next][first][last][top][bottom][index][help] */
 353    while ((c = cngetc()) == 0);
 354    _printk("\r         \r");  /* Erase prompt */
     /* [previous][next][first][last][top][bottom][index][help] */
 355    if (c == ' ')
 356    {
 357       line_num = 0;
 358    } else
 359    if (c == 'n')
 360    {
 361       line_num = -1;  /* Turn off pause */
 362    } else
 363    if ((c == '\r') || (c == '\n'))
 364    {
 365       line_num = MAX_LINES-1;
 366    } else
 367    if (c == 0x03) /* ^C */
 368    {
 369         abort();
     /* [previous][next][first][last][top][bottom][index][help] */
 370    } else
 371    {
 372       line_num = MAX_LINES - (MAX_LINES/3);
 373    }
 374    _enable_interrupts(s);
     /* [previous][next][first][last][top][bottom][index][help] */
 375 }
 376 
 377 void cnpause(void)
 378 {
 379    int c;
 380    int s = _disable_interrupts();
     /* [previous][next][first][last][top][bottom][index][help] */
 381    printk("-- More? ");
     /* [previous][next][first][last][top][bottom][index][help] */
 382    while ((c = cngetc()) == 0);
 383    printk("\r         \r");  /* Erase prompt */
     /* [previous][next][first][last][top][bottom][index][help] */
 384    _enable_interrupts(s);
     /* [previous][next][first][last][top][bottom][index][help] */
 385 }
 386 
 387 volatile struct NS16550 *NS16550_init(int chan)
 388 {
 389         volatile struct NS16550 *com_port;
 390         volatile unsigned char xx;
 391         com_port = (struct NS16550 *) COM_PORTS[chan];
 392         /* See if port is present */
 393         com_port->lcr = 0x00;
 394         com_port->ier = 0xFF;
 395 #if 0   
 396         if (com_port->ier != 0x0F) return ((struct NS16550 *)0);
 397 #endif  
 398         com_port->ier = 0x00;
 399         com_port->lcr = 0x80;  /* Access baud rate */
 400         com_port->dll = 12;  /* 9600 baud */
 401         com_port->dlm = 12 >> 8;
 402         com_port->lcr = 0x03;  /* 8 data, 1 stop, no parity */
 403         com_port->mcr = 0x03;  /* RTS/DTR */
 404         com_port->fcr = 0x07;  /* Clear & enable FIFOs */
 405         return (com_port);
 406 }
 407 
 408 
 409 void NS16550_putc(volatile struct NS16550 *com_port, unsigned char c)
 410 {
 411         volatile int i;
 412         while ((com_port->lsr & LSR_THRE) == 0) ;
 413         com_port->thr = c;
 414 }
 415 
 416 
 417 unsigned char NS16550_getc(volatile struct NS16550 *com_port)
 418 {
 419         while ((com_port->lsr & LSR_DR) == 0) ;
 420         return (com_port->rbr);
 421 }
 422 
 423 NS16550_test(volatile struct NS16550 *com_port)
 424 {
 425         return ((com_port->lsr & LSR_DR) != 0);
 426 }
 427 
 428 typedef unsigned short u_short;
 429 typedef unsigned char  u_char;
 430 
 431 #define COL             80
 432 #define ROW             25
 433 #define CHR             2
 434 #define MONO_BASE       0x3B4
 435 #define MONO_BUF        0xB0000
 436 #define CGA_BASE        0x3D4
 437 #define CGA_BUF         0xB8000
 438 #define ISA_mem         ((unsigned char *)0xC0000000)
 439 #define ISA_io          ((unsigned char *)0x80000000)
 440 
 441 unsigned char background = 0;
 442 unsigned char foreground = 6;
 443 
 444 unsigned int addr_6845;
 445 unsigned short *Crtat;
 446 int lastpos;
 447 int scroll;
 448 
 449 static void
 450 outb(int port, unsigned char c)
 451 {
 452         ISA_io[port] = c;
 453 }
 454 
 455 static unsigned char
 456 inb(int port)
 457 {
 458         return (ISA_io[port]);
 459 }
 460 
 461 /*
 462  * The current state of virtual displays
 463  */
 464 struct screen {
 465         u_short *cp;            /* the current character address */
 466         enum state {
 467                 NORMAL,                 /* no pending escape */
 468                 ESC,                    /* saw ESC */
 469                 EBRAC,                  /* saw ESC[ */
 470                 EBRACEQ                 /* saw ESC[= */
 471         } state;                /* command parser state */
 472         int     cx;             /* the first escape seq argument */
 473         int     cy;             /* the second escape seq argument */
 474         int     *accp;          /* pointer to the current processed argument */
 475         int     row;            /* current column */
 476         int     so;             /* standout mode */
 477         u_short color;          /* normal character color */
 478         u_short color_so;       /* standout color */
 479         u_short save_color;     /* saved normal color */
 480         u_short save_color_so;  /* saved standout color */
 481 } screen;
 482 
 483 /*
 484  * Color and attributes for normal, standout and kernel output
 485  * are stored in the least-significant byte of a u_short
 486  * so they don't have to be shifted for use.
 487  * This is all byte-order dependent.
 488  */
 489 #define CATTR(x) (x)            /* store color/attributes un-shifted */
 490 #define ATTR_ADDR(which) (((u_char *)&(which))+1) /* address of attributes */
 491 
 492 unsigned short  pccolor;                /* color/attributes for tty output */
 493 unsigned short  pccolor_so;             /* color/attributes, standout mode */
 494 
 495 /*
 496  * cursor() sets an offset (0-1999) into the 80x25 text area   
 497  */
 498 static void cursor(void)
 499 {
 500         int pos = screen.cp - Crtat;
 501 
 502         if (lastpos != pos) {
 503                 outb(addr_6845, 14);
 504                 outb(addr_6845+1, pos >> 8);
 505                 outb(addr_6845, 15);
 506                 outb(addr_6845+1, pos);
 507                 lastpos = pos;
 508         }
 509 }
 510 
 511 static void initscreen(void )
 512 {
 513         struct screen *d = &screen;
 514 
 515         pccolor = CATTR((background<<4)|foreground);
 516         pccolor_so = CATTR((foreground<<4)|background);
 517         d->color = pccolor;
 518         d->save_color = pccolor;
 519         d->color_so = pccolor_so;
 520         d->save_color_so = pccolor_so;
 521 }
 522 
 523 
 524 #define wrtchar(c, d) { \
 525         *(d->cp) = c; \
 526         d->cp++; \
 527         d->row++; \
 528 }
 529 
 530 fillw(unsigned short val, unsigned short *buf, int num)
 531 {
 532         /* Need to byte swap value */
 533         unsigned short tmp;
 534         tmp = val;
 535         while (num-- > 0)
 536         {
 537                 *buf++ = tmp;
 538         }
 539 }
 540 
 541 /*
 542  * CRT_putc (nee sput) has support for emulation of the 'ibmpc' termcap entry.
 543  * This is a bare-bones implementation of a bare-bones entry
 544  * One modification: Change li#24 to li#25 to reflect 25 lines
 545  * "ca" is the color/attributes value (left-shifted by 8)
 546  * or 0 if the current regular color for that screen is to be used.
 547  */
 548 int CRT_putc(int port, unsigned char c)
 549 {
 550         struct screen *d = &screen;
 551         u_short *base;
 552         int i, j;
 553         u_short *pp;
 554 
 555         base = Crtat;
 556 
 557         switch (d->state) {
 558         case NORMAL:
 559                 switch (c) {
 560                 case 0x0:               /* Ignore pad characters */
 561                         return;
 562 
 563                 case 0x1B:
 564                         d->state = ESC;
 565                         break;
 566 
 567                 case '\t':
 568                         do {
 569                                 wrtchar(d->color | ' ', d);
 570                         } while (d->row % 8);
 571                         break;
 572 
 573                 case '\b':  /* non-destructive backspace */
 574                         if (d->cp > base) {
 575                                 d->cp--;
 576                                 d->row--;
 577                                 if (d->row < 0)
 578                                         d->row += COL;  /* prev column */
 579                         }
 580                         break;
 581 
 582                 case '\r':
 583                         d->cp -= d->row;
 584                         d->row = 0;
 585                         break;
 586 
 587                 case '\n':
 588                         d->cp += COL;
 589                         break;
 590 
 591                 case '\007':
 592                         break;
 593 
 594                 default:
 595                         if (d->so) {
 596                                 wrtchar(d->color_so|(c<<8), d); 
 597                         } else {
 598                                 wrtchar(d->color | (c<<8), d); 
 599                         }
 600                         if (d->row >= COL)
 601                                 d->row = 0;
 602                         break;
 603                 }
 604                 break;
 605 
 606         case EBRAC:
 607                 /*
 608                  * In this state, the action at the end of the switch
 609                  * on the character type is to go to NORMAL state,
 610                  * and intermediate states do a return rather than break.
 611                  */
 612                 switch (c) {
 613                 case 'm':
 614                         d->so = d->cx;
 615                         break;
 616 
 617                 case 'A': /* back one row */
 618                         if (d->cp >= base + COL)
 619                                 d->cp -= COL;
 620                         break;
 621 
 622                 case 'B': /* down one row */
 623                         d->cp += COL;
 624                         break;
 625 
 626                 case 'C': /* right cursor */
 627                         d->cp++;
 628                         d->row++;
 629                         break;
 630 
 631                 case 'D': /* left cursor */
 632                         if (d->cp > base) {
 633                                 d->cp--;
 634                                 d->row--;
 635                                 if (d->row < 0)
 636                                         d->row += COL;  /* prev column ??? */
 637                         }
 638                         break;
 639 
 640                 case 'J': /* Clear to end of display */
 641                         fillw(d->color|(' '<<8), d->cp, base + COL * ROW - d->cp);
 642                         break;
 643 
 644                 case 'K': /* Clear to EOL */
 645                         fillw(d->color|(' '<<8), d->cp, COL - (d->cp - base) % COL);
 646                         break;
 647 
 648                 case 'H': /* Cursor move */
 649                         if (d->cx > ROW)
 650                                 d->cx = ROW;
 651                         if (d->cy > COL)
 652                                 d->cy = COL;
 653                         if (d->cx == 0 || d->cy == 0) {
 654                                 d->cp = base;
 655                                 d->row = 0;
 656                         } else {
 657                                 d->cp = base + (d->cx - 1) * COL + d->cy - 1;
 658                                 d->row = d->cy - 1;
 659                         }
 660                         break;
 661 
 662                 case '_': /* set cursor */
 663                         if (d->cx)
 664                                 d->cx = 1;              /* block */
 665                         else
 666                                 d->cx = 12;     /* underline */
 667                         outb(addr_6845, 10);
 668                         outb(addr_6845+1, d->cx);
 669                         outb(addr_6845, 11);
 670                         outb(addr_6845+1, 13);
 671                         break;
 672 
 673                 case ';': /* Switch params in cursor def */
 674                         d->accp = &d->cy;
 675                         return;
 676 
 677                 case '=': /* ESC[= color change */
 678                         d->state = EBRACEQ;
 679                         return;
 680 
 681                 case 'L':       /* Insert line */
 682                         i = (d->cp - base) / COL;
 683                         /* avoid deficiency of bcopy implementation */
 684                         pp = base + COL * (ROW-2);
 685                         for (j = ROW - 1 - i; j--; pp -= COL)
 686                                 bcopy(pp, pp + COL, COL * CHR);
 687                         fillw(d->color|(' '<<8), base + i * COL, COL);
 688                         break;
 689                         
 690                 case 'M':       /* Delete line */
 691                         i = (d->cp - base) / COL;
 692                         pp = base + i * COL;
 693                         bcopy(pp + COL, pp, (ROW-1 - i)*COL*CHR);
 694                         fillw(d->color|(' '<<8), base + COL * (ROW - 1), COL);
 695                         break;
 696 
 697                 default: /* Only numbers valid here */
 698                         if ((c >= '0') && (c <= '9')) {
 699                                 *(d->accp) *= 10;
 700                                 *(d->accp) += c - '0';
 701                                 return;
 702                         } else
 703                                 break;
 704                 }
 705                 d->state = NORMAL;
 706                 break;
 707 
 708         case EBRACEQ: {
 709                 /*
 710                  * In this state, the action at the end of the switch
 711                  * on the character type is to go to NORMAL state,
 712                  * and intermediate states do a return rather than break.
 713                  */
 714                 u_char *colp;
 715 
 716                 /*
 717                  * Set foreground/background color
 718                  * for normal mode, standout mode
 719                  * or kernel output.
 720                  * Based on code from kentp@svmp03.
 721                  */
 722                 switch (c) {
 723                 case 'F':
 724                         colp = ATTR_ADDR(d->color);
 725         do_fg:
 726                         *colp = (*colp & 0xf0) | (d->cx);
 727                         break;
 728 
 729                 case 'G':
 730                         colp = ATTR_ADDR(d->color);
 731         do_bg:
 732                         *colp = (*colp & 0xf) | (d->cx << 4);
 733                         break;
 734 
 735                 case 'H':
 736                         colp = ATTR_ADDR(d->color_so);
 737                         goto do_fg;
 738 
 739                 case 'I':
 740                         colp = ATTR_ADDR(d->color_so);
 741                         goto do_bg;
 742 
 743                 case 'S':
 744                         d->save_color = d->color;
 745                         d->save_color_so = d->color_so;
 746                         break;
 747 
 748                 case 'R':
 749                         d->color = d->save_color;
 750                         d->color_so = d->save_color_so;
 751                         break;
 752 
 753                 default: /* Only numbers valid here */
 754                         if ((c >= '0') && (c <= '9')) {
 755                                 d->cx *= 10;
 756                                 d->cx += c - '0';
 757                                 return;
 758                         } else
 759                                 break;
 760                 }
 761                 d->state = NORMAL;
 762             }
 763             break;
 764 
 765         case ESC:
 766                 switch (c) {
 767                 case 'c':       /* Clear screen & home */
 768                         fillw(d->color|(' '<<8), base, COL * ROW);
 769                         d->cp = base;
 770                         d->row = 0;
 771                         d->state = NORMAL;
 772                         break;
 773                 case '[':       /* Start ESC [ sequence */
 774                         d->state = EBRAC;
 775                         d->cx = 0;
 776                         d->cy = 0;
 777                         d->accp = &d->cx;
 778                         break;
 779                 default: /* Invalid, clear state */
 780                         d->state = NORMAL;
 781                         break;
 782                 }
 783                 break;
 784         }
 785         if (d->cp >= base + (COL * ROW)) { /* scroll check */
 786                 bcopy(base + COL, base, COL * (ROW - 1) * CHR);
 787                 fillw(d->color|(' '<<8), base + COL * (ROW - 1), COL);
 788                 d->cp -= COL;
 789         }       
 790         cursor();
 791 }
 792 
 793 void video_on(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 794 { /* Enable video */
 795         outb(0x3C4, 0x01);
 796         outb(0x3C5, inb(0x3C5)&~20);
 797 }
 798 
 799 int CRT_init(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 800 {
 801         unsigned long *PCI_base = (unsigned long *)0x80808010;  /* Magic */
 802         struct screen *d = &screen;
 803         if (*PCI_base)
 804         { /* No CRT configured */
 805                 return (0);
 806         }
 807         video_on();
 808         d->cp = Crtat = (u_short *)&ISA_mem[0x0B8000];
 809         addr_6845 = CGA_BASE;
 810         initscreen();
 811         fillw(pccolor|(' '<<8), d->cp, COL * ROW);
 812         return (1);
 813 }
 814 
 815 /* Keyboard handler */
 816 
 817 #define L               0x0001  /* locking function */
 818 #define SHF             0x0002  /* keyboard shift */
 819 #define ALT             0x0004  /* alternate shift -- alternate chars */
 820 #define NUM             0x0008  /* numeric shift  cursors vs. numeric */
 821 #define CTL             0x0010  /* control shift  -- allows ctl function */
 822 #define CPS             0x0020  /* caps shift -- swaps case of letter */
 823 #define ASCII           0x0040  /* ascii code for this key */
 824 #define STP             0x0080  /* stop output */
 825 #define FUNC            0x0100  /* function key */
 826 #define SCROLL          0x0200  /* scroll lock key */
 827 
 828 /* #include "pcconstab.US" */
 829 /*      BSDI $Id: pcconstab.US,v 1.1.1.1 1994/03/31 13:29:09 gary Exp $ */
 830 /*-
 831  * Copyright (c) 1990 The Regents of the University of California.
 832  * All rights reserved.
 833  *
 834  * This code is derived from software contributed to Berkeley by
 835  * William Jolitz and Don Ahn.
 836  *
 837  * Redistribution and use in source and binary forms, with or without
 838  * modification, are permitted provided that the following conditions
 839  * are met:
 840  * 1. Redistributions of source code must retain the above copyright
 841  *    notice, this list of conditions and the following disclaimer.
 842  * 2. Redistributions in binary form must reproduce the above copyright
 843  *    notice, this list of conditions and the following disclaimer in the
 844  *    documentation and/or other materials provided with the distribution.
 845  * 3. All advertising materials mentioning features or use of this software
 846  *    must display the following acknowledgement:
 847  *      This product includes software developed by the University of
 848  *      California, Berkeley and its contributors.
 849  * 4. Neither the name of the University nor the names of its contributors
 850  *    may be used to endorse or promote products derived from this software
 851  *    without specific prior written permission.
 852  *
 853  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 854  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 855  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 856  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 857  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 858  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 859  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 860  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 861  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 862  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 863  * SUCH DAMAGE.
 864  *
 865  *      from @(#)pccons.c       5.11 (Berkeley) 5/21/91
 866  */
 867 
 868 /*
 869  *      US Keyboard mapping tables
 870  */
 871 
 872 const unsigned short action[] = {
 873         0,     ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan  0- 7 */
 874         ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan  8-15 */
 875         ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 16-23 */
 876         ASCII, ASCII, ASCII, ASCII, ASCII,   CTL, ASCII, ASCII, /* scan 24-31 */
 877         ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 32-39 */
 878         ASCII, ASCII,   SHF, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 40-47 */
 879         ASCII, ASCII, ASCII, ASCII, ASCII, ASCII,   SHF, ASCII, /* scan 48-55 */
 880           ALT, ASCII,   CPS,  FUNC,  FUNC,  FUNC,  FUNC,  FUNC, /* scan 56-63 */
 881          FUNC,  FUNC,  FUNC,  FUNC,  FUNC,   NUM,SCROLL, ASCII, /* scan 64-71 */
 882         ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 72-79 */
 883         ASCII, ASCII, ASCII, ASCII,     0,     0,     0,     0, /* scan 80-87 */
 884         0,0,0,0,0,0,0,0,        /* scan 88-95 */
 885         0,0,0,0,0,0,0,0,        /* scan 96-103 */
 886         0,0,0,0,0,0,0,0,        /* scan 104-111 */
 887         0,0,0,0,0,0,0,0,        /* scan 112-119 */
 888         0,0,0,0,0,0,0,0,        /* scan 120-127 */
 889 };
 890 
 891 const unsigned char unshift[] = {       /* no shift */
 892           0,   033,   '1',   '2',   '3',   '4',   '5',   '6',   /* scan  0- 7 */
 893         '7',   '8',   '9',   '0',   '-',   '=',   010,  '\t',   /* scan  8-15 */
 894         'q',   'w',   'e',   'r',   't',   'y',   'u',   'i',   /* scan 16-23 */
 895         'o',   'p',   '[',   ']',  '\r',   CTL,   'a',   's',   /* scan 24-31 */
 896         'd',   'f',   'g',   'h',   'j',   'k',   'l',   ';',   /* scan 32-39 */
 897         '\'',  '`',   SHF,   '\\',  'z',   'x',   'c',   'v',   /* scan 40-47 */
 898         'b',   'n',   'm',   ',',   '.',   '/',   SHF,   '*',   /* scan 48-55 */
 899         ALT,   ' ',   CPS,     1,     2,     3,     4,     5,   /* scan 56-63 */
 900           6,     7,     8,     9,    10,   NUM,   STP,   '7',   /* scan 64-71 */
 901         '8',   '9',   '-',   '4',   '5',   '6',   '+',   '1',   /* scan 72-79 */
 902         '2',   '3',   '0',   0177,    0,     0,     0,     0,   /* scan 80-87 */
 903         0,0,0,0,0,0,0,0,        /* scan 88-95 */
 904         0,0,0,0,0,0,0,0,        /* scan 96-103 */
 905         0,0,0,0,0,0,0,0,        /* scan 104-111 */
 906         0,0,0,0,0,0,0,0,        /* scan 112-119 */
 907         0,0,0,0,0,0,0,0,        /* scan 120-127 */
 908 };
 909 
 910 const unsigned char shift[] = { /* shift shift */
 911           0,   033,   '!',   '@',   '#',   '$',   '%',   '^',   /* scan  0- 7 */
 912         '&',   '*',   '(',   ')',   '_',   '+',   010,  '\t',   /* scan  8-15 */
 913         'Q',   'W',   'E',   'R',   'T',   'Y',   'U',   'I',   /* scan 16-23 */
 914         'O',   'P',   '{',   '}',  '\r',   CTL,   'A',   'S',   /* scan 24-31 */
 915         'D',   'F',   'G',   'H',   'J',   'K',   'L',   ':',   /* scan 32-39 */
 916         '"',   '~',   SHF,   '|',   'Z',   'X',   'C',   'V',   /* scan 40-47 */
 917         'B',   'N',   'M',   '<',   '>',   '?',   SHF,   '*',   /* scan 48-55 */
 918         ALT,   ' ',   CPS,     0,     0,   ' ',     0,     0,   /* scan 56-63 */
 919           0,     0,     0,     0,     0,   NUM,   STP,   '7',   /* scan 64-71 */
 920         '8',   '9',   '-',   '4',   '5',   '6',   '+',   '1',   /* scan 72-79 */
 921         '2',   '3',   '0',  0177,     0,     0,     0,     0,   /* scan 80-87 */
 922         0,0,0,0,0,0,0,0,        /* scan 88-95 */
 923         0,0,0,0,0,0,0,0,        /* scan 96-103 */
 924         0,0,0,0,0,0,0,0,        /* scan 104-111 */
 925         0,0,0,0,0,0,0,0,        /* scan 112-119 */
 926         0,0,0,0,0,0,0,0,        /* scan 120-127 */
 927 };
 928 
 929 const unsigned char ctl[] = {   /* CTL shift */
 930           0,   033,   '!',   000,   '#',   '$',   '%',   036,   /* scan  0- 7 */
 931         '&',   '*',   '(',   ')',   037,   '+',   034,'\177',   /* scan  8-15 */
 932         021,   027,   005,   022,   024,   031,   025,   011,   /* scan 16-23 */
 933         017,   020,   033,   035,  '\r',   CTL,   001,   023,   /* scan 24-31 */
 934         004,   006,   007,   010,   012,   013,   014,   ';',   /* scan 32-39 */
 935         '\'',  '`',   SHF,   034,   032,   030,   003,   026,   /* scan 40-47 */
 936         002,   016,   015,   '<',   '>',   '?',   SHF,   '*',   /* scan 48-55 */
 937         ALT,   ' ',   CPS,     0,     0,   ' ',     0,     0,   /* scan 56-63 */
 938         CPS,     0,     0,     0,     0,     0,     0,     0,   /* scan 64-71 */
 939           0,     0,     0,     0,     0,     0,     0,     0,   /* scan 72-79 */
 940           0,     0,     0,  0177,     0,     0,     0,     0,   /* scan 80-87 */
 941           0,     0,   033,   '7',   '4',   '1',     0,   NUM,   /* scan 88-95 */
 942         '8',   '5',   '2',     0,   STP,   '9',   '6',   '3',   /* scan 96-103*/
 943         '.',     0,   '*',   '-',   '+',     0,     0,     0,   /*scan 104-111*/
 944         0,0,0,0,0,0,0,0,        /* scan 112-119 */
 945         0,0,0,0,0,0,0,0,        /* scan 120-127 */
 946 };
 947 
 948 
 949 unsigned char shfts, ctls, alts, caps, num, stp;
 950 
 951 #define KBDATAP         0x60    /* kbd data port */
 952 #define KBSTATUSPORT    0x61    /* kbd status */
 953 #define KBSTATP         0x64    /* kbd status port */
 954 #define KBINRDY         0x01
 955 #define KBOUTRDY        0x02
 956 
 957 #define _x__ 0x00  /* Unknown / unmapped */
 958 
 959 const unsigned char keycode[] = {
 960         _x__, 0x43, 0x41, 0x3F, 0x3D, 0x3B, 0x3C, _x__, /* 0x00-0x07 */
 961         _x__, 0x44, 0x42, 0x40, 0x3E, 0x0F, 0x29, _x__, /* 0x08-0x0F */
 962         _x__, 0x38, 0x2A, _x__, 0x1D, 0x10, 0x02, _x__, /* 0x10-0x17 */
 963         _x__, _x__, 0x2C, 0x1F, 0x1E, 0x11, 0x03, _x__, /* 0x18-0x1F */
 964         _x__, 0x2E, 0x2D, 0x20, 0x12, 0x05, 0x04, _x__, /* 0x20-0x27 */
 965         _x__, 0x39, 0x2F, 0x21, 0x14, 0x13, 0x06, _x__, /* 0x28-0x2F */
 966         _x__, 0x31, 0x30, 0x23, 0x22, 0x15, 0x07, _x__, /* 0x30-0x37 */
 967         _x__, _x__, 0x32, 0x24, 0x16, 0x08, 0x09, _x__, /* 0x38-0x3F */
 968         _x__, 0x33, 0x25, 0x17, 0x18, 0x0B, 0x0A, _x__, /* 0x40-0x47 */
 969         _x__, 0x34, 0x35, 0x26, 0x27, 0x19, 0x0C, _x__, /* 0x48-0x4F */
 970         _x__, _x__, 0x28, _x__, 0x1A, 0x0D, _x__, _x__, /* 0x50-0x57 */
 971         0x3A, 0x36, 0x1C, 0x1B, _x__, 0x2B, _x__, _x__, /* 0x58-0x5F */
 972         _x__, _x__, _x__, _x__, _x__, _x__, 0x0E, _x__, /* 0x60-0x67 */
 973         _x__, 0x4F, _x__, 0x4B, 0x47, _x__, _x__, _x__, /* 0x68-0x6F */
 974         0x52, 0x53, 0x50, 0x4C, 0x4D, 0x48, 0x01, 0x45, /* 0x70-0x77 */
 975         _x__, 0x4E, 0x51, 0x4A, _x__, 0x49, 0x46, 0x54, /* 0x78-0x7F */
 976 };
 977 
 978 int kbd(int noblock)
     /* [previous][next][first][last][top][bottom][index][help] */
 979 {
 980         unsigned char dt, brk, act;
 981         int first = 1;  
 982 loop:
 983         if (noblock) {
 984                 if ((inb(KBSTATP) & KBINRDY) == 0)
 985                         return (-1);
 986         } else while((inb(KBSTATP) & KBINRDY) == 0)
 987                 ;
 988         dt = inb(KBDATAP);
 989 
 990         brk = dt & 0x80;        /* brk == 1 on key release */
 991         dt = dt & 0x7f;         /* keycode */
 992 
 993         act = action[dt];
 994         if (act&SHF)
 995                 shfts = brk ? 0 : 1;
 996         if (act&ALT)
 997                 alts = brk ? 0 : 1;
 998         if (act&NUM)
 999                 if (act&L) {
1000                         /* NUM lock */
1001                         if(!brk)
1002                                 num = !num;
1003                 } else
1004                         num = brk ? 0 : 1;
1005         if (act&CTL)
1006                 ctls = brk ? 0 : 1;
1007         if (act&CPS)
1008                 if (act&L) {
1009                         /* CAPS lock */
1010                         if(!brk)
1011                                 caps = !caps;
1012                 } else
1013                         caps = brk ? 0 : 1;
1014         if (act&STP)
1015                 if (act&L) {
1016                         if(!brk)
1017                                 stp = !stp;
1018                 } else
1019                         stp = brk ? 0 : 1;
1020 
1021         if ((act&ASCII) && !brk) {
1022                 unsigned char chr;
1023 
1024                 if (shfts)
1025                         chr = shift[dt];
1026                 else if (ctls)
1027                         chr = ctl[dt];
1028                 else
1029                         chr = unshift[dt];
1030 
1031                 if (alts)
1032                         chr |= 0x80;
1033 
1034                 if (caps && (chr >= 'a' && chr <= 'z'))
1035                         chr -= 'a' - 'A' ;
1036 #define CTRL(s) (s & 0x1F)                      
1037                 if ((chr == '\r') || (chr == '\n') || (chr == CTRL('A')) || (chr == CTRL('S')))
1038                 {
1039                         /* Wait for key up */
1040                         while (1)
1041                         {
1042                                 while((inb(KBSTATP) & KBINRDY) == 0) ;
1043                                 dt = inb(KBDATAP);
1044                                 if (dt & 0x80) /* key up */ break;
1045                         }
1046                 }
1047                 return (chr);
1048         }
1049         if (first && brk) return (0);  /* Ignore initial 'key up' codes */
1050         goto loop;
1051 }
1052 
1053 int scankbd(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1054 {
1055         return (kbd(1) != -1);
1056 }
1057 
1058 void kbdreset(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1059 {
1060         unsigned char c;
1061 
1062         /* Enable interrupts and keyboard controller */
1063         while (inb(KBSTATP) & KBOUTRDY)
1064                 ;
1065         outb(KBSTATP,0x60);
1066         while (inb(KBSTATP) & KBOUTRDY)
1067                 ;
1068         outb(KBDATAP,0x4D);
1069 
1070         /* Start keyboard stuff RESET */
1071         while (inb(KBSTATP) & KBOUTRDY)
1072                 ;       /* wait input ready */
1073         outb(KBDATAP,0xFF);     /* RESET */
1074 
1075         while ((c = inb(KBDATAP)) != 0xFA)
1076                 ;
1077 }
1078 
1079 int CRT_getc(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1080 {
1081         int c;
1082         while ((c = kbd(0)) == 0) ;
1083         return(c);
1084 }
1085 
1086 int CRT_test(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1087 {
1088         return ((inb(KBSTATP) & KBINRDY) != 0);
1089 }
1090 
1091 
1092 _dump_buf_with_offset(unsigned char *p, int s, unsigned char *base)
     /* [previous][next][first][last][top][bottom][index][help] */
1093 {
1094    int i, c;
1095    if ((unsigned int)s > (unsigned int)p)
1096    {
1097         s = (unsigned int)s - (unsigned int)p;
1098    }
1099    while (s > 0)
1100    {
1101       if (base)
1102       {
1103          _printk("%06X: ", (int)p - (int)base);
1104       } else
1105       {
1106          _printk("%06X: ", p);
1107       }
1108       for (i = 0;  i < 16;  i++)
1109       {
1110          if (i < s)
1111          {
1112             _printk("%02X", p[i] & 0xFF);
1113          } else
1114          {
1115             _printk("  ");
1116          }
1117          if ((i % 2) == 1) _printk(" ");
1118          if ((i % 8) == 7) _printk(" ");
1119       }
1120       _printk(" |");
1121       for (i = 0;  i < 16;  i++)
1122       {
1123          if (i < s)
1124          {
1125             c = p[i] & 0xFF;
1126             if ((c < 0x20) || (c >= 0x7F)) c = '.';
1127          } else
1128          {
1129             c = ' ';
1130          }
1131          _printk("%c", c);
1132       }
1133       _printk("|\n");
1134       s -= 16;
1135       p += 16;
1136    }
1137 }
1138 
1139 _dump_buf(unsigned char *p, int s)
     /* [previous][next][first][last][top][bottom][index][help] */
1140 {
1141    _dump_buf_with_offset(p, s, 0);
1142 }
1143 
1144 
1145 dump_buf_with_offset(unsigned char *p, int s, unsigned char *base)
     /* [previous][next][first][last][top][bottom][index][help] */
1146 {
1147    int i, c;
1148    if ((unsigned int)s > (unsigned int)p)
1149    {
1150         s = (unsigned int)s - (unsigned int)p;
1151    }
1152    while (s > 0)
1153    {
1154       if (base)
1155       {
1156          printk("%06X: ", (int)p - (int)base);
1157       } else
1158       {
1159          printk("%06X: ", p);
1160       }
1161       for (i = 0;  i < 16;  i++)
1162       {
1163          if (i < s)
1164          {
1165             printk("%02X", p[i] & 0xFF);
1166          } else
1167          {
1168             printk("  ");
1169          }
1170          if ((i % 2) == 1) printk(" ");
1171          if ((i % 8) == 7) printk(" ");
1172       }
1173       printk(" |");
1174       for (i = 0;  i < 16;  i++)
1175       {
1176          if (i < s)
1177          {
1178             c = p[i] & 0xFF;
1179             if ((c < 0x20) || (c >= 0x7F)) c = '.';
1180          } else
1181          {
1182             c = ' ';
1183          }
1184          printk("%c", c);
1185       }
1186       printk("|\n");
1187       s -= 16;
1188       p += 16;
1189    }
1190 }
1191 
1192 dump_buf(unsigned char *p, int s)
     /* [previous][next][first][last][top][bottom][index][help] */
1193 {
1194    dump_buf_with_offset(p, s, 0);
1195 }
1196 
1197 

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