|
|
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.