/* tlr.c: read a R.VAR file from telex paper tape on tl: */ /* please assign tl: to a full-duplex-driver tty: terminal */ #include #include #include #include #include #include #define EFN 1 #define LUN 6 helpless() {puts("usage: TLR >output-file-name"); puts("will copy a telex tape from tl: to STDOUT"); puts("type a SPACE on the TTY to signal end-of-tape"); exit(); } main(argc) int argc; {int dev; /* device name in ascii */ int dsw; /* directive status word */ char getachar(); /* suck one char from TL: */ char ascii(); /* convert baudot to ascii */ char fromtl; /* the char from TL: */ char tooutput; /* the char we output */ int lettershift; /* TRUE if currently in lettershift */ int endoffile; /* TRUE when tape end hit */ if (argc>1) helpless(); dev = 'T' | 'L'<<8; dsw = alun(LUN,dev,0); if (dsw!=IS_SUC) {error("\7Can't attach to teletype %c%c: dsw=%o#",dev,dev>>8,dsw); } ; /* assume TL: is ^Q SET /WRAP=TL: SET /RPA=TL: SET /FDX=TL: SET /FORMFEED=TL: SET /HFILL=TL:0 SET /HHT=TL: SET /ECHO=TL: SET /TYPEAHEAD=TL: SET /NOCRT=TL: SET /SLAVE=TL: SET /LOWER=TL: SET /TERM=TL:ASR33 SET /NOVFILL=TL: SET /EBC=TL: */ errputs("+--------------------------------------+\r"); errputs("| |\r"); errputs("| Please turn paper tape reader on NOW |\r"); errputs("| |\r"); errputs("+--------------------------------------+\r"); /* we could achieve above with a SF.SMC QIO - but the task would then need priviledge: so trust boot to set up these parameters */ /* ordinary telex tape will only generate codes 11100000 - 11111111 so when user types a space (x0100000) we use that as end-of-file */ /* endoffile is also set if there is a timeout */ endoffile = FALSE; while ( (fromtl=getachar(&endoffile)) , fromtl == 0 || endoffile ) endoffile = FALSE; /* ignore timeouts and blank tape until at least 1 char read */ while (endoffile==FALSE) {if (fromtl==' ') {endoffile = TRUE; /* space means end of file */ } ; if (endoffile==FALSE) {if (fromtl) /* if not clear tape leader */ {tooutput = ascii(fromtl,&lettershift); if (tooutput) putchar(tooutput); } ; } ; fromtl = getachar(&endoffile); } ; } char ascii (telex,lettershift) /* return 0 or ASCII char */ char telex; /* telex char as read */ int *lettershift; /* TRUE if currently letter shifted */ /* returns with new value */ /* | o | | o | | o | | o | | A B C o D E | bits in the telex tape, looking down | o | front of TTY \ o / hole: 1 no hole: 0 \ o / \ o / \ o / \ o / \ o/ \ / V +-+-+-+-+-+-+-+-+ |A|B|C|D|E| | bits as they appear in a C char +-+-+-+-+-+-+-+-+ l m s s b b +-+-+-+-+-+-+-+-+ | |E|D|C|B|A| bits as they appear in a C char +-+-+-+-+-+-+-+-+ m l s s b b m l s s b b ED CBA . leader leader . * T 5 . * car-ret car-ret . ** O 9 .* space space .* * H unknown .** N , .*** M . *. linefed linefed *. * L ) *. * R 4 *. ** G $ *.* I 8 *.* * P 0 *.** C : *.*** V = * . E 3 * . * Z + * . * D who-r-u * . ** B ? * .* S ' * .* * Y 6 * .** F % * .*** X / **. A - **. * W 2 **. * J bell **. ** figure **.* U 7 **.* * Q 1 **.** K ( **.*** letter ED CBA m l s s b b */ {int let; /* TRUE if letter shift */ char *c; /* 0th: letter 1st: number */ let = *lettershift; switch (telex & 0x1F) { case 0: c = "\0\0"; break; case 1: c = "T5"; break; case 2: c = "\r\r"; break; case 3: c = "O9"; break; case 4: c = " "; break; case 5: c = "H*"; break; case 6: c = "N,"; break; case 7: c = "M."; break; case 8: c = "\n\n"; break; case 9: c = "L)"; break; case 10: c = "R4"; break; case 11: c = "G$"; break; case 12: c = "I8"; break; case 13: c = "P0"; break; case 14: c = "C:"; break; case 15: c = "V="; break; case 16: c = "E3"; break; case 17: c = "Z+"; break; case 18: c = "D\5"; break; case 19: c = "B?"; break; case 20: c = "S'"; break; case 21: c = "Y6"; break; case 22: c = "F%"; break; case 23: c = "X/"; break; case 24: c = "A-"; break; case 25: c = "W2"; break; case 26: c = "J\7"; break; case 27: c = "\0\0"; let = FALSE; break; case 28: c = "U7"; break; case 29: c = "Q1"; break; case 30: c = "K("; break; case 31: c = "\0\0"; let = TRUE; break; } ; *lettershift = let; return (c[let?0:1]); } char getachar(endoffile) /* get a char from TL: */ int *endoffile; /* set TRUE if timeout occurs */ { int qiow(); int dsw; /* directive status word */ int isb[2]; /* io status block */ int prl[6]; /* QIOW parameter list */ int mask[32]; /* says "pass all chars as terminators" */ int i; for (i=31; i--; ) mask[i] = -1; /* set all bits in mask */ prl[0] = mask; /* buffer address: we never read into it, so use mask as buffer */ prl[1] = 1; /* give it 1 byte so FDX term driver is happy */ prl[2] = 1; /* wait ten seconds until time-out (end-of-file) */ prl[3] = mask; /* the character mask that says ALL chars break */ dsw = qiow(IO_RTT|TF_TMO,LUN,EFN,isb,0,prl); /* expect in isb: byte 0: directive status code: 1 for success byte 1: character input byte 2-3: the count of characters input to buffer this is always zero, because we break on every character */ /* check for return code 2: timeout */ if ( (dsw & 0xFF) == IS_SUC && (isb[0] & 0xFF) == IS_TMO ) {/* timeout */ *endoffile = TRUE; isb[0] = IS_SUC; /* lies, damned lies and comments */ } ; if ( (dsw & 0xFF) != IS_SUC || (isb[0] & 0xFF) != IS_SUC ) {error("\7Can't read from TL: dsw=%xx isb=%xx %xx",dsw,isb[0],isb[1]); } ; return ((isb[0]>>8) & 0x7F); /* only yield 7 bits */ } errputs(string) /* put a string to human */ char *string; {int strlen(); fput(string,strlen(string),stderr); }