home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / sys / i386 / isa / pccons.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-06-29  |  20.9 KB  |  867 lines

  1. /*-
  2.  * Copyright (c) 1990 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * This code is derived from software contributed to Berkeley by
  6.  * William Jolitz and Don Ahn.
  7.  *
  8.  * Redistribution and use in source and binary forms, with or without
  9.  * modification, are permitted provided that the following conditions
  10.  * are met:
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in the
  15.  *    documentation and/or other materials provided with the distribution.
  16.  * 3. All advertising materials mentioning features or use of this software
  17.  *    must display the following acknowledgement:
  18.  *    This product includes software developed by the University of
  19.  *    California, Berkeley and its contributors.
  20.  * 4. Neither the name of the University nor the names of its contributors
  21.  *    may be used to endorse or promote products derived from this software
  22.  *    without specific prior written permission.
  23.  *
  24.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  25.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  28.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  29.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  30.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  31.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  32.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  33.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  34.  * SUCH DAMAGE.
  35.  *
  36.  *    @(#)pccons.c    5.11 (Berkeley) 5/21/91
  37.  */
  38.  
  39. /*
  40.  * code to work keyboard & display for PC-style console
  41.  */
  42. #include "param.h"
  43. #include "conf.h"
  44. #include "ioctl.h"
  45. #include "proc.h"
  46. #include "user.h"
  47. #include "tty.h"
  48. #include "uio.h"
  49. #include "i386/isa/isa_device.h"
  50. #include "callout.h"
  51. #include "systm.h"
  52. #include "kernel.h"
  53. #include "syslog.h"
  54. #include "i386/isa/icu.h"
  55. #include "i386/i386/cons.h"
  56.  
  57. struct    tty pccons;
  58.  
  59. struct    pcconsoftc {
  60.     char    cs_flags;
  61. #define    CSF_ACTIVE    0x1    /* timeout active */
  62. #define    CSF_POLLING    0x2    /* polling for input */
  63.     char    cs_lastc;    /* last char sent */
  64.     int    cs_timo;    /* timeouts since interrupt */
  65.     u_long    cs_wedgecnt;    /* times restarted */
  66. } pcconsoftc;
  67.  
  68. int pcprobe(), pcattach();
  69.  
  70. struct    isa_driver pcdriver = {
  71.     pcprobe, pcattach, "pc",
  72. };
  73.  
  74. #define    COL        80
  75. #define    ROW        25
  76. #define    CHR        2
  77. #define MONO_BASE    0x3B4
  78. #define MONO_BUF    0xfe0B0000
  79. #define CGA_BASE    0x3D4
  80. #define CGA_BUF        0xfe0B8000
  81. #define IOPHYSMEM    0xA0000
  82.  
  83. u_char    color = 0xe ;
  84. static unsigned int addr_6845 = MONO_BASE;
  85. u_short *Crtat = (u_short *)MONO_BUF;
  86. static openf;
  87.  
  88. /*
  89.  * We check the console periodically to make sure
  90.  * that it hasn't wedged.  Unfortunately, if an XOFF
  91.  * is typed on the console, that can't be distinguished
  92.  * from more catastrophic failure.
  93.  */
  94. #define    CN_TIMERVAL    (hz)        /* frequency at which to check cons */
  95. #define    CN_TIMO        (2*60)        /* intervals to allow for output char */
  96.  
  97. int    pcstart();
  98. int    pcparam();
  99. int    ttrstrt();
  100. char    partab[];
  101.  
  102. /*
  103.  * Wait for CP to accept last CP command sent
  104.  * before setting up next command.
  105.  */
  106. #define    waitforlast(timo) { \
  107.     if (pclast) { \
  108.         (timo) = 10000; \
  109.         do \
  110.             uncache((char *)&pclast->cp_unit); \
  111.         while ((pclast->cp_unit&CPTAKE) == 0 && --(timo)); \
  112.     } \
  113. }
  114.  
  115. u_char inb();
  116.  
  117. pcprobe(dev)
  118. struct isa_device *dev;
  119. {
  120.     u_char c;
  121.     int again = 0;
  122.  
  123.     /* Enable interrupts and keyboard controller */
  124.     while (inb(0x64)&2); outb(0x64,0x60);
  125.     while (inb(0x64)&2); outb(0x60,0x4D);
  126.  
  127.     /* Start keyboard stuff RESET */
  128.     while (inb(0x64)&2);    /* wait input ready */
  129.     outb(0x60,0xFF);    /* RESET */
  130.     while((c=inb(0x60))!=0xFA) {
  131.         if ((c == 0xFE) ||  (c == 0xFF)) {
  132.             if(!again)printf("KEYBOARD disconnected: RECONNECT \n");
  133.             while (inb(0x64)&2);    /* wait input ready */
  134.             outb(0x60,0xFF);    /* RESET */
  135.             again = 1;
  136.         }
  137.     }
  138.     /* pick up keyboard reset return code */
  139.     while((c=inb(0x60))!=0xAA);
  140.     return 1;
  141. }
  142.  
  143. pcattach(dev)
  144. struct isa_device *dev;
  145. {
  146.     u_short *cp = Crtat + (CGA_BUF-MONO_BUF)/CHR;
  147.     u_short was;
  148.  
  149.     /* Crtat initialized to point to MONO buffer   */
  150.     /* if not present change to CGA_BUF offset     */
  151.     /* ONLY ADD the difference since locore.s adds */
  152.     /* in the remapped offset at the right time    */
  153.  
  154.     was = *Crtat;
  155.     *Crtat = (u_short) 0xA55A;
  156.     if (*Crtat != 0xA55A)
  157.         printf("<mono>");
  158.     else    printf("<color>");
  159.     *Crtat = was;
  160.     cursor();
  161. }
  162.  
  163. /* ARGSUSED */
  164. #ifdef __STDC__
  165. pcopen(dev_t dev, int flag, int mode, struct proc *p)
  166. #else
  167. pcopen(dev, flag, mode, p)
  168.     dev_t dev;
  169.     int flag, mode;
  170.     struct proc *p;
  171. #endif
  172. {
  173.     register struct tty *tp;
  174.  
  175.     tp = &pccons;
  176.     tp->t_oproc = pcstart;
  177.     tp->t_param = pcparam;
  178.     tp->t_dev = dev;
  179.     openf++;
  180.     if ((tp->t_state & TS_ISOPEN) == 0) {
  181.         tp->t_state |= TS_WOPEN;
  182.         ttychars(tp);
  183.         tp->t_iflag = TTYDEF_IFLAG;
  184.         tp->t_oflag = TTYDEF_OFLAG;
  185.         tp->t_cflag = TTYDEF_CFLAG;
  186.         tp->t_lflag = TTYDEF_LFLAG;
  187.         tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
  188.         pcparam(tp, &tp->t_termios);
  189.         ttsetwater(tp);
  190.     } else if (tp->t_state&TS_XCLUDE && p->p_ucred->cr_uid != 0)
  191.         return (EBUSY);
  192.     tp->t_state |= TS_CARR_ON;
  193.     return ((*linesw[tp->t_line].l_open)(dev, tp));
  194. }
  195.  
  196. pcclose(dev, flag, mode, p)
  197.     dev_t dev;
  198.     int flag, mode;
  199.     struct proc *p;
  200. {
  201.     (*linesw[pccons.t_line].l_close)(&pccons, flag);
  202.     ttyclose(&pccons);
  203.     return(0);
  204. }
  205.  
  206. /*ARGSUSED*/
  207. pcread(dev, uio, flag)
  208.     dev_t dev;
  209.     struct uio *uio;
  210. {
  211.     return ((*linesw[pccons.t_line].l_read)(&pccons, uio, flag));
  212. }
  213.  
  214. /*ARGSUSED*/
  215. pcwrite(dev, uio, flag)
  216.     dev_t dev;
  217.     struct uio *uio;
  218. {
  219.     return ((*linesw[pccons.t_line].l_write)(&pccons, uio, flag));
  220. }
  221.  
  222. /*
  223.  * Got a console receive interrupt -
  224.  * the console processor wants to give us a character.
  225.  * Catch the character, and see who it goes to.
  226.  */
  227. pcrint(dev, irq, cpl)
  228.     dev_t dev;
  229. {
  230.     int c;
  231.  
  232.     c = sgetc(1);
  233.     if (c&0x100) return;
  234.     if (pcconsoftc.cs_flags&CSF_POLLING)
  235.         return;
  236. #ifdef KDB
  237.     if (kdbrintr(c, &pccons))
  238.         return;
  239. #endif
  240.     (*linesw[pccons.t_line].l_rint)(c&0xff, &pccons);
  241. }
  242.  
  243. pcioctl(dev, cmd, data, flag)
  244.     dev_t dev;
  245.     caddr_t data;
  246. {
  247.     register struct tty *tp = &pccons;
  248.     register error;
  249.  
  250.     error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);
  251.     if (error >= 0)
  252.         return (error);
  253.     error = ttioctl(tp, cmd, data, flag);
  254.     if (error >= 0)
  255.         return (error);
  256.     return (ENOTTY);
  257. }
  258.  
  259. int    pcconsintr = 1;
  260. /*
  261.  * Got a console transmission interrupt -
  262.  * the console processor wants another character.
  263.  */
  264. pcxint(dev)
  265.     dev_t dev;
  266. {
  267.     register struct tty *tp;
  268.     register int unit;
  269.  
  270.     if (!pcconsintr)
  271.         return;
  272.     pccons.t_state &= ~TS_BUSY;
  273.     pcconsoftc.cs_timo = 0;
  274.     if (pccons.t_line)
  275.         (*linesw[pccons.t_line].l_start)(&pccons);
  276.     else
  277.         pcstart(&pccons);
  278. }
  279.  
  280. pcstart(tp)
  281.     register struct tty *tp;
  282. {
  283.     register c, s;
  284.  
  285.     s = spltty();
  286.     if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
  287.         goto out;
  288.     do {
  289.     if (tp->t_outq.c_cc <= tp->t_lowat) {
  290.         if (tp->t_state&TS_ASLEEP) {
  291.             tp->t_state &= ~TS_ASLEEP;
  292.             wakeup((caddr_t)&tp->t_outq);
  293.         }
  294.         if (tp->t_wsel) {
  295.             selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
  296.             tp->t_wsel = 0;
  297.             tp->t_state &= ~TS_WCOLL;
  298.         }
  299.     }
  300.     if (tp->t_outq.c_cc == 0)
  301.         goto out;
  302.     c = getc(&tp->t_outq);
  303.     splx(s);
  304.     sput(c,0x7);
  305.     s = spltty();
  306.     } while(1);
  307. out:
  308.     splx(s);
  309. }
  310.  
  311. pccnprobe(cp)
  312.     struct consdev *cp;
  313. {
  314.     int maj;
  315.     extern int pcopen();
  316.  
  317.     /* locate the major number */
  318.     for (maj = 0; maj < nchrdev; maj++)
  319.         if (cdevsw[maj].d_open == pcopen)
  320.             break;
  321.  
  322.     /* initialize required fields */
  323.     cp->cn_dev = makedev(maj, 0);
  324.     cp->cn_tp = &pccons;
  325.     cp->cn_pri = CN_INTERNAL;
  326. }
  327.  
  328. /* ARGSUSED */
  329. pccninit(cp)
  330.     struct consdev *cp;
  331. {
  332.     /*
  333.      * For now, don't screw with it.
  334.      */
  335.     /* crtat = 0; */
  336. }
  337.  
  338. static __color;
  339.  
  340. /* ARGSUSED */
  341. pccnputc(dev, c)
  342.     dev_t dev;
  343.     char c;
  344. {
  345.     int clr = __color;
  346.  
  347.     if (clr == 0)
  348.         clr = 0x30;
  349.     else
  350.         clr |= 0x60;
  351.     if (c == '\n')
  352.         sput('\r', clr);
  353.     sput(c, clr);
  354. }
  355.  
  356. /*
  357.  * Print a character on console.
  358.  */
  359. pcputchar(c, tp)
  360.     char c;
  361.     register struct tty *tp;
  362. {
  363.     sput(c,0x2);
  364.     if (c=='\n') getchar();
  365. }
  366.  
  367.  
  368. /* ARGSUSED */
  369. pccngetc(dev)
  370.     dev_t dev;
  371. {
  372.     register int c, s;
  373.  
  374.     s = spltty();        /* block pcrint while we poll */
  375.     c = sgetc(0);
  376.     if (c == '\r') c = '\n';
  377.     splx(s);
  378.     return (c);
  379. }
  380.  
  381. pcgetchar(tp)
  382.     register struct tty *tp;
  383. {
  384.     int c;
  385.  
  386.     c = sgetc(0);
  387.     return (c&0xff);
  388. }
  389.  
  390. /*
  391.  * Set line parameters
  392.  */
  393. pcparam(tp, t)
  394.     register struct tty *tp;
  395.     register struct termios *t;
  396. {
  397.     register int cflag = t->c_cflag;
  398.         /* and copy to tty */
  399.         tp->t_ispeed = t->c_ispeed;
  400.         tp->t_ospeed = t->c_ospeed;
  401.         tp->t_cflag = cflag;
  402.  
  403.     return(0);
  404. }
  405.  
  406. #ifdef KDB
  407. /*
  408.  * Turn input polling on/off (used by debugger).
  409.  */
  410. pcpoll(onoff)
  411.     int onoff;
  412. {
  413. }
  414. #endif
  415.  
  416. extern int hz;
  417.  
  418. static beeping;
  419. sysbeepstop()
  420. {
  421.     /* disable counter 2 */
  422.     outb(0x61,inb(0x61)&0xFC);
  423.     beeping = 0;
  424. }
  425.  
  426. sysbeep()
  427. {
  428.  
  429.     /* enable counter 2 */
  430.     outb(0x61,inb(0x61)|3);
  431.     /* set command for counter 2, 2 byte write */
  432.     outb(0x43,0xB6);
  433.     /* send 0x637 for 750 HZ */
  434.     outb(0x42,0x37);
  435.     outb(0x42,0x06);
  436.     if(!beeping)timeout(sysbeepstop,0,hz/4);
  437.     beeping = 1;
  438. }
  439.  
  440. /* cursor() sets an offset (0-1999) into the 80x25 text area    */
  441.  
  442. static u_short *crtat = 0;
  443. char bg_at = 0x0f;
  444. char so_at = 0x70;
  445.  
  446. cursor()
  447. {     int pos = crtat - Crtat;
  448.  
  449.     outb(addr_6845,14);
  450.     outb(addr_6845+1,pos >> 8);
  451.     outb(addr_6845,15);
  452.     outb(addr_6845+1,pos&0xff);
  453.     timeout(cursor,0,hz/10);
  454. }
  455.  
  456. u_char shfts, ctls, alts, caps, num, stp, scroll;
  457.  
  458. /*
  459.  * Compensate for abysmally stupid frame buffer aribitration with macro
  460.  */
  461. #define    wrtchar(c) { do *crtat = (c); while ((c) != *crtat); crtat++; row++; }
  462.  
  463. /* sput has support for emulation of the 'ibmpc' termcap entry. */
  464. /* This is a bare-bones implementation of a bare-bones entry    */
  465. /* One modification: Change li#24 to li#25 to reflect 25 lines  */
  466.  
  467. sput(c, ca)
  468. u_char c, ca;
  469. {
  470.  
  471.     static int esc,ebrac,eparm,cx,cy,row,so;
  472.  
  473.     if (crtat == 0) {
  474.         u_short *cp = Crtat + (CGA_BUF-MONO_BUF)/CHR, was;
  475.         unsigned cursorat;
  476.  
  477.         /* Crtat initialized to point to MONO buffer   */
  478.         /* if not present change to CGA_BUF offset     */
  479.         /* ONLY ADD the difference since locore.s adds */
  480.         /* in the remapped offset at the right time    */
  481.  
  482.         was = *cp;
  483.         *cp = (u_short) 0xA55A;
  484.         if (*cp != 0xA55A) {
  485.             addr_6845 = MONO_BASE;
  486.         } else {
  487.             *cp = was;
  488.             addr_6845 = CGA_BASE;
  489.             Crtat = Crtat + (CGA_BUF-MONO_BUF)/CHR;
  490.         }
  491.         /* Extract cursor location */
  492.         outb(addr_6845,14);
  493.         cursorat = inb(addr_6845+1)<<8 ;
  494.         outb(addr_6845,15);
  495.         cursorat |= inb(addr_6845+1);
  496.  
  497.         crtat = Crtat + cursorat;
  498.         fillw((bg_at<<8)|' ', crtat, COL*ROW-cursorat);
  499.     }
  500.     switch(c) {
  501.     case 0x1B:
  502.         esc = 1; ebrac = 0; eparm = 0;
  503.         break;
  504.  
  505.     case '\t':
  506.         do {
  507.             wrtchar((ca<<8)| ' ');
  508.         } while (row % 8);
  509.         break;
  510.  
  511.     case '\010':
  512.         crtat--; row--;
  513.         if (row < 0) row += COL;  /* non-destructive backspace */
  514.         break;
  515.  
  516.     case '\r':
  517.         crtat -= row ; row = 0;
  518.         break;
  519.  
  520.     case '\n':
  521.         crtat += COL ;
  522.         break;
  523.  
  524.     default:
  525.         if (esc) {
  526.             if (ebrac) {
  527.                 switch(c) {
  528.                 case 'm': /* no support for standout */
  529.                     if (!cx) so = 0;
  530.                     else so = 1;
  531.                     esc = 0; ebrac = 0; eparm = 0;
  532.                     break;
  533.                 case 'A': /* back one row */
  534.                     crtat -= COL;
  535.                     esc = 0; ebrac = 0; eparm = 0;
  536.                     break;
  537.                 case 'B': /* down one row */
  538.                     crtat += COL;
  539.                     esc = 0; ebrac = 0; eparm = 0;
  540.                     break;
  541.                 case 'C': /* right cursor */
  542.                     crtat++; row++;
  543.                     esc = 0; ebrac = 0; eparm = 0;
  544.                     break;
  545.                 case 'J': /* Clear to end of display */
  546.                     fillw((bg_at<<8)+' ', crtat,
  547.                         Crtat+COL*ROW-crtat);
  548.                     esc = 0; ebrac = 0; eparm = 0;
  549.                     break;
  550.                 case 'K': /* Clear to EOL */
  551.                     fillw((bg_at<<8)+' ', crtat,
  552.                         COL-(crtat-Crtat)%COL);
  553.                     esc = 0; ebrac = 0; eparm = 0;
  554.                     break;
  555.                 case 'H': /* Cursor move */
  556.                     if ((!cx)||(!cy)) {
  557.                         crtat = Crtat;
  558.                         row = 0;
  559.                     } else {
  560.                         crtat = Crtat+(cx-1)*COL+cy-1;
  561.                         row = cy-1;
  562.                     }
  563.                     esc = 0; ebrac = 0; eparm = 0;
  564.                     break;
  565.                 case ';': /* Switch params in cursor def */
  566.                     eparm = 1;
  567.                     return;
  568.                 default: /* Only numbers valid here */
  569.                     if ((c >= '0')&&(c <= '9')) {
  570.                         if (eparm) {
  571.                             cy *= 10;
  572.                             cy += c - '0';
  573.                         } else {
  574.                             cx *= 10;
  575.                             cx += c - '0';
  576.                         }
  577.                     } else {
  578.                         esc = 0; ebrac = 0; eparm = 0;
  579.                     }
  580.                     return;
  581.                 }
  582.                 break;
  583.             } else if (c == 'c') { /* Clear screen & home */
  584.                 fillw((bg_at<<8)+' ', Crtat,COL*ROW);
  585.                 crtat = Crtat; row = 0;
  586.                 esc = 0; ebrac = 0; eparm = 0;
  587.             } else if (c == '[') { /* Start ESC [ sequence */
  588.                 ebrac = 1; cx = 0; cy = 0; eparm = 0;
  589.             } else { /* Invalid, clear state */
  590.                  esc = 0; ebrac = 0; eparm = 0;
  591.             }
  592.         } else {
  593.             if (c == 7)
  594.                 sysbeep();
  595.             /* Print only printables */
  596.             else /*if (c >= ' ') */ {
  597.                 if (so) {
  598.                     wrtchar((so_at<<8)| c); 
  599.                 } else {
  600.                     wrtchar((ca<<8)| c); 
  601.                 }
  602.                 if (row >= COL) row = 0;
  603.                 break ;
  604.             }
  605.         }
  606.     }
  607.     if (crtat >= Crtat+COL*(ROW)) { /* scroll check */
  608.         if (openf) do sgetc(1); while (scroll);
  609.         bcopy(Crtat+COL,Crtat,COL*(ROW-1)*CHR);
  610.         fillw ((bg_at<<8) + ' ', Crtat+COL*(ROW-1),COL) ;
  611.         crtat -= COL ;
  612.     }
  613. }
  614.  
  615. #define    L        0x0001    /* locking function */
  616. #define    SHF        0x0002    /* keyboard shift */
  617. #define    ALT        0x0004    /* alternate shift -- alternate chars */
  618. #define    NUM        0x0008    /* numeric shift  cursors vs. numeric */
  619. #define    CTL        0x0010    /* control shift  -- allows ctl function */
  620. #define    CPS        0x0020    /* caps shift -- swaps case of letter */
  621. #define    ASCII        0x0040    /* ascii code for this key */
  622. #define    STP        0x0080    /* stop output */
  623. #define    FUNC        0x0100    /* function key */
  624. #define    SCROLL        0x0200    /* scroll lock key */
  625.  
  626. unsigned    __debug = 0; /*0xffe */;
  627. u_short action[] = {
  628. 0,     ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII,        /* scan  0- 7 */
  629. ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII,        /* scan  8-15 */
  630. ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII,        /* scan 16-23 */
  631. ASCII, ASCII, ASCII, ASCII, ASCII,   CTL, ASCII, ASCII,        /* scan 24-31 */
  632. ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII,        /* scan 32-39 */
  633. ASCII, ASCII, SHF  , ASCII, ASCII, ASCII, ASCII, ASCII,        /* scan 40-47 */
  634. ASCII, ASCII, ASCII, ASCII, ASCII, ASCII,  SHF,  ASCII,        /* scan 48-55 */
  635.   ALT, ASCII, CPS  , FUNC , FUNC , FUNC , FUNC , FUNC ,        /* scan 56-63 */
  636. FUNC , FUNC , FUNC , FUNC , FUNC , NUM, SCROLL, ASCII,        /* scan 64-71 */
  637. ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII,        /* scan 72-79 */
  638. ASCII, ASCII, ASCII, ASCII,     0,     0,     0,     0,        /* scan 80-87 */
  639. 0,0,0,0,0,0,0,0,
  640. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  641. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,    } ;
  642.  
  643. u_char unshift[] = {    /* no shift */
  644. 0,     033  , '1'  , '2'  , '3'  , '4'  , '5'  , '6'  ,        /* scan  0- 7 */
  645. '7'  , '8'  , '9'  , '0'  , '-'  , '='  , 0177 ,'\t'  ,        /* scan  8-15 */
  646.  
  647. 'q'  , 'w'  , 'e'  , 'r'  , 't'  , 'y'  , 'u'  , 'i'  ,        /* scan 16-23 */
  648. 'o'  , 'p'  , '['  , ']'  , '\r' , CTL  , 'a'  , 's'  ,        /* scan 24-31 */
  649.  
  650. 'd'  , 'f'  , 'g'  , 'h'  , 'j'  , 'k'  , 'l'  , ';'  ,        /* scan 32-39 */
  651. '\'' , '`'  , SHF  , '\\' , 'z'  , 'x'  , 'c'  , 'v'  ,        /* scan 40-47 */
  652.  
  653. 'b'  , 'n'  , 'm'  , ','  , '.'  , '/'  , SHF  ,   '*',        /* scan 48-55 */
  654. ALT  , ' '  , CPS,     1,     2,    3 ,     4,     5,        /* scan 56-63 */
  655.  
  656.     6,     7,     8,     9,    10, NUM, STP,   '7',        /* scan 64-71 */
  657.   '8',   '9',   '-',   '4',   '5',   '6',   '+',   '1',        /* scan 72-79 */
  658.  
  659.   '2',   '3',   '0',   '.',     0,     0,     0,     0,        /* scan 80-87 */
  660. 0,0,0,0,0,0,0,0,
  661. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  662. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,    } ;
  663.  
  664. u_char shift[] = {    /* shift shift */
  665. 0,     033  , '!'  , '@'  , '#'  , '$'  , '%'  , '^'  ,        /* scan  0- 7 */
  666. '&'  , '*'  , '('  , ')'  , '_'  , '+'  , 0177 ,'\t'  ,        /* scan  8-15 */
  667. 'Q'  , 'W'  , 'E'  , 'R'  , 'T'  , 'Y'  , 'U'  , 'I'  ,        /* scan 16-23 */
  668. 'O'  , 'P'  , '{'  , '}'  , '\r' , CTL  , 'A'  , 'S'  ,        /* scan 24-31 */
  669. 'D'  , 'F'  , 'G'  , 'H'  , 'J'  , 'K'  , 'L'  , ':'  ,        /* scan 32-39 */
  670. '"'  , '~'  , SHF  , '|'  , 'Z'  , 'X'  , 'C'  , 'V'  ,        /* scan 40-47 */
  671. 'B'  , 'N'  , 'M'  , '<'  , '>'  , '?'  , SHF  ,   '*',        /* scan 48-55 */
  672. ALT  , ' '  , CPS,     0,     0, ' '  ,     0,     0,        /* scan 56-63 */
  673.     0,     0,     0,     0,     0, NUM, STP,   '7',        /* scan 64-71 */
  674.   '8',   '9',   '-',   '4',   '5',   '6',   '+',   '1',        /* scan 72-79 */
  675.   '2',   '3',   '0',   '.',     0,     0,     0,     0,        /* scan 80-87 */
  676. 0,0,0,0,0,0,0,0,
  677. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  678. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,    } ;
  679.  
  680. u_char ctl[] = {    /* CTL shift */
  681. 0,     033  , '!'  , 000  , '#'  , '$'  , '%'  , 036  ,        /* scan  0- 7 */
  682. '&'  , '*'  , '('  , ')'  , 037  , '+'  , 034  ,'\177',        /* scan  8-15 */
  683. 021  , 027  , 005  , 022  , 024  , 031  , 025  , 011  ,        /* scan 16-23 */
  684. 017  , 020  , 033  , 035  , '\r' , CTL  , 001  , 023  ,        /* scan 24-31 */
  685. 004  , 006  , 007  , 010  , 012  , 013  , 014  , ';'  ,        /* scan 32-39 */
  686. '\'' , '`'  , SHF  , 034  , 032  , 030  , 003  , 026  ,        /* scan 40-47 */
  687. 002  , 016  , 015  , '<'  , '>'  , '?'  , SHF  ,   '*',        /* scan 48-55 */
  688. ALT  , ' '  , CPS,     0,     0, ' '  ,     0,     0,        /* scan 56-63 */
  689. CPS,     0,     0,     0,     0,     0,     0,     0,        /* scan 64-71 */
  690.     0,     0,     0,     0,     0,     0,     0,     0,        /* scan 72-79 */
  691.     0,     0,     0,     0,     0,     0,     0,     0,        /* scan 80-87 */
  692.     0,     0,   033, '7'  , '4'  , '1'  ,     0, NUM,        /* scan 88-95 */
  693. '8'  , '5'  , '2'  ,     0, STP, '9'  , '6'  , '3'  ,        /*scan  96-103*/
  694. '.'  ,     0, '*'  , '-'  , '+'  ,     0,     0,     0,        /*scan 104-111*/
  695. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,    } ;
  696.  
  697. #ifdef notdef
  698. struct key {
  699.     u_short action;        /* how this key functions */
  700.     char    ascii[8];    /* ascii result character indexed by shifts */
  701. };
  702. #endif
  703.  
  704.  
  705. #define    KBSTAT        0x64    /* kbd status port */
  706. #define    KBS_INP_BUF_FUL    0x02    /* kbd char ready */
  707. #define    KBDATA        0x60    /* kbd data port */
  708. #define    KBSTATUSPORT    0x61    /* kbd status */
  709.  
  710. update_led()
  711. {
  712.     while (inb(0x64)&2);    /* wait input ready */
  713.     outb(0x60,0xED);    /* LED Command */
  714.     while (inb(0x64)&2);    /* wait input ready */
  715.     outb(0x60,scroll | 2*num | 4*caps);
  716. }
  717.  
  718. reset_cpu() {
  719.     while(1) {
  720.         while (inb(0x64)&2);    /* wait input ready */
  721.         outb(0x64,0xFE);    /* Reset Command */
  722.         DELAY(4000000);
  723.         while (inb(0x64)&2);    /* wait input ready */
  724.         outb(0x64,0xFF);    /* Keyboard Reset Command */
  725.     }
  726.     /* NOTREACHED */
  727. }
  728.  
  729. /*
  730. sgetc(noblock) : get a character from the keyboard. If noblock = 0 wait until
  731. a key is gotten.  Otherwise return a 0x100 (256).
  732. */
  733. int sgetc(noblock)
  734. {
  735.     u_char dt; unsigned key;
  736. loop:
  737.     /* First see if there is something in the keyboard port */
  738.     if (inb(KBSTAT)&1) dt = inb(KBDATA);
  739.     else { if (noblock) return (0x100); else goto loop; }
  740.  
  741.     /* Check for cntl-alt-del */
  742.     if ((dt == 83)&&ctls&&alts) _exit();
  743.  
  744.     /* Check for make/break */
  745.     if (dt & 0x80) {
  746.         /* break */
  747.         dt = dt & 0x7f ;
  748.         switch (action[dt]) {
  749.         case SHF: shfts = 0; break;
  750.         case ALT: alts = 0; break;
  751.         case CTL: ctls = 0; break;
  752.         case FUNC:
  753.             /* Toggle debug flags */
  754.             key = unshift[dt];
  755.             if(__debug & (1<<key)) __debug &= ~(1<<key) ;
  756.             else __debug |= (1<<key) ;
  757.             break;
  758.         }
  759.     } else {
  760.         /* make */
  761.         dt = dt & 0x7f ;
  762.         switch (action[dt]) {
  763.         /* LOCKING KEYS */
  764.         case NUM: num ^= 1; update_led(); break;
  765.         case CPS: caps ^= 1; update_led(); break;
  766.         case SCROLL: scroll ^= 1; update_led(); break;
  767.         case STP: stp ^= 1; if(stp) goto loop; break;
  768.  
  769.         /* NON-LOCKING KEYS */
  770.         case SHF: shfts = 1; break;
  771.         case ALT: alts = 1; break;
  772.         case CTL: ctls = 1; break;
  773.         case ASCII:
  774.             if (shfts) dt = shift[dt];
  775.             else if (ctls) dt = ctl[dt];
  776.             else dt = unshift[dt];
  777.             if (caps && (dt >= 'a' && dt <= 'z')) dt -= 'a' - 'A';
  778.             return(dt);
  779.         }
  780.     }
  781.     if (noblock) return (0x100); else goto loop;
  782. }
  783.  
  784. pg(p,q,r,s,t,u,v,w,x,y,z) char *p; {
  785.     printf(p,q,r,s,t,u,v,w,x,y,z);
  786.     printf("\n");
  787.     return(getchar());
  788. }
  789.  
  790. /* special characters */
  791. #define bs    8
  792. #define lf    10    
  793. #define cr    13    
  794. #define cntlc    3    
  795. #define del    0177    
  796. #define cntld    4
  797.  
  798. getchar()
  799. {
  800.     register char thechar;
  801.     register delay;
  802.     int x;
  803.  
  804.     pcconsoftc.cs_flags |= CSF_POLLING;
  805.     x=splhigh();
  806.     sput('>',0x6);
  807.     /*while (1) {*/
  808.         thechar = (char) sgetc(0);
  809.         pcconsoftc.cs_flags &= ~CSF_POLLING;
  810.         splx(x);
  811.         switch (thechar) {
  812.             default: if (thechar >= ' ')
  813.                      sput(thechar,0x6);
  814.                  return(thechar);
  815.             case cr:
  816.             case lf: sput(cr,0x6);
  817.                  sput(lf,0x6);
  818.                  return(lf);
  819.             case bs:
  820.             case del:
  821.                  sput(bs,0x6);
  822.                  sput(' ',0x6);
  823.                  sput(bs,0x6);
  824.                  return(thechar);
  825.             /*case cntlc:
  826.                  sput('^',0xe) ; sput('C',0xe) ; sput('\r',0xe) ; sput('\n',0xe) ;
  827.                  _exit(-2) ; */
  828.             case cntld:
  829.                  sput('^',0x6) ; sput('D',0x6) ; sput('\r',0x6) ; sput('\n',0x6) ;
  830.                  return(0);
  831.         }
  832.     /*}*/
  833. }
  834.  
  835. #include "machine/dbg.h"
  836. #include "machine/stdarg.h"
  837. static nrow;
  838.  
  839. void
  840. #ifdef __STDC__
  841. dprintf(unsigned flgs, const char *fmt, ...)
  842. #else
  843. dprintf(flgs, fmt /*, va_alist */)
  844.         char *fmt;
  845.     unsigned flgs;
  846. #endif
  847. {    extern unsigned __debug;
  848.     va_list ap;
  849.  
  850.     if((flgs&__debug) > DPAUSE) {
  851.         __color = ffs(flgs&__debug)+1;
  852.         va_start(ap,fmt);
  853.         kprintf(fmt, 1, (struct tty *)0, ap);
  854.         va_end(ap);
  855.     if (flgs&DPAUSE || nrow%24 == 23) { 
  856.         int x;
  857.         x = splhigh();
  858.         if (nrow%24 == 23) nrow = 0;
  859.         sgetc(0);
  860.         splx(x);
  861.     }
  862.     }
  863.     __color = 0;
  864. }
  865.  
  866. consinit() {}
  867.