Google
 

Trailing-Edge - PDP-10 Archives - AP-D471B-SB_1978 - mcsonc.bli
There are no other files named mcsonc.bli in the archive.
!***COPYRIGHT (C) 1974, 1975, 1976, 1977 DIGITAL EQUIPMENT CORP., MAYNARD, MASS.***
MODULE MCSONC(RESERVE(#11, #12, #13, #14), SREG = #17, FREG = #16,
 DREGS = 4, VREG = #15, MLIST, TIMER = EXTERNAL(SIX12), FSAVE ) = 
    BEGIN
	REQUIRE	 DATA.BLI;			! EVERYONE NEEDS THIS

	EXTERNAL
		LEAFDSKTAB,TRMDSKTAB,DELDSKGH,DELGH,DGPURGE,GPURGE,BUILD,MOVE,LINK,CHKRUN;

	FORWARD	FIXLEAVES, FIXTERMINALS, FIXGROUP;

	BIND	DEFERRED = TRUE;

	STRUCTURE
		HALFFORMAT[ I ] = IF .I THEN ( .HALFFORMAT + .I / 2 )<RH>
					ELSE ( .HALFFORMAT + .I / 2 )<LH>;

	STRUCTURE
		SIMPLEFORMAT[WD,I,J] = (.SIMPLEFORMAT + .WD)<.I,.J>;

	GLOBAL ROUTINE MCSONCE =
	    BEGIN
		FIXLEAVES();
		FIXTERMINALS()
	    END;
	COMMENT;

	! ROUTINE FIXLEAVES
	! ======= =========
	! THIS ROUTINE READS THE FAILSOFT FILE AND FIXES THE IN-CORE DATABASE

	ROUTINE FIXLEAVES =
	    BEGIN

		REGISTER
			NEXT,
			DSKGHTABPTR;
		LOCAL	PTL,
			DSKGHADDR,
			LEAFPTR,
			GHPTR,
			DSKMHPTR;
		LOCAL	EMPTYFLAG;
		LOCAL	PTAB[ PTLSIZE ],	! THIS IS USED TO STORE THE LEAF DSKGH TABLE
			DSKGHTAB[ PTLSIZE ],	! THIS IS USED TO STORE A DSKGH
			LPTPTL;			! NEXT LEAF DSKGHPTR PLT TO USE

		MAP	SIMPLEFORMAT DSKGHTAB;
		MAP	FORMAT GHPTR;
		MAP	FORMAT LEAFPTR;
		MAP	HALFFORMAT PTAB;

		LPTPTL _ .IBASE;			! START WITH THE FIRST PARTICLE
							! OF THE LEAF GROUP POINTER TABLE

		NEXT _ LEAFPERPTL;			! FORCE A READ THE FIRST TIME THRU THE LOOP

		INCR LEAFNO FROM 0 TO .N0LFNO DO	! FOR ALL LEAVES DO
		    BEGIN
			IF .NEXT GEQ LEAFPERPTL THEN	! DO WE NEED TO READ
			    BEGIN
				MOVE( DREAD( .LPTPTL ), PTAB, PTLSIZE );	! YES THEN DO SO AND STORE IN PTAB
				NEXT _ 0;		! RESET OUR INDEX INTO PTAB
				LPTPTL _ .LPTPTL + 1	! SET NEXT PTL TO READ
			    END
			    ELSE NEXT _ .NEXT + 1;	! NO READ THEN INC THE INDEX

			DSKGHTABPTR _ .PTAB[ .NEXT ];	! GET A DSK GH TABLE POINTER

			LEAFPTR _ .LFPTRTAB[ .LEAFNO ];	! GET THE LEAF'S ADDRESS BASE UPON IT'S NUMBER

			WHILE .DSKGHTABPTR NEQ 0 DO	! WHILE THERE ARE DSKGH'S
			    BEGIN
				MOVE( DREAD( PTL _ .DSKGHTABPTR ), DSKGHTAB, PTLSIZE );	! READ A GROUP
				EMPTYFLAG _ TRUE;	!ASSUME EMPTY
				IF .DSKGHTAB[DG0NEXT] EQL 0 THEN LEAFDSKTAB[.LEAFNO] _ .PTL;
				DSKGHTABPTR _ .DSKGHTAB[ DG0NEXT ];			! NEXT GROUP TO READ
				INCR I FROM 1 TO DG0MAX DO	! AND PROCESS THE GROUP
					IF ( DSKMHPTR _ .DSKGHTAB[ DG0MH( .I ) ] ) NEQ 0 THEN	! IF NON-ZERO
					    BEGIN
						EMPTYFLAG _ FALSE;	!NOT EMPTY
						DSKGHADDR<LH> _ .I;
						DSKGHADDR<RH> _ .PTL;
						IF ( GHPTR _ FIXGROUP( .DSKGHTAB[ DG0TSN( .I ) ],
						     .DSKGHTAB[ DG0SENDER( .I ) ],
						     .DSKMHPTR,
							.DSKGHADDR,
						     NOT DEFERRED ) ) NEQ 0 THEN
										! RECONSTITUTE THE GROUP
						    BEGIN
							LINK( LEAFPTR[N0GHS], .GHPTR );	! ATTACH IT TO THE TREE
							GHPTR[ G0LFPTR ] _ .LEAFPTR;	! STORE POINTER TO OWNER
							CHKRUN( .LEAFPTR, 1, .GHPTR );	! AND SEE IF ANYONE TO START
							LEAFPTR[N0TSCORE] _ 0	!NO TRANSACTIONS IN CORE ON RESTART
						    END
					    END;
				IF .EMPTYFLAG THEN DELDSKGH( 1^18 + .PTL, LEAFTYPE)
			    END
		    END
	    END;
COMMENT;

! ROUTINE FIXTERMINALS
! ======= ============
! THIS ROUTINE FIXES THE IN-CORE DATABASE FOR THE TERMINALS

ROUTINE FIXTERMINALS =
    BEGIN

		REGISTER
			NEXT,
			DSKGHTABPTR;
		LOCAL	PTL,
			DSKGHADDR,
			GHPTR,
			DEST,
			DSKMHPTR;
		LOCAL	EMPTYFLAG;
		LOCAL	PTAB[ PTLSIZE ],	! THIS IS USED TO STORE THE LEAF DSKGH TABLE
			DSKGHTAB[ PTLSIZE ],	! THIS IS USED TO STORE A DSKGH
			LPTPTL;			! NEXT LEAF DSKGHPTR PLT TO USE

		MAP	SIMPLEFORMAT DSKGHTAB;
		MAP	FORMAT DEST;
		MAP	HALFFORMAT PTAB;

		LPTPTL _ .OBASE;			! START WITH THE FIRST PARTICLE
							! OF THE DESTINATION GROUP POINTER TABLE

		NEXT _ LEAFPERPTL;			! FORCE A READ THE FIRST TIME THRU THE LOOP

		DEST _ .SRCTAB + 1;			! FIRST DESTINATION

		INCR DESTNO FROM 0 TO .S0CNT DO		! FOR ALL DESTINATIONS DO
		    BEGIN
			IF .NEXT GEQ LEAFPERPTL THEN	! DO WE NEED TO READ
			    BEGIN
				MOVE( DREAD( .LPTPTL ), PTAB, PTLSIZE );	! YES THEN DO SO AND STORE IN PTAB
				NEXT _ 0;		! RESET OUR INDEX INTO PTAB
				LPTPTL _ .LPTPTL + 1	! SET NEXT PTL TO READ
			    END
			    ELSE NEXT _ .NEXT + 1;	! NO READ THEN INC THE INDEX

			DSKGHTABPTR _ .PTAB[ .NEXT ];	! GET A DSK GH TABLE POINTER

			WHILE .DSKGHTABPTR NEQ 0 DO	! WHILE THERE ARE DSKGH'S
			    BEGIN
				MOVE( DREAD( PTL _ .DSKGHTABPTR ), DSKGHTAB, PTLSIZE );	! READ A GROUP
				EMPTYFLAG _ TRUE;	!ASSUME EMPTY
				IF .DSKGHTAB[DG0NEXT] EQL 0 THEN TRMDSKTAB[.DESTNO] _ .PTL;
				DSKGHTABPTR _ .DSKGHTAB[ DG0NEXT ];			! NEXT GROUP TO READ
				INCR I FROM 1 TO DG0MAX DO				! AND PROCESS THE GROUP
					IF ( DSKMHPTR _ .DSKGHTAB[ DG0MH( .I ) ] ) NEQ 0 THEN	! IF NON-ZERO
					    BEGIN
						EMPTYFLAG _ FALSE;	!NOT EMPTY
						DSKGHADDR<LH> _ .I;
						DSKGHADDR<RH> _ .PTL;
						IF ( GHPTR _ FIXGROUP( .DSKGHTAB[ DG0TSN( .I ) ],
						     .DSKGHTAB[ DG0SENDER( .I ) ],
						     .DSKMHPTR,
							.DSKGHADDR,
						     DEFERRED ) ) NEQ 0 THEN
										! RECONSTITUTE THE GROUP
						    BEGIN
							LINK( DEST[S0DGHS], .GHPTR );	! ATTACH IT TO THE DEST
							DEST[ S0DFGCNT ] _ .DEST[ S0DFGCNT ] + 1
						    END
					    END;
				IF .EMPTYFLAG THEN DELDSKGH( 1^18 + .PTL, TERMINAL)
			    END;
			DEST _ .DEST + .S0SIZE
		    END
	    END;
	COMMENT;

	! ROUTINE FIXGROUP
	! ======= ========
	! THIS ROUTINE CREATES GROUPS AND MESSAGES FROM THE DISK IMMAGE

	ROUTINE FIXGROUP( TSN, SENDERID, DSKMH, DSKGH, TYPEDEFERRED ) =
	    BEGIN
		REGISTER
			GHPTR,
			MHPTR,
			DSKMHPTR;
		LOCAL	M,
			LASTENDI,
			N,
			X,
			Y;
		LABEL	LOOP;
		MAP	FORMAT GHPTR;
		MAP	FORMAT MHPTR;
		MAP	FORMAT DSKMHPTR;
		MAP	FORMAT N;
		MAP	FORMAT X;
		MAP	FORMAT Y;

		DSKMHPTR _ .DSKMH;				! PICK UP THE DSK MESSAGE HEADER PTL NUMBER
		GHPTR _ CREATEGH(0);				! MAKE A GROUP HEADER
		GHPTR[ G0TSN ] _ .TSN;				! AND FILL IT WITH GOODIES
		GHPTR[ G0SENDER ] _ .SENDERID;			! ...
		GHPTR[G0ONDSK ] _ TRUE;				! ...
		GHPTR[G0DSKGHADDR ] _ .DSKGH;			! STORE DSK GROUP ADDRESS IN THE GH

		WHILE .DSKMHPTR NEQ 0 DO			! FOR ALL MESSAGES OF THE GROUP
		    BEGIN
LOOP:			IF .TYPEDEFERRED THEN
			 BEGIN
			  X _ .SRCTAB + 1;
			  INCR M FROM 0 TO .S0CNT DO
			   BEGIN
			    IF ( N _ .X[S0FDGHPTR] ) NEQ 0 THEN DO
			     IF ( Y _ .N[G0FMHPTR] ) NEQ 0 THEN DO
			      IF .DSKMHPTR EQL .Y[M0DSKADDR] THEN
			       BEGIN
			        Y[M0DSCNT] _ .Y[M0DSCNT] + 1;
			        GHPTR[G0MHS] _ .N[G0MHS];
			        LEAVE LOOP
			       END
			      WHILE ( Y _ .Y[M0FORE] ) NEQ 0
			     WHILE ( N _ .N[G0FORE] ) NEQ 0;
			   X _ .X + .S0SIZE
			   END;
			  MHPTR _ CREATEMH( GHPTR[G0MHS] );
			  MHPTR[M0DSCNT] _ 1;
			  MHPTR[M0DSKADDR] _ .DSKMHPTR
			 END
			 ELSE
			 BEGIN
			  MHPTR _ CREATEMH( GHPTR[ G0MHS ] );	! AMKE A MESSAGE HEADER
			  MHPTR[ M0DSKADDR ] _ .DSKMHPTR		! SAVE THE DSK PTL NUMBER IN THE MH
			 END;
			DSKMHPTR _ DREAD( .DSKMHPTR );		! READ THE DISK MESSAGE HEADER
			IF NOT .TYPEDEFERRED THEN
			 BEGIN
			   IF(MHPTR[M0DATE]_.DSKMHPTR[DM0DATE]) EQL 0 THEN DSKMHPTR[DM0ENDI]_0;
			   MHPTR[M0TIME]_.DSKMHPTR[DM0TIME];
			   MHPTR[M0SOT]_.DSKMHPTR[DM0SOT]	! MOVE INTERESTING NUMBERS
			 END;
			LASTENDI _ .DSKMHPTR[ DM0ENDI ];	! SAVE THE LAST END INDICATOR
			DSKMHPTR _ .DSKMHPTR[ DM0NEXTMH ];	! GET THE NEXT DISK MESSAGE HEADER
		   END;
								! NOT MORE MESSAGES IN THE GROUP
		IF NOT .TYPEDEFERRED AND .LASTENDI LSS EGI THEN	! INPUT PARTIALLY ENTERED
		    BEGIN					! YES... TOO BAD ZAP IT
		         GPURGE( .GHPTR[ G0DSKGHADDR ] );	! CLEAN UP THE DISK
			 DELGH( .GHPTR );			! AND DELETE WHAT'S IN CORE
			 RETURN 0				! RETURN NO GH
		    END;
								! GOT A GOOD GROUP
		GHPTR[ G0ENDI ] _ TRUE;				! MARK THE GROUP COMPLETE
		GHPTR[ G0OUTMH ] _ .GHPTR[ G0FMHPTR ];
		GHPTR[ G0CHKPNT ] _ TRUE;

		.GHPTR						! ABND RETURN A POINTER TO THE GROUP HEADER
	    END;



! END OF MCSONC.BLI