|
|
1.1 root 1: /* ut.c 6.1 83/07/29 */
2:
3: /*
4: * SI Model 9700 -- emulates TU45 on the UNIBUS
5: */
6: #include "../machine/pte.h"
7:
8: #include "../h/param.h"
9: #include "../h/inode.h"
10: #include "../h/fs.h"
11:
12: #include "../vaxuba/ubareg.h"
13: #include "../vaxuba/utreg.h"
14:
15: #include "saio.h"
16: #include "savax.h"
17:
18: #define MASKREG(reg) ((reg)&0xffff)
19:
20: u_short utstd[] = { 0172440 }; /* non-standard */
21:
22: utopen(io)
23: register struct iob *io;
24: {
25: int skip;
26:
27: utstrategy(io, UT_REW);
28: skip = io->i_boff;
29: while (skip-- > 0)
30: utstrategy(io, UT_SFORWF);
31: }
32:
33: utclose(io)
34: register struct iob *io;
35: {
36:
37: utstrategy(io, UT_REW);
38: }
39:
40: #define utwait(addr) {do word=addr->utcs1; while((word&UT_RDY)==0);}
41:
42: utstrategy(io, func)
43: register struct iob *io;
44: {
45: register u_short word;
46: register int errcnt;
47: register struct utdevice *addr =
48: (struct utdevice *)ubamem(io->i_unit, utstd[0]);
49: int info, resid;
50: u_short dens;
51:
52: dens = (io->i_unit&07) | PDP11FMT | UT_PE;
53: errcnt = 0;
54: retry:
55: utquiet(addr);
56: addr->uttc = dens;
57: info = ubasetup(io, 1);
58: addr->utwc = -((io->i_cc+1) >> 1);
59: addr->utfc = -io->i_cc;
60: if (func == READ) {
61: addr->utba = info;
62: addr->utcs1 = UT_RCOM | ((info>>8) & 0x30) | UT_GO;
63: } else if (func == WRITE) {
64: addr->utba = info;
65: addr->utcs1 = UT_WCOM | ((info>>8) & 0x30) | UT_GO;
66: } else if (func == UT_SREV) {
67: addr->utcs1 = UT_SREV | UT_GO;
68: return (0);
69: } else
70: addr->utcs1 = func | UT_GO;
71: utwait(addr);
72: ubafree(io, info);
73: word = addr->utds;
74: if (word&(UTDS_EOT|UTDS_TM)) {
75: addr->utcs1 = UT_CLEAR | UT_GO;
76: goto done;
77: }
78: if ((word&UTDS_ERR) || (addr->utcs1&UT_TRE)) {
79: if (errcnt == 0)
80: printf("tj error: cs1=%b er=%b cs2=%b ds=%b",
81: addr->utcs1, UT_BITS, addr->uter, UTER_BITS,
82: addr->utcs2, UTCS2_BITS, word, UTDS_BITS);
83: if (errcnt == 10) {
84: printf("\n");
85: return (-1);
86: }
87: errcnt++;
88: if (addr->utcs1&UT_TRE)
89: addr->utcs2 |= UTCS2_CLR;
90: addr->utcs1 = UT_CLEAR | UT_GO;
91: utstrategy(io, UT_SREV);
92: utquiet(addr);
93: if (func == WRITE) {
94: addr->utcs1 = UT_ERASE | UT_GO;
95: utwait(addr);
96: }
97: goto retry;
98: }
99: if (errcnt)
100: printf(" recovered by retry\n");
101: done:
102: if (func == READ) {
103: resid = 0;
104: if (io->i_cc > MASKREG(addr->utfc))
105: resid = io->i_cc - MASKREG(addr->utfc);
106: } else
107: resid = MASKREG(-addr->utfc);
108: return (io->i_cc - resid);
109: }
110:
111: utquiet(addr)
112: register struct utdevice *addr;
113: {
114: register u_short word;
115:
116: utwait(addr);
117: do
118: word = addr->utds;
119: while ((word&UTDS_DRY) == 0 && (word&UTDS_PIP));
120: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.