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 } 121