Research V4 development
[unix-history] / sys / dmr / dp.c
CommitLineData
a0afbc8c
DR
1#
2/*
3 * DP-11 Synchronous interface driver
4 */
5
6#include "/sys/nsys/param.h"
7#include "/sys/nsys/conf.h"
8#include "/sys/nsys/user.h"
9#include "/sys/nsys/buf.h"
10
11/* control info */
12struct {
13 char *dp_buf;
14 char *dp_bufp;
15 char *dp_ebufp;
16 char dp_state;
17 char dp_timer;
18 int dp_proc;
19} dp11;
20
21/* device registers */
22struct {
23 int dprcsr;
24 char dprbuf;
25 char dpsyn0;
26 int dptcsr;
27 char dptbuf;
28 char dpsyn1;
29};
30
31/* bits */
32#define ODDPAR 010000
33#define IENABLE 0100
34#define HDUPLX 02
35
36#define CTRANS 0100000
37#define RORUN 040000
38#define RING 020000
39#define DSRDY 010000
40#define CARRIER 04000
41#define DONE 0200
42#define IENABLE 0100
43#define SIENABL 040
44
45#define WRITE 1
46#define READ 0
47
48#define DTRDY 01
49#define RCVACT 04000
50
51#define JDP 3
52#define DPADDR 0174770
53#define DPPRI 5
54
55dpopen(dev, flag)
56{
57 int dptimeout();
58
59 if (dp11.dp_proc!=0 && dp11.dp_proc!=u.u_procp) {
60 u.u_error = ENXIO;
61 return;
62 }
63 dp11.dp_proc = u.u_procp;
64 dp11.dp_state = READ;
65 if (dp11.dp_buf==0) {
66 dp11.dp_buf = getblk(NODEV);
67 dp11.dp_bufp = dp11.dp_buf->b_addr;
68 dp11.dp_timer = 60;
69 timeout(dptimeout, 0, 60);
70 }
71 DPADDR->dpsyn0 = 026;
72 DPADDR->dprcsr = HDUPLX|IENABLE;
73 DPADDR->dptcsr = IENABLE|SIENABL|DTRDY;
74}
75
76dpclose(dev, flag)
77{
78 DPADDR->dprcsr = 0;
79 DPADDR->dptcsr = 0;
80 dp11.dp_timer = 0;
81 dp11.dp_proc = 0;
82 if (dp11.dp_buf != 0) {
83 brelse(dp11.dp_buf);
84 dp11.dp_buf = 0;
85 }
86}
87
88dpread()
89{
90 char *dpbp;
91
92 for(;;) {
93 if(dpwait())
94 return;
95 if (dp11.dp_bufp > dp11.dp_buf->b_addr)
96 break;
97 if (dp11.dp_timer <= 1)
98 return;
99 sleep(&dp11, DPPRI);
100 }
101 if (u.u_count>512)
102 u.u_count = 512;
103 dpbp = dp11.dp_buf->b_addr;
104 while (passc(*dpbp)>=0 && ++dpbp < dp11.dp_bufp);
105}
106
107dpwrite()
108{
109 int c;
110 extern char partab[];
111
112 if (dpwait())
113 return;
114 if (u.u_count>512)
115 u.u_count = 512;
116 dp11.dp_state = WRITE;
117 dp11.dp_ebufp = dp11.dp_bufp = dp11.dp_buf->b_addr;
118 while (cpass(&c)>=0) {
119 c =& 0177;
120 *dp11.dp_ebufp++ = c | ~partab[c]&0200;
121 }
122 dpstart();
123}
124
125dpwait()
126{
127 for(;;) {
128 if ((DPADDR->dptcsr&DSRDY)==0 || dp11.dp_buf==0) {
129 u.u_error = EIO;
130 return(1);
131 }
132 if (dp11.dp_state==READ && (DPADDR->dptcsr&CARRIER)==0)
133 return(0);
134 sleep(&dp11, DPPRI);
135 }
136}
137
138dpstart()
139{
140 dp11.dp_timer = 5;
141 if (dp11.dp_ebufp > dp11.dp_bufp)
142 DPADDR->dptbuf = *dp11.dp_bufp++;
143 else {
144 dp11.dp_bufp = dp11.dp_buf->b_addr;
145 dp11.dp_state = READ;
146 }
147}
148
149dptimeout()
150{
151 if (dp11.dp_timer==0)
152 return;
153 if (--dp11.dp_timer==0) {
154 dpturnaround();
155 dp11.dp_timer = 1;
156 }
157 timeout(dptimeout, 0, 60);
158}
159
160dprint()
161{
162 register int c;
163
164 c = DPADDR->dprbuf & 0177;
165 if (dp11.dp_state==READ) {
166 if ((DPADDR->dprcsr&ODDPAR) == 0)
167 c =| 0200;
168 if (dp11.dp_bufp < dp11.dp_buf->b_addr+512)
169 *dp11.dp_bufp++ = c;
170 }
171}
172
173dpxint()
174{
175 register int dpstat;
176
177 dpstat = DPADDR->dptcsr;
178 DPADDR->dptcsr =& ~(CTRANS|RORUN|RING|DONE);
179 if (dpstat & (CTRANS|RORUN))
180 dpturnaround();
181 else if (dpstat&DONE && dp11.dp_state==WRITE)
182 dpstart();
183}
184
185dpturnaround()
186{
187 dp11.dp_timer = 5;
188 DPADDR->dprcsr =& ~RCVACT;
189 if (dp11.dp_state==WRITE) {
190 dp11.dp_state = READ;
191 dp11.dp_bufp = dp11.dp_buf->b_addr;
192 }
193 wakeup(&dp11);
194}