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