!***COPYRIGHT (C) 1974, 1975, 1976, 1977 DIGITAL EQUIPMENT CORP., MAYNARD, MASS.*** ! *** LAST MODIFIED BY ILG ON 30-MAY-76 MODULE TRM(SREG = #17, FREG = #16, VREG = #15, MLIST,TIMER=EXTERNAL(SIX12),FSAVE)= BEGIN ! THIS MODULE CONTAINS ALL THE ROUTINES REQUIRED TO MAKE A TERMINAL TABLE !NOTE - PHONE NUMBER QUESTIONS HAVE BEEN ! REMOVED BY PLACING TWO EXCLAMATION POINTS IN FRONT OF THEM ! TO RESTORE THEM MEERLY TECO THE !!'S OUT ! HOWEVER!!! --> THE OUTPUT TO THE MACRO FILE ROUTINE FOR ! IT STILL NEEDS TO BE WRITTEN GLOBAL BIND TRM = 2; REQUIRE MGNMAC.BLI; REQ(MGNEXT); REQ(MGNMC2); GLOBAL TRMCOUNT; EXTERNAL MOVE, LINK, UNLINK, COMPARE, MAKUPORT, DPNAME, GETNODEADDR, PRNODENAME, MAKENODE, TIDEL, TIDELC; BIND INITIAL = 0, PERMANENT = 1; COMMENT; ! ROUTINE TERMUNHOOK ! ======= ========== ! THIS ROUTINE BREAKS THE CONNECTION BETWEEN A TERMINAL AND A PORT ! PORT ROUTINE TERMUNHOOK( TERMADDR ) = BEGIN REGISTER PORTADDR; MAP FORMAT TERMADDR; MAP FORMAT PORTADDR; PORTADDR _ .TERMADDR[T0PORTPTR]; TERMADDR[T0PORTPTR] _ 0; PORTADDR[PT0SRCPTR] _ 0 NOTE; MIGHT IT BE NICE TO INFORM THE USER OF THE BREAK? END; COMMENT; ! ROUTINE PRINTTERMNAME ! ======= ============= ! OUTPUTS TERMNAME TO CONTROLLING TTY ROUTINE PRINTTERMNAME( TERMNAME ) = BEGIN TYPE( 'FOR [TERMINAL ]'); OUTSA( .TERMNAME ); TYPE( '[:?M?J]' ) END; COMMENT; ! ROUTINE INTERM ! ======= ====== ! THIS ROUTINE ASKS FOR AND ACCEPTS A TERM NAME FROM THE USER ROUTINE INTERM(A)= BEGIN LOCAL NONEFLG; NONEFLG _ FALSE; !INIT LOCAL XTYPE(.A); !OUTPUT THE QUESTION IF (ACHAR _ INPUT(ALINE,ALINELENGTH)) EQL CRCHAR THEN RETURN 0; IF .ACHAR EQL "<" THEN BEGIN ADV(ABUFF,ABPTR,ACOUNT,ACHAR); !EAT LEADING "<" NONEFLG _ TRUE !AND REMEMBER IT END; IF NOT .ERRORFLG THEN GETNAME(ALINE,ACHAR); ! IF NO ERROR ACCEPTING THE LINE THEN GATHER A NAME IF .ACHAR EQL ">" AND .PRIM[0] EQL 'NONE' AND .NONEFLG THEN BEGIN PRIM[0] _ NONETOKEN; !FORCE PSEUDO-TOKEN ADV(ABUFF,ABPTR,ACOUNT,ACHAR) !EAT THE > END; IF NOT .ERRORFLG THEN TOOMUCHINPUT(); ! IF NOT END OF LINE THEN ERROR IF NOT .ERRORFLG THEN IF SUBQUEUES() OR .PERIODS NEQ 0 THEN ERROR( 45 ); ! IF STILL NO ERRORS, SEE IF THE USER ! PUT PERIODS IN THE TERM NAME IF .ERRORFLG THEN 0 ELSE 1 ! IF ERROR IN ANY PART, RETURN 0 ELSE 1 END; COMMENT; ! ROUTINE NUMTRM ! ======= =========== ! THIS ROUTINE NUMBERS THE TERMINALS GLOBAL ROUTINE NUMTRM = BEGIN REGISTER I, TERMADDR; MAP FORMAT TERMADDR; TERMADDR _ .TERMTAB; I _ 0; WHILE .TERMADDR NEQ 0 DO BEGIN TERMADDR[T0TTYNO] _ I _ .I + 1; TERMADDR _ .TERMADDR[T0FORE] END; TRMCOUNT _ .I END; COMMENT; ! ROUTINE CREATETERM ! ======= ========== ! THIS ROUTINE STUFFS A NEW TERM IN THE TERMTAB ! INPUT POINTER TO TERMNAME ! OUTPUT POINTER TO TERM TABLE ENTRY ROUTINE CREATETERM( TERMNAME ) = BEGIN REGISTER TERMADDR; MAP FORMAT TERMADDR; TERMADDR _ GMEM(T0SIZE); TERMADDR[T0LINKS] _ 0; MOVE( %FROM% .TERMNAME, %TO% TERMADDR[T0CNAME], T0CNAMELEN %WORDS%); LINK( %TO% TERMTAB, .TERMADDR ); .TERMADDR END; COMMENT; ! ROUTINE NULLTERMNAME ! ======= ============ ! RETURNS TRUE IF THE TERMNAME IS NULL ROUTINE NULLTERMNAME(LOC)= BEGIN ! RETURNS TRUE IF THE CONTENTS OF LOC IS NULL, ELSE FALSE RETURN IF ..LOC EQL 0 THEN TRUE ELSE FALSE END; FORWARD GETTERMADDR(1); COMMENT; ! ROUTINE MAKUTERM ! ======= ======== ! THIS ROUTINE MAKES A TERM TO ATTACH TO A PORT GLOBAL ROUTINE MAKUTERM( PORTADDR, UTYPE ) = BEGIN OWN DONE, TERMADDR; MAP FORMAT TERMADDR; MAP FORMAT PORTADDR; %LOCAL% ROUTINE TRYANOTHER = BEGIN WARN( 0 ) END; %LOCAL% ROUTINE SETSRC( PORTADDR ) = BEGIN TERMADDR[T0PORTPTR] _ .PORTADDR; DONE _ TRUE END; %LOCAL% ROUTINE FIXUP( PORTADDR ) = BEGIN TERMUNHOOK( .TERMADDR ); SETSRC( .PORTADDR ) END; LABEL LOOP1, LOOP2; DONE _ FALSE; LOOP1: REPEAT ! UNTIL WE GET AN ACCEPTABLE ANSWER BEGIN LOOP2: REPEAT ! UNTIL WE GET A GOOD TERM NAME BEGIN IF .UTYPE EQL MODTYPE THEN TYPE( '[NEW ]' ); TYPE( 'ATTACHED [TERMINAL]?R(' ); IF .UTYPE EQL MODTYPE THEN TYPE( ',' ); IF INTERM( PAZ '"",?R)[: ??]') EQL 0 THEN IF NOT .ERRORFLG THEN BEGIN IF .UTYPE EQL MODTYPE THEN RETURN -1; ERROR(90); WARN(0) END ELSE BEGIN ! IF THE ANSWER WAS UNACCEPTABLE ERROR( 87 ); ! TELL THE USER AND ASK AGAIN WARN( 0 ) END ELSE LEAVE LOOP2 END; ! WE GOT A TERM NAME IF .PRIM[0] EQL NONETOKEN THEN RETURN 0; IF (TERMADDR _ GETTERMADDR( PRIM<36,7> )) EQL 0 THEN BEGIN TERMADDR _ CREATETERM( PRIM<36,7> ); SETSRC( .PORTADDR ); TERMADDR[T0TOBEDEFINED] _ TRUE; LEAVE LOOP1 END ELSE BEGIN SETSRC(.PORTADDR); IF .DONE THEN LEAVE LOOP1 END END; .TERMADDR END; FORWARD ACCEPTTERM(1),MAKTERM(1); COMMENT; ! ROUTINE MAKETERM ! ======= ======== ! GIVEN THE ADDRESS OF A TERMNAME, THIS ROUTINE CAUSE THE APPROPRIATE ! QUESTIONS TO BE ASKED TO GENERATE ONE OR MORE TERMS ( MORE IF ! THE TERM NAME WAS NULL) GLOBAL ROUTINE MAKETERM(TERMNAME)= BEGIN REGISTER TERMADDR; MAP FORMAT TERMADDR; IF .ALLSWITCH THEN BEGIN TERMADDR _ .TERMTAB; WHILE .TERMADDR NEQ 0 DO BEGIN IF .TERMADDR[T0TOBEDEFINED] THEN BEGIN PRINTTERMNAME( TERMADDR[T0CNAME] ); MAKTERM( .TERMADDR); END; TERMADDR _ .TERMADDR[T0FORE]; CRLF END; ZERO( .TERMNAME, .TERMNAME + N0NAMELEN * 4 ) END; IF SUBQUEUES() OR .PERIODS NEQ 0 THEN RETURN( ERROR( 45 ) ); ! PERIODS IN A TERM NAME ARE NO NO'S IF NULLTERMNAME(.TERMNAME) THEN ! IF NO TERM SPECIFIED BEGIN ! ASK THE USER FOR TERM NAMES REPEAT ! UNTIL HE INPUTS A BY BEGIN ! ITSELF IF INTERM( PAZ '[COBOL NAME]?R(,?R)[: ??') EQL 0 THEN IF NOT .ERRORFLG THEN RETURN ELSE BEGIN ! IF THE ANSWER WAS UNACCEPTABLE ERROR( 87 ); WARN( 0 ) END ELSE ACCEPTTERM(PRIM<36,7>); ! IF OK NAME EXECUTE THE FUNCTION CRLF END END; ACCEPTTERM(.TERMNAME) ! IF A TERM WAS SPECIFIED, USE IT END; COMMENT; ! ROUTINE GETTERMADDR ! ======= =========== ! SEARCHES THE TERMTAB FOR THE TERMNAME CONTAINED AT THE CONTENTS OF TERMNAME ! IF FOUND, RETURNS THE ADDRESS OF THE TERM TABLE ENTRY ! OTHERWISE RETURNS 0 ROUTINE GETTERMADDR(TERMNAME) = BEGIN REGISTER TERMADDR; MAP FORMAT TERMADDR; IF TOOLONG(.TERMNAME,T0CNAMESIZE, T0CNAMELEN * 5) THEN BEGIN WARN( 4 ); TRUNCATE(.TERMNAME, T0CNAMESIZE, T0CNAMELEN * 5) END; IF ( TERMADDR _ .TERMTAB ) EQL 0 THEN RETURN 0; ! START AT THE BEGINNING ! WHILE THE NAME AT TERMNAME ISN'T THE NAME IN THE TABLE DO WHILE NOT COMPARE(.TERMNAME,TERMADDR[T0CNAME],T0CNAMELEN) DO ! IF END OF TABLE RETURN 0 IF (TERMADDR _ .TERMADDR[T0FORE]) EQL 0 THEN RETURN 0; .TERMADDR ! A MATCH! SO RETURN THE ADDRESS END; FORWARD MAKTERM(1), MODTERM(1); COMMENT; ! ROUTINE ACCEPTTERM ! ======= ========== ! THIS ROUTINE CREATES A TERM TABLE ENTRY IF ONE DOES NOT EXIST ! THEN CALLS MAKTERM TO ASK THE QUESTIONS TO FILL THE ENTRY ! IF THE TERM ALREADY EXISTS, THE USER IS ASKED HOW HE WANTS TO ! HANDLE IT ROUTINE ACCEPTTERM(TERMNAME)= BEGIN REGISTER TERMADDR; MAP FORMAT TERMADDR; PRINTTERMNAME( .TERMNAME ); ! SEE IF ALREADY DEFINED IF (TERMADDR _ GETTERMADDR(.TERMNAME)) EQL 0 THEN TERMADDR _ CREATETERM( .TERMNAME ) ! MAKE A TERM TABLE ENTRY ELSE BEGIN IF NOT .TERMADDR[T0TOBEDEFINED] THEN BEGIN ASKSTR( 'TERM [ALREADY EXISTS]?R(IGNORE, MODIFY, REPLACE?R)[: ??]', PLIT( ASCII 'REPLA', MAKTERM, ASCII 'MODIF', MODTERM, 0, IGNORE, ASCII 'IGNOR', IGNORE), .TERMADDR); RETURN END END; MAKTERM(.TERMADDR) END; FORWARD ASKALTERNATES(1), DTATTACHEDPORT(1); FORWARD ASKLEAFSTAT(1); COMMENT; ! ROUTINE MAKTERM ! ======= ======= ! THIS ROUTINE ASKS THE QUESTIONS TO MAKE ONE (AND ONLY ONE) TERM ! AND RECORDS THE RESPONSES IN THE APPROPRIATE TERM TABLE ENTRY ROUTINE MAKTERM(TERMADDR)= BEGIN REGISTER PORTPTR; MAP FORMAT PORTPTR; MAP FORMAT TERMADDR; IF .TERMADDR[T0PORTPTR] NEQ 0 THEN DTATTACHEDPORT(.TERMADDR) ELSE TERMADDR[T0PORTPTR] _ MAKUPORT(.TERMADDR,NEWTYPE); ASKALTERNATES( .TERMADDR ); TERMADDR[T0OSTAT] _ ASKSTAT( PAZ 'INITIAL [(O)STAT]US FOR OUTPUT?R(ENABLED,DISABLED?R)[: ??]', ENABLED ); ASKLEAFSTAT( .TERMADDR ); TERMADDR[T0TOBEDEFINED] _ FALSE END; FORWARD ADDALTERNATES; COMMENT; ! ROUTINE ASKALTERNATES ! ======= ============= ! THIS ROUTINE ASKS THE NAMES OF ANY ALTERNATE TERMINALS ROUTINE ASKALTERNATES( TERMADDR ) = BEGIN MAP FORMAT TERMADDR; TERMADDR[T0ALTERPTR] _ 0; ASKNAME( '[ALTERNATE TERMINALS]?R(,?R)[: ??]', T0CNAMESIZE ); ADDALTERNATES( .TERMADDR ) END; COMMENT; ! ROUTINE ADDALTERNATES ! ======= ============= ! THIS ROUTINE ASKS FOR THE ALTERNATES AFTER THE FIRST AND STORES THEM ROUTINE ADDALTERNATES( TERMADDR ) = BEGIN REGISTER ALTADDR, TERM, ALTPTR, ALTER; LABEL LOOP; MAP FORMAT TERMADDR; MAP FORMAT TERM; MAP FORMAT ALTER; MAP FORMAT ALTPTR; WHILE .PRIM NEQ 0 DO BEGIN IF ( ALTADDR _ GETTERMADDR( PRIM<36,7> )) EQL 0 THEN BEGIN TERM _ CREATETERM( PRIM<36,7> ); TERM[T0TOBEDEFINED] _ TRUE END; IF .ALTADDR EQL .TERMADDR THEN BEGIN ERROR( 100 ); WARN( 0 ) END ELSE BEGIN ALTPTR _ .TERMADDR[ T0FIRSTALTERNATE ]; LOOP: WHILE .ALTPTR NEQ 0 DO BEGIN IF COMPARE( ALTPTR[ A0CNAME ], PRIM, T0CNAMELEN ) THEN LEAVE LOOP; ALTPTR _ .ALTPTR[ A0FORE ] END; IF .ALTPTR NEQ 0 THEN WARN( 11 ) ELSE BEGIN ALTER _ GMEM( A0SIZE ); MOVE( PRIM, ALTER[A0CNAME], T0CNAMELEN ); ALTER[A0LINKS] _ 0; LINK( TERMADDR[T0ALTERPTR], .ALTER ); END END; ASKNAME( '[ ??]', T0CNAMESIZE) END END; !!FORWARD ASKPHONENUMBER; !! !!COMMENT; !! !!! ROUTINE ASKPHONE !!! ======= ======== !!! THIS ROUTINE ASKS FOR A PHONE NUMBER AND STORES IT AWAY !! !!ROUTINE ASKPHONE( TERMADDR ) = !! BEGIN !! MAP FORMAT TERMADDR; !! !! TERMADDR[T0PHONE] _ ASKPHONENUMBER( PAZ '[PHONE] NUMBER?R(,?R)[: ??]', NOT NONEOK ); !! END; !!COMMENT; !! !!! ROUTINE ASKPHONENUMBER !!! ======= ============== !!! THIS ROUTINE ASKS A QUESTION AND ACEPTS A PHONE NUMBER AS A RESPONSE !! !!ROUTINE ASKPHONENUMBER( QUESTION, NONEFLAG ) = !! BEGIN !! !! OWN PNUMBER, !! BP, !! COUNT; !! !! LABEL LOOP1, !! SEL; !! !! MACRO STORE = REPLACEI( BP, .ACHAR )$; !! !! REPEAT ! UNTIL WE GET A GOOD ANSWER !! BEGIN !! IF ASKL( .QUESTION ) THEN RETURN 0; ! IF CARRIAGE RETURN ONLY RETURN 0 !! !! IF .NONEFLAG THEN ! IF ALLOWED THEN !! IF MATCHALINE( NONE ) THEN RETURN -1; ! THEN IF RETURN -1 !! !! ! ELSE ! !! !! PNUMBER _ GMEM( PN0SIZE ); ! GET CORE FOR THE PHONE NUMBER !! BP _ ( .PNUMBER )< 36, 7>; ! MAKE A BYTE POINTER TO STORE STUFF !! COUNT _ PN0LEN - 1; ! HOW MANY CHARACTERS ARE OK !! !! LOOP1: REPEAT ! UNTIL DONE OR ERROR !! BEGIN !! SEL: SELECT TRUE OF !! NSET !! NUMERIC( ACHAR ): ( STORE; LEAVE SEL ); ! DIGITS ARE GOOD !! .ACHAR EQL "-": ( STORE; LEAVE SEL ); ! HYPENS ARE ACCEPTABLE !! BLANK( ACHAR ): ( STORE; LEAVE SEL ); ! BLANKS ARE OK !! EOL( ACHAR ): RETURN .PNUMBER; ! END OF LINE MEANS DONE !! OTHERWISE: ( ERROR( 108 ); LEAVE LOOP1 ); ! ANYTHING ELSE IS AN ERROR !! TESN; !! ADV( ABUFF, ABPTR, ACOUNT, ACHAR ); ! GET THE NEXT CHARACTER IN ALINE !! IF ( COUNT _ .COUNT - 1 ) LEQ 0 THEN ! CHECK TO SEE IF THE RESPONSE IS TOO LONG !! BEGIN !! ERROR( 109 ); ! IF IT IS THEN ERROR !! LEAVE LOOP1 !! END !! END; !! WARN( 0 ); ! TELL THE USER TO TRY AGAIN !! PMEM( .PNUMBER, PN0SIZE ) ! RELEASE THE CORE FOR THIS MESSAGE !! END !! !! END; FORWARD ASKLEAVES; COMMENT; ! ROUTINE ASKLEAFSTAT ! ======= =========== ! THIS ROUTINE ASKS ALL THE GARBAGE ABOUT DISABLING TERMINALS ROUTINE ASKLEAFSTAT( TERMADDR ) = BEGIN MAP FORMAT TERMADDR; OWN DIS, DPS; %LOCAL% ROUTINE SETENA = DPS _ ENABLED; %LOCAL% ROUTINE SETDIS = DPS _ DISABLED; IF NOT ( ASKYESORNO( 'ARE ANY [LEAVES ]TO BE PERMANENTLY AND/OR INITIALLY [DISABLED] FOR THIS TERMINAL?R(NO,YES?R)[: ??]', NO ) ) THEN BEGIN TERMADDR[ T0STATUS ] _ ENABLED ^ 1 + ENABLED; RETURN END; DIS _ ASKSTAT( PAZ '[DEFAULT INITIAL STATUS] ?R(ENABLED, DISABLED?R)[: ??]', ENABLED ); ASKLEAVES( .DIS, INITIAL, .TERMADDR ); ASKSTR( '[DEFAULT PERMANENT STATUS] ?R(NOT-DISABLED,DISABLED?R)[: ??]', PLIT( ASCII 'NOT-D', SETENA, ASCII 'DISAB', SETDIS, 0, SETENA ), 0 ); ASKLEAVES( .DPS, PERMANENT, .TERMADDR ); TERMADDR[T0STATUS] _ .DPS ^ 1 + .DIS END; COMMENT; ! ROUTINE ASKLEAVES ! ======= ======= ! THIS ROUTINE ASKS FOR LEAVES AND ATTACHES THEM TO THE LEAFSTATUS ! LIST FOR THE SPECIFIED TERMINAL ROUTINE ASKLEAVES( DEFAULT, STATTYPE, TERMADDR ) = BEGIN REGISTER LEAF, LEAFPTR, FIRST; LABEL LOOP, INNERLOOP, INNERLOOP2; MAP FORMAT TERMADDR; MAP FORMAT LEAF; MAP FORMAT LEAFPTR; CASE .STATTYPE ^ 1 + .DEFAULT OF SET %00% TYPE( '[INITIALLY ENABLED]' ); %01% TYPE( '[INITIALLY DISABLED]' ); %10% TYPE( '[NOT PERMANENTLY DISABLED]' ); %11% TYPE( '[PERMANENTLY DISABLED]' ); TES; TYPE( '[ LEAVES]?R(,?R)[: ??]' ); FIRST _ TRUE; LOOP: REPEAT BEGIN IF .FIRST THEN FIRST _ FALSE ELSE TYPE( '[?I?I?I??' ); ACHAR _ INPUT( ALINE, ALINELENGTH ); SKIPBLANKS( ABUFF, ABPTR, ACOUNT, ACHAR ); IF EOL( ACHAR ) THEN RETURN; INNERLOOP: WHILE NOT EOL( ACHAR ) DO BEGIN GETNAME( ABUFF, ABPTR, ACOUNT, ACHAR ); IF GETNODEADDR( PRIM<0,0> ) EQL 0 THEN LEAVE INNERLOOP WITH ERROR( 33 ); LEAFPTR _ .TERMADDR[ T0FIRSTLEAF ]; INNERLOOP2: WHILE .LEAFPTR NEQ 0 DO BEGIN IF COMPARE( LEAFPTR[ L0NODENAME ], PRIM, N0NAMELEN * 4 ) THEN IF .STATTYPE EQL .LEAFPTR[ L0TYPE ] THEN LEAVE INNERLOOP2; LEAFPTR _ .LEAFPTR[ L0FORE ] END; IF .LEAFPTR NEQ 0 THEN WARN( 12 ) ELSE BEGIN LEAF _ GMEM( L0SIZE ); MOVE( PRIM, LEAF[L0NODENAME], N0NAMELEN * 4 ); LEAF[L0STATUS] _ (NOT .DEFAULT) AND 1; LEAF[L0TYPE] _ .STATTYPE; LINK( %TO% TERMADDR[T0LEAFSTATUS], .LEAF ) END; SKIPBLANKS( ABUFF, ABPTR, ACOUNT, ACHAR ); IF .ACHAR EQL "," THEN ADV( ABUFF, ABPTR, ACOUNT, ACHAR ) ELSE IF NOT EOL( ACHAR ) THEN LEAVE INNERLOOP WITH ERROR( 46 ) END END END; FORWARD DISTERM(1); COMMENT; ! ROUTINE DISPTERM ! ======= =========== ! THIS ROUTINE HANDLES THE INDIVIDUAL CASES OF DISPLAY TERM:... ! CASE 1: IF AN INDIVIDUAL TERM IS REQUESTED ( BY NAME ), DISTERM IS ! CALLED WITH THE ADDRESS OF THE TERM TABLE ENTRY ! CASE 2: IF /ALL WAS SPECIFIED, DISTERM IS CALLED FOR EACH ENTRY IN ! TERM TABLE ! CASE 3: IF NO NAME OR SWITCH WAS GIVEN, THE USER IS ASKED FOR THE ! NAMES OF THE TERMS TO BE DISPLAYED GLOBAL ROUTINE DISPTERM(TERMNAME)= BEGIN REGISTER TERMADDR; MAP FORMAT TERMADDR; IF SUBQUEUES() OR .PERIODS NEQ 0 THEN RETURN( ERROR( 45 ) ); ! PERIODS IN A TERM NAME ARE NO NO'S IF NULLTERMNAME(.TERMNAME) AND NOT .ALLSWITCH THEN BEGIN ! ASK THE USER FOR TERM NAMES REPEAT ! UNTIL HE INPUTS A BY BEGIN ! ITSELF IF INTERM( PAZ '[COBOL NAME]?R(, ?R)[: ??') EQL 0 THEN IF NOT .ERRORFLG THEN RETURN ELSE BEGIN ERROR( 87 ); WARN( 0 ) END ELSE IF (TERMADDR _ GETTERMADDR(PRIM)) EQL 0 THEN RETURN(ERROR(43)) ELSE DISTERM(.TERMADDR); CRLF END END; IF .ALLSWITCH THEN BEGIN TERMADDR _ .TERMTAB; WHILE .TERMADDR NEQ 0 DO BEGIN DISTERM( .TERMADDR); TERMADDR _ .TERMADDR[T0FORE] END; RETURN END; IF (TERMADDR _ GETTERMADDR(.TERMNAME)) EQL 0 THEN RETURN(ERROR(43)) ELSE DISTERM(.TERMADDR) END; FORWARD DTCNAME , DTOSTAT, DTLEAFSTAT; FORWARD DTALTERNATES; !!FORWARD DTPHONE; COMMENT; ! ROUTINE DISTERM ! ======= ======= ! THIS ROUTINE DISPLAYS THE TERM'S NAME, AND IF THE TERM IS UNDEFINED, ! THEN "NOT YET DEFINED..." IS DISPLAYED, OTHERWISE THE TERM PARAMETERS ! ARE DISPLAYED ROUTINE DISTERM(TERMADDR)= BEGIN MAP FORMAT TERMADDR; DTCNAME(.TERMADDR); IF .TERMADDR[T0TOBEDEFINED] THEN BEGIN OUTPUT('NOT YET DEFINED, PLEASE MAKE OR MODIFY IT?M?J'); DTATTACHEDPORT(.TERMADDR) END ELSE BEGIN DTATTACHEDPORT(.TERMADDR); DTALTERNATES(.TERMADDR); DTOSTAT(.TERMADDR); DTLEAFSTAT(.TERMADDR); END; OUTPUTCRLF END; COMMENT; ! ROUTINE DTCNAME ! ======= ========= ! THIS ROUTINE DISPLAYS THE TERM NAME ROUTINE DTCNAME(TERMADDR)= BEGIN MAP FORMAT TERMADDR; OUTPUT('COBOL NAME: '); XOUTPUT(TERMADDR[T0CNAME]); OUTPUTCRLF END; COMMENT; ! ROUTINE DTERMCNAME ! ======= ========= ! THIS ROUTINE DISPLAYS THE TERM NAME WITHOUT LABEL GLOBAL ROUTINE DTERMCNAME(TERMADDR)= BEGIN MAP FORMAT TERMADDR; XOUTPUT(TERMADDR[T0CNAME]) END; COMMENT; COMMENT; ! ROUTINE DTALTERNATES ! ======= ========= ! THIS ROUTINE DISPLAYS THE TERMINAL'S ALTERNATES ROUTINE DTALTERNATES(TERMADDR)= BEGIN MAP FORMAT TERMADDR; REGISTER ALTERPTR; MAP FORMAT ALTERPTR; OUTPUT( 'ALTERNATE TERMINALS: ' ); IF .TERMADDR[T0ALTERPTR] EQL 0 THEN OUTPUT( '?M?J' ) ELSE BEGIN ALTERPTR _ .TERMADDR[T0ALTERPTR]; WHILE .ALTERPTR NEQ 0 DO BEGIN XOUTPUT( ALTERPTR[A0CNAME] ); OUTPUTCRLF; ALTERPTR _ .ALTERPTR[A0FORE]; IF .ALTERPTR NEQ 0 THEN OUTPUT( ' ' ) END END END; COMMENT; ! ROUTINE DTATTACHEDPORT ! ======= ========= ! THIS ROUTINE DISPLAYS THE ATTACHED PORT'S NAME ROUTINE DTATTACHEDPORT(TERMADDR)= BEGIN MAP FORMAT TERMADDR; OUTPUT( 'ATTACHED PORT: '); IF .TERMADDR[T0PORTPTR] NEQ 0 THEN DPNAME( .TERMADDR[T0PORTPTR]) ELSE OUTPUT(''); OUTPUTCRLF END; !!! ======= ======== !!! THIS ROUTINE DISPLAYS THE TERMINAL'S PHONE NUMBER !! !!ROUTINE DTPHONE(TERMADDR)= !! BEGIN !! MAP FORMAT TERMADDR; !! OUTPUT( 'PHONE NUMBER: '); !! IF .TERMADDR[T0PHONE] EQL 0 THEN !! OUTPUT( '' ) !! ELSE !! XOUTPUT( .TERMADDR[ T0PHONE ] ); !! !! OUTPUTCRLF !! END; COMMENT; ! ROUTINE DTOSTAT ! ======= ======== ! THIS ROUTINE DISPLAYS THE TERMINAL'S INITIAL OUTPUT STATUS ROUTINE DTOSTAT(TERMADDR)= BEGIN MAP FORMAT TERMADDR; OUTPUT( 'OUTPUT STATUS: '); IF .TERMADDR[T0OSTAT] THEN OUTPUT( 'ENABLED' ) ELSE OUTPUT( 'DISABLED' ); OUTPUTCRLF END; COMMENT; ! ROUTINE DTLEAFSTAT ! ======= ========= ! THIS ROUTINE DISPLAYS THE SIGNOFF CAPABILITY OF THE TERM ROUTINE DTLEAFSTAT(TERMADDR)= BEGIN REGISTER LEAFPTR; MAP FORMAT LEAFPTR; MAP FORMAT TERMADDR; IF ( LEAFPTR _ .TERMADDR[T0FIRSTLEAF] ) EQL 0 THEN BEGIN OUTPUT( 'LEAVES: '); SELECT .TERMADDR[T0STATUS] OF NSET 3: OUTPUT( '?M?J' ); 2: OUTPUT( '?M?J' ); OTHERWISE: OUTPUT( '?M?J' ); TESN END ELSE BEGIN IF .LEAFPTR[L0TYPE] NEQ INITIAL THEN BEGIN OUTPUT( 'LEAVES: ' ) ELSE OUTPUT( 'DISABLED>' ); OUTPUTCRLF END ELSE BEGIN OUTPUT( 'LEAVES INITIALLY '); IF NOT .TERMADDR[T0STATUS] THEN OUTPUT( 'ENABLED: ' ) ELSE OUTPUT( 'DISABLED: ' ); WHILE ( .LEAFPTR NEQ 0 ) AND ( .LEAFPTR[L0TYPE] EQL INITIAL ) DO BEGIN PRNODENAME( LEAFPTR[L0NODENAME] ); IF ( LEAFPTR _ .LEAFPTR[L0FORE] ) NEQ 0 AND .LEAFPTR[L0TYPE] EQL INITIAL THEN OUTPUTCOMMA; END; OUTPUTCRLF END; IF .LEAFPTR NEQ 0 THEN BEGIN IF NOT ( .TERMADDR[T0STATUS] ^ (-1) ) THEN OUTPUT( 'LEAVES NOT PERMANENTLY DISABLED: ' ) ELSE OUTPUT( 'LEAVES PERMANENTLY DISABLED: '); WHILE ( .LEAFPTR NEQ 0 ) DO BEGIN PRNODENAME( LEAFPTR[L0NODENAME] ); IF ( LEAFPTR _ .LEAFPTR[L0FORE] ) NEQ 0 THEN OUTPUTCOMMA END END ELSE BEGIN OUTPUT( 'LEAVES: ' ) ELSE OUTPUT( 'PERMANENTLY DISABLED>'); END END; OUTPUTCRLF END; COMMENT; ! ROUTINE DTRMNAMES ! ======= =========== ! THIS ROUTINE DISPLAYS THE COBOL NAMES OF ALL TERMINALS IN THE TERMTAB GLOBAL ROUTINE DTRMNAMES = BEGIN REGISTER TERMADDR; MAP FORMAT TERMADDR; TERMADDR _ .TERMTAB; WHILE .TERMADDR NEQ 0 DO BEGIN XOUTPUT(TERMADDR[T0CNAME]); TERMADDR _ .TERMADDR[T0FORE]; OUTPUTCRLF END END; ! ROUTINE MODITERM ! ======= =========== ! THIS ROUTINE HANDLES THE INDIVIDUAL CASES OF MODIFY TERM:... ! CASE 1: IF AN INDIVIDUAL TERM IS REQUESTED ( BY NAME ), MODTERM IS ! CALLED WITH THE ADDRESS OF THE TERM TABLE ENTRY ! CASE 2: IF /ALL WAS SPECIFIED, MODTERM IS CALLED FOR EACH ENTRY IN ! TERM TABLE ! CASE 3: IF NO NAME OR SWITCH WAS GIVEN, THE USER IS ASKED FOR THE ! NAMES OF THE TERMS TO BE MODIFIED GLOBAL ROUTINE MODITERM(TERMNAME)= BEGIN REGISTER TERMADDR; MAP FORMAT TERMADDR; IF SUBQUEUES() OR .PERIODS NEQ 0 THEN RETURN( ERROR( 45 ) ); ! PERIODS IN A TERM NAME ARE NO NO'S IF NULLTERMNAME(.TERMNAME) AND NOT .ALLSWITCH THEN BEGIN ! ASK THE USER FOR TERM NAMES REPEAT ! UNTIL HE INPUTS A BY BEGIN ! ITSELF IF INTERM( PAZ '[COBOL NAME]?R(, ?R)[: ??') EQL 0 THEN IF NOT .ERRORFLG THEN RETURN ELSE BEGIN ERROR( 87 ); WARN( 0 ) END ELSE IF (TERMADDR _ GETTERMADDR(PRIM)) EQL 0 THEN RETURN(ERROR(43)) ELSE MODTERM(.TERMADDR); CRLF END END; IF .ALLSWITCH THEN BEGIN TERMADDR _ .TERMTAB; WHILE .TERMADDR NEQ 0 DO BEGIN MODTERM( .TERMADDR); TERMADDR _ .TERMADDR[T0FORE] END; RETURN END; IF (TERMADDR _ GETTERMADDR(.TERMNAME)) EQL 0 THEN RETURN(ERROR(43)) ELSE MODTERM(.TERMADDR); END; FORWARD MTERMCNAME(1),MTERMOSTAT(1),MTERMPORT(1), MTERMLEAFSTAT(1),MTERMALL(1),TELLTERMCHANGES(1); FORWARD MTERMALTERNATES(1); !!FORWARD MTERMPHONE(1); COMMENT; ! ROUTINE MODTERM ! ======= ======= ! THIS ROUTINE TYPES THE NAME OF THE TERM TO BE MODIFIED, AND THEN ! ASKS FOR THE CHANGES TO BE MADE. MODTERM DOES ONLY ONE TERM AT A ! TIME. ROUTINE MODTERM(TERMADDR)= BEGIN OWN DONE; MAP FORMAT TERMADDR; %LOCAL% ROUTINE SETDONE = DONE _ TRUE; PRINTTERMNAME( TERMADDR[T0CNAME] ); ! TYPE THE NAME OF THE TERM TO BE MODIFIED IF .TERMADDR[T0TOBEDEFINED] THEN ! IF UNDEFINED THEN BEGIN MAKTERM(.TERMADDR) ! MAKE IT END ELSE BEGIN DONE _ FALSE; WHILE NOT .DONE DO ! OTHERWISE, UNTIL THE USER GIVES US A LONE DO BEGIN ASKSTR( '[CHANGE: ??]', ! ASK WHAT CHANGES PLIT( ASCII '??', TELLTERMCHANGES, ASCII 'COBOL', MTERMCNAME, ASCII 'ALTER', MTERMALTERNATES, ASCII 'LEAFS', MTERMLEAFSTAT, ASCII 'OSTAT', MTERMOSTAT, ASCII 'PORT', MTERMPORT, ASCII 'ALL', MTERMALL, 0, SETDONE), .TERMADDR); CRLF END END END; COMMENT; ! ROUTINE TELLTERMCHANGES ! ======= =============== ! THIS ROUTINE TELLS ( WITH LOTS OF WIND ) WHAT CHANGES CAN BE MADE ON ! A TERM ROUTINE TELLTERMCHANGES = BEGIN TYPE( 'TYPE [COBOL] TO CHANGE THE COBOL NAME OF THE TERMINAL[,]?J ?M' ); TYPE( 'TYPE [ALTER] TO CHANGE THE ALTERNATES OF THE TERMINAL[,]?J ?M' ); TYPE( 'TYPE [LEAFS] TO CHANGE THE LEAF STATUS OF THE TERMINAL[,]?J ?MTYPE [OSTATUS] TO CHANGE THE INITIAL TERMINAL OUTPUT STATUS[,]?J ?MTYPE [PORT] TO CHANGE THE ATTACHED PORT[,]?J ?MTYPE [ALL] TO CHANGE ALL OF THE ABOVE[,]?J ?MTYPE A CARRIAGE RETURN TO FINISH CHANGING THIS TERMINAL[(?R( WHEN DONE?R))]'); CRLF; END; COMMENT; ! ROUTINE MTERMALL ! ======= ======== ! THIS ROUTINE ASKS ALL THE QUESTIONS TO CHANGE A TERM ROUTINE MTERMALL(TERMADDR) = BEGIN REGISTER PORTPTR; MAP FORMAT PORTPTR; MAP FORMAT TERMADDR; MTERMCNAME( .TERMADDR); MTERMPORT( .TERMADDR); MTERMALTERNATES( .TERMADDR); MTERMOSTAT( .TERMADDR ); MTERMLEAFSTAT( .TERMADDR) END; COMMENT; ! ROUTINE MTERMCNAME ! ======= ========= ! THIS ROUTINE ASKS THE QUESTION TO CHANGE A TERMINAL'S COBOL NAME ROUTINE MTERMCNAME(TERMADDR)= BEGIN MAP FORMAT TERMADDR; IF .SHOW THEN DTCNAME(.TERMADDR); IF INTERM( PAZ 'NEW [COBOL NAME: ??]') EQL 0 THEN RETURN; IF GETTERMADDR(PRIM) NEQ 0 THEN RETURN (ERROR(44)); MOVE(PRIM, TERMADDR[T0CNAME], T0CNAMELEN) END; COMMENT; ! ROUTINE MTERMPORT ! ======= ========= ! THIS ROUTINE ASKS THE QUESTION TO CHANGE A TERMINAL'S ATTACHED PORT ROUTINE MTERMPORT(TERMADDR)= BEGIN REGISTER NEWPORT, OLDPORT; MAP FORMAT OLDPORT; MAP FORMAT TERMADDR; IF .SHOW THEN DTATTACHEDPORT(.TERMADDR); IF ( OLDPORT _ .TERMADDR[ T0PORTPTR ] ) NEQ 0 THEN TERMUNHOOK( .TERMADDR ); IF ( NEWPORT _ MAKUPORT( .TERMADDR, MODTYPE ) ) LSS 0 THEN BEGIN IF .OLDPORT NEQ 0 THEN BEGIN TERMADDR[ T0PORTPTR ] _ .OLDPORT; OLDPORT[ PT0SRCPTR ] _ .TERMADDR END END ELSE TERMADDR[ T0PORTPTR ] _ .NEWPORT END; COMMENT; FORWARD ZAPALTERNATES; COMMENT; ! ROUTINE MTERMALTERNATES ! ======= ========= ! THIS ROUTINE ASKS THE QUESTION TO CHANGE A TERMINAL'S ALTERNATES ROUTINE MTERMALTERNATES(TERMADDR)= BEGIN MAP FORMAT TERMADDR; IF .SHOW THEN DTALTERNATES( .TERMADDR ); TYPE( '[NEW ALTERNATE TERMINALS]?R(,"", ?R)[: ??]' ); ACHAR _ INPUT( ALINE, ALINELENGTH ); SKIPBLANKS( ABUFF, ABPTR, ACOUNT, ACHAR ); IF EOL( ACHAR ) THEN RETURN; ! ELSE ! ZAPALTERNATES( .TERMADDR ); IF MATCHALINE( NONE ) THEN RETURN; ! ELSE ! ZERO( PRIM, PRIM + T0CNAMELEN ); GATHER( ALINE, ACHAR, PRIM, T0CNAMESIZE ); ADDALTERNATES( .TERMADDR ) END; FORWARD ZAPLEAFSTAT; COMMENT; ! ROUTINE MTERMLEAFSTAT ! ======= ========= ! THIS ROUTINE ASKS THE QUESTION ABOUT CHANGING THE LEAF STATUS INFO ! OF THE TERM ROUTINE MTERMLEAFSTAT( TERMADDR ) = BEGIN MAP FORMAT TERMADDR; LOCAL ANSWER; OWN DIS, DPS; %LOCAL% ROUTINE SETENA = DPS _ ENABLED; %LOCAL% ROUTINE SETDIS = DPS _ DISABLED; %LOCAL% ROUTINE ZAPLEAVES( TERMADDR, ZAPTYPE ) = BEGIN LOCAL NEXT2, LEAFPTR, SIB; MAP FORMAT TERMADDR; MAP FORMAT LEAFPTR; MAP FORMAT SIB; LEAFPTR _ .TERMADDR[ T0FIRSTLEAF ]; WHILE .LEAFPTR NEQ 0 DO BEGIN NEXT2 _ .LEAFPTR[L0FORE]; IF .LEAFPTR[ L0TYPE ] EQL .ZAPTYPE THEN BEGIN IF ( SIB _ .LEAFPTR[L0FORE] ) EQL 0 THEN TERMADDR[T0LASTLEAF] _ .LEAFPTR[L0AFT] ELSE SIB[L0AFT] _ .LEAFPTR[L0AFT]; IF ( SIB _ .LEAFPTR[L0AFT] ) EQL 0 THEN TERMADDR[T0FIRSTLEAF] _ .LEAFPTR[L0FORE] ELSE SIB[L0FORE] _ .LEAFPTR[L0FORE]; PMEM( .LEAFPTR, L0SIZE ); END; LEAFPTR _ .NEXT2 END END; ! BEGIN ! IF .SHOW THEN DTLEAFSTAT( .TERMADDR ); DIS _ .TERMADDR[ T0STATUS ] AND 1; DPS _ .TERMADDR[ T0STATUS ] ^ (-1); IF ASKYESORNO( '[CHANGE INITIAL STATUS OF LEAVES]?R(NO, YES?R)[: ??]', NO ) THEN BEGIN DIS _ .TERMADDR[ T0STATUS ] AND 1; DIS _ ASKSTAT( PAZ '[NEW DEFAULT INITIAL STATUS] ?R(,ENABLED, DISABLED?R)[: ??]', .DIS ); ZAPLEAVES( .TERMADDR, INITIAL ); TYPE( '[NEW ]' ); ASKLEAVES( .DIS, INITIAL, .TERMADDR ) END ELSE BEGIN IF ASKYESORNO( 'DO YOU WISH TO [CHANGE ]THE [INITIAL LEAVES]?R(NO,YES?R)[: ??]', NO ) THEN BEGIN DIS _ .TERMADDR[ T0STATUS ] AND 1; ZAPLEAVES( .TERMADDR, INITIAL ); TYPE( '[NEW ]' ); ASKLEAVES( .DIS, INITIAL, .TERMADDR ) END END; IF ASKYESORNO( '[CHANGE PERMANENT STATUS OF LEAVES]?R(NO, YES?R)[: ??]', NO ) THEN BEGIN DPS _ ( .TERMADDR[ T0STATUS ] ^ (-1) ) AND 1; ASKSTR( '[NEW DEFAULT PERMANENT STATUS] ?R(,NOT-DISABLED,DISABLED?R)[: ??]', PLIT( ASCII 'NOT-D', SETENA, ASCII 'DISAB', SETDIS, 0, IGNORE ), 0 ); ZAPLEAVES( .TERMADDR, PERMANENT ); TYPE( '[NEW ]' ); ASKLEAVES( .DPS, PERMANENT, .TERMADDR ); END ELSE BEGIN IF ASKYESORNO( 'DO YOU WISH TO [CHANGE ]THE [PERMANENT LEAVES]?R(NO,YES?R)[: ??]', NO ) THEN BEGIN DPS _ ( .TERMADDR[ T0STATUS ] ^ (-1) ) AND 1; ZAPLEAVES( .TERMADDR, PERMANENT ); TYPE( '[NEW ]' ); ASKLEAVES( .DPS, PERMANENT, .TERMADDR ); END END; TERMADDR[T0STATUS] _ .DPS ^ 1 + .DIS END; COMMENT; ! ROUTINE MTERMOSTAT ! ======= ====== ! THIS ROUTINE ASKS THE QUESTION TO MODIFY THE INITIAL TERMINAL OUTPUT ! STATUS ROUTINE MTERMOSTAT( TERMADDR ) = BEGIN MAP FORMAT TERMADDR; OWN HIST32; !HIST:NEWTNAME IN MMTERMNAME OBSOLETED REGISTER NEWSTAT; IF .SHOW THEN DTOSTAT( .TERMADDR ); IF ( NEWSTAT _ ASKSTAT( PAZ 'NEW INITIAL [(O)STAT]US FOR OUTPUT?R(ENABLED,DISABLED?R)[: ??]', -1 ) ) EQL -1 THEN RETURN; TERMADDR[T0OSTAT] _ .NEWSTAT END; FORWARD DELTERM(1),KILLTERMS(); ! ROUTINE DELETM ! ======= =========== ! THIS ROUTINE HANDLES THE INDIVIDUAL CASES OF DELETE TERM:... ! CASE 1: IF AN INDIVIDUAL TERM IS REQUESTED ( BY NAME ), DELTERM IS ! CALLED WITH THE ADDRESS OF THE TERM TABLE ENTRY ! CASE 2: IF /ALL WAS SPECIFIED, DELTERM IS CALLED FOR EACH ENTRY IN ! TERM TABLE ! CASE 3: IF NO NAME OR SWITCH WAS GIVEN, THE USER IS ASKED FOR THE ! NAMES OF THE TERMS TO BE DELETED GLOBAL ROUTINE DELETM(TERMNAME)= BEGIN REGISTER TERMADDR; MAP FORMAT TERMADDR; IF SUBQUEUES() OR .PERIODS NEQ 0 THEN RETURN( ERROR( 45 ) ); ! PERIODS IN A TERM NAME ARE NO NO'S IF NULLTERMNAME(.TERMNAME) AND NOT .ALLSWITCH THEN BEGIN ! ASK THE USER FOR TERM NAMES REPEAT ! UNTIL HE INPUTS A BY BEGIN ! ITSELF IF INTERM( PAZ '[COBOL NAME]?R(, ?R)[: ??') EQL 0 THEN IF NOT .ERRORFLG THEN RETURN ELSE BEGIN ERROR( 87 ); WARN( 0 ) END ELSE IF (TERMADDR _ GETTERMADDR(PRIM)) EQL 0 THEN RETURN(ERROR(43)) ELSE DELTERM(.TERMADDR); CRLF END END; IF .DELTYPEFLAG THEN TYPE( 'TERMINIALS DELETED:[?M?J]'); IF .ALLSWITCH THEN BEGIN IF NOT(CONFIRMED()) THEN RETURN; KILLTERMS(); RETURN END; IF (TERMADDR _ GETTERMADDR(.TERMNAME)) EQL 0 THEN RETURN(ERROR(43)) ELSE DELTERM(.TERMADDR); END; COMMENT; ! ROUTINE KILLTERMS ! ======= =========== ! THIS ROUTINE DELETES ALL TERMINALS IN THE TERMTAB GLOBAL ROUTINE KILLTERMS = BEGIN REGISTER TERMADDR; MAP FORMAT TERMADDR; TERMADDR _ .TERMTAB; WHILE .TERMADDR NEQ 0 DO TERMADDR _ DELTERM(.TERMADDR) END; FORWARD ZAPLEAFSTAT; COMMENT; ! ROUTINE DELTERM ! ======= ======= ! THIS ROUTINE DELETES THE TERM SPECIFIED FROM THE TERM TABLE ! RETURNS THE ADDRESS OF THE NEXT TERM IN THE TERM TABLE ROUTINE DELTERM(TERMADDR)= BEGIN OWN NEXT; REGISTER NEXT2, LEAFPTR; MAP FORMAT LEAFPTR; MAP FORMAT TERMADDR; XTYPE( TERMADDR[T0CNAME] ); ! TYPE THE NAME OF THE TERM DELETED, IF MSGLEVEL EQL LONG TYPECRLF; NEXT _ .TERMADDR[T0FORE]; UNLINK(%FROM% TERMTAB, .TERMADDR); IF .TERMADDR[T0PORTPTR] NEQ 0 THEN TERMUNHOOK( .TERMADDR ); ! CLEAR TERMPTR IN THE PORTTAB ENTRY POINTED TO ZAPALTERNATES( .TERMADDR ); ZAPLEAFSTAT( .TERMADDR ); !! ZAPPHONENUMBER( .TERMADDR ); PMEM(.TERMADDR,T0SIZE); .NEXT END; !!COMMENT; !! !!! ROUTINE ZAPPHONENUMBER !!! ======= ============== !!! THIS ROUTINE RETURNS THE CORE USED BY A PHONE NUMBER IF ANY !! !!ROUTINE ZAPPHONENUMBER( TERMADDR ) = !! BEGIN !! MAP FORMAT TERMADDR; !! !! IF .TERMADDR[ T0PHONE ] NEQ 0 THEN !! PMEM( .TERMADDR[ T0PHONE ], PN0SIZE ) !! !! END; COMMENT; ! ROUTINE ZAPALTERNATES ! ======= ============= ! THIS ROUTINE DLETES ALL THE ALTERNATE POINTERS IN A TERMINAL DEF ! NOTE - IT DOESN'T DELETE ANY TERMINALS THOUGH ROUTINE ZAPALTERNATES( TERMADDR ) = BEGIN REGISTER NEXT2, ALTERPTR; MAP FORMAT ALTERPTR; MAP FORMAT TERMADDR; ALTERPTR _ .TERMADDR[T0FIRSTALTERNATE]; ! KILL ALTERNATES WHILE .ALTERPTR NEQ 0 DO BEGIN NEXT2 _ .ALTERPTR[A0FORE]; PMEM( .ALTERPTR, A0SIZE ); ALTERPTR _ .NEXT2 END; TERMADDR[ T0ALTERPTR ] _ 0 END; COMMENT; ! ROUTINE ZAPLEAFSTAT ! ======= ============= ! THIS ROUTINE DELETES ALL THE STATUS INFO FOR THE TERMINAL ROUTINE ZAPLEAFSTAT( TERMADDR ) = BEGIN REGISTER NEXT2, LEAFPTR; MAP FORMAT LEAFPTR; MAP FORMAT TERMADDR; LEAFPTR _ .TERMADDR[T0FIRSTLEAF]; ! KILL LEAFSTATUS LIST WHILE .LEAFPTR NEQ 0 DO BEGIN NEXT2 _ .LEAFPTR[L0FORE]; PMEM( .LEAFPTR, L0SIZE ); LEAFPTR _ .NEXT2 END; END; FORWARD WCTERMNAME, WCTNM, WCTSTAT; FORWARD OUTPUTAT, OUTPUTXWD, OUTPUTALT; COMMENT; ! ROUTINE WCTERM ! ======= ====== ! THIS ROUTINE WRITES THE TERM SECTION OF THE COMPILE FILE GLOBAL ROUTINE WCTERM= BEGIN ! IT IS ASSUMED THAT THE PORTS AND LEAVES HAVE BEEN NUMBERED ! THEN FOR EACH TERM ! OUTPUT Tnnnn: %SRC(NAME,MODE,OSTAT,<>, POINTER TO ALTERNATE LIST ) REGISTER ALTPTR, TERMADDR; OWN LEFTXWD; MAP FORMAT ALTPTR; MAP FORMAT TERMADDR; ! WRITE SOME HEADER GARBAGE OUTPUT( '?L SUBTTL TERMINALS?M?J?M?J INTERN TRMDSKTAB?M?J?M?J LFSTSSIZE=<+1>?M?J?M?J ' ); OUTPUT( 'INTERNAL SRCTAB,S0SIZE,S0CNT?M?J?M?JSRCTAB:: .+1?M?J XWD SRCNAMESIZE,/5+1?M?J' ); OUTPUT( 'SRCCNT=0?M?J?M?J' ); TERMADDR _ .TERMTAB; WHILE .TERMADDR NEQ 0 DO BEGIN WCTNM( .TERMADDR ); OUTPUT(': %SRC('); ! OUTPUT NAME, WCTERMNAME(.TERMADDR); OUTPUTCOMMA; !OUTPUT INITIAL OUTPUT STATUS, XOUTPUT(IF .TERMADDR[T0OSTAT] THEN PLIT ASCIZ 'ENABLED,' ELSE PLIT ASCIZ 'DISABLED,'); WCTSTAT( .TERMADDR ); ! WRITE THE LEAF STATUS TABLE INFO IF .TERMADDR[ T0ALTERPTR ] NEQ 0 THEN BEGIN OUTPUTCOMMA; OUTPUTAT( .TERMADDR[ T0TTYNO ] ) END; XOUTPUT(PLIT ASCIZ ')?M?J' ); TERMADDR _ .TERMADDR[T0FORE] END; ! WRITE SOME TRAILER GARBAGE IF .TRMCOUNT EQL 1 THEN OUTPUT( 'TT2:' ); ! IF ONLY ONE TERMINAL WE STILL NEED THIS LABEL OUTPUT( ' %SRC() ;THIS MUST BE THE LAST ENTRY IN SRCTAB?M?J?M?JS0SIZE:: EXP TT2-TT1?M?J' ); OUTPUT( 'S0CNT:: EXP SRCCNT-1?M?J?M?JTRMDSKTAB:: BLOCK SRCCNT?M?J' ); OUTPUT( '?L?ISUBTTL ALTERNATE TERMINAL LISTS?M?J?M?J' ); TERMADDR _ .TERMTAB; WHILE .TERMADDR NEQ 0 DO ! OUTPUT THE ALTERNATE TERMINAL LISTS BEGIN IF ( ALTPTR _ .TERMADDR[ T0FIRSTALTERNATE ] ) NEQ 0 THEN BEGIN OUTPUTAT( .TERMADDR[ T0TTYNO ] ); OUTPUT( ':' ); LEFTXWD _ TRUE; WHILE .ALTPTR NEQ 0 DO BEGIN OUTPUTXWD( LEFTXWD ); OUTPUTALT( .ALTPTR ); ALTPTR _ .ALTPTR[ A0FORE ] END; OUTPUTXWD( LEFTXWD ); OUTPUT( '0' ); OUTPUTXWD( LEFTXWD ); OUTPUTAT( .TERMADDR[ T0TTYNO ] ); OUTPUTCRLF END; TERMADDR _ .TERMADDR[T0FORE] END; END; COMMENT; ! ROUTINE WCTERMNAME ! ======= ======== ! THIS ROUTINE WRITES THE TERM NAME TO THE COMPILE FILE ROUTINE WCTERMNAME(TERMADDR)= BEGIN MAP FORMAT TERMADDR; XOUTPUT(TERMADDR[T0CNAME]) END; COMMENT; ! ROUTINE WCTNM ! ======= ======== ! THIS ROUTINE WRITES THE TERM NUMBER TO THE COMPILE FILE GLOBAL ROUTINE WCTNM(TERMADDR)= BEGIN MAP FORMAT TERMADDR; OUTPUT( 'TT' ); OUTPUTD(.TERMADDR[T0TTYNO]) END; COMMENT; ! ROUTINE OUTPUTAT ! ======= ======== ! THIS ROUTINE OUTPUTS THE NAME OF AN ALTERNATE TERMINAL LIST ROUTINE OUTPUTAT( TTYNO ) = BEGIN OUTPUT( 'AT' ); OUTPUTD( .TTYNO ) END; COMMENT; ! ROUTINE OUTPUTXWD ! ======= ========= ! THIS ROUTINE FLIPS FLIP-FLOP FLIPFLOP AND PUTS OUT ! XWD OR , DEPENDING ON FLIPFLOP ROUTINE OUTPUTXWD( FLIPFLOP ) = BEGIN IF @@FLIPFLOP THEN OUTPUT( '?M?J?IXWD?I' ) ELSE OUTPUT( ',' ); @FLIPFLOP _ NOT @@FLIPFLOP END; COMMENT; ! ROUTINE OUTPUTALT ! ======= ========= ! THIS ROUTINE WRITES THE ADDRESS NAME OF THE ALTERNATE GIVEN ROUTINE OUTPUTALT( ALTPTR ) = BEGIN REGISTER ALTPTRREG, TERMADDR; MAP FORMAT ALTPTRREG; MAP FORMAT TERMADDR; ALTPTRREG _ .ALTPTR; TERMADDR _ .TERMTAB; WHILE NOT COMPARE( ALTPTRREG[ A0CNAME ], TERMADDR[ T0CNAME ], T0CNAMELEN ) DO BEGIN TERMADDR _ .TERMADDR[ T0FORE ]; IF .TERMADDR EQL 0 THEN BEGIN ERROR( 19 ); OUTPUT( 'FUBAR' ); RETURN END END; WCTNM( .TERMADDR ) END; COMMENT; ! ROUTINE WCTSTAT ! ======= ======= ! THIS ROUTINE WRITES THE STATUS TABLE MACRO CALL ROUTINE WCTSTAT( TERMADDR ) = BEGIN REGISTER LEAFPTR, NODEPTR; MAP FORMAT TERMADDR; MAP FORMAT LEAFPTR; MAP FORMAT NODEPTR; %LOCAL% ROUTINE OUTPUTSTAT( STAT, STATTYPE ) = BEGIN CASE .STATTYPE ^ 1 + .STAT OF SET %00% OUTPUT( 'DISABLED' ); %01% OUTPUT( 'ENABLED' ); %10% OUTPUT( 'INACC' ); %11% OUTPUT( 'NOTINACC' ); TES END; %LOCAL% ROUTINE OUTPUTLEAF( LEAFPTR, NODEPTR ) = BEGIN MAP FORMAT LEAFPTR; MAP FORMAT NODEPTR; OUTPUTCOMMA; OUTPUTC( "<" ); OUTPUTSTAT( .LEAFPTR[L0STATUS], .LEAFPTR[L0TYPE] ); OUTPUTCOMMA; OUTPUTD( .NODEPTR[N0LEAFNO] ); OUTPUTC( ">") END; %LOCAL% ROUTINE WALLLEAVES( ARG, LEAFPTR )= BEGIN REGISTER NODEPTR; MAP FORMAT NODEPTR; MACRO NAME = NODEPTR[N0NAME]$, NEXTTHIS = NODEPTR[N0RSIB]$, NEXTLEVEL = NODEPTR[N0FIRSTCHILD]$, LEAF = (.NEXTLEVEL EQL 0)$; LABEL B; NODEPTR_.ARG; B: REPEAT BEGIN IF LEAF THEN OUTPUTLEAF( .LEAFPTR, .NODEPTR ) ELSE WALLLEAVES( .NEXTLEVEL, .LEAFPTR ); WHILE .NEXTTHIS EQL 0 DO RETURN; IF(NODEPTR_.NEXTTHIS) EQL 0 THEN LEAVE B; END END; !BEGIN! OUTPUT( '<<' ); SELECT .TERMADDR[ T0STATUS ] OF NSET 3: OUTPUT( 'ENABLED' ); 2: OUTPUT( 'DISABLED' ); OTHERWISE: OUTPUT( 'INACC' ); TESN; IF ( LEAFPTR _ .TERMADDR[T0FIRSTLEAF] ) NEQ 0 THEN BEGIN DO BEGIN IF (NODEPTR _ GETNODEADDR( LEAFPTR[L0NODENAME] ) ) EQL 0 THEN ERROR( 73 ) ELSE IF .NODEPTR[N0CHILDREN] NEQ 0 THEN WALLLEAVES( .NODEPTR[N0FIRSTCHILD], .LEAFPTR ) ELSE OUTPUTLEAF( .LEAFPTR, .NODEPTR ) END WHILE ( LEAFPTR _ .LEAFPTR[L0FORE] ) NEQ 0 END; OUTPUT( '>>' ) END; FORWARD CHECKALTERNATES; FORWARD CHECKLEAFSTAT; COMMENT; ! ROUTINE WHATTERMS ! ======= ========= ! THIS ROUTINE CHECKS THE TERM TABLE FOR UNDEFINED TERMS AND TERMS ! WHOSE CONNECTED ( CONV ) PORTS HAVE GONE AWAY OR DON'T EXIST ! WHATTERMS RETURNS GOOD IF EVERYTHING IS OK, ELSE BAD GLOBAL ROUTINE WHATTERMS(TELL)= BEGIN ! IF TELL THEN ONLY TELL THE USER WHAT IS UNDEFINED, ELSE REQUEST UNDEFINED INFO !FOUR POSSIBLE PROBLEMS ! 1. IF TERM TOBEDEFINED FLAG IS ON ! 3. THE ASSOCIATED LEAVES ARE NOT KNOWN REGISTER STATUS, PORTADDR, TERMADDR; MAP FORMAT TERMADDR; MAP FORMAT PORTADDR; STATUS _ GOOD; IF ( TERMADDR _ .TERMTAB ) EQL 0 THEN BEGIN IF .TELL THEN BEGIN ERROR( 36 ); RETURN BAD ! IF NO TERMINALS SPECIFIED THEN ERROR END ELSE BEGIN ALLSWITCH _ TRUE; ZERO( ARGLIST, %THRU% SUB3 + 2 ); MAKETERM( PRIM<0,0> ); RETURN END END; IF .TELL THEN BEGIN DO BEGIN IF .TERMADDR[T0TOBEDEFINED] THEN BEGIN ERROR( 64 ); OUTSA(TERMADDR[T0CNAME]); TYPE('[ TO BE DEFINED?M?J]'); STATUS _ BAD END ELSE BEGIN CHECKALTERNATES( .TERMADDR, .TELL ); CHECKLEAFSTAT( .TERMADDR, .TELL ) END END WHILE (TERMADDR _ .TERMADDR[T0FORE]) NEQ 0 END ELSE BEGIN DO BEGIN IF .TERMADDR[T0TOBEDEFINED] THEN BEGIN ERROR( 64 ); OUTSA(TERMADDR[T0CNAME]); TYPE('[ TO BE DEFINED?M?J?M?J]'); PRINTTERMNAME( TERMADDR[ T0CNAME ] ); MAKTERM(.TERMADDR) END ELSE BEGIN CHECKALTERNATES( .TERMADDR, .TELL ); CHECKLEAFSTAT( .TERMADDR, .TELL ) END END WHILE (TERMADDR _ .TERMADDR[T0FORE]) NEQ 0 END; .STATUS END; COMMENT; ! ROUTINE CHECKALTERNATES ! ======= =============== ! THIS ROUTINE CHECKS THE ALTERNATE OF THE SPECIFIED TERMINAL TO ! MAKE SURE THEY EXIST ROUTINE CHECKALTERNATES( TERMADDR, TELL ) = BEGIN REGISTER NEXT2, ALTERPTR; MAP FORMAT ALTERPTR; MAP FORMAT TERMADDR; %LOCAL% FUNCTION MAKALT( ALTERPTR ) = BEGIN MAP FORMAT ALTERPTR; MAKETERM( ALTERPTR[ A0CNAME ] ) END; %LOCAL% FUNCTION ZAPALT( ALTERPTR ) = BEGIN REGISTER SIB; MAP FORMAT ALTERPTR; MAP FORMAT TERMADDR; MAP FORMAT SIB; IF ( SIB _ .ALTERPTR[A0FORE] ) EQL 0 THEN BEGIN IF .TERMADDR NEQ 0 THEN TERMADDR[T0LASTALTERNATE] _ .ALTERPTR[A0AFT] END ELSE SIB[A0AFT] _ .ALTERPTR[A0AFT]; IF ( SIB _ .ALTERPTR[A0AFT] ) EQL 0 THEN BEGIN IF .TERMADDR NEQ 0 THEN TERMADDR[T0FIRSTALTERNATE] _ .ALTERPTR[A0FORE] END ELSE SIB[A0FORE] _ .ALTERPTR[A0FORE] END; ALTERPTR _ .TERMADDR[T0FIRSTALTERNATE]; WHILE .ALTERPTR NEQ 0 DO BEGIN NEXT2 _ .ALTERPTR[A0FORE]; IF GETTERMADDR( ALTERPTR[ A0CNAME ] ) EQL 0 THEN BEGIN IF .TELL THEN BEGIN ERROR( 111 ); OUTSA( ALTERPTR[ A0CNAME ] ); TYPE( '[ IS USED AS AN ALTERNATE BUT NOT DEFINED?M?J]' ) END ELSE BEGIN ERROR( 111 ); OUTSA( ALTERPTR[ A0CNAME ] ); TYPE( '[ IS USED AS AN ALTERNATE BUT NOT DEFINED?M?J]' ); ASKSTR( 'DO YOU WISH TO [DELETE ]THE ALTERNATE[OR ADD] THE TERMINAL?R(,DELETE, ADD?R)[: ??]', PLIT( ASCII 'DELET', ZAPALT, ASCII 'ADD', MAKALT ), .ALTERPTR ) END END; ALTERPTR _ .NEXT2 END END; COMMENT; ! ROUTINE CHECKLEAFSTAT ! ======= ============= ! THIS ROUTINE CHECKS THE LEAF STATUS INFO OF THE SPECIFIED TERMINAL ! TO MAKE SURE THE NODES EXIST ROUTINE CHECKLEAFSTAT( TERMADDR, TELL ) = BEGIN REGISTER NEXT2, LEAFPTR; MAP FORMAT LEAFPTR; MAP FORMAT TERMADDR; %LOCAL% FUNCTION ADDLEAF( LEAFPTR ) = BEGIN MAP FORMAT LEAFPTR; MAKENODE( LEAFPTR[ L0NODENAME ] ) END; %LOCAL% FUNCTION ZAPLEAF( LEAFPTR ) = BEGIN REGISTER SIB; MAP FORMAT LEAFPTR; MAP FORMAT TERMADDR; MAP FORMAT SIB; IF ( SIB _ .LEAFPTR[L0FORE] ) EQL 0 THEN BEGIN IF .TERMADDR NEQ 0 THEN TERMADDR[T0LASTLEAF] _ .LEAFPTR[L0AFT] END ELSE SIB[L0AFT] _ .LEAFPTR[L0AFT]; IF ( SIB _ .LEAFPTR[L0AFT] ) EQL 0 THEN BEGIN IF .TERMADDR NEQ 0 THEN TERMADDR[T0FIRSTLEAF] _ .LEAFPTR[L0FORE] END ELSE SIB[L0FORE] _ .LEAFPTR[L0FORE] END; LEAFPTR _ .TERMADDR[T0FIRSTLEAF]; WHILE .LEAFPTR NEQ 0 DO BEGIN NEXT2 _ .LEAFPTR[L0FORE]; IF GETNODEADDR( LEAFPTR[ L0NODENAME ] ) EQL 0 THEN BEGIN IF .TELL THEN BEGIN ERROR( 112 ); PRNODENAME( LEAFPTR[ L0NODENAME ] ); TYPE( '[ REFERRED TO IN THE LEAF STATUS INFO, BUT DOESN''T EXIST ]' ); END ELSE BEGIN ERROR( 112 ); PRNODENAME( LEAFPTR[ L0NODENAME ] ); TYPE( '[ REFERRED TO IN THE LEAF STATUS INFO, BUT DOESN''T EXIST ]' ); ASKSTR( 'DO YOU WISH TO [DELETE ]THIS NODE[OR ADD] TO THE TREE?R(DELETE, ADD?R): ??]', PLIT( ASCII 'DELET', ZAPLEAF, ASCII 'ADD', ADDLEAF ), .LEAFPTR ) END END; LEAFPTR _ .NEXT2 END END; END; ! END OF MGNTRM.BLI