# /* * cdc u200 emulator. * * copyright march 1976 ian johnstone. * * amended by Piers Lauder for DU11 interface * Sep 1977 */ #include "../defines.h" #include "../param.h" #include "../conf.h" #include "../user.h" #include "../buf.h" #include "du.h" /* (not DIAGNOSTICS) #define DIAGNOSTICS /* for "printf" tracing of receive states */ /* (not CYSGTTY) #define CYSGTTY /* for inclusion of sgtty routine */ #ifdef POWER_FAIL #define PUDELAY 1*HZ /* wait one second before restart */ #define PURETRY 5*HZ /* wait five secs before trying again */ #define PATIENCE 5 /* give up after 5 retrys */ #endif int yjwritp; /* proc pointer for job writing process */ int yjreadp; /* proc pointer for job reading process */ #define SPLEI spl6 #define ps PS->integ /* * buffers and buffer pointers */ /* receive buffer pointers */ char ycrbuffer[1050]; char *ycrbuf ycrbuffer; char *ycrbufe ycrbuffer+1049; char *ycrbufp ycrbuffer; /* transmit buffer pointers */ char *yctbufp; /* card buffer pointers */ int ycjpadding; char ycjbuffer[984-14]; struct buf ycjbaddr { 0,0,0,0,0,0,0,ycjbuffer }; /* print buffer pointers */ char yclbuffer[1050-14]; struct buf yclbaddr { 0,0,0,0,0,0,0,yclbuffer }; #define yclbuf yclbaddr.b_addr char *yclbufp yclbuffer; char *yclbufe yclbuffer+1049; int yclbufl; /* answer buffer pointers */ char ycabuf[740]; int ycabufl; #define ycabufe (&ycabuf[730]) /* command buffer pointers */ char yccbuf[22]; #define yccbufl (22-(1+3)) /* * flags to control all */ int ycflag; #define CRDY (1<<0) /* set if cmd queued to cyber */ #define RRDY (1<<1) /* set if message from cyber avail */ #define RUSE (1<<2) /* set if message being passed */ #define JRDY (1<<3) /* another batch of cards ready to go */ #define RDE2 (1<<4) /* set if a 'read e2' sent for card reader */ #define WJOPN (1<<5) /* cyb.jobs open for write */ #define RJOPN (1<<6) /* cyb.jobs open for read */ #define WCOPN (1<<7) /* cyb.cntrl open for write */ #define RCOPN (1<<8) /* cyb.cntrl open for read */ #define JFAVL (1<<9) /* set if print buffer ready */ #define PRE2 (1<<10) /* set if a 'read e2' sent for printer */ #define WPRT (1<<11) /* set if waiting for prt output */ #define WCRD (1<<12) /* set if waiting for card buffer */ #define WMSG (1<<13) /* set if waiting for message */ #define WCOM (1<<14) /* set if waiting for command buffer */ #define AWFUL (1<<15) /* set if ycawful running */ #define CYOPN (WJOPN|RJOPN|WCOPN|RCOPN) int yceoj; /* * symbolic equates */ #define this_site 0170 #define stoh 0001 #define eot 0003 #define qeot 0203 #define escp 0076 #define qescp 0276 #define reject 0030 /* u-200 */ #define qreject 0230 #define sync 0026 /* u-200 */ #define error 0025 /* u-200 */ #define qerror 0225 #define read 0023 /* u-200 */ #define qread 0223 #define ack 0006 /* u-200 */ #define qack 0206 #define write 0021 /* u-200 */ #define cwrite 0022 /* u-200 */ #define rwrite 0014 /* u-200 */ #define poll 0005 /* u-200 */ #define alert 0007 /* u-200 */ #define ff 0014 #define vt 0013 #define space3 0040 /* cyber */ #define space2 0112 /* cyber */ #define space1 /* cyber */ #define space0 0060 /* cyber */ #define eject 0101 /* cyber */ #define skipc4 0105 /* cyber */ #define eoj 0126 /* cyber */ #define ceol 0120 /* cyber */ #define ccr 0101 /* cyber */ #define lowbcd 0040 #define highbcd 0137 #define e1 0102 #define qe1 0302 #define e2 0040 #define qe2 0240 #define e3 0041 #define qe3 0241 #define eoi 0126 /* cyber */ #define qeoi 0326 #define eor 0127 /* cyber */ #define qeor 0327 #define ctrlr 0022 #define null 0000 /* cyber talking control words */ char ycrerrs; /* non-zero => xmit errors */ char ycerrf; /* non-zero => receive error */ /* * 0 ==> o.k. * 1 ==> format error in received msg. * 2 ==> lpc error in received msg. * 3 ==> hardware detected receive error. * 4 ==> last msg. transmitted no good. * 5 ==> last msg. received too long. * 6 ==> talk syncronizing error. * 7 ==> hardware detected char overun error * 8 ==> hardware detected char parity error * * * short error description * 1 2 3 4 5 6 7 8 */ char ycerrfm[] "fmtlpcrecxmtlenproovrpar"; int ycerrfc[8]; /* error counts */ #define FMTERR 1 #define LPCERR 2 #define RECERR 3 #define XMTERR 4 #define LENERR 5 #define PROERR 6 #define OVRERR 7 #define PARERR 8 char ycdiag1[] "\ncyber modem not ready\n"; char ycdiag2[] "\ncyberr "; char ycsite; /* site address from last msg. */ char ycstat; /* station address from last msg. */ char yccode; /* control code from last msg. */ char ycetyp; /* end code from last msg. */ char ycwstat 0141; /* station address from last write msg. */ char yctstat; /* station address to be transmitted */ char *ycbmsg[10]; /* a 10 msg stack */ int ycb; /* msg stack pointer */ int ycnsync 1; char *ycmsg -1; /* ptr to last 'msg' sent to cyber */ char *ycnowmsg; /* ptr to an immediate msg */ int ycrnext 1; int yctnext 1; /* * std. messages for cyber */ char ycackm[] { qack, qeot }; char ycrejm[] { qreject, qeot }; char ycerrm[] { qerror, qeot }; char yclogin[] { qread, 'l',',','u','n','i','x', qescp, qe1, qeot }; char ycreed[] { qread, 'r', qescp, qe1, qeot }; char yccont[] { qread, 'c', qescp, qe1, qeot }; char yci[] { qread, 'i', qescp, qe1, qeot }; char ycgo[] { qread, 'g', qescp, qe1, qeot }; char yce1m[] { qread, qescp, qe1, qeot }; char yce2m[] { qread, qescp, qe2, qeot }; char yce3m[] { qread, qescp, qe3, qeot }; char ycbtoa[] /* bcd to ascii conversion */ { 0055,0112,0113,0114,0115,0116,0117,0120, 0121,0122,0041,0044,0052,0047,0077,0076, 0053,0101,0102,0103,0104,0105,0106,0107, 0110,0111,0074,0056,0051,0134,0072,0073, 0072,0061,0062,0063,0064,0065,0066,0067, 0070,0071,0060,0075,0042,0100,0045,0133, 0040,0057,0123,0124,0125,0126,0127,0130, 0131,0132,0135,0054,0050,0137,0043,0046 }; char ycatob[] /* ascii to bcd conversion */ { 0120,0052,0114,0136,0053,0116,0137,0055, 0134,0074,0054,0060,0133,0040,0073,0121, 0112,0101,0102,0103,0104,0105,0106,0107, 0110,0111,0100,0077,0072,0113,0057,0056, 0115,0061,0062,0063,0064,0065,0066,0067, 0070,0071,0041,0042,0043,0044,0045,0046, 0047,0050,0051,0122,0123,0124,0125,0126, 0127,0130,0131,0117,0075,0132,0075,0135, 0120,0061,0062,0063,0064,0065,0066,0067, 0070,0071,0041,0042,0043,0044,0045,0046, 0047,0050,0051,0122,0123,0124,0125,0126, 0127,0130,0131,0120,0120,0120,0120,0120 }; /******************/ /* cyber commands */ /******************/ ycopen(dev,flag) { register int x; if ( flag==0 ) x = RCOPN; else x = WCOPN; if ( (ycflag&x) | cystart() ) u.u_error = ENXIO; else ycflag =| x; } ycclose(dev,flag) { ycflag =& ~(flag==0 ? RCOPN : WCOPN); } ycmsgout(msg,len) /* place msgs for ops for cyb.cdn */ char *msg; int len; { char register *x,*y,*z; if ( !(ycflag&RUSE) ) { if ( (z=ycabufe-ycabuf) > (y=len) ) z = ycabufl = y; else ycabufl=z; x = ycabuf; y = msg; while(z--) *x++ = *y++; ycflag =| RRDY; if ( ycflag & WMSG ) { ycflag =& ~WMSG; wakeup(&ycabuf); } return(x); /* indicate all okay */ } return(0); } ycwrite() /* to send commands to cyber */ { register char x, *y; if ( ycflag&CRDY || u.u_count>yccbufl ) u.u_error = ENXIO; else { y = yccbuf; *y++ = qread; while ((x=cpass())>0) *y++ = x&0177; *y++ = qescp; *y++ = qe1; *y++ = qeot; ycflag =| CRDY; ycqmsg(yccbuf); } if ( !(ycflag & AWFUL) ) ycawful(); } ycread() /* to read response from cyber */ { register char *x; register int y; SPLEI(); while (!(ycflag&RRDY)) { ycflag =| WMSG; sleep(&ycabuf,1); } ycflag =& ~RRDY; ycflag =| RUSE; spl0(); x = ycabuf; y = (ycabufl>u.u_count) ? u.u_count : ycabufl; while(y--) passc(*x++); ycflag =& ~RUSE; } /***************/ /* cyber jobs */ /***************/ yjopen(dev,flag) { register int x, y; if ( flag==0 ) { x = RJOPN; yjreadp = u.u_procp; y = PRE2; } else { x = WJOPN; yjwritp = u.u_procp; y = RDE2; } if ( (ycflag&x) | cystart() ) u.u_error = ENXIO; else ycflag =| x|y; } yjclose(dev,flag) { if ( flag ) { ycflag =& ~(WJOPN | JRDY | RDE2); yjwritp = 0; } else { ycflag =& ~(RJOPN | JFAVL); yjreadp = 0; } } yjwrite() /* to send jobs to the cyber */ { int register n, m; SPLEI(); while (ycflag&JRDY) { ycflag =| WCRD; sleep(&ycjbuffer,1); } spl0(); ycjbaddr.b_addr=ycjbuffer; if ( m=(n=u.u_count)&01776 ) iomove(&ycjbaddr, 0, m, B_WRITE); if (n&1) ycjbuffer[m++] = cpass(); if (!m) return; ycjbuffer[m++]=qescp; ycjbuffer[m++]=qe3; ycjbuffer[m++]=qeot; ycflag =| JRDY; if ( ycflag&RDE2 ) { ycqmsg(ycreed); ycflag =& ~RDE2; } } yjread() /* to read jobs output from the cyber. as much as possible each time */ { int register n, m; SPLEI(); while ( !(ycflag&JFAVL) && !yceoj ) { ycflag =| WPRT; sleep(&yclbuf,1); } spl0(); if (yceoj) /* terminate last job */ { yceoj=0; u.u_error=ENXIO; return; } m = (n = (u.u_count<yclbufl?u.u_count:yclbufl) )&03776; if ( m ) iomove(&yclbaddr,0,m,B_READ); if ( n&1 ) passc(yclbuf[m]); ycflag =& ~JFAVL; /* buffer all used */ } /******************/ /* other */ /******************/ ycawful() /* stir up export -- yes it is needed */ { static count; ycflag =& ~AWFUL; SPLEI(); if ( (ycflag&CYOPN) ) { if ( ycb < 2 ) { ycqmsg(yci); if ( count++ >= 2 ) { count = 0; ycqmsg(yccont); if ( ycflag & JRDY ) ycqmsg(ycgo); } } if ( timeout(ycawful,0,20*HZ) ) ycflag =| AWFUL; } spl5(); /* return to timeout priority */ } ycqmsg(mp) /* place messages for cyber in 'fifo' queue */ char *mp; { int register x, y; if ( ycb > 8 ) return; y = ps; SPLEI(); x = ++ycb; while( x > 1 ) ycbmsg[x-1] = ycbmsg[(x--)-2]; ycbmsg[0] = mp; ps = y; } ycerep(en) /* called to log errors && optionally tell op */ register int en; { char register *x,*y; ycerrfc[en-1]++; if (SW->integ&020000) return; x = &ycerrfm[en*3-3]; y = ycdiag2+8; *y++ = *x++; *y++ = *x++; *y = *x; ycmsgout(ycdiag2,11); } /******************/ /* interrupt */ /******************/ ycwpro() /* process cyber write commands -- called from receive interrupt routine */ { char register *x, *y; int register *z; if ( ycmsg == &ycjbuffer[-1]) { ycflag =& ~JRDY; if ( ycflag & WCRD ) { ycflag =& ~WCRD; wakeup(&ycjbuffer); } }else if ( ycmsg==yccbuf ) ycflag =& ~CRDY; ycmsg = 0; /* last 'msg' to cyber was accepted */ switch(ycetyp) /* process write according to type code */ { case e1: z = &ycrbuf[2]; if ( *z == 'AR' && ycrbuf[13] == 'D' ) /* ' card reader disabled' */ ycflag =| RDE2; else if ( *z == '**' ) /* ' **** idle ....' */ { if ( yjreadp ) psignal( yjreadp, SIGHUP ); if ( yjwritp ) psignal( yjwritp, SIGHUP ); ycqmsg( yclogin ); ycqmsg( ycreed ); ycflag =| RDE2; goto outcomp; } else if ( *z == 'UT' ) /* ' output complete' */ { outcomp: yceoj++; wakeup( &yclbuf ); } /* if bit #12 in swreg is set throw away useless crap */ if (SW->integ&010000) switch ( *z ) { case 'EA': /* ' ready' */ case 'O ': /* ' no [file is suspended][input active]' */ case 'UT': /* ' output complete.' */ case 'ER': /* ' terminal idle */ case '..': /* ' ........' */ case 'AR': /* ' card reader not ready' */ case 'RI': /* ' printer not ready' */ case 'LE': /* ' please login' */ case 'OO': /* ' too many jobs' */ goto esac; } /* can't just ignore last job read messages */ if ((!ycmsgout(ycrbuf,ycrbufp-ycrbuf))&&(*z=='OB')){ /* ' JOB ID = XXX.' */ yctbufp = ycrejm; return; } break; case e2: /* print output */ /* if cant accept pretend not ready */ if ( (ycflag&JFAVL) || (!(ycflag&RJOPN)) ) { ycnowmsg = yce2m; ycflag =| PRE2; break; } x = ycrbufp; y = ycrbuf; z = ycrbufe; switch(*y) { /* adjust first char */ default: *y = '\n'; case '\n': case '\r': case ff: case vt: break; } ycrbufp = ycrbuf = yclbuf; ycrbufe = yclbufe; yclbufp = yclbuf = y; yclbufe = z; yclbufl = x - y; ycflag =| JFAVL; if ( ycflag & WPRT ) { ycflag =& ~WPRT; wakeup(&yclbuf); } /* tell cyber want more output */ if ( !ycb ) ycnowmsg = yce3m; break; case e3: /* card input */ if ( ycflag&JRDY ) { ycnowmsg = &ycjbuffer[-1]; ycjbuffer[-1] = qread; } else { /* no cards to go so go not ready */ ycnowmsg = yce2m; ycflag =| RDE2; } esac:; } yctbufp = ycackm; /* acknowlege receipt of write */ # ifdef DIAGNOSTICS yprintf( "EIPRO %o\n", ycflag ); # endif DIAGNOSTICS } cyrint() /* receive interrupt routine */ #define YCRSTOH 1 #define YCRSITA 2 #define YCRSTAA 3 #define YCRCC 4 #define YCRMSG 5 #define YCRMSG1 6 #define YCRMSG2 7 #define YCREND 8 #define YCREOT 9 #define YCRLPC 10 #define YCRERR 11 { int register c; int static lpc; rintdone: if ( (c = DURCSR) < 0 ) { /* data set change */ if ( (c & (CLR_TO_SND|REQ_TO_SND)) == (CLR_TO_SND|REQ_TO_SND) ) { DUTCSR = DNA_INTEB|HALF_DUP|SEND; DUTBUF = SYN; }else if ( c & CARRIER ) DURCSR =| (RX_INTEB|STRIP_SYNC|SCH_SYNC); else if ((c & DATA_SET_RDY) == 0) printf( ycdiag1 ); # ifdef DIAGNOSTICS yprintf( "EI DST=%o\n", c ); # endif DIAGNOSTICS return; } if ( (c & RX_DONE) == 0 ) return; /* if (char not available) rti */ if ( (c = DURBUF) < 0 ) { /* byte error */ ycerrf = RECERR; /* e_recv */ if ( c & E_PARITY ) ycerrf = PARERR; /* e_parity */ if ( c & E_OVR_RUN ) ycerrf = OVRERR; /* e_overun */ goto ycrerros; } c =& 0177; /* obtain next char sans parity */ lpc =^ c; /* calc longtitudinal parity */ switch(ycrnext) { /* message sequence */ case YCRSTOH: /* first char must be start of header */ if ( c != stoh ) goto ycrerror; ycrstoh1: ycrnext = YCRSITA; lpc = stoh; goto rintdone; case YCRSITA: /* second char <=0177 & >=0160 */ if ( c<0160 ) goto ycrerror; ycrnext = YCRSTAA; ycsite = c; goto rintdone; case YCRSTAA: /* third char 0140,0141,0160,0161 */ switch(c) { default: goto ycrerror; case 0140: case 0141: case 0160: case 0161: ycrnext = YCRCC; ycstat = c; } goto rintdone; case YCRCC: /* fourth must be acceptable command */ switch(c) { default: goto ycrerror; case write: case cwrite: case rwrite: yccode = write; ycrnext = YCRMSG; goto rintdone; case poll: case alert: yccode = c; ycrnext =YCREOT; goto rintdone; } case YCRMSG: /* process data portion of message */ ycrnext = YCRMSG2; switch(c) { /* carriage control */ case space3: *ycrbufp++ ='\n'; case space2: *ycrbufp++ ='\n'; default: if ( ycrbufp==ycrbuf ) goto ycrtr; c ='\n'; break; case space0: c ='\r'; break; case eject: c = ff; break; case skipc4: c = vt; break; case escp: ycrnext = YCRMSG1; goto rintdone; } goto ycrmsg3; case YCRMSG1: switch(c) { /* function code */ case e1: case e2: case e3: /* ending code */ DURCSR =& ~STRIP_SYNC; /* recognise lpc==SYN after eot */ ycetyp = c; ycrnext = YCREOT; goto rintdone; case eoj: yceoj++; case ceol: case ccr: ycrnext = YCRMSG; goto rintdone; default: /* '0' or ' ' expansion */ if ( ((c=- 040)>=3) && (c<=037) ) *ycrbufp++=0377; else { if (((c=- 040)>=3)&&(c<=017)) *ycrbufp++ = 0376; else c=' '; } ycrnext = YCRMSG2; goto ycrmsg3; } case YCRMSG2: switch(c) { /* bcd data */ case escp: ycrnext = YCRMSG1; goto rintdone; ycrtr: default: if ( (c>highbcd) || (c<lowbcd) ) c = ' '; else c = ycbtoa[c-lowbcd]; } ycrmsg3: if ( ycrbufp > ycrbufe ) { if( !ycerrf ) ycerrf = LENERR; goto ycrerros; } /* e_length */ *ycrbufp++ = c; goto rintdone; case YCREND: /* look for end of message */ if ( c==stoh ) { ycrbufp=ycrbuf; goto ycrstoh1; } goto rintdone; case YCREOT: /* this char must be "eot" */ if ( c!=eot ) goto ycrerror; ycrnext = YCRLPC; goto rintdone; case YCRERR: ycrerror: if ( !ycerrf ) ycerrf = FMTERR; /* e_format */ # ifdef DIAGNOSTICS yprintf( "EI E=%o,N=%o,C=%o\n", ycerrf, ycrnext, c ); # endif DIAGNOSTICS ycrerros: ycrnext = YCREND; DURCSR = DS_INTEB|DATA_TERM_RDY; goto rintdone; case YCRLPC: /* this char is longtitudinal parity */ if ( (lpc != 0177) && !ycerrf ) ycerrf = LPCERR; /* e_lpc */ ycrnext = YCRSTOH; /* set for next receive */ if ( ycsite != this_site ) { DURCSR = DS_INTEB|DATA_TERM_RDY; ycerrf = 0; }else { if ( ycerrf ) { ycerep(ycerrf); ycerrf = 0; yctbufp = ycerrm; } else { if ( ycstat & 1 ) switch(yccode) { /* odd station address */ case write: ycrerrs = 0; /* save write address */ ycwstat = ycstat; ycwpro(); break; case alert: yctbufp = ycackm; ycqmsg(yce1m); break; default: yctbufp = ycerrm; ycerep(PROERR); /* e_protocol */ } else switch(yccode) { /* even station address */ case poll: if ( ycmsg == -1){ ycmsg = 0; yctbufp = ycrejm; } else if ( (yctbufp=ycmsg) ) { ycerep(XMTERR); /* e_xmit */ if ( ++ycrerrs > 10 ) { # ifdef DIAGNOSTICS yprintf( "EI fail/reset\n" ); # endif DIAGNOSTICS ycrerrs = 0; if ( ycmsg == ycbmsg[ycb] ) ycb++; yctbufp = ycmsg = yci; } }else if ( ycnowmsg ) { yctbufp=ycmsg=ycnowmsg; ycnowmsg=0; }else yctbufp= (ycb ? (ycmsg=ycbmsg[--ycb]) : ycrejm); break; default: yctbufp = ycerrm; ycerep(PROERR); /* e_protocol */ } /* reject to 'poll' is different */ if ( (yccode==poll) && (*yctbufp==0177630) ) /* ==qreject */ yctstat = ycwstat & 0176; else yctstat = ycwstat; # ifdef DIAGNOSTICS yprintf( "EI RC=%o\n", yccode ); # endif DIAGNOSTICS } /* SEND */ ycrbufp = ycrbuf; DURCSR = DS_INTEB|REQ_TO_SND|DATA_TERM_RDY; } } } cyxint() /* transmitter status interrupt routine */ /* yctbufp points to the message to be sent to the cyber */ /* qeot signals end of message. */ /* any char with parity bit on is not translated */ #define YCXSYNC 1 #define YCXSTOH 2 #define YCXSITA 3 #define YCXSTAA 4 #define YCXMSG 5 #define YCXLPC 6 #define YCXEND 7 { register c; int static lpc; switch(yctnext) { /* transmit message sequence */ case YCXSYNC: /* send 4 syncs */ c = DUTCSR; /* clear DNA interrupt */ if ( ++ycnsync < 4 ) return; DUTCSR = TX_INTEB|HALF_DUP|SEND; case YCXSTOH: /* 1st char is start of header */ c = stoh; yctnext = YCXSITA; lpc = 0; goto ycxmit; case YCXSITA: /* 2nd char is site address */ c=ycsite; yctnext = YCXSTAA; goto ycxmit; case YCXSTAA: /* 3rd char is station address */ c = yctstat; yctnext = YCXMSG; goto ycxmit; case YCXMSG: /* output data till eot found */ c = *yctbufp++; if ( c&0200 ) { c =& 0177; if ( c==eot ) yctnext = YCXLPC; }else if ( c<' ' ) c = 0120; else c = ycatob[c-040]; ycxmit: lpc =^ c; /* long. parity */ DUTBUF = c; return; case YCXLPC: /* output long. parity */ c = (~ lpc); yctnext = YCXEND; DUTCSR = DNA_INTEB|HALF_DUP|SEND; goto ycxmit; case YCXEND: /* all msg sent - tidy up */ if ( ycflag&CYOPN ) { DUTCSR = 0; DURCSR = DS_INTEB|DATA_TERM_RDY; }else { DUTCSR = MSTRST; /* no open devices so close down */ } ycrnext = YCRSTOH; yctnext = YCXSYNC; ycnsync = 1; } } cystart() /* initiate receive on DU11 if necessary */ { if ( (DURCSR & DATA_SET_RDY)==0 ) { printf(ycdiag1); /* modem not ready */ return(1); } if ( !(ycflag&CYOPN) ) { DUPSR = INT_SYNC|C8BIT|ODD_PAR|SYN; DURCSR = DS_INTEB|DATA_TERM_RDY; /* reinit necessary variables */ ycerrf = ycflag = ycb = 0; ycmsg = -1; ycrbuf = ycrbufp = ycrbuffer; ycrbufe = ycrbuffer+1049; yclbuf = yclbufp = yclbuffer; yclbufe = yclbuffer+1049; ycrnext = YCRSTOH; yctnext = YCXSYNC; ycnsync = 1; } if ( !(ycflag & AWFUL) ) ycawful(); return(0); } #ifdef CYSGTTY cysgtty( dev, v ) register *v; { if ( v ) { *v++ = ycflag; *v++ = (ycsite<<8)|ycstat; *v = (yccode<<8)|ycetyp; } return( v ); } #endif CYSGTTY #ifdef POWER_FAIL cypowerf() { extern cyrestart(); if ( ycflag & cyopen ) timeout( cyrestart , 0 , PUDELAY ); } cyrestart( count ) { register f; if ( DURCSR & DATA_SET_RDY || ++count > PATIENCE ) { f = ycflag; ycflag = 0; cystart(); ycflag = f; }else timeout( cyrestart , count , PURETRY ); } #endif POWER_FAIL #ifdef DIAGNOSTICS yprintf( s, a1, a2, a3 ) { if ( !(SW->integ & 040000) ) printf( s, a1, a2, a3 ); } #endif DIAGNOSTICS