Trailing-Edge
-
PDP-10 Archives
-
AP-D471B-SB_1978
-
mgnmpp.bli
There are no other files named mgnmpp.bli in the archive.
!***COPYRIGHT (C) 1974, 1975, 1976, 1977 DIGITAL EQUIPMENT CORPORATION., MAYNARD, MASS.***
MODULE MPP(SREG = #17, FREG = #16, VREG = #15,
!*** LAST MODIFIED BY CDO 21-JUN-76
MLIST,TIMER=EXTERNAL(SIX12),FSAVE)=
BEGIN
! THIS MODULE CONTAINS THOSE ROUTINES REQUIRED TO HANDLE MPP GENERATIONS
GLOBAL BIND MPP = 1;
REQUIRE MGNMAC.BLI;
REQ(MGNEXT);
REQ(MGNMC2);
EXTERNAL
MOVE,
LINK,
UNLINK,
COMPARE,
GETNODEPTR,
HASMPP,
MAXSLOTS;
OWN LASTMPP;
COMMENT;
! ROUTINE PRINTMPPNAME
! ======= =============
! OUTPUTS MPPNAME TO CONTROLLING TTY
ROUTINE PRINTMPPNAME( MPPNAME ) =
BEGIN
TYPE( 'FOR [MPP ]'); OUTSA( .MPPNAME ); TYPE( '[:?M?J]' );
END;
COMMENT;
! ROUTINE INMPP
! ======= ======
! THIS ROUTINE ASKS FOR AND ACCEPTS A MPP NAME FROM THE USER
ROUTINE INMPP(A)=
BEGIN
! TYPE THE QUESTION
IF ASKL( .A ) THEN RETURN 0; ! ACCEPT AN ALTERNATE LINE ANSWER
! IF THE LINE WAS EMPTY RETURN 0
IF NOT .ERRORFLG THEN GETNAME(ALINE,ACHAR); ! IF NO ERROR ACCEPTING THE LINE THEN GATHER A NAME
IF NOT .ERRORFLG THEN TOOMUCHINPUT(); ! IF NOT END OF LINE THEN ERROR
IF NOT .ERRORFLG THEN IF SUBQUEUES() OR .PERIODS NEQ 0 THEN ERROR( 18 ); ! IF STILL NO ERRORS, SEE IF THE USER
! PUT PERIODS IN THE MPP NAME
IF .ERRORFLG THEN 0 ELSE 1 ! IF ERROR IN ANY PART, RETURN 0 ELSE 1
END;
COMMENT;
! ROUTINE NUMMPPS
! ======= ==========
! THIS ROUTINE KILLS ALL MPP SPECS
GLOBAL ROUTINE NUMMPPS =
BEGIN
REGISTER
I,
MPPADDR;
MAP FORMAT MPPADDR;
MPPADDR _ .MPPTAB<FORE>;
I _ -1;
WHILE .MPPADDR NEQ 0 DO
BEGIN
MPPADDR[M0MPPNO] _ I _ .I + 1;
MPPADDR _ .MPPADDR[M0FORE]
END;
LASTMPP _ .I
END;
COMMENT;
! ROUTINE CREATEMPP
! ======= ==========
! THIS ROUTINE STUFFS A NEW MPP IN THE MPPTAB
! INPUT POINTER TO MPPNAME
! OUTPUT POINTER TO MPP TABLE ENTRY
ROUTINE CREATEMPP( MPPNAME ) =
BEGIN
REGISTER MPPADDR;
MAP FORMAT MPPADDR;
MPPADDR _ GMEM(M0SIZE);
MPPADDR[M0LINKS] _ 0;
MOVE( %FROM% .MPPNAME, %TO% MPPADDR[M0NAME], M0NAMELEN %WORDS%);
LINK( %TO% MPPTAB, MPPADDR[M0LINKS]);
.MPPADDR
END;
COMMENT;
! ROUTINE NULLMPPNAME
! ======= ============
! RETURNS TRUE IF THE MPPNAME IS NULL
ROUTINE NULLMPPNAME(LOC)=
BEGIN
! RETURNS TRUE IF THE CONTENTS OF LOC IS NULL, ELSE FALSE
RETURN IF ..LOC EQL 0 THEN TRUE ELSE FALSE
END;
FORWARD GETMPPADDR(1);
COMMENT;
! ROUTINE MAKUMPP
! ======= ========
! THIS ROUTINE MAKES A MPP TO ATTACH TO A NODE
GLOBAL ROUTINE MAKUMPP( NODEPTR, QUESTION ) =
BEGIN
OWN
MPPADDR;
LABEL LOOP;
MAP FORMAT MPPADDR;
MAP FORMAT NODEPTR;
LOOP: REPEAT ! UNTIL WE GET A GOOD ANSWER OR A LONE <CRLF>
BEGIN
IF INMPP( .QUESTION ) NEQ 0 THEN
LEAVE LOOP ! GOT A GOOD ONE SO CONTINUE
ELSE
BEGIN
IF .ERRORFLG THEN
BEGIN
ERROR( 75 ); !BAD MPP NAME
WARN( 0 );
ERRORFLG _ 0
END
ELSE
IF EOL( ACHAR ) THEN RETURN 0 ! <CRLF> ONLY ? YES THEN RETURN
END
END;
! IF WE GOT A MPP NAME
IF (MPPADDR _ GETMPPADDR( PRIM<36,7> )) EQL 0 THEN
BEGIN
MPPADDR _ CREATEMPP( PRIM<36,7> );
MPPADDR[M0TOBEDEFINED] _ TRUE
END;
ATTACH( %TO% MPPADDR[M0LISTPTRS], .NODEPTR, N0MPPOFFSETT );
.MPPADDR
END;
FORWARD ACCEPTMPP(1),MAKMPP(1);
COMMENT;
! ROUTINE MAKEMPP
! ======= ========
! GIVEN THE ADDRESS OF A MPPNAME, THIS ROUTINE CAUSE THE APPROPRIATE
! QUESTIONS TO BE ASKED TO GENERATE ONE OR MORE MPPS ( MORE IF
! THE MPP NAME WAS NULL)
GLOBAL ROUTINE MAKEMPP(MPPNAME)=
BEGIN
REGISTER MPPADDR;
MAP FORMAT MPPADDR;
ERRORFLG _ 0;
IF .ALLSWITCH THEN
BEGIN
MPPADDR _ .MPPTAB<FORE>;
WHILE .MPPADDR NEQ 0 DO
BEGIN
IF .MPPADDR[M0TOBEDEFINED] THEN
BEGIN
PRINTMPPNAME( MPPADDR[M0NAME] );
MAKMPP( .MPPADDR);
END;
MPPADDR _ .MPPADDR[M0FORE];
CRLF
END;
ZERO( .MPPNAME, .MPPNAME + M0NAMELEN )
END;
IF SUBQUEUES() OR .PERIODS NEQ 0 THEN RETURN( ERROR( 18 ) ); ! PERIODS IN A MPP NAME ARE NO NO'S
IF NULLMPPNAME(.MPPNAME) THEN ! IF NO MPP SPECIFIED
BEGIN ! ASK THE USER FOR MPP NAMES
REPEAT ! UNTIL HE INPUTS A <CR> BY
BEGIN ! ITSELF
IF INMPP( PAZ '[MPPNAME]?R(<done>,<NAME>?R)[: ??') EQL 0 THEN
IF NOT .ERRORFLG THEN RETURN
ELSE
BEGIN
! IF THE ANSWER WAS UNACCEPTABLE
ERROR( 75 ); ! TELL THE USER IT WAS BAD
WARN( 0 ); ! AND HAVE HIM TRY AGAIN
ERRORFLG _ 0;
END
ELSE ACCEPTMPP(PRIM<36,7>); ! IF OK NAME EXECUTE THE FUNCTION
CRLF
END
END;
ACCEPTMPP(.MPPNAME) ! IF A MPP WAS SPECIFIED, USE IT
END;
COMMENT;
! ROUTINE GETMPPADDR
! ======= ===========
! SEARCHES THE MPPTAB FOR THE MPPNAME CONTAINED AT THE CONTENTS OF MPPNAME
! IF FOUND, RETURNS THE ADDRESS OF THE MPP TABLE ENTRY
! OTHERWISE RETURNS 0
ROUTINE GETMPPADDR(MPPNAME) =
BEGIN
REGISTER MPPADDR;
MAP FORMAT MPPADDR;
IF TOOLONG(.MPPNAME,M0NAMESIZE, M0NAMELEN * 5) THEN
BEGIN
WARN( 5 );
TRUNCATE(.MPPNAME, M0NAMESIZE, M0NAMELEN * 5)
END;
IF ( MPPADDR _ .MPPTAB<FORE> ) EQL 0 THEN RETURN 0; ! START AT THE BEGINNING
! WHILE THE NAME AT MPPNAME ISN'T THE NAME IN THE TABLE DO
WHILE NOT COMPARE(.MPPNAME,MPPADDR[M0NAME],M0NAMELEN) DO
! IF END OF TABLE RETURN 0
IF (MPPADDR _ .MPPADDR[M0FORE]) EQL 0 THEN RETURN 0;
.MPPADDR ! A MATCH! SO RETURN THE ADDRESS
END;
FORWARD MAKMPP(1), MODMPP(1);
COMMENT;
! ROUTINE ACCEPTMPP
! ======= ==========
! THIS ROUTINE CREATES A MPP TABLE ENTRY IF ONE DOES NOT EXIST
! THEN CALLS MAKMPP TO ASK THE QUESTIONS TO FILL THE ENTRY
! IF THE MPP ALREADY EXISTS, THE USER IS ASKED HOW HE WANTS TO
! HANDLE IT
ROUTINE ACCEPTMPP(MPPNAME)=
BEGIN
REGISTER MPPADDR;
MAP FORMAT MPPADDR;
PRINTMPPNAME( .MPPNAME );
! SEE IF ALREADY DEFINED
IF (MPPADDR _ GETMPPADDR(.MPPNAME)) EQL 0 THEN
MPPADDR _ CREATEMPP( .MPPNAME ) ! MAKE A MPP TABLE ENTRY
ELSE
BEGIN
IF NOT .MPPADDR[M0TOBEDEFINED] THEN
BEGIN
ASKSTR( '[MPP ALREADY EXISTS]?R(IGNORE, MODIFY, REPLACE?R)[: ??]',
PLIT( ASCII 'REPLA', MAKMPP,
ASCII 'MODIF', MODMPP,
0, IGNORE,
ASCII 'IGNOR', IGNORE),
.MPPADDR);
RETURN
END
END;
MAKMPP(.MPPADDR)
END;
COMMENT;
!!
!!! ROUTINE SETLOCK
!!! ======= =======
!!! SETS THE LOCK BIT TO TRUE INDICATING LOCKING IS DESIRED
!!
!!ROUTINE SETLOCK( MPPADDR ) =
!! BEGIN
!! MAP FORMAT MPPADDR;
!!
!! MPPADDR[M0LOCK] _ TRUE
!!
!! END;
!!
!!COMMENT;
!!
!!! ROUTINE CLEARLOCK
!!! ======= =========
!!! SETS THE LOCK BIT TO FALSE INDICATING LOCKING IS NOT DESIRED
!!
!!ROUTINE CLEARLOCK( MPPADDR ) =
!! BEGIN
!! MAP FORMAT MPPADDR;
!!
!! MPPADDR[M0LOCK] _ FALSE
!!
!! END;
!!
COMMENT;
! ROUTINE SETIMMORTAL
! ======= =======
! SETS THE IMMORTAL BIT TO TRUE INDICATING IMMORTAL IS DESIRED
ROUTINE SETIMMORTAL( MPPADDR ) =
BEGIN
MAP FORMAT MPPADDR;
MPPADDR[M0IMMORTAL] _ TRUE
END;
COMMENT;
! ROUTINE CLEARIMMORTAL
! ======= =========
! SETS THE IMMORTAL BIT TO FALSE INDICATING IMMORTAL IS NOT DESIRED
ROUTINE CLEARIMMORTAL( MPPADDR ) =
BEGIN
MAP FORMAT MPPADDR;
MPPADDR[M0IMMORTAL] _ FALSE
END;
FORWARD MAKEEGO(2);
COMMENT;
! ROUTINE MAKMPP
! ======= =======
! THIS ROUTINE ASKS THE QUESTIONS TO MAKE ONE (AND ONLY ONE) MPP
! AND RECORDS THE RESPONSES IN THE APPROPRIATE MPP TABLE ENTRY
ROUTINE MAKMPP(MPPADDR)=
BEGIN
OWN SPECBLK[4];
MAP FORMAT MPPADDR;
WHILE ASKFSPEC( '[FILE] DESIGNATION ?R(<FILE-SPEC>?R)[: ??]', SPECBLK) EQL CRONLY DO
BEGIN
ERROR( 76 );
WARN( 0 );
END;
MAKEEGO( SPECBLK, .MPPADDR );
TYPE( '[BACKUPS]?R(<DONE>, <FILE-SPEC> ?R)[:]' );
WHILE NOT (ASKFSPEC('[ ??]', SPECBLK) EQL CRONLY) DO
BEGIN
MAKEEGO( SPECBLK, .MPPADDR )
END;
MPPADDR[M0MAX] _ ASKDNUM( '[MAX]IMUM[ COPIES] THAT CAN RUN?R(<MAX AVAILABLE JOB SLOTS>, <DECIMAL NUMBER>?R)[: ??]',
DEFAULTOK,
BIGNUMBER,
0,
.MAXSLOTS);
MPPADDR[M0MIN] _ ASKDNUM( '[MIN]IMUM[ COPIES] THAT MUST RUN?R(0, <DECIMAL NUMBER>?R)[: ??]',
DEFAULTOK,
0,
0,
.MPPADDR[ M0MAX ]);
MPPADDR[M0INITIAL] _ ASKDNUM( '[COPIES] TO START[ INITIALLY]?R(0, <DECIMAL NUMBER>?R)[: ??]',
DEFAULTOK,
0,
0,
.MPPADDR[ M0MAX ]);
MPPADDR[M0HPQ] _ ASKDNUM( '[HPQ] TO USE?R(<none>,<DECIMAL NUMBER BETWEEN 1 AND 15 INCLUSIVE>?R)[: ??]',
DEFAULTOK,
0,
1,
15);
!! ASKSTR('[LOCK] JOB IN CORE?R(NO,YES?R)[: ??]',
!! PLIT( ASCII 'YES', SETLOCK,
!! ASCII 'NO', CLEARLOCK,
!! 0, CLEARLOCK),
!! .MPPADDR);
ASKSTR('CAN THIS [MPP ]BE [KILL(ABLE)]ED BY MCS?R(YES,NO?R)[: ??]',
PLIT( ASCII 'YES', CLEARIMMORTAL,
ASCII 'NO', SETIMMORTAL,
0, CLEARIMMORTAL),
.MPPADDR);
MPPADDR[M0TOBEDEFINED] _ FALSE
END;
COMMENT;
! ROUTINE MAKEEGO
! ======= ========
! THIS ROUTINE GETS CORE FOR AN ALTEREGO, STORES THE FILE SPEC, AND ASKS
! FOR THE AMOUNT OF CORE REQUIRED BY THE PROGRAM.
ROUTINE MAKEEGO( SPECBLK, MPPADDR ) =
BEGIN
REGISTER EGOPTR;
MAP FORMAT MPPADDR;
MAP FORMAT EGOPTR;
MAP FORMAT SPECBLK;
IF .SPECBLK[ SB0EXT ] NEQ 0 THEN
BEGIN
WARN(27); !EXTENSION IGNORED
SPECBLK[SB0EXT] _ 0 ! AND FORCE TO ZERO
END;
EGOPTR _ GMEM( E0SIZE );
EGOPTR[E0EGOS] _ 0;
LINK( %TO% MPPADDR[M0EGOS], .EGOPTR);
MOVE( %FROM% .SPECBLK, %TO% EGOPTR[E0SPECBLK], SPECBLKLEN );
EGOPTR[E0CORE] _ ASKSIZE( '?I?I[CORE] TO START MPP WITH ?R(<AS REQ''D>, <CORE-SPEC>?R)[: ??]');
END;
FORWARD DISMPP(1);
COMMENT;
! ROUTINE DISPMPP
! ======= ===========
! THIS ROUTINE HANDLES THE INDIVIDUAL CASES OF DISPLAY MPP:...
! CASE 1: IF AN INDIVIDUAL MPP IS REQUESTED ( BY NAME ), DISMPP IS
! CALLED WITH THE ADDRESS OF THE MPP TABLE ENTRY
! CASE 2: IF /ALL WAS SPECIFIED, DISMPP IS CALLED FOR EACH ENTRY IN
! MPP TABLE
! CASE 3: IF NO NAME OR SWITCH WAS GIVEN, THE USER IS ASKED FOR THE
! NAMES OF THE MPPS TO BE DISPLAYED
GLOBAL ROUTINE DISPMPP(MPPNAME)=
BEGIN
REGISTER MPPADDR;
MAP FORMAT MPPADDR;
IF SUBQUEUES() OR .PERIODS NEQ 0 THEN RETURN( ERROR( 18 ) ); ! PERIODS IN A MPP NAME ARE NO NO'S
IF NULLMPPNAME(.MPPNAME) AND NOT .ALLSWITCH THEN
BEGIN ! ASK THE USER FOR MPP NAMES
REPEAT ! UNTIL HE INPUTS A <CR> BY
BEGIN ! ITSELF
IF INMPP( PAZ '[MPPNAME]?R(<done>,<NAME>?R)[: ??') EQL 0 THEN
IF NOT .ERRORFLG THEN RETURN
ELSE
BEGIN
! IF THE ANSWER WAS UNACCEPTABLE
ERROR( 75 ); ! TELL THE USER IT WAS BAD
WARN( 0 ); ! AND HAVE HIM TRY AGAIN
ERRORFLG _ 0;
END
ELSE IF (MPPADDR _ GETMPPADDR(PRIM)) EQL 0 THEN
RETURN(ERROR(16))
ELSE DISMPP(.MPPADDR);
CRLF
END
END;
IF .ALLSWITCH THEN
BEGIN
MPPADDR _ .MPPTAB<FORE>;
WHILE .MPPADDR NEQ 0 DO
BEGIN
DISMPP( .MPPADDR);
MPPADDR _ .MPPADDR[M0FORE]
END;
RETURN
END;
IF (MPPADDR _ GETMPPADDR(.MPPNAME)) EQL 0 THEN RETURN(ERROR(16))
ELSE DISMPP(.MPPADDR)
END;
FORWARD DMPPNAME,DMPPFILE,DMPPBACKUPS,DMPPMAX,DMPPMIN,DMPPINIT,DMPPHPQ,DMPPIMMORTAL;
!!FORWARD DMPPLOCK;
COMMENT;
! ROUTINE DISMPP
! ======= =======
! THIS ROUTINE DISPLAYS THE MPP'S NAME, AND IF THE MPP IS UNDEFINED,
! THEN "NOT YET DEFINED..." IS DISPLAYED, OTHERWISE THE MPP PARAMETERS
! ARE DISPLAYED
ROUTINE DISMPP(MPPADDR)=
BEGIN
MAP FORMAT MPPADDR;
DMPPNAME(.MPPADDR);
IF .MPPADDR[M0TOBEDEFINED] THEN
BEGIN
OUTPUT('NOT YET DEFINED, PLEASE MAKE OR MODIFY IT');
END
ELSE
BEGIN
DMPPFILE( .MPPADDR );
DMPPBACKUPS( .MPPADDR );
DMPPMAX(.MPPADDR);
DMPPMIN(.MPPADDR);
DMPPINIT(.MPPADDR);
DMPPHPQ(.MPPADDR);
!! DMPPLOCK(.MPPADDR);
DMPPIMMORTAL(.MPPADDR);
END;
OUTPUTCRLF
END;
COMMENT;
! ROUTINE DMPPNAME
! ======= =========
! THIS ROUTINE DISPLAYS THE MPP NAME
ROUTINE DMPPNAME(MPPADDR)=
BEGIN
MAP FORMAT MPPADDR;
OUTPUT('MPPNAME: '); XOUTPUT(MPPADDR[M0NAME]);
OUTPUTCRLF
END;
COMMENT;
! ROUTINE DMNAME
! ======= =========
! THIS ROUTINE DISPLAYS THE MPP NAME WITHOUT LABEL
GLOBAL ROUTINE DMNAME(MPPADDR)=
BEGIN
MAP FORMAT MPPADDR;
XOUTPUT(MPPADDR[M0NAME])
END;
FORWARD DEGO(1);
COMMENT;
! ROUTINE DMPPFILE
! ======= =========
! THIS ROUTINE DISPLAYS THE MPP'S PRIMARY FILE SPECIFICATION
ROUTINE DMPPFILE(MPPADDR)=
BEGIN
REGISTER EGOPTR;
MAP FORMAT EGOPTR;
MAP FORMAT MPPADDR;
EGOPTR _ .MPPADDR[M0FEGO];
OUTPUT('FILE DESIGNATION: ');
DEGO( .EGOPTR );
END;
! ROUTINE DMPPBACKUPS
! ======= =========
! THIS ROUTINE DISPLAYS THE MPP'S BACKUPS' SPECIFICATIONS
ROUTINE DMPPBACKUPS(MPPADDR)=
BEGIN
REGISTER EGOPTR;
MAP FORMAT EGOPTR;
MAP FORMAT MPPADDR;
EGOPTR _ .MPPADDR[M0FEGO];
OUTPUT('BACKUPS: ');
IF .EGOPTR[E0FORE] EQL 0 THEN OUTPUT('<none>?M?J')
ELSE
WHILE ( EGOPTR _ .EGOPTR[E0FORE] ) NEQ 0 DO
BEGIN
DEGO( .EGOPTR );
IF .EGOPTR[E0FORE] NEQ 0 THEN OUTPUT( ' ' )
END
END;
COMMENT;
! ROUTINE DEGO
! ======= ====
! THIS ROUTINE DISPLAYS THE FILE SPEC OF AN ALTEREGO, GIVEN A POINTER
! TO THE ALTEREGO
ROUTINE DEGO( EGOPTR ) =
BEGIN
MAP FORMAT EGOPTR;
OUTPUTFSPEC( EGOPTR[E0SPECBLK] );
OUTPUT('?I( CORE: ');
IF .EGOPTR[E0KCORE] EQL 0 THEN
OUTPUT( '<as req''d> ')
ELSE
BEGIN
OUTPUTD( .EGOPTR[E0KCORE] );
OUTPUTC( IF .EGOPTR[E0KFLAG] THEN "K" ELSE "P" );
END;
OUTPUTC( ")" );
OUTPUTCRLF
END;
COMMENT;
! ROUTINE DMPPMAX
! ======= ========
! THIS ROUTINE DISPLAYS THE MAXIMUM NUMBER OF COPIES OF THE MPP TO RUN
ROUTINE DMPPMAX(MPPADDR)=
BEGIN
MAP FORMAT MPPADDR;
OUTPUT('MAXIMUM COPIES TO RUN: ');
IF .MPPADDR[M0MAX] EQL BIGNUMBER THEN OUTPUT('<MAXIMUM AVAILABLE JOB SLOTS>')
ELSE OUTPUTD( .MPPADDR[M0MAX] );
OUTPUTCRLF
END;
COMMENT;
! ROUTINE DMPPMIN
! ======= ========
! THIS ROUTINE DISPLAYS THE MINIMUM NUMBER OF COPIES OF THE MPP TO RUN
ROUTINE DMPPMIN(MPPADDR)=
BEGIN
MAP FORMAT MPPADDR;
OUTPUT('MINIMUM COPIES TO RUN: ');
OUTPUTD( .MPPADDR[M0MIN] );
OUTPUTCRLF
END;
COMMENT;
! ROUTINE DMPPINIT
! ======= ========
! THIS ROUTINE DISPLAYS THE NUMBER OF COPIES OF THE MPP TO START INITIALLY
ROUTINE DMPPINIT(MPPADDR)=
BEGIN
MAP FORMAT MPPADDR;
OUTPUT('COPIES TO START INITIALLY: ');
OUTPUTD( .MPPADDR[M0INITIAL] );
OUTPUTCRLF
END;
COMMENT;
! ROUTINE DMPPHPQ
! ======= =======
! THIS ROUTINE DISPLAYS THE HPQ THAT THE MPP IS TO BE RUN IN
ROUTINE DMPPHPQ( MPPADDR ) =
BEGIN
MAP FORMAT MPPADDR;
OUTPUT('HPQ TO BE USED: ');
IF .MPPADDR[M0HPQ] EQL 0 THEN OUTPUT('<none>')
ELSE OUTPUTD( .MPPADDR[M0HPQ] );
OUTPUTCRLF
END;
COMMENT;
!!! ROUTINE DMPPLOCK
!!! ======= =========
!!! THIS ROUTINE DISPLAYS THE LOCK CAPABILITY OF THE MPP
!!
!!ROUTINE DMPPLOCK(MPPADDR)=
!! BEGIN
!! MAP FORMAT MPPADDR;
!! OUTPUT('LOCK JOB IN CORE: ');
!! XOUTPUT(IF .MPPADDR[M0LOCK] THEN PLIT ASCII 'YES' ELSE PLIT ASCIZ 'NO');
!! OUTPUTCRLF
!! END;
COMMENT;
! ROUTINE DMPPIMMORTAL
! ======= =========
! THIS ROUTINE DISPLAYS THE IMMORTAL CAPABILITY OF THE MPP
ROUTINE DMPPIMMORTAL(MPPADDR)=
BEGIN
MAP FORMAT MPPADDR;
OUTPUT('JOB KILLABLE BY MCS: ');
XOUTPUT(IF NOT .MPPADDR[M0IMMORTAL] THEN PLIT ASCII 'YES' ELSE PLIT ASCIZ 'NO');
OUTPUTCRLF
END;
! ROUTINE MODIMPP
! ======= ===========
! THIS ROUTINE HANDLES THE INDIVIDUAL CASES OF MODIFY MPP:...
! CASE 1: IF AN INDIVIDUAL MPP IS REQUESTED ( BY NAME ), MODMPP IS
! CALLED WITH THE ADDRESS OF THE MPP TABLE ENTRY
! CASE 2: IF /ALL WAS SPECIFIED, MODMPP IS CALLED FOR EACH ENTRY IN
! MPP TABLE
! CASE 3: IF NO NAME OR SWITCH WAS GIVEN, THE USER IS ASKED FOR THE
! NAMES OF THE MPPS TO BE MODIFIED
GLOBAL ROUTINE MODIMPP(MPPNAME)=
BEGIN
REGISTER MPPADDR;
MAP FORMAT MPPADDR;
IF SUBQUEUES() OR .PERIODS NEQ 0 THEN RETURN( ERROR( 18 ) ); ! PERIODS IN A MPP NAME ARE NO NO'S
IF NULLMPPNAME(.MPPNAME) AND NOT .ALLSWITCH THEN
BEGIN ! ASK THE USER FOR MPP NAMES
REPEAT ! UNTIL HE INPUTS A <CR> BY
BEGIN ! ITSELF
IF INMPP( PAZ '[MPPNAME]?R(<done>,<NAME>?R)[: ??') EQL 0 THEN
IF NOT .ERRORFLG THEN RETURN
ELSE
BEGIN
! IF THE ANSWER WAS UNACCEPTABLE
ERROR( 75 ); ! TELL THE USER IT WAS BAD
WARN( 0 ); ! AND HAVE HIM TRY AGAIN
ERRORFLG _ 0;
END
ELSE IF (MPPADDR _ GETMPPADDR(PRIM)) EQL 0 THEN
RETURN(ERROR(16))
ELSE MODMPP(.MPPADDR);
CRLF
END
END;
IF .ALLSWITCH THEN
BEGIN
MPPADDR _ .MPPTAB<FORE>;
WHILE .MPPADDR NEQ 0 DO
BEGIN
MODMPP( .MPPADDR);
MPPADDR _ .MPPADDR[M0FORE]
END;
RETURN
END;
IF (MPPADDR _ GETMPPADDR(.MPPNAME)) EQL 0 THEN RETURN(ERROR(16))
ELSE MODMPP(.MPPADDR);
END;
FORWARD MMPPNAME,MMPPFILE,MMPPBACKUPS,MMPPMAX,MMPPMIN,
MMPPINITIAL,MMPPHPQ,MMPPIMMORTAL,MMPPALL,TELLMPPCHANGES;
!!FORWARD MMPPLOCK;
COMMENT;
! ROUTINE MODMPP
! ======= =======
! THIS ROUTINE TYPES THE NAME OF THE MPP TO BE MODIFIED, AND THEN
! ASKS FOR THE CHANGES TO BE MADE. MODMPP DOES ONLY ONE MPP AT A
! TIME.
ROUTINE MODMPP(MPPADDR)=
BEGIN
OWN DONE;
MAP FORMAT MPPADDR;
%LOCAL% ROUTINE SETDONE = DONE _ TRUE;
PRINTMPPNAME( MPPADDR[M0NAME] ); ! TYPE THE NAME OF THE MPP TO BE MODIFIED
IF .MPPADDR[M0TOBEDEFINED] THEN ! IF UNDEFINED THEN
BEGIN
MAKMPP(.MPPADDR) ! MAKE IT
END
ELSE
BEGIN
DONE _ FALSE;
WHILE NOT .DONE DO ! OTHERWISE, UNTIL THE USER GIVES US A LONE <CR> DO
BEGIN
ASKSTR( '[CHANGE: ??]', ! ASK WHAT CHANGES
PLIT( ASCII '??', TELLMPPCHANGES,
ASCII 'NAME', MMPPNAME,
ASCII 'FILE', MMPPFILE,
ASCII 'BACKU', MMPPBACKUPS,
ASCII 'MAX', MMPPMAX,
ASCII 'MIN', MMPPMIN,
ASCII 'INITI', MMPPINITIAL,
ASCII 'HPQ', MMPPHPQ,
!! ASCII 'LOCK', MMPPLOCK,
ASCII 'KILLA', MMPPIMMORTAL,
ASCII 'ALL', MMPPALL,
0, SETDONE),
.MPPADDR);
CRLF
END
END
END;
COMMENT;
! ROUTINE TELLMPPCHANGES
! ======= ===============
! THIS ROUTINE TELLS ( WITH LOTS OF WIND ) WHAT CHANGES CAN BE MADE ON
! AN MPP
ROUTINE TELLMPPCHANGES =
BEGIN
TYPE( 'TYPE [NAME] TO CHANGE THE NAME OF THE MPP[,]?J
?MTYPE [FILE] TO CHANGE THE FILE SPECIFICATION OF THE MPP[,]?J
?MTYPE [BACKUPS] TO CHANGE THE BACKUPS TO THE MPP[,]?J
?MTYPE [MAX] TO CHANGE THE MAXIMUM NUMBER OF COPIES OF THE MPP TO RUN[,]?J
?MTYPE [MIN] TO CHANGE THE MINIMUM NUMBER OF COPIES OF THE MPP TO RUN[,]?J
?MTYPE [INITIAL] TO CHANGE THE NUMBER OF COPIES OF THE MPP TO START INITIALLY[,]?J
?MTYPE [HPQ] TO CHANGE THE HPQ TO RUN THE MPP IN[,]?M?J' );
!! TYPE( 'TYPE [LOCK] TO CHANGE THE LOCKING ABILITY OF THE MPP[,]?M?J' );
TYPE( 'TYPE [KILLABLE] TO CHANGE THE KILLABILITY OF THE MPP[,]?J
?MTYPE [ALL] TO CHANGE ALL OF THE ABOVE[,]?J
?MTYPE A CARRIAGE RETURN TO FINISH CHANGING THIS MPP[(?R(<CR> WHEN DONE?R))]');
CRLF;
END;
COMMENT;
! ROUTINE MMPPALL
! ======= ========
! THIS ROUTINE ASKS ALL THE QUESTIONS TO CHANGE AN MPP
ROUTINE MMPPALL(MPPADDR) =
BEGIN
MMPPNAME( .MPPADDR);
MMPPFILE( .MPPADDR);
MMPPBACKUPS( .MPPADDR);
MMPPMAX( .MPPADDR);
MMPPMIN( .MPPADDR);
MMPPINITIAL( .MPPADDR);
MMPPHPQ( .MPPADDR);
!! MMPPLOCK( .MPPADDR);
MMPPIMMORTAL( .MPPADDR)
END;
COMMENT;
! ROUTINE MMPPNAME
! ======= =========
! THIS ROUTINE ASKS THE QUESTION TO CHANGE AN MPP'S NAME
ROUTINE MMPPNAME(MPPADDR)=
BEGIN
MAP FORMAT MPPADDR;
LABEL LOOP;
IF .SHOW THEN DMPPNAME(.MPPADDR);
LOOP: REPEAT
BEGIN
IF INMPP( PAZ 'NEW [MPPNAME]?R(,<NAME>?R)[: ??]') EQL 0 THEN
BEGIN
IF .ERRORFLG THEN
BEGIN
ERROR ( 75 );
WARN ( 0 );
ERRORFLG _ 0
END
ELSE RETURN
END
ELSE LEAVE LOOP;
END;
IF GETMPPADDR(PRIM) NEQ 0 THEN RETURN (ERROR(17));
MOVE(PRIM, MPPADDR[M0NAME], M0NAMELEN)
END;
COMMENT;
! ROUTINE MMPPFILE
! ======= =========
! THIS ROUTINE ASKS THE QUESTIONS NECESSARY TO CHANGE THE FILE
! SPECIFICATION OF THE MPP
ROUTINE MMPPFILE(MPPADDR)=
BEGIN
OWN SPECBLK[ SPECBLKLEN];
REGISTER
OLDCORE,
EGOPTR;
MAP FORMAT EGOPTR;
MAP FORMAT MPPADDR;
EGOPTR _ .MPPADDR[M0FEGO];
OLDCORE _ .EGOPTR[E0CORE];
IF .SHOW THEN DMPPFILE(.MPPADDR);
IF ( ASKFSPEC( '[NEW FILE] DESIGNATION ?R(,<FILE-SPEC>?R)[: ??]', SPECBLK) ) NEQ CRONLY THEN
MOVE( %FROM% SPECBLK, %TO% EGOPTR[E0SPECBLK], SPECBLKLEN );
EGOPTR[ E0CORE ] _ NEWASKSIZE( '[NEW CORE]?R(, <CORE-SPEC>, "<AS REQ''D>" ?R)[: ??]',
PLIT( 0, ASCIZ '<AS REQ''D>' ), .OLDCORE );
END;
COMMENT;
! ROUTINE MMPPBACKUPS
! ======= ========
! THIS ROUTINE ASKS THE QUESTION ABOUT CHANGING THE BACKUPS TO THE MPP
ROUTINE MMPPBACKUPS(MPPADDR)=
BEGIN
REGISTER
EGOPTR,
NEXTEGO;
OWN SPECBLK[SPECBLKLEN];
MAP FORMAT EGOPTR;
MAP FORMAT MPPADDR;
IF .SHOW THEN DMPPBACKUPS(.MPPADDR);
IF ( NEWASKFSPEC( '[NEW BACKUPS]?R(,"<NONE>",<FILE-SPEC>?R)[: ??]',
SPECBLK,
PLIT( PLIT( SPECBLKLEN : 0 ), ASCIZ '<NONE>' ),
EGOPTR[ E0SPECBLK ] ) ) EQL CRONLY THEN RETURN %?? CHANGE CORE ONLY%;
! ELSE !
EGOPTR _ .MPPADDR[M0FEGO];
EGOPTR _ .EGOPTR[E0FORE]; ! SKIP THE PRIMARY EGO
WHILE .EGOPTR NEQ 0 DO ! THE DELETE THE ALTEREGOS
BEGIN
NEXTEGO _ .EGOPTR[E0FORE];
UNLINK( %FROM% MPPADDR[M0EGOS], .EGOPTR );
PMEM( .EGOPTR, E0SIZE );
EGOPTR _ .NEXTEGO
END;
IF NULL( SPECBLK, SPECBLKLEN ) THEN RETURN; ! IF <NONE> THEN DONE
MAKEEGO( SPECBLK, .MPPADDR );
WHILE NOT (ASKFSPEC('[ ??]', SPECBLK) EQL CRONLY) DO
BEGIN
MAKEEGO( SPECBLK, .MPPADDR )
END
END;
COMMENT;
! ROUTINE MMPPMAX
! ======= =========
! THIS ROUTINE ASKS THE QUESTION ABOUT CHANGING THE MAXIMUM COPIES
! OF THE MPP TO RUN
ROUTINE MMPPMAX(MPPADDR)=
BEGIN
MAP FORMAT MPPADDR;
IF .SHOW THEN DMPPMAX(.MPPADDR);
MPPADDR[M0MAX] _ NEWASKDNUM( 'NEW [MAX]IMUM[ COPIES] THAT CAN RUN?R(,"<MAX AVAILABLE JOB SLOTS>", <DECIMAL NUMBER>?R)[: ??]',
DEFAULTOK,
.MPPADDR[ M0MAX ],
PLIT( BIGNUMBER, ASCIZ '<MAX AVAILABLE JOB SLOTS>' ),
0,
.MAXSLOTS);
END;
COMMENT;
! ROUTINE MMPPMIN
! ======= =========
! THIS ROUTINE ASKS THE QUESTION TO CHANGE THE MINIMUM NUMBER OF COPIES OF THE MPP TO RUN
ROUTINE MMPPMIN(MPPADDR)=
BEGIN
REGISTER CHANGE;
MAP FORMAT MPPADDR;
IF .SHOW THEN DMPPMIN(.MPPADDR);
IF (CHANGE _ ASKDNUM( 'NEW [MIN]IMUM[ COPIES] THAT MUST RUN?R(,<DECIMAL NUMBER>?R)[: ??]',
DEFAULTOK,
-1,
0,
.MPPADDR[ M0MAX ]) ) NEQ -1 THEN MPPADDR[M0MIN] _ .CHANGE;
END;
COMMENT;
! ROUTINE MMPPINITIAL
! ======= =========
! THIS ROUTINE ASKS THE QUESTION TO CHANGE THE NUMBER OF COPIES OF THE MPP TO START INITIALLY
ROUTINE MMPPINITIAL(MPPADDR)=
BEGIN
REGISTER CHANGE;
MAP FORMAT MPPADDR;
IF .SHOW THEN DMPPINIT(.MPPADDR);
IF (CHANGE _ ASKDNUM( 'NEW [COPIES] TO START[ INITIALLY]?R(,<DECIMAL NUMBER>?R)[: ??]',
DEFAULTOK,
-1,
0,
.MPPADDR[ M0MAX ]) ) NEQ -1 THEN MPPADDR[M0INITIAL] _ .CHANGE;
END;
COMMENT;
! ROUTINE MMPPHPQ
! ======= =========
! THIS ROUTINE ASKS THE QUESTION TO CHANGE THE HPQ TO RUN THE MPP IN
ROUTINE MMPPHPQ(MPPADDR)=
BEGIN
MAP FORMAT MPPADDR;
IF .SHOW THEN DMPPHPQ(.MPPADDR);
MPPADDR[ M0HPQ ] _ NEWASKDNUM( 'NEW [HPQ] TO USE?R(,"<none>",<DECIMAL NUMBER BETWEEN 1 AND 15 INCLUSIVE>?R)[: ??]',
DEFAULTOK,
.MPPADDR[ M0HPQ ],
PLIT( 0, ASCIZ '<NONE>' ),
1,
15);
END;
COMMENT;
!!! ROUTINE MMPPLOCK
!!! ======= =========
!!! THIS ROUTINE ASKS THE QUESTION ABOUT CHANGING THE LOCK CAPABILITY
!!! OF THE MPP
!!
!!ROUTINE MMPPLOCK(MPPADDR)=
!! BEGIN
!! IF .SHOW THEN DMPPLOCK(.MPPADDR);
!! ASKSTR('NEW [LOCK] JOB IN CORE?R(,NO,YES?R)[: ??]',
!! PLIT( ASCII 'YES', SETLOCK,
!! ASCII 'NO', CLEARLOCK,
!! 0, IGNORE),
!! .MPPADDR);
!!
!! END;
COMMENT;
! ROUTINE MMPPIMMORTAL
! ======= =========
! THIS ROUTINE ASKS THE QUESTION ABOUT CHANGING THE IMMORTAL CAPABILITY
! OF THE MPP
ROUTINE MMPPIMMORTAL(MPPADDR)=
BEGIN
IF .SHOW THEN DMPPIMMORTAL(.MPPADDR);
ASKSTR('IS THE MPP NOW [KILLABLE] BY MCS?R(,NO,YES?R)[: ??]',
PLIT( ASCII 'YES', CLEARIMMORTAL,
ASCII 'NO', SETIMMORTAL,
0, IGNORE),
.MPPADDR);
END;
FORWARD DELMPP(1),KILLMPPS();
COMMENT;
! ROUTINE DELEMPP
! ======= ===========
! THIS ROUTINE HANDLES THE INDIVIDUAL CASES OF DELETE MPP:...
! CASE 1: IF AN INDIVIDUAL MPP IS REQUESTED ( BY NAME ), DELMPP IS
! CALLED WITH THE ADDRESS OF THE MPP TABLE ENTRY
! CASE 2: IF /ALL WAS SPECIFIED, DELMPP IS CALLED FOR EACH ENTRY IN
! MPP TABLE
! CASE 3: IF NO NAME OR SWITCH WAS GIVEN, THE USER IS ASKED FOR THE
! NAMES OF THE MPPS TO BE DELETED
GLOBAL ROUTINE DELEMPP(MPPNAME)=
BEGIN
REGISTER MPPADDR;
MAP FORMAT MPPADDR;
IF SUBQUEUES() OR .PERIODS NEQ 0 THEN RETURN( ERROR( 18 ) ); ! PERIODS IN A MPP NAME ARE NO NO'S
IF NULLMPPNAME(.MPPNAME) AND NOT .ALLSWITCH THEN
BEGIN ! ASK THE USER FOR MPP NAMES
REPEAT ! UNTIL HE INPUTS A <CR> BY
BEGIN ! ITSELF
IF INMPP( PAZ '[MPPNAME]?R(<done>,<NAME>?R)[: ??') EQL 0 THEN
IF NOT .ERRORFLG THEN RETURN
ELSE
BEGIN
! IF THE ANSWER WAS UNACCEPTABLE
ERROR( 75 ); ! TELL THE USER IT WAS BAD
WARN( 0 ); ! AND HAVE HIM TRY AGAIN
ERRORFLG _ 0;
END
ELSE IF (MPPADDR _ GETMPPADDR(PRIM)) EQL 0 THEN
RETURN(ERROR(16))
ELSE DELMPP(.MPPADDR);
CRLF
END
END;
IF .DELTYPEFLAG THEN TYPE( 'MPPS DELETED[?M?J]');
IF .ALLSWITCH THEN
BEGIN
IF NOT(CONFIRMED()) THEN RETURN;
KILLMPPS();
RETURN
END;
IF (MPPADDR _ GETMPPADDR(.MPPNAME)) EQL 0 THEN RETURN(ERROR(16))
ELSE DELMPP(.MPPADDR);
END;
COMMENT;
! ROUTINE KILLMPPS
! ======= ==========
! THIS ROUTINE KILLS ALL MPP SPECS
GLOBAL ROUTINE KILLMPPS =
BEGIN
REGISTER MPPADDR;
MAP FORMAT MPPADDR;
MPPADDR _ .MPPTAB<FORE>;
WHILE .MPPADDR NEQ 0 DO
MPPADDR _ DELMPP(.MPPADDR)
END;
COMMENT;
! ROUTINE DELMPP
! ======= =======
! THIS ROUTINE DELETES THE MPP SPECIFIED FROM THE MPP TABLE
! RETURNS THE ADDRESS OF THE NEXT MPP IN THE MPP TABLE
GLOBAL ROUTINE DELMPP(MPPADDR)=
BEGIN
OWN NEXT;
REGISTER
NEXTNODE,
NODEPTR,
EGOPTR,
NEXTEGO;
MAP FORMAT EGOPTR;
MAP FORMAT MPPADDR;
MAP FORMAT NODEPTR;
XTYPE( MPPADDR[M0NAME] ); ! TYPE THE NAME OF THE MPP DELETED, IF MSGLEVEL EQL LONG
TYPECRLF;
NEXT _ .MPPADDR[M0FORE];
! ZAP ALTEREGOS
EGOPTR _ .MPPADDR[M0FEGO];
WHILE .EGOPTR NEQ 0 DO
BEGIN
NEXTEGO _ .EGOPTR[E0FORE];
PMEM( .EGOPTR, E0SIZE );
EGOPTR _ .NEXTEGO
END;
NOTE - HOW DO WE WANT TO HANDLE POINTERS IN THE TREE? NOW I DELETE THEM
IF .MPPADDR[M0LISTPTRS] NEQ 0 THEN ! DELETE THE POINTERS TO THIS MPP IN THE TREE
BEGIN
NODEPTR _ .MPPADDR[M0FLIST]; ! GET FIRST NODE ADDR
WHILE .NODEPTR NEQ 0 DO
BEGIN
NODEPTR[N0MPPPTR] _ 0;
NEXTNODE _ .NODEPTR[N0MPPFORE];
NODEPTR[N0MPPLINKS] _ 0;
NODEPTR _ .NEXTNODE
END;
MPPADDR[M0LISTPTRS] _ 0
END;
UNLINK(%FROM% MPPTAB, .MPPADDR);
PMEM(.MPPADDR,M0SIZE);
.NEXT
END;
FORWARD WCMPPNAME(1), OUTPUTMPPNO, OUTPUTMPPEGO, OUTPUTMM, OUTPUTMPR;
COMMENT;
! ROUTINE WCMPP
! ======= ======
! THIS ROUTINE WRITES THE MPP SECTION OF THE COMPILE FILE
GLOBAL ROUTINE WCMPP=
BEGIN
! IT IS ASSUMED THAT THE MPPS AND LEAVES HAVE BEEN NUMBERED
! THEN FOR EACH MPP
REGISTER
MPR,
J,
THISEGO,
MPPADDR;
MAP FORMAT MPPADDR;
%LOCAL% ROUTINE OUTPUTPAIR( WHICH ) =
BEGIN
OUTPUT( ' XWD ' );
OUTPUTMPPNO( .WHICH );
OUTPUTCOMMA;
OUTPUTMPPNO( .WHICH );
OUTPUTCRLF
END;
OUTPUT( '?L SUBTTL MPPS?M?J?M?J' );
OUTPUT('EXTERNAL SON,SOFF,DMR,DCR,ERR?M?J');
OUTPUT( '?M?JMPPTAB::?M?J' );
INCR I FROM 0 TO .LASTMPP DO OUTPUTPAIR( .I );
OUTPUT( ' M.ERR=.-MPPTAB?M?J' );
MPR _ .LASTMPP + 1;
OUTPUTPAIR( .MPR );
OUTPUT( ' M.SON=.-MPPTAB?M?J' );
MPR _ .MPR + 1;
OUTPUTPAIR( .MPR );
OUTPUT( ' M.SOFF=.-MPPTAB?M?J' );
MPR _ .MPR + 1;
OUTPUTPAIR( .MPR );
OUTPUT( ' M.RDM=.-MPPTAB?M?J' );
MPR _ .MPR + 1;
OUTPUTPAIR( .MPR );
OUTPUT( ' M.RDMC=.-MPPTAB?M?J' );
MPR _ .MPR + 1;
OUTPUTPAIR( .MPR );
OUTPUT( '?M?JFMPPS==: 10?M?J?IBLOCK FMPPS?M?J?M?JMPPS==:' );
OUTPUTD( .MPR + 1 );
OUTPUTCRLF;
OUTPUTCRLF;
MPPADDR _ .MPPTAB<FORE>;
J _ 0;
INCR I FROM 0 TO .LASTMPP DO
BEGIN
THISEGO _ .MPPADDR[M0FEGO];
WHILE .THISEGO NEQ 0 DO
BEGIN
THISEGO _ OUTPUTMPPEGO( .I, .J, .THISEGO, .MPPADDR );
J _ .J + 1
END;
OUTPUTCRLF;
J _ 0;
MPPADDR _ .MPPADDR[M0FORE]
END;
OUTPUTCRLF;
MPR _ .LASTMPP + 1;
OUTPUTMPR( .MPR, PAZ 'ERR' );
MPR _ .MPR + 1;
OUTPUTMPR( .MPR, PAZ 'SON' );
MPR _ .MPR + 1;
OUTPUTMPR( .MPR, PAZ 'SOFF' );
MPR _ .MPR + 1;
OUTPUTMPR( .MPR, PAZ 'DMR' );
MPR _ .MPR + 1;
OUTPUTMPR( .MPR, PAZ 'DCR' );
END;
COMMENT;
! ROUTINE WCMPPNAME
! ======= ========
! THIS ROUTINE WRITES THE MPP NAME TO THE COMPILE FILE
ROUTINE WCMPPNAME(MPPADDR)=
BEGIN
MAP FORMAT MPPADDR;
XPUT(MPPADDR[M0NAME])
END;
COMMENT;
! ROUTINE WCMPPNO
! ======= ========
! THIS ROUTINE WRITES THE MPP NAME TO THE COMPILE FILE
ROUTINE WCMPPNO( MPPADDR ) =
BEGIN
MAP FORMAT MPPADDR;
OUTPUTMPPNO( .MPPADDR[M0MPPNO] )
END;
COMMENT;
! ROUTINE WCMPPNUMBER
! ======= ========
! THIS ROUTINE WRITES THE MPP NUMBER TO THE COMPILE FILE
GLOBAL ROUTINE WCMPPNUMBER( MPPADDR ) =
BEGIN
MAP FORMAT MPPADDR;
OUTPUTD( .MPPADDR[M0MPPNO] )
END;
COMMENT;
! ROUTINE OUTPUTMPPNO
! ======= ===========
! THIS ROUTINE WRITES AN MPP NAME OF THE FORM "M"NUMBER.0
ROUTINE OUTPUTMPPNO( MAJOR ) =
BEGIN
OUTPUTMM( .MAJOR, 0 )
END;
COMMENT;
! ROUTINE OUTPUTMM
! ======= ========
! THIS ROUTINE WRITES AN MPPNAME OF THE FORM: "M"NUMBER1.NUMBER2
ROUTINE OUTPUTMM( MAJOR, MINOR ) =
BEGIN
OUTPUTC( "M" );
OUTPUTD( .MAJOR );
OUTPUTC( "." );
OUTPUTD( .MINOR );
END;
COMMENT;
! ROUTINE OUTPUTMPPEGO
! ======= ============
! THIS ROUTINE WRITES AN MPP MACRO CALL FOR AN EGO AND RETURNS
! A POINTER TO THE NEXT EGO
ROUTINE OUTPUTMPPEGO( MAJOR, MINOR, EGO, MPPADDR ) =
BEGIN
MAP FORMAT EGO;
MAP FORMAT MPPADDR;
OUTPUTMM( .MAJOR, .MINOR );
OUTPUT( ': %MPP(' );
OUTPUTD( .MAJOR );
OUTPUTCOMMA;
IF .EGO[E0FORE] NEQ 0 THEN
OUTPUTMM( .MAJOR, .MINOR + 1)
ELSE OUTPUTC( "0" );
OUTPUTCOMMA;
IF .EGO[ E0DEVICE ] EQL 0 THEN OUTPUT( 'DSK' ) ELSE OUTPUTSWORD( .EGO[E0DEVICE] );
OUTPUTCOMMA;
OUTPUTSWORD( .EGO[E0FILENAME] );
OUTPUTCOMMA;
OUTPUT( '<^O' );
OUTPUTO( .EGO[E0PROJ] );
OUTPUT( ', ^O' );
OUTPUTO( .EGO[E0PROG] );
OUTPUTC( ">" );
OUTPUTCOMMA;
OUTPUTD( IF .EGO[E0KFLAG] THEN .EGO[E0KCORE] * 2 ELSE .EGO[E0KCORE] );
OUTPUTCOMMA;
OUTPUTD( .MPPADDR[M0MIN] );
OUTPUTCOMMA;
OUTPUTD( .MPPADDR[M0MAX] );
OUTPUTCOMMA;
OUTPUTD( .MPPADDR[M0INITIAL] );
OUTPUTCOMMA;
OUTPUTD( .MPPADDR[M0HPQ] );
OUTPUTCOMMA;
OUTPUTB( .MPPADDR[M0LOCK] );
OUTPUTCOMMA;
OUTPUTB( FALSE ); ! NOT LOCAL
OUTPUTCOMMA;
OUTPUTB( .MPPADDR[M0IMMORTAL] );
OUTPUT( ')?M?J' );
.EGO[E0FORE]
END;
COMMENT;
! ROUTINE OUTPUTMPR
! ======= ============
! THIS ROUTINE WRITES AN MPP MACRO CALL FOR AN MPR
ROUTINE OUTPUTMPR( MAJOR, MPR ) =
BEGIN
OUTPUTMM( .MAJOR, 0 );
OUTPUT( ': %MPP(' );
OUTPUTD( .MAJOR );
OUTPUTCOMMA;
OUTPUT( '0,COR,' );
XOUTPUT( .MPR );
OUTPUTCOMMA;
OUTPUT( '<0,0>,0,0,0,0,0,0,TRUE,TRUE)?M?J' );
END;
FORWARD MPPATTACH(1);
COMMENT;
! ROUTINE WHATMPPS
! ======= =========
! THIS ROUTINE CHECKS THE MPP TABLE FOR UNDEFINED MPPS AND MPPS
! WHICH DON'T BELONG TO LEAVES
! WHATMPPS RETURNS GOOD IF EVERYTHING IS OK, ELSE BAD
GLOBAL ROUTINE WHATMPPS(TELL)=
BEGIN
! IF TELL THEN ONLY TELL THE USER WHAT IS UNDEFINED, ELSE REQUEST UNDEFINED INFO
!TWO POSSIBLE PROBLEMS
! 1. IF MPP TOBEDEFINED FLAG IS ON
! 2. IF THE MPP DOES NOT BELONG TO A LEAF
REGISTER
NEXT,
STATUS,
MPPADDR;
MAP FORMAT MPPADDR;
STATUS _ GOOD;
IF ( MPPADDR _ .MPPTAB<FORE> ) EQL 0 THEN RETURN GOOD; ! IF THERE ARN'T ANY THEN THEY MUST BE GOOD!
IF .TELL THEN
BEGIN
DO
BEGIN
IF .MPPADDR[M0TOBEDEFINED] THEN
BEGIN
ERROR( 49 );
OUTSA(MPPADDR[M0NAME]);
TYPE('[ TO BE DEFINED?M?J]');
STATUS _ BAD
END
ELSE
BEGIN
IF .MPPADDR[M0LISTPTRS] EQL 0 THEN
BEGIN
WARN( 28 );
OUTSA(MPPADDR[M0NAME]);
TYPE('[ HAS NO NODE ASSOCIATED WITH IT?M?J]' );
! NO STATUS CHANGE / ONLY WARNING
END
END
END
WHILE (MPPADDR _ .MPPADDR[M0FORE]) NEQ 0
END
ELSE
BEGIN
DO
BEGIN
NEXT _ .MPPADDR[ M0FORE ];
IF .MPPADDR[M0TOBEDEFINED] THEN
BEGIN
ERROR( 49 );
OUTSA(MPPADDR[M0NAME]);
TYPE('[ TO BE DEFINED?M?J?M?J]');
PRINTMPPNAME( MPPADDR[ M0NAME ] );
MAKMPP(.MPPADDR)
END
ELSE
BEGIN
IF .MPPADDR[M0LISTPTRS] EQL 0 THEN
BEGIN
WARN( 28 );
OUTSA(MPPADDR[M0NAME]);
TYPE('[ HAS NO NODE ASSOCIATED WITH IT?M?J?M?J]' );
PRINTMPPNAME( MPPADDR[ M0NAME ] );
ASKSTR( 'DO YOU WISH TO [DELETE THIS MPP OR ATTACH IT TO A NODE]?R(,DELETE,ATTACH?R)[: ??]',
PLIT( ASCII 'DELET', DELMPP,
ASCII 'ATTAC', MPPATTACH,
0, IGNORE ),
.MPPADDR )
END
END
END
WHILE (MPPADDR _ .NEXT) NEQ 0
END;
.STATUS
END;
COMMENT;
! ROUTINE MPPATTACH
! ======= =========
! THIS ROUTINE ATTACHES THE MPP TO A NODE
ROUTINE MPPATTACH( MPPADDR ) =
BEGIN
REGISTER
NODEPTR;
LABEL LOOP;
MAP FORMAT MPPADDR;
TYPE( '[ATTACH TO WHAT NODE: ??]' );
LOOP: REPEAT ! UNTIL WE GET A GOOD ANSWER
BEGIN
WHILE ( ACHAR _ INPUT( ALINE, ALINELENGTH ) ) EQL CRONLY DO ! GET AN INPUT, MUST HAVE ONE
BEGIN
ERROR( 32 );
WARN( 0 );
TYPE( '[ ??]' )
END;
IF ( NODEPTR _ GETNODEPTR( PRIM<0,0> ) ) NEQ 0 THEN ! FIND THE NODE'S ADDRESS
BEGIN
IF NOT HASMPP( .NODEPTR ) THEN LEAVE LOOP
ELSE ERROR( 91 );
NOTE - COULD MAKE THIS ASK REPLACE OR IGNORE ?
END
ELSE
BEGIN
ERROR( 33 )
END;
RETURN
END;
ATTACH( %TO% MPPADDR[M0LISTPTRS], .NODEPTR, N0MPPOFFSETT )
END;
END;
! END OF MGNMPP.BLI