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. s
  9. NS16550_init
  10. c
  11. c
  12. _cnpause
  13. _disable_interrupts
  14. _printk
  15. _printk
  16. abort
  17. s
  18. _disable_interrupts
  19. printk
  20. printk
  21. s
  22. video_on
  23. CRT_init
  24. kbd
  25. scankbd
  26. kbdreset
  27. CRT_getc
  28. CRT_test
  29. _dump_buf_with_offset
  30. _dump_buf
  31. dump_buf_with_offset
  32. dump_buf

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

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