|
|
1.1 ! root 1: /* ! 2: * Line printer driver ! 3: */ ! 4: ! 5: #include "../h/param.h" ! 6: #include "../h/dir.h" ! 7: #include "../h/user.h" ! 8: #include "../h/tty.h" ! 9: #include "../h/uba.h" ! 10: ! 11: struct device *lp_addr[] = { (struct device *)(UBA0_DEV+0177514) }; ! 12: ! 13: #define LPPRI PZERO+10 ! 14: #define LPLOWAT 50 ! 15: #define LPHIWAT 100 ! 16: #define LPMAX 2 ! 17: ! 18: struct device { ! 19: short lpcsr, lpbuf; ! 20: }; ! 21: int lp_cnt = 1; ! 22: ! 23: struct lp { ! 24: struct clist l_outq; ! 25: char flag, ind; ! 26: short ccc, mcc, mlc; ! 27: short line, col; ! 28: } lp_dt[LPMAX]; ! 29: ! 30: #define OPEN 010 ! 31: #define CAP 020 ! 32: #define NOCR 040 ! 33: #define ASLP 0100 ! 34: ! 35: #define FORM 014 ! 36: ! 37: lpopen(dev, flag) ! 38: { ! 39: register unit; ! 40: register struct lp *lp; ! 41: ! 42: unit = dev&07; ! 43: if (unit >= lp_cnt || unit >= LPMAX || ! 44: (lp = &lp_dt[unit])->flag || lp_addr[unit]->lpcsr <0 ) { ! 45: u.u_error = EIO; ! 46: return; ! 47: } ! 48: lp->flag = (dev&077)|OPEN; ! 49: lp->ind = 4; ! 50: lp->col = 80; ! 51: lp->line = 66; ! 52: lp_addr[unit]->lpcsr |= IENABLE; ! 53: lpoutput(unit, FORM); ! 54: } ! 55: ! 56: lpclose(dev) ! 57: { ! 58: register unit; ! 59: ! 60: unit = dev&07; ! 61: lpoutput(unit, FORM); ! 62: lp_dt[unit].flag = 0; ! 63: } ! 64: ! 65: lpwrite(dev) ! 66: { ! 67: register c; ! 68: ! 69: while ((c=cpass())>=0) ! 70: lpoutput(dev&07, c); ! 71: } ! 72: ! 73: lpoutput(dev, c) ! 74: register dev, c; ! 75: { ! 76: register struct lp *lp; ! 77: ! 78: lp = &lp_dt[dev]; ! 79: if(lp->flag&CAP) { ! 80: if(c>='a' && c<='z') ! 81: c += 'A'-'a'; else ! 82: switch(c) { ! 83: case '{': ! 84: c = '('; ! 85: goto esc; ! 86: case '}': ! 87: c = ')'; ! 88: goto esc; ! 89: case '`': ! 90: c = '\''; ! 91: goto esc; ! 92: case '|': ! 93: c = '!'; ! 94: goto esc; ! 95: case '~': ! 96: c = '^'; ! 97: esc: ! 98: lpoutput(dev, c); ! 99: lp->ccc--; ! 100: c = '-'; ! 101: } ! 102: } ! 103: switch(c) { ! 104: case '\t': ! 105: lp->ccc = ((lp->ccc+8-lp->ind) & ~7) + lp->ind; ! 106: return; ! 107: case '\n': ! 108: lp->mlc++; ! 109: if(lp->mlc >= lp->line ) ! 110: c = FORM; ! 111: case FORM: ! 112: lp->mcc = 0; ! 113: if (lp->mlc) { ! 114: lpputc(dev, c); ! 115: if(c == FORM) ! 116: lp->mlc = 0; ! 117: } ! 118: case '\r': ! 119: lp->ccc = lp->ind; ! 120: return; ! 121: case 010: ! 122: if(lp->ccc > lp->ind) ! 123: lp->ccc--; ! 124: return; ! 125: case ' ': ! 126: lp->ccc++; ! 127: return; ! 128: default: ! 129: if(lp->ccc < lp->mcc) { ! 130: if (lp->flag&NOCR) { ! 131: lp->ccc++; ! 132: return; ! 133: } ! 134: lpputc(dev, '\r'); ! 135: lp->mcc = 0; ! 136: } ! 137: if(lp->ccc < lp->col) { ! 138: while(lp->ccc > lp->mcc) { ! 139: lpputc(dev, ' '); ! 140: lp->mcc++; ! 141: } ! 142: lpputc(dev, c); ! 143: lp->mcc++; ! 144: } ! 145: lp->ccc++; ! 146: } ! 147: } ! 148: ! 149: lpputc(dev, c) ! 150: register dev, c; ! 151: { ! 152: register struct lp *lp; ! 153: ! 154: lp = &lp_dt[dev]; ! 155: spl4(); ! 156: while (lp->l_outq.c_cc > LPHIWAT) { ! 157: lp->flag |= ASLP; ! 158: sleep(lp, LPPRI); ! 159: } ! 160: putc(c, &lp->l_outq); ! 161: lpintr(dev); ! 162: spl0(); ! 163: } ! 164: ! 165: lpintr(dev) ! 166: register dev; ! 167: { ! 168: register struct lp *lp; ! 169: register c; ! 170: ! 171: lp = &lp_dt[dev]; ! 172: while (lp_addr[dev]->lpcsr&DONE && (c = getc(&lp->l_outq)) >= 0) ! 173: lp_addr[dev]->lpbuf = c; ! 174: if (lp->l_outq.c_cc <= LPLOWAT && lp->flag&ASLP) { ! 175: lp->flag &= ~ASLP; ! 176: wakeup(lp); ! 177: } ! 178: } ! 179: ! 180: lpioctl(dev, cmd, addr, flag) ! 181: register caddr_t addr; ! 182: { ! 183: register int m; ! 184: struct lp *lp; ! 185: struct {char lsg_flag, lsg_ind; short lsg_line, lsg_col;} lpios; ! 186: ! 187: lp = &lp_dt[dev]; ! 188: switch (cmd) { ! 189: ! 190: case ('v'<<8)+0: ! 191: lpios.lsg_flag = lp->flag; ! 192: lpios.lsg_ind = lp->ind; ! 193: lpios.lsg_line = lp->line; ! 194: lpios.lsg_col = lp->col; ! 195: copyout(&lpios, addr, sizeof lpios); ! 196: return; ! 197: ! 198: case ('v'<<8)+1: ! 199: m = copyin(addr, &lpios, sizeof lpios); ! 200: if (m == -1) { ! 201: u.u_error = EFAULT; ! 202: return; ! 203: } ! 204: lp->flag = lpios.lsg_flag; ! 205: lp->ind = lpios.lsg_ind; ! 206: lp->line = lpios.lsg_line; ! 207: lp->col = lpios.lsg_col; ! 208: return; ! 209: ! 210: default: ! 211: u.u_error = ENOTTY; ! 212: return; ! 213: } ! 214: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.