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