added my responsibility for the `cpm' port
[unix-history] / sys / i386 / isa / pccons.c
index 8267af6..ca5621f 100644 (file)
@@ -34,7 +34,7 @@
  * SUCH DAMAGE.
  *
  *     from: @(#)pccons.c      5.11 (Berkeley) 5/21/91
  * SUCH DAMAGE.
  *
  *     from: @(#)pccons.c      5.11 (Berkeley) 5/21/91
- *     $Id: pccons.c,v 1.9 1993/11/25 01:31:46 wollman Exp $
+ *     $Id: pccons.c,v 1.16 1994/05/03 19:38:49 davidg Exp $
  */
 
 /*
  */
 
 /*
@@ -63,7 +63,7 @@
 int pc_xmode;
 #endif /* XSERVER */
 
 int pc_xmode;
 #endif /* XSERVER */
 
-struct tty pccons;
+struct tty *pccons;
 
 struct pcconsoftc {
        char    cs_flags;
 
 struct pcconsoftc {
        char    cs_flags;
@@ -289,13 +289,12 @@ pcopen(dev, flag, mode, p)
 
        if (minor(dev) != 0)
                return (ENXIO);
 
        if (minor(dev) != 0)
                return (ENXIO);
-       tp = &pccons;
+       tp = pccons = ttymalloc(pccons);
        tp->t_oproc = pcstart;
        tp->t_param = pcparam;
        tp->t_dev = dev;
        openf++;
        if ((tp->t_state & TS_ISOPEN) == 0) {
        tp->t_oproc = pcstart;
        tp->t_param = pcparam;
        tp->t_dev = dev;
        openf++;
        if ((tp->t_state & TS_ISOPEN) == 0) {
-               tp->t_state |= TS_WOPEN;
                ttychars(tp);
                tp->t_iflag = TTYDEF_IFLAG;
                tp->t_oflag = TTYDEF_OFLAG;
                ttychars(tp);
                tp->t_iflag = TTYDEF_IFLAG;
                tp->t_oflag = TTYDEF_OFLAG;
@@ -316,8 +315,12 @@ pcclose(dev, flag, mode, p)
        int flag, mode;
        struct proc *p;
 {
        int flag, mode;
        struct proc *p;
 {
-       (*linesw[pccons.t_line].l_close)(&pccons, flag);
-       ttyclose(&pccons);
+       (*linesw[pccons->t_line].l_close)(pccons, flag);
+       ttyclose(pccons);
+#ifdef broken /* session holds a ref to the tty; can't deallocate */
+       ttyfree(pccons);
+       pccons = (struct tty *)NULL;
+#endif
        return(0);
 }
 
        return(0);
 }
 
@@ -328,7 +331,7 @@ pcread(dev, uio, flag)
        struct uio *uio;
        int flag;
 {
        struct uio *uio;
        int flag;
 {
-       return ((*linesw[pccons.t_line].l_read)(&pccons, uio, flag));
+       return ((*linesw[pccons->t_line].l_read)(pccons, uio, flag));
 }
 
 /*ARGSUSED*/
 }
 
 /*ARGSUSED*/
@@ -338,7 +341,7 @@ pcwrite(dev, uio, flag)
        struct uio *uio;
        int flag;
 {
        struct uio *uio;
        int flag;
 {
-       return ((*linesw[pccons.t_line].l_write)(&pccons, uio, flag));
+       return ((*linesw[pccons->t_line].l_write)(pccons, uio, flag));
 }
 
 /*
 }
 
 /*
@@ -347,10 +350,8 @@ pcwrite(dev, uio, flag)
  * Catch the character, and see who it goes to.
  */
 void
  * Catch the character, and see who it goes to.
  */
 void
-pcrint(dev, irq, cpl)
-       dev_t dev;
-       int irq;                /* XXX ??? */
-       int cpl;
+pcrint(unit)
+       int unit;
 {
        int c;
        char *cp;
 {
        int c;
        char *cp;
@@ -361,7 +362,7 @@ pcrint(dev, irq, cpl)
        if (pcconsoftc.cs_flags & CSF_POLLING)
                return;
 #ifdef KDB
        if (pcconsoftc.cs_flags & CSF_POLLING)
                return;
 #ifdef KDB
-       if (kdbrintr(c, &pccons))
+       if (kdbrintr(c, pccons))
                return;
 #endif
        if (!openf)
                return;
 #endif
        if (!openf)
@@ -369,11 +370,11 @@ pcrint(dev, irq, cpl)
 
 #ifdef XSERVER                                         /* 15 Aug 92*/
        /* send at least one character, because cntl-space is a null */
 
 #ifdef XSERVER                                         /* 15 Aug 92*/
        /* send at least one character, because cntl-space is a null */
-       (*linesw[pccons.t_line].l_rint)(*cp++ & 0xff, &pccons);
+       (*linesw[pccons->t_line].l_rint)(*cp++ & 0xff, pccons);
 #endif /* XSERVER */
 
        while (*cp)
 #endif /* XSERVER */
 
        while (*cp)
-               (*linesw[pccons.t_line].l_rint)(*cp++ & 0xff, &pccons);
+               (*linesw[pccons->t_line].l_rint)(*cp++ & 0xff, pccons);
 }
 
 #ifdef XSERVER                                         /* 15 Aug 92*/
 }
 
 #ifdef XSERVER                                         /* 15 Aug 92*/
@@ -389,7 +390,7 @@ pcioctl(dev, cmd, data, flag)
        caddr_t data;
        int flag;
 {
        caddr_t data;
        int flag;
 {
-       register struct tty *tp = &pccons;
+       register struct tty *tp = pccons;
        register error;
 
 #ifdef XSERVER                                         /* 15 Aug 92*/
        register error;
 
 #ifdef XSERVER                                         /* 15 Aug 92*/
@@ -436,12 +437,12 @@ pcxint(dev)
 
        if (!pcconsintr)
                return;
 
        if (!pcconsintr)
                return;
-       pccons.t_state &= ~TS_BUSY;
+       pccons->t_state &= ~TS_BUSY;
        pcconsoftc.cs_timo = 0;
        pcconsoftc.cs_timo = 0;
-       if (pccons.t_line)
-               (*linesw[pccons.t_line].l_start)(&pccons);
+       if (pccons->t_line)
+               (*linesw[pccons->t_line].l_start)(pccons);
        else
        else
-               pcstart(&pccons);
+               pcstart(pccons);
 }
 
 void
 }
 
 void
@@ -454,20 +455,11 @@ pcstart(tp)
        if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
                goto out;
        do {
        if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
                goto out;
        do {
-       if (RB_LEN(&tp->t_out) <= tp->t_lowat) {
-               if (tp->t_state&TS_ASLEEP) {
-                       tp->t_state &= ~TS_ASLEEP;
-                       wakeup((caddr_t)&tp->t_out);
-               }
-               if (tp->t_wsel) {
-                       selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
-                       tp->t_wsel = 0;
-                       tp->t_state &= ~TS_WCOLL;
-               }
-       }
-       if (RB_LEN(&tp->t_out) == 0)
+       if (tp->t_state & (TS_SO_OCOMPLETE | TS_SO_OLOWAT) || tp->t_wsel)
+               ttwwakeup(tp);
+       if (RB_LEN(tp->t_out) == 0)
                goto out;
                goto out;
-       c = getc(&tp->t_out);
+       c = getc(tp->t_out);
        tp->t_state |= TS_BUSY;                         /* 21 Aug 92*/
        splx(s);
        sput(c, 0);
        tp->t_state |= TS_BUSY;                         /* 21 Aug 92*/
        splx(s);
        sput(c, 0);
@@ -491,7 +483,7 @@ pccnprobe(cp)
 
        /* initialize required fields */
        cp->cn_dev = makedev(maj, 0);
 
        /* initialize required fields */
        cp->cn_dev = makedev(maj, 0);
-       cp->cn_tp = &pccons;
+       cp->cn_tp = pccons;
        cp->cn_pri = CN_INTERNAL;
 }
 
        cp->cn_pri = CN_INTERNAL;
 }
 
@@ -639,11 +631,13 @@ static u_char shift_down, ctrl_down, alt_down, caps, num, scroll;
 /* translate ANSI color codes to standard pc ones */
 static char fgansitopc[] =
 {      FG_BLACK, FG_RED, FG_GREEN, FG_BROWN, FG_BLUE,
 /* translate ANSI color codes to standard pc ones */
 static char fgansitopc[] =
 {      FG_BLACK, FG_RED, FG_GREEN, FG_BROWN, FG_BLUE,
-       FG_MAGENTA, FG_CYAN, FG_LIGHTGREY};
+       FG_MAGENTA, FG_CYAN, FG_LIGHTGREY
+};
 
 static char bgansitopc[] =
 {      BG_BLACK, BG_RED, BG_GREEN, BG_BROWN, BG_BLUE,
 
 static char bgansitopc[] =
 {      BG_BLACK, BG_RED, BG_GREEN, BG_BROWN, BG_BLUE,
-       BG_MAGENTA, BG_CYAN, BG_LIGHTGREY};
+       BG_MAGENTA, BG_CYAN, BG_LIGHTGREY
+};
 
 /*
  *   sput has support for emulation of the 'pc3' termcap entry.
 
 /*
  *   sput has support for emulation of the 'pc3' termcap entry.
@@ -707,7 +701,7 @@ sput(c,  ka)
                }
                vs.kern_bg_at = BG_BLACK;
 
                }
                vs.kern_bg_at = BG_BLACK;
 
-               fillw(((vs.bg_at|vs.fg_at)<<8)|' ', (caddr_t)crtat,
+               fillw(((vs.bg_at|vs.fg_at)<<8)|' ', crtat,
                      COL*ROW-cursorat);
        }
 
                      COL*ROW-cursorat);
        }
 
@@ -754,7 +748,9 @@ sput(c,  ka)
                if (vs.esc) {
                        if (vs.ebrac) {
                                switch(c) {
                if (vs.esc) {
                        if (vs.ebrac) {
                                switch(c) {
-                                       int pos;
+                                       int pos, posy, count;
+                                       u_short *src, *dst;
+
                                case 'm':
                                        if (!vs.cx) vs.so = 0;
                                        else vs.so = 1;
                                case 'm':
                                        if (!vs.cx) vs.so = 0;
                                        else vs.so = 1;
@@ -806,17 +802,17 @@ sput(c,  ka)
                                        if (vs.cx == 0)
                                                /* ... to end of display */
                                                fillw((at << 8) + ' ',
                                        if (vs.cx == 0)
                                                /* ... to end of display */
                                                fillw((at << 8) + ' ',
-                                                       (caddr_t)crtat,
+                                                       crtat,
                                                        Crtat + vs.ncol * vs.nrow - crtat);
                                        else if (vs.cx == 1)
                                                /* ... to next location */
                                                fillw((at << 8) + ' ',
                                                        Crtat + vs.ncol * vs.nrow - crtat);
                                        else if (vs.cx == 1)
                                                /* ... to next location */
                                                fillw((at << 8) + ' ',
-                                                       (caddr_t)Crtat,
+                                                       Crtat,
                                                        crtat - Crtat + 1);
                                        else if (vs.cx == 2)
                                                /* ... whole display */
                                                fillw((at << 8) + ' ',
                                                        crtat - Crtat + 1);
                                        else if (vs.cx == 2)
                                                /* ... whole display */
                                                fillw((at << 8) + ' ',
-                                                     (caddr_t)Crtat,
+                                                       Crtat,
                                                        vs.ncol * vs.nrow);
                                                
                                        vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
                                                        vs.ncol * vs.nrow);
                                                
                                        vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
@@ -825,17 +821,17 @@ sput(c,  ka)
                                        if (vs.cx == 0)
                                                /* ... current to EOL */
                                                fillw((at << 8) + ' ',
                                        if (vs.cx == 0)
                                                /* ... current to EOL */
                                                fillw((at << 8) + ' ',
-                                                       (caddr_t)crtat,
+                                                       crtat,
                                                        vs.ncol - (crtat - Crtat) % vs.ncol);
                                        else if (vs.cx == 1)
                                                /* ... beginning to next */
                                                fillw((at << 8) + ' ',
                                                        vs.ncol - (crtat - Crtat) % vs.ncol);
                                        else if (vs.cx == 1)
                                                /* ... beginning to next */
                                                fillw((at << 8) + ' ',
-                                                       (caddr_t)crtat - (crtat - Crtat) % vs.ncol,
+                                                       crtat - (crtat - Crtat) % vs.ncol,
                                                        ((crtat - Crtat) % vs.ncol) + 1);
                                        else if (vs.cx == 2)
                                                /* ... entire line */
                                                fillw((at << 8) + ' ',
                                                        ((crtat - Crtat) % vs.ncol) + 1);
                                        else if (vs.cx == 2)
                                                /* ... entire line */
                                                fillw((at << 8) + ' ',
-                                                     (caddr_t)crtat - (crtat - Crtat) % vs.ncol,
+                                                       crtat - (crtat - Crtat) % vs.ncol,
                                                        vs.ncol);
                                        vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
                                        break;
                                                        vs.ncol);
                                        vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
                                        break;
@@ -852,21 +848,51 @@ sput(c,  ka)
                                        break;
                                case 'S':  /* scroll up cx lines */
                                        if (vs.cx <= 0) vs.cx = 1;
                                        break;
                                case 'S':  /* scroll up cx lines */
                                        if (vs.cx <= 0) vs.cx = 1;
-                                       bcopy(Crtat+vs.ncol*vs.cx, Crtat, vs.ncol*(vs.nrow-vs.cx)*CHR);
+                                       posy = (crtat - Crtat) / vs.ncol;
+                                       if (vs.cx > posy)
+                                               vs.cx = posy;
+                                       bcopyw(Crtat+vs.ncol*vs.cx, Crtat, vs.ncol*(vs.nrow-vs.cx)*CHR);
                                        fillw((at <<8)+' ',
                                        fillw((at <<8)+' ',
-                                             ((caddr_t) Crtat
-                                              + vs.ncol * (vs.nrow - vs.cx)),
-                                             vs.ncol * vs.cx);
+                                               (Crtat + vs.ncol * (vs.nrow - vs.cx)),
+                                               vs.ncol * vs.cx);
                                        /* crtat -= vs.ncol*vs.cx;*/ /* XXX */
                                        vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
                                        break;
                                case 'T':  /* scroll down cx lines */
                                        if (vs.cx <= 0) vs.cx = 1;
                                        /* crtat -= vs.ncol*vs.cx;*/ /* XXX */
                                        vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
                                        break;
                                case 'T':  /* scroll down cx lines */
                                        if (vs.cx <= 0) vs.cx = 1;
-                                       bcopy(Crtat, Crtat+vs.ncol*vs.cx, vs.ncol*(vs.nrow-vs.cx)*CHR);
-                                       fillw((at <<8)+' ', (caddr_t)Crtat, vs.ncol*vs.cx);
+                                       posy = (crtat - Crtat) / vs.ncol;
+                                       if (vs.cx > vs.nrow - posy)
+                                               vs.cx = vs.nrow - posy;
+                                       bcopyw(Crtat, Crtat+vs.ncol*vs.cx, vs.ncol*(vs.nrow-vs.cx)*CHR);
+                                       fillw((at <<8)+' ', Crtat, vs.ncol*vs.cx);
                                        /* crtat += vs.ncol*vs.cx;*/ /* XXX */
                                        vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
                                        break;
                                        /* crtat += vs.ncol*vs.cx;*/ /* XXX */
                                        vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
                                        break;
+                               case 'L':       /* Insert cx lines */
+                                       if (vs.cx <= 0) vs.cx = 1;
+                                       posy = (crtat - Crtat) / vs.ncol;
+                                       if (vs.cx > vs.nrow - posy)
+                                               vs.cx = vs.nrow - posy;
+                                       src = Crtat + posy * vs.ncol;
+                                       dst = src + vs.cx * vs.ncol;
+                                       count = vs.nrow - (posy + vs.cx);
+                                       bcopyw(src, dst, count * vs.ncol * CHR);
+                                       fillw((at <<8)+' ', src, vs.cx * vs.ncol);
+                                       vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
+                                       break;
+                               case 'M':       /* Delete cx lines */
+                                       if (vs.cx <= 0) vs.cx = 1;
+                                       posy = (crtat - Crtat) / vs.ncol;
+                                       if (vs.cx > vs.nrow - posy)
+                                               vs.cx = vs.nrow - posy;
+                                       dst = Crtat + posy * vs.ncol;
+                                       src = dst + vs.cx * vs.ncol;
+                                       count = vs.nrow - (posy + vs.cx);
+                                       bcopyw(src, dst, count * vs.ncol * CHR);
+                                       src = dst + count * vs.ncol;
+                                       fillw((at <<8)+' ', src, vs.cx * vs.ncol);
+                                       vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
+                                       break;
                                case ';': /* Switch params in cursor def */
                                        vs.eparm = 1;
                                        break;
                                case ';': /* Switch params in cursor def */
                                        vs.eparm = 1;
                                        break;
@@ -928,7 +954,7 @@ sput(c,  ka)
                                }
                                break;
                        } else if (c == 'c') { /* Clear screen & home */
                                }
                                break;
                        } else if (c == 'c') { /* Clear screen & home */
-                               fillw((at << 8) + ' ', (caddr_t)Crtat, vs.ncol*vs.nrow);
+                               fillw((at << 8) + ' ', Crtat, vs.ncol*vs.nrow);
                                crtat = Crtat; vs.col = 0;
                                vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
                        } else if (c == '[') { /* Start ESC [ sequence */
                                crtat = Crtat; vs.col = 0;
                                vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
                        } else if (c == '[') { /* Start ESC [ sequence */
@@ -952,8 +978,8 @@ sput(c,  ka)
        }
        if (sc && crtat >= Crtat+vs.ncol*vs.nrow) { /* scroll check */
                if (openf) do (void)sgetc(1); while (scroll);
        }
        if (sc && crtat >= Crtat+vs.ncol*vs.nrow) { /* scroll check */
                if (openf) do (void)sgetc(1); while (scroll);
-               bcopy(Crtat+vs.ncol, Crtat, vs.ncol*(vs.nrow-1)*CHR);
-               fillw ((at << 8) + ' ', (caddr_t)Crtat + vs.ncol*(vs.nrow-1),
+               bcopyw(Crtat+vs.ncol, Crtat, vs.ncol*(vs.nrow-1)*CHR);
+               fillw ((at << 8) + ' ', Crtat + vs.ncol*(vs.nrow-1),
                        vs.ncol);
                crtat -= vs.ncol;
        }
                        vs.ncol);
                crtat -= vs.ncol;
        }
@@ -1510,6 +1536,12 @@ loop:
 #endif /* !XSERVER*/
        }
 
 #endif /* !XSERVER*/
        }
 
+       /*
+        *   Check for cntl-alt-del
+        */
+       if ((dt == 83) && ctrl_down && alt_down)
+               cpu_reset();
+
 #include "ddb.h"
 #if NDDB > 0
        /*
 #include "ddb.h"
 #if NDDB > 0
        /*
@@ -1517,7 +1549,7 @@ loop:
         */
        if ((dt == 1) && ctrl_down && alt_down) {
                Debugger("manual escape to debugger");
         */
        if ((dt == 1) && ctrl_down && alt_down) {
                Debugger("manual escape to debugger");
-               dt |= 0x80;     /* discard esc (ddb discarded ctrl-alt) */
+               goto loop;
        }
 #endif
 
        }
 #endif
 
@@ -1750,7 +1782,7 @@ void cons_normal()
 
 int pcmmap(dev_t dev, int offset, int nprot)
 {
 
 int pcmmap(dev_t dev, int offset, int nprot)
 {
-       if (offset > 0x20000)
+       if (offset > 0x20000 - PAGE_SIZE)
                return -1;
        return i386_btop((0xa0000 + offset));
 }
                return -1;
        return i386_btop((0xa0000 + offset));
 }
@@ -1762,20 +1794,20 @@ int pcmmap(dev_t dev, int offset, int nprot)
 static void
 pc_xmode_on (void)
 {
 static void
 pc_xmode_on (void)
 {
-       struct syscframe *fp;
+       struct trapframe *fp;
 
        if (pc_xmode)
                return;
        pc_xmode = 1;
 
 
        if (pc_xmode)
                return;
        pc_xmode = 1;
 
-       fp = (struct syscframe *)curproc->p_regs;
-       fp->sf_eflags |= PSL_IOPL;
+       fp = (struct trapframe *)curproc->p_regs;
+       fp->tf_eflags |= PSL_IOPL;
 }
 
 static void
 pc_xmode_off ()
 {
 }
 
 static void
 pc_xmode_off ()
 {
-       struct syscframe *fp;
+       struct trapframe *fp;
 
        if (pc_xmode == 0)
                return;
 
        if (pc_xmode == 0)
                return;
@@ -1783,8 +1815,8 @@ pc_xmode_off ()
 
        cursor(0, 0);
 
 
        cursor(0, 0);
 
-       fp = (struct syscframe *)curproc->p_regs;
-       fp->sf_eflags &= ~PSL_IOPL;
+       fp = (struct trapframe *)curproc->p_regs;
+       fp->tf_eflags &= ~PSL_IOPL;
 }
 #endif /* XSERVER*/
 
 }
 #endif /* XSERVER*/