Research V5 development
[unix-history] / usr / sys / dmr / tc.c
CommitLineData
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
15struct {
16 int tccsr;
17 int tccm;
18 int tcwc;
19 int tcba;
20 int tcdt;
21};
22
23struct 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
49tcclose(dev)
50{
51 bflush(dev);
52}
53
54tcstrategy(abp)
55struct 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
77tcstart()
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
97tcintr()
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}