1 /* ut.c 4.5 82/12/17 */ 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 19 u_short utstd[] = { 0172440 }; /* non-standard */ 20 21 utopen(io) 22 register struct iob *io; 23 { 24 register skip; 25 26 utstrategy(io, UT_REW); 27 skip = io->i_boff; 28 while (skip--) { 29 io->i_cc = 0; 30 utstrategy(io, UT_SFORW); 31 } 32 } 33 34 utclose(io) 35 register struct iob *io; 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; 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 return(0); 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 return (func == READ ? 102 io->i_cc - ((-addr->utfc) & 0xffff) : -addr->utwc << 1); 103 } 104 105 utquiet(addr) 106 register struct utdevice *addr; 107 { 108 register u_short word; 109 110 utwait(addr); 111 do 112 word = addr->utds; 113 while ((word&UTDS_DRY) == 0 && (word&UTDS_PIP)); 114 } 115