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