Commit | Line | Data |
---|---|---|
b74a9dc6 DR |
1 | # |
2 | /* | |
3 | * Copyright 1973 Bell Telephone Laboratories Inc | |
4 | */ | |
5 | ||
6 | /* | |
7 | * TC-11 DECtape driver | |
8 | */ | |
9 | ||
10 | #include "../param.h" | |
11 | #include "../conf.h" | |
12 | #include "../buf.h" | |
13 | #include "../user.h" | |
14 | ||
15 | struct { | |
16 | int tccsr; | |
17 | int tccm; | |
18 | int tcwc; | |
19 | int tcba; | |
20 | int tcdt; | |
21 | }; | |
22 | ||
23 | struct devtab tctab; | |
24 | ||
25 | #define TCADDR 0177340 | |
26 | #define NTCBLK 578 | |
27 | ||
28 | #define TAPERR 0100000 | |
29 | #define TREV 04000 | |
30 | #define READY 0200 | |
31 | #define IENABLE 0100 | |
32 | #define UPS 0200 | |
33 | #define ENDZ 0100000 | |
34 | #define BLKM 02000 | |
35 | #define ILGOP 010000 | |
36 | #define SELERR 04000 | |
37 | ||
38 | #define SAT 0 | |
39 | #define RNUM 02 | |
40 | #define RDATA 04 | |
41 | #define SST 010 | |
42 | #define WDATA 014 | |
43 | #define GO 01 | |
44 | ||
45 | #define SFORW 1 | |
46 | #define SREV 2 | |
47 | #define SIO 3 | |
48 | ||
49 | tcclose(dev) | |
50 | { | |
51 | bflush(dev); | |
52 | } | |
53 | ||
54 | tcstrategy(abp) | |
55 | struct buf *abp; | |
56 | { | |
57 | register struct buf *bp; | |
58 | ||
59 | bp = abp; | |
60 | if(bp->b_blkno >= NTCBLK) { | |
61 | bp->b_flags =| B_ERROR; | |
62 | iodone(bp); | |
63 | return; | |
64 | } | |
65 | bp->av_forw = 0; | |
66 | spl6(); | |
67 | if (tctab.d_actf==0) | |
68 | tctab.d_actf = bp; | |
69 | else | |
70 | tctab.d_actl->av_forw = bp; | |
71 | tctab.d_actl = bp; | |
72 | if (tctab.d_active==0) | |
73 | tcstart(); | |
74 | spl0(); | |
75 | } | |
76 | ||
77 | tcstart() | |
78 | { | |
79 | register struct buf *bp; | |
80 | register int *tccmp, com; | |
81 | ||
82 | if ((bp = tctab.d_actf) == 0) | |
83 | return; | |
84 | tccmp = &TCADDR->tccm; | |
85 | if (((*tccmp).hibyte&07) != bp->b_dev.d_minor) | |
86 | (*tccmp).lobyte = SAT|GO; | |
87 | tctab.d_errcnt = 20; | |
88 | tctab.d_active = SFORW; | |
89 | com = (bp->b_dev.d_minor<<8) | IENABLE|RNUM|GO; | |
90 | if ((TCADDR->tccsr & UPS) == 0) { | |
91 | com =| TREV; | |
92 | tctab.d_active = SREV; | |
93 | } | |
94 | *tccmp = com; | |
95 | } | |
96 | ||
97 | tcintr() | |
98 | { | |
99 | register struct buf *bp; | |
100 | register int *tccmp; | |
101 | register int *tcdtp; | |
102 | ||
103 | tccmp = &TCADDR->tccm; | |
104 | tcdtp = &TCADDR->tccsr; | |
105 | bp = tctab.d_actf; | |
106 | if (*tccmp&TAPERR) { | |
107 | if((*tcdtp & (ENDZ|BLKM)) == 0) | |
108 | deverror(bp, *tcdtp); | |
109 | if(*tcdtp & (ILGOP|SELERR)) | |
110 | tctab.d_errcnt = 0; | |
111 | *tccmp =& ~TAPERR; | |
112 | if (--tctab.d_errcnt <= 0) { | |
113 | bp->b_flags =| B_ERROR; | |
114 | goto done; | |
115 | } | |
116 | if (*tccmp&TREV) { | |
117 | setforw: | |
118 | tctab.d_active = SFORW; | |
119 | *tccmp =& ~TREV; | |
120 | } else { | |
121 | setback: | |
122 | tctab.d_active = SREV; | |
123 | *tccmp =| TREV; | |
124 | } | |
125 | (*tccmp).lobyte = IENABLE|RNUM|GO; | |
126 | return; | |
127 | } | |
128 | tcdtp = &TCADDR->tcdt; | |
129 | switch (tctab.d_active) { | |
130 | ||
131 | case SIO: | |
132 | done: | |
133 | tctab.d_active = 0; | |
134 | if (tctab.d_actf = bp->av_forw) | |
135 | tcstart(); | |
136 | else | |
137 | TCADDR->tccm.lobyte = SAT|GO; | |
138 | iodone(bp); | |
139 | return; | |
140 | ||
141 | case SFORW: | |
142 | if (*tcdtp > bp->b_blkno) | |
143 | goto setback; | |
144 | if (*tcdtp < bp->b_blkno) | |
145 | goto setforw; | |
146 | *--tcdtp = bp->b_addr; /* core address */ | |
147 | *--tcdtp = bp->b_wcount; | |
148 | tccmp->lobyte = (bp->b_flags&B_XMEM) | IENABLE|GO | |
149 | | (bp->b_flags&B_READ?RDATA:WDATA); | |
150 | tctab.d_active = SIO; | |
151 | return; | |
152 | ||
153 | case SREV: | |
154 | if (*tcdtp+3 > bp->b_blkno) | |
155 | goto setback; | |
156 | goto setforw; | |
157 | } | |
158 | } |