! File: DRIVER.BLI ! ! This work was supported by the Advanced Research ! Projects Agency of the Office of the Secretary of ! Defense (F44620-73-C-0074) and is monitored by the ! Air Force Office of Scientific Research. MODULE DRIVER(CCL,STACK=EXTERNAL(STACK,#3000),TIMER=EXTERNAL(SIX12),RESERVE(7,9))= BEGIN ! ! DRIVER MODULE ! ------------- ! ! ! THIS IS THE MAIN PROGRAM FOR THE BLISS-11 COMPILER. IT ALSO ! CONTAINS SOME COMMON UTILITY ROUTINES. THIS MODULE RESIDES IN ! THE LOW SEGMENT IN THE OVERLAID VERSION OF THE COMPILER. ! ! SWITCHES NOLIST; REQUIRE COMMON.BEG; REQUIRE IOMACS.BEG; REQUIRE OVLYLO.BEG; REQUIRE ERROR.BEG; REQUIRE LDSF.BEG; REQUIRE GTX.BEG; REQUIRE STRUCT.BEG; REQUIRE TABONC.BEG; SWITCHES LIST; REQUIRE IO.BEG; BEGIN ! IO ROUTINES ! ----------- GLOBAL ROUTINE OUTSEVERAL(CHAR,N)= (DECR I FROM .N-1 TO 0 DO OUTPUT(.CHAR); .N); GLOBAL ROUTINE OUTNUM(NUM,BSE,REQD)= BEGIN REGISTER N,B,RD,T; ROUTINE XONUM= BEGIN LOCAL R; IF .N EQL 0 THEN RETURN WHILE .T LSS .RD DO(OUTPUT("0"); T_.T+1); R_ABS(.N MOD .B); N_.N/.B; T_.T+1; XONUM(); OUTPUT(.R+"0"); END; IF .BSE LSS 0 THEN BEGIN IF .NUM LSS 0 THEN (OUTPUT("-");NUM_-.NUM); BSE_-.BSE; END; T_0; B_.BSE; N_.NUM; RD_.REQD; XONUM(); .T END; GLOBAL ROUTINE OUTCRLF= BEGIN ! OUTPUT CR,LF SEQUENCE AND SKIP TO TOP OF PAGE IF NECESSARY OUTPUT(EOL); OUTPUT(LINEF); IF NOT .LSTFLG AND NOT .TTYLST THEN IF (NLINES_.NLINES+1) GTR 51 THEN PAGE(); END; GLOBAL ROUTINE FORCELINE= BEGIN ! THIS ROUTINE FORCES OUT THE CURRENT INPUT BUFFER LINE ! IF IT IS VALID (IE, IT HASN'T BEEN PRINTED ALREADY. ! THE GLOBAL VARIABLE DEVICE SPECIFIES THE OUTPUT DEVICE. IF .VALIDBUF THEN BEGIN IF .DOPAGE AND NOT .LSTFLG AND NOT .TTYLST THEN PAGE() ELSE DOPAGE_0; OUTXSTRING(LEFTMARGIN,8,8); OUTDEC(.LINCNT^(-4),4); TAB; OUTXSTRING(BUFF<22,7>,BUFFSIZ*5,0); CRLF; VALIDBUF_0; END; END; BIND ERMSGPLIT=PLIT( % IDERR % MSG(UNDECLARED IDENTIFIER), % DCLERR % MSG(MISPLACED DECLARATION), % EXPRERR % MSG(EXPRESSION IN WRONG CONTEXT), % BRACERR % PLIT (ASCIZ 'BEGIN...) AND (...END ARE ILLEGAL')<29,7>, % OPERR1 % MSG(BINARY (UNARY) OPERATOR IN ILLEGAL CONTEXT), % OPERR2 % MSG(CONTROL EXPRESSION MUST BE PARENTHESIZED), % OPERR3 % MSG(MISSING OR EXTRA OPERAND), % OPERR4 % MSG(MISSING OPERAND), % IFERR % MSG(MISSING THEN IN IF EXPRESSION), % WUERR % MSG(MISSING DO AFTER WHILE OR UNTIL), % DOERR % MSG(MISSING WHILE OR UNTIL AFTER DO), % 11 % PLIT(0), % REPERR2 % MSG(MISSING DO AFTER INCR OR DECR), % PARAERR % MSG(PARAMETER LIST NOT CLOSED PROPERLY), % CASERR1 % MSG(IMPROPER SELECTION LIST IN CASE), % CASERR2 % MSG(MISSING SET AFTER CASE), % CASERR3 % MSG(MISSING TES AFTER SET), % SELERR1 % MSG(IMPROPER SELECTION LIST IN SELECT), % SELERR2 % MSG(MISSING NSET AFTER SELECT), % SELERR3 % MSG(COLON MISSING IN SELECT EXPRESSION), % SELERR4 % MSG(MISSING TESN AFTER NSET), % WALOCERR % MSG(ADDRESS ARITHMETIC INVOLVING LOCAL), % ERILLPTR % MSG(ILLEGAL OCCURRENCE OF POINTER EXPRESSION), % PERR1 % MSG(INVALID POSITION EXPRESSION IN POINTER), % PERR2 % MSG(INVALID SIZE EXPRESSION IN POINTER), % WAPSOVFL % MSG(POINTER EXPRESSION CROSSES WORD BOUNDARY), % WAPOSOVFL % MSG(POSITION SPECIFIED IS GREATER THAN 16), % INERR1 % MSG(BAD SYNTAX IN INLINE), % INERR2 % MSG(INLINE ARGUMENT MUST BE STRING), % INERR3 % MSG(CAVEAT EMPTOR!), % ENERR1 % MSG(MISSING COLON IN ENABLE), % ENERR2 % MSG(MISSING ELBANE AFTER ENABLE), % ENERR0 % MSG(MORE THAN ONE ENABLE IN BLOCK), % CREATERR1 % MSG(FIRST ARGUMENT TO CREATE MUST BE A ROUTINE CALL), % CREATERR2 % MSG(MISSING AT AFTER CREATE), % CREATERR3 % MSG(MISSING LENGTH AFTER AT), % CREATERR4 % MSG(MISSING THEN IN CREATE EXPRESSION), % WABLKMTCH % MSG(BLOCK BEGIN AND END NAMES DO NOT MATCH), % WATMPARMS % MSG(TOO MANY PARAMETERS IN ROUTINE OR SPECIAL FUNCTION CALL), % BADSYMERR % MSG(NON-ADDRESSABLE SYMBOL USED AS EXPRESSION), % EXITERR0 % MSG(LABEL NOT USED ON THIS EXPRESSION), % NOFOUNDEXERR % MSG(LABEL NOT YET ENCOUNTERED), % LABELERR % MSG(MUST LEAVE TO LABEL), % LABUSERR % MSG(LABEL ALREADY USED ELSEWHERE), % EXITERR1 % MSG("RETURN" (OR "EXITLOOP") NOT WITHIN ROUTINE (OR LOOP)), % WILLNSARG % MSG(ILLEGAL ARGUMENT TO $NAME OR $STRING), % WACANTRES % MSG(REGISTER NOT AVAILABLE FOR RESERVATION), % ERMISSBRC % MSG(TOO MANY CLOSE BRACKETS OR MISSING OPEN BRACKET), % WABADMOD % MSG(ERROR IN MODULE HEAD, SCAN RESTARTED AT FIRST BEGIN), % WASWNONX % MSG(INVALID SWITCH SPECIFIED), % WASMPREV % MSG(SYMBOL ALREADY DECLARED IN THIS BLOCK), % WASWSYN % MSG(SYNTAX ERROR IN SWITCH SPECIFICATION), % ERMBADEXP % MSG(EXPRESSION MUST BE LITERAL), % WAINVSTRUC % MSG(INVALID STRUCTURE OR LINKAGE NAME), % WASMNOTSTR % MSG(NAME NOT DECLARED AS STRUCTURE OR LINKAGE), % ERSYMEQ % MSG(MISSING EQUAL SIGN), % DCLDELERR % MSG(DELIMITER MUST BE COMMA OR SEMICOLON), % ERSYMNPRD % MSG(MORE THAN 1 EXPRESSION IN PARENTHESES), % DECLSYMERR % MSG(ILLEGAL SYMBOL BEFORE DECLARATOR NAME), % ERSMNDEC % MSG(REGISTER NOT AVAILABLE), % ERSYMBRAC % MSG(MISSING BRACKET AFTER SIZE FIELD), % ERSYMGRLD % MSG(MISSING SEMICOLON AFTER DECLARATION), % ERSYINVMDEC % MSG(MODULE DECLARATION INSIDE MODULE BODY), % LSIZERR % MSG(SIZE FIELD ILLEGAL IN LABEL DECLARATIONS), % WANOEQL % MSG(EQUAL NOT ALLOWED IN THIS DECLARATION), % ERREQRDEC % MSG(MISSING EQUAL IN ROUTINE DECLARATION), % NOOPERATOR % MSG(MISSING OPERATOR), % ERRBYTEFOL % MSG(NO DECLARATION FOLLOWING BYTE), % ERDCLRESWD % MSG(NAME TO BE DECLARED IS A RESERVED WORD), % ERSNMBDOT % MSG(STRUCTURE NAME MUST BE DOTTED IN ITS BODY), % ERNODOTS % MSG(MUST NOT DOT FORMAL IN SIZE EXPRESSION), % ERSMSQBCLOSE % MSG(MISSING CLOSING BRACKET IN PARAMETER LIST), % ERSYMFOL % MSG(SYMBOL OR LITERAL AFTER CLOSE BRACKET), % ERMEQ % MSG(EQUAL SIGN MISSING IN STRUCTURE OR MACRO), % ERMPL % MSG(MISSING MACRO ACTUAL PARAMETER LIST), % ERMFPL % MSG(MISSING ACTUAL PARAMETER), % ERXACTS % MSG(EXTRA ACTUAL PARAMETERS IN STRUCTURE ACCESS), % WAMSPLNKG % MSG(MISSPELLED LINKAGE NAME), % WACANTMAP % MSG(SYMBOL TO BE MAPPED IS UNDECLARED OR NON-MAPPABLE), % ERMAPLD % MSG(MISSING ACTUAL PARAMETER LIST DELIMITER), % ERSYIQC % MSG(INVALID ESCAPE CHARACTER), % ERSYMRQ % MSG(MISSING RIGHT QUOTE), % ERSYPLMRP % MSG(MISSING CLOSE PARENTHESIS IN PLIT), % ERSMPLNLI % MSG(PLIT DUPLICATION FACTOR NOT LITERAL), % ERSMPLNLO % MSG(PLIT OR GLOBAL BIND ARGUMENT NOT LITERAL AT LOAD TIME), % ERILSUSE % MSG(ILLEGAL USE OF LONG STRING), % ERMRD % MSG(ROUTINE DECLARED FORWARD IS NOT DEFINED), % ERISEDS % MSG(SIZE OF INITIAL VALUE SPECIFICATION EXCEEDS DECLARED SIZE), % ERNEEDLS % MSG(STRING FUNCTION REQUIRES STRING ARGUMENT), % WBADCSECT % MSG(CSECT DECLARATION ERROR - IGNORED), % LNKGNOEQUAL % MSG(MISSING EQUAL IN LINKAGE DECLARATION), % LNKGNOTYP % MSG(NO LINKAGE TYPE SPECIFIED), % LNKGTOOMANYP % MSG(TOO MANY PARAMETERS IN LINKAGE DECLARATION), % LNKGINVSYNTAX % MSG(MISSING COMMA IN LINKAGE DECLARATION), % LNKGINVPARM % MSG(INVALID PARAMETER TYPE), % LNKGNOTREG % MSG(INVALID REGISTER NUMBER), % ERRLKNAME % MSG(CANNOT MAP TRAP LINKAGE TYPE), % WABADRAD50 % MSG(ILLEGAL CHARACTER IN RADIX 50 STRING), % NOTENUFREGS % MSG(PDP-11 HAS BUT EIGHT WORKING REGISTERS), % REGTOOCROWD % MSG(TRIED TO PUT TWO QUANTITIES AT ONCE IN REG. # ), % DIVERR % MSG(ATTEMPT TO DIVIDE BY ZERO), % ERNOSYM % MSG(MISSING SYMBOL IN DECLARATION), % WASTATERR % MSG(I/O ERROR DURING COMPILER STATISTICS WRITEOUT), % ERUPLVL % MSG(INVALID UP-LEVEL ADDRESSING (OF FORMAL,LOCAL, OR REGISTER)), % WAMODDOM % MSG(MODULE MUST MATCH ELUDOM), % NOTIMPL % MSG(NOT IMPLEMENTED YET), % ERREQNEST % MSG(REQUIRE FILES NESTED TOO DEEP), % ERREQDEV % MSG(REQUIRE DEVICE NOT AVAILABLE), % ERREQDPPN % MSG(INVALID FORMAT FOR REQUIRE PPN), % ERREQCPPN % MSG(REQUIRE CMU-PPN NOT TRANSLATABLE), % ERREQFIND % MSG(REQUIRE FILE NOT FOUND), % ERUNTCOM % MSG(UNTERMINATED COMMENT), % ERUNTMAC % MSG(UNTERMINATED MACRO DEFINITION), % ERMSEND % MSG(MISSING END OR RIGHT PARENTHESIS), % ERINVBNSYN % MSG(INVALID BLOCK NAME SYNTAX), % ERINVBNARG % MSG(INVALID BLOCK NAME - MAYBE EXPANDED MACRO??), % WASTRUCTREC % MSG(STRUCTURE MAY NOT CALL ITSELF RECURSIVELY) ); ROUTINE OUTFLAG(TYPE) = ! ! OUTPUT THE CHARACTER THAT SIGNALS AN ERROR OR WARNING ! TO BATCH, TO THE TTY; OUTPUT A SEMICOLON TO THE LISTING FILE. ! BEGIN DEVICE_TTYDEV; OUTPUT(IF .TYPE EQL 'ERR ' THEN "??" ELSE "%"); DEVICE_LSTDEV; OUTPUT(";"); DEVICE_ERRDEV; NOVALUE END; ROUTINE ERROUT(TYPE,LASTOPEN,NUM,POSN)= ! ! OUTPUT ERROR OR WARNING MESSAGE, WITH POINTERS, ETC. ! BEGIN MACRO NAMEPTR=1,0,18$; ! USED IN OUTSTE MACRO LOCAL MAX; IF NOT .ERRBIT THEN DEVICE_ERRDEV; FORCELINE(); OUTFLAG(.TYPE); OUTPXFLD(TYPE,4); OUTPUT("#"); OUTDEC(.NUM,3); IF .POSN NEQ 0 THEN BEGIN TAB; MAX_.POSN<0,7>; IF .MAX LSS .LASTOPEN<0,7> THEN MAX_.LASTOPEN<0,7>; IF .LASTOPEN NEQ 0 THEN IF .MAX LSS .LCBRAC<0,7> THEN MAX_.LCBRAC<0,7>; INCR I FROM 1 TO .MAX DO SELECT .I OF NSET .POSN<0,7>: EXITSELECT OUTPUT("1"); .LASTOPEN<0,7>: EXITSELECT OUTPUT("2"); .LCBRAC<0,7>: IF .LASTOPEN NEQ 0 THEN EXITSELECT OUTPUT("3"); ALWAYS: OUTPUT(".") TESN; OUTS(' L1:'); OUTDEC(.POSN<22,14>,4); IF .LASTOPEN NEQ 0 THEN BEGIN OUTS(' L2:'); OUTDEC(.LASTOPEN<22,14>,4); OUTS(' L3:'); OUTDEC(.LCBRAC<22,14>,4); END; END; CRLF; OUTPUT(";"); OUTXSTRING(.ERMSGPLIT[.NUM],64,0); IF .NUM EQL REGTOOCROWD THEN OUTDEC(.ERRINFO[0],1); CRLF; IF .NUM EQL IDERR OR .NUM EQL ERUPLVL THEN (OUTS('; ');OUTSTE(.SYM);CRLF) ELSE IF .NUM EQL ERMRD OR .NUM EQL BADSYMERR OR .NUM EQL ERMPL OR .NUM EQL WASMPREV THEN (OUTS('; ');OUTSTE(.ERRINFO[0]);CRLF) ELSE IF .NUM EQL WABLKMTCH THEN (OUTS('; '); IF .ERRINFO[0] EQL 0 THEN OUTS('(NONE)') ELSE OUTSTE(.ERRINFO[0]); OUTPUT(" "); IF .ERRINFO[1] EQL 0 THEN OUTS('(NONE)') ELSE OUTSTE(.ERRINFO[1]); CRLF); DEVICE_LSTDEV; END; GLOBAL ROUTINE ERRPRNT(LASTOPEN,POSN,NUM)= IF NOT .ERRLEVEL THEN (ERROUT('ERR ',.LASTOPEN,.NUM,.POSN);ERRORFOUND_.ERRORFOUND+1); GLOBAL ROUTINE WARNEM(POSN,NUM)= (ERROUT('WARN',0,.NUM,.POSN); WARNINGFOUND_.WARNINGFOUND+1;0); ROUTINE PLURAL(N)= IF .N EQL 0 OR .N GTR 1 THEN OUTPUT("s") ELSE NOVALUE; ROUTINE WRITEFINAL= BEGIN ! THIS ROUTINE WRITES THE FINAL GOOD-BYE TO THE USER ERRBIT_0; CRLF; CRLF; DEVICE_ERRDEV; CRLF; IF (.ERRORFOUND+.WARNINGFOUND) NEQ 0 THEN BEGIN OUTSXFLD('; # Warnings =',16); OUTDEC(.WARNINGFOUND,1); CRLF; OUTSXFLD('; # Errors =',16); OUTDEC(.ERRORFOUND,1); CRLF; END; CRLF; CRLF; DEVICE_LSTDEV; ! IF NOT.LSTFLG THEN FORCE(2); ! IF NOT.BINFLG THEN FORCE(1); END; GLOBAL ROUTINE READALINE= BEGIN ! ! READ THE NEXT INPUT LINE INTO 'BUFF', PRINTING THE PREVIOUS ! LINE IF THIS HAS NOT ALREADY BEEN DONE (EG., BY AN ERROR ! MESSAGE. A LINE NUMBER IS ASSIGNED TO THE INPUT LINE. ! EXTERNAL READTEXT, ! FROM ION.MAC QUOTETYPE; ! FROM LEXAN FORCELINE(); VALIDBUF_1; LINCNT_.LINCNT+16; READTEXT(); IF .FINFLG THEN BEGIN BUFF[0] _ ' ;)?M?1' ; VALIDBUF_0; IF .LASTLINE EQL #777777 THEN LASTLINE_.LINCNT-16; SELECT .SCANTYPE OF NSET "S": (ERRPRNT(0,.SCANCHANGE,ERSYMRQ); BUFF[0]<29,7>_.QUOTETYPE); "C": (ERRPRNT(0,.SCANCHANGE,ERUNTCOM); BUFF[0]<29,7>_ "%" ); "M": (ERRPRNT(.LOBRAC,.SCANCHANGE,ERUNTMAC); BUFF[0]<29,7>_ "$" ); OTHERWISE: EXITSELECT; ALWAYS: ERRLEVEL_1 TESN END; NCBUFF_#777777+.LINCNT^18; !START AT CHARACTER -1 SINCE WE ! TACK ON EXTRA BLANK IN FRONT END; ! INITIALIZATION ROUTINES !------------------------ OWN BEGTIME; MACHOP CALLI=#047; MACRO RUNTIM=(REGISTER R; R_0; CALLI(R,#27))$; ROUTINE REINIT= BEGIN ! THIS ROUTINE IS THE PRIMARY INITIALIZATION OF THE COMPILER. ! IT IS CALLED TO RE-INIT THE SYSTEM FOR EACH COMPILATION. EXTERNAL FREEVEC, HT, PLHEAD, UNAMNO; CLEARCORE(FREEVEC,MAXSEPLST+1); TOPOFTABLE_.SAVTOP; MOVECORE(.SAVHASH,HT,HTSIZE); TNCHAIN_TNCHAIN_TNCHAIN<0,0>; PLHEAD_'P$AAA'; UNAMNO_LABELNO_0; MODMAIN[0]_MODMAIN[1]_-2; MODDONE_ALDON_0; DEVICE_LSTDEV; BUFFL_BUFFSIZ*5; WHILE NOT INITIO(0) DO; BEGTIME_RUNTIM; !MUST BE DONE AFTER INITIO IF .ACCUM EQL -2 THEN (MODNAME_'$MODU'; MODNAME[1]_'LE') ELSE (MODNAME_.ACCUM; MODNAME[1]_.ACCUM[1]); CSNAME_.MODNAME; CSFLAG_-1; CODESIZE_DATASIZE_NINLINES_0; SYM_DEL_0; VALIDBUF_0; PAGE(); NLINES_0; LINCNT_0; LASTLINE_#777777; CLEARCORE(ROOM[ROOMTOBE0],ROOMSIZE-ROOMTOBE0); SYNINIT(1); NOVALUE END; ROUTINE MODINIT= BEGIN EXTERNAL ELTOS,LASTELMARK,NUMPARMS; NEXTLOCAL_MAXLOCALS_NEXTOWN_NEXTGLOBAL_0; TOS_LASTMARK_ELTOS_LASTELMARK_0; PURGED_.LASTPUR; MODDONE_MAINDECL_RESERVED_0; ERRORFOUND_WARNINGFOUND_ERRLEVEL_0; LOOPDEPTH_MAXPARMS_NUMPARMS_0; BLOCKLEVEL_1; STRUCLEVEL_#777777; 0 END; GLOBAL ROUTINE GENIT(DUMMY)= BEGIN BIND RTN=DUMMY[1]; EXTERNAL NOWSEG,GETSEG; LOCAL VSAV,OLDSEG; IF .ERRORFOUND EQL 0 THEN BEGIN OLDSEG_.NOWSEG; VSAV_.VALIDBUF; VALIDBUF_0; DELAYDRIVER(.SYM); TNBIND(.SYM); CODEDRIVER(.SYM); FINALDRIV(0); CRLF; CRLF; RSTRTHREAD(.PURGED); PURGED_.LASTPUR; VALIDBUF_.VSAV; IF .RTN<0,18> GTR #400000 THEN GETSEG(.OLDSEG); END; END; !--------------------------HERE IT IS FOLKS------------------------- ! ! ! BLISS COMPILER MAIN DRIVER CODE ! ---------------------------------- ! ! REGISTER R9=9,R7=7; EXTERNAL JOBREL,SWAPDEV,SWAPPPN; MACHOP TTCALL=#51; CCLCTL_.VREG; ! INITIALIZE THE SWAPPING DATA NOWSEG_0; IF .SWAPDEV EQL 0 ! WILL BE NON-ZERO AFTER ^C-START OR PUNT THEN (IF .CCLCTL THEN (R9_SIXBIT 'SYS'; R7_0); ! CMU-SPECIFIC KLUDGE SEGBLK[0]_SWAPDEV_.R9; SEGBLK[4]_SWAPPPN_.R7; SEGBLK[2]_SEGBLK[3]_SEGBLK[5]_0); ONCEONLY(0); CONTINUOUSLY DO BEGIN REINIT(); OUTS('.PDP10');CRLF; DO BEGIN IF .MODDONE THEN IF .DEL NEQ HMODULE THEN (ERRPRNT(.NDEL,.NDEL,ERMISSBRC); EXITLOOP); MODINIT(); DOMODULE(0); LASTPUR_0; MODDONE_-1; IF NOT .NOTREE THEN GENIT(); WRITEFINAL(); IF .DEL EQL HELUDOM THEN SYNINIT(0); END UNTIL .FINFLG; DEVICE_ERRDEV; CRLF; CRLF; OUTS('; Size: '); OUTDEC(.CODESIZE,1); OUTPUT("+"); OUTDEC(.DATASIZE,1); IF .NINLINES GTR 0 THEN (OUTS(' + '); OUTDEC(.NINLINES,1); OUTS(' INLINE'); PLURAL(.NINLINES)); CRLF; OUTS('; Run Time: '); RUTIME_((RUNTIM-.BEGTIME+5)/10); IF .RUTIME LEQ 6000 THEN BEGIN OUTDEC((.RUTIME+50)/100,1); OUTS(' Second'); PLURAL((.RUTIME+50)/100) END ELSE BEGIN OUTDEC(.RUTIME/6000,1); OUTPUT("."); OUTDEC((.RUTIME/60) MOD 100,2); OUTS(' Minutes') END; CRLF; OUTS('; Core Used: '); OUTDEC(B11LO_((.JOBREL+1^9)^(-10)),1); OUTPUT("K"); CRLF; OUTS('; Compilation Complete'); CRLF; ! IF STATOUT() THEN WARNEM(0,WASTATERR); DEVICE_LSTDEV; CRLF; OUTS('.END '); OUTPXLIM(MODMAIN,10); CRLF; DEVICE_ERRDEV; INCR I FROM 0 TO IF .TTYLST THEN 8 ELSE 2 DO CRLF; DEVICE_LSTDEV; RESET(); IF .TTYDIR LSS 0 THEN TTCALL(3, PLIT(ASCIZ 'NEW BLISS.TTO WRITTEN?M?J')); END; END END ELUDOM