*COMDECK ALOUTDIRS
      OVERLAY(6,0)
      PROGRAM OUTDIRS 
C 
C 
C 
C        THIS ROUTINE GENERATES THE OUTPUT DIRECTIVES, WHICH ARE TO 
C        BE USED LATER BY MPLINK.  ALSO A COPY OF THESE DIRECTIVES IS 
C        LISTED IF REQUESTED. 
C 
C 
*CALL ALCOMMON
      LOGICAL ONEMOD,NEEDAD,CONTIG,BASEPAG
      DIMENSION FMTARAY(10) 
C 
C 
      DATA NOCNTRL, CRCNTRL / 6H(3H*L, , 7H(4H *L, /
      DATA ADDRHOL, PGRGHOL / "     ,7H,$" , "     ,4H:$" / 
      DATA NAMEFMT, NAM2FMT / "       ,A6" , "      ,7H-" / 
      DATA NAM2BLK, ENDFMT  / 4R     , ",1H.)" /
      DATA COMAFMT / ",1H," / 
C 
C 
C 
C 
C        SKIP AROUND IF WE ARE NOT CREATING A COPY OF THE DIRECTIVES. 
C 
      IF (.NOT.DIRRPT) GO TO 2
C 
C        OTHERWISE, PRINT THE HEADER AND READ AND PRINT THE DIRECTIVES
C        THAT WERE CREATED BY PREVIOUS PHASES.
C 
      WRITE (LIST,11) 
   11 FORMAT (*1AUTOLINK OUTPUT DIRECTIVES LIST*//) 
      REWIND TMPUNIT
    9 READ (TMPUNIT,1) (CARD(I),I=1,80) 
    1 FORMAT (80R1) 
      IF (EOF(TMPUNIT)) 2,7 
    7 WRITE (LIST,8) (CARD(I),I=1,80) 
    8 FORMAT (1X,80R1)
       GO TO 9
C 
C        SORT THE MODTABL ARRAY ACCORDING TO ASCENDING LOAD ADDRESS.
C 
    2 CALL SORTARY(SRTDADR,MODCNTR,4) 
C 
C 
      RPTCNTR = MODCNTR - 1 
C 
C        SHIFT "SRTDADR" ARRAY TO ELIMINATE ALL MODULES WHICH 
C        WILL NOT BECOME DIRECTIVES.
C 
         DO 320 J2 = 1,MODCNTR
      DO 310 J3=1,RPTCNTR 
         IF ((MODTABL(3,SRTDADR(J3)).AND.DEFMASK) .EQ. 0) GO TO 303 
      ADDRESS = AND(MODTABL(1,SRTDADR(J3)),LDADMSK) 
      IF (ADDRESS .NE. 0) GO TO 310 
      IF (MODTABL(1,SRTDADR(J3)) .EQ. ZERONAM) GO TO 310
303      CONTINUE 
      DO 305 J4=J3,RPTCNTR
      SRTDADR(J4) = SRTDADR(J4+1) 
  305 CONTINUE
      RPTCNTR = RPTCNTR - 1 
  310 CONTINUE
  320 CONTINUE
  321 RPTCNTR = RPTCNTR + 1 
      I2 = 1
      FRSTLOD = I2
C 
C        RETURN IF NO DIRECTIVES ARE TO BE GENERATED OR LISTED. 
C 
      IF (.NOT.OUTDIRD .AND. .NOT.DIRRPT) RETURN
      IF (NOBIN2) GO TO 12
      IF (OUTDIRD) WRITE (DIRUNIT,13) 
      IF (DIRRPT) WRITE (LIST,14) 
   13 FORMAT (5H*LIB.)
   14 FORMAT (6H *LIB.) 
C 
C        OUTPUT THE CORE SIZE DIRECTIVE.
C 
   12 CALL HEXCNVT(CORESIZ-1,SIZE,5)
      IF (OUTDIRD) WRITE (DIRUNIT,16) SIZE
   16 FORMAT (6H*COR,$,A5,1H.)
      IF (DIRRPT) WRITE (LIST,17) SIZE
   17 FORMAT (7H *COR,$,A5,1H.) 
C 
C 
C        GO THROUGH AND CREATE SYN DIRECTIVES FOR THOSE MODULES 
C        REQUIRING ONE. 
C 
      DO 10 I=1,MODCNTR 
      ADDR = AND(MODTABL(1,I),LDADMSK)
C 
C        IGNORE THOSE MODULES THAT DO NOT REQUIRE A SYN.
C 
      SYNFLAG = AND(MODTABL(4,I),SYNRMSK) 
      IF (SYNFLAG.EQ.0) GO TO 10
C 
C        IF A SYN IS REQUIRED, OUTPUT IT TO THE OUTPUT DIRECTIVES 
C        FILE AND/OR THE LIST FILE, AS REQUESTED BY THE USER. 
C 
      IF (OUTDIRD) WRITE (DIRUNIT,4) MODTABL(4,I),MODTABL(1,I)
    4 FORMAT (5H*SYN,,A6,1H,,A6,1H.)
      IF (DIRRPT) WRITE (LIST,6) MODTABL(4,I),MODTABL(1,I)
    6 FORMAT (6H *SYN,,A6,1H,,A6,1H.) 
   10 CONTINUE
C 
C        CONVERT THE PAGE REGISTER SPECIFIED BY THE USER TO HEX ASCII.
C 
      CALL HEXCNVT(PAGEREG,HEXPGRG,2) 
C 
C        INDICATE THAT THE NEXT MODULE MUST HAVE A LOAD ADDRESS 
C        SPECIFIED WITH IT. 
C 
      NEEDAD = .TRUE. 
      BASEPAG = .FALSE. 
C 
C        SAVE THE INDEX OF THE NEXT MODULE TO EXAMINE.
C 
      I =SRTDADR(I2)
C 
C        GET THE CURRENT OBJECT FILE SEQUENCE NUMBER AND A
C        POINTER TO THE FIRST MODULE IN THIS BLOCK. 
C 
   15 CURSEQ = AND(MODTABL(5,I),BINOMSK)
      INDEX1 = I
C 
C        INDICATE THAT WE ONLY HAVE ONE MODULE SO FAR.
C 
      ONEMOD = .TRUE. 
C 
C        CONTIG IS TRUE AS LONG AS EACH MODULE EXAMINED IS TO 
C        BE LOADED INTO CONTIGUOUS MEMORY LOCATIONS.
C 
      CONTIG = .TRUE. 
C 
C        GET THE BEGINNING AND ENDING ADDRESS OF THE NEXT MODULE. 
C 
      ADDR = AND (MODTABL(1,I),LDADMSK) 
C 
C        BRANCH IF WE ARE AT THE OVERLAY PROGRAMS.
C 
      IF (ADDR.EQ.LDADMSK) GO TO 100
      LAST = ADDR + MODTABL(2,I)
C 
C        NOW GET THE ADDRESS OF THE MODULE FOLLOWING THE LAST ONE.
C        BRANCH OUT IF WE HIT THE END.
C 
   20 I2 = I2 + 1 
      IF (I2.GT.RPTCNTR) GO TO 25 
      I = SRTDADR(I2) 
      ADDR = AND(MODTABL(1,I),LDADMSK)
C 
C        BRANCH IF THIS IS THE FIRST OVERLAY PROGRAM. 
C 
      IF (ADDR.EQ.LDADMSK) GO TO 25 
C 
C        BRANCH IF THIS MODULE IS NOT CONTIGUOUS. 
C 
      IF (ADDR.NE.LAST) GO TO 23
C 
C        BRANCH IF THIS MODULE IS NOT IMMEDIATELY FOLLOWING THE 
C        PREVIOUSLY LOADED MODULE ON THE OBJECT FILE. 
C 
      ORDER = AND(MODTABL(5,I),BINOMSK) 
      IF (ORDER.NE.CURSEQ+1) GO TO 25 
C 
C        OTHERWISE, FLAG THAT WE HAVE MORE THAN ONE MODULE IN THIS
C        BLOCK, UPDATE THE SEQUENCE NUMBER AND NEXT LOAD ADDRESS, 
C        AND GO CHECK THE NEXT MODULE.
C 
      ONEMOD = .FALSE.
      CURSEQ = ORDER
      LAST = ADDR + MODTABL(2,I)
      INDEX2 = I
      GO TO 20
C 
C 
C        INDICATE THAT WE HAVE LOST CONTIGUITY IN THE BUILD.
C 
   23 CONTIG = .FALSE.
C 
C        SET UP AN EXECUTION-TIME FORMAT ARRAY, BASED ON THE
C        PARAMETERS THAT MUST BE INCLUDED IN THE LOAD DIRECTIVE.
C 
   25 FMTARAY(1) = NOCNTRL
      FMTINDX = 2 
C 
C        INSERT THE NAME OF THE FIRST MODULE TO LOAD THIS BLOCK.
C 
      FMTARAY(FMTINDX) = NAMEFMT
      FMTINDX = FMTINDX + 1 
C 
C        BRANCH IF ONLY ONE MODULE IS LOADED IN THIS DIRECTIVE. 
C 
      IF (ONEMOD) GO TO 30
C 
C        IF MORE THAN ONE MODULE CAN BE LOADED, INCLUDE THE NAME
C        OF THE LAST MODULE.
C 
      FMTARAY(FMTINDX) = NAM2FMT
      FMTARAY(FMTINDX+1) = OR(AND(MODTABL(1,INDEX2),MODNAME),NAM2BLK) 
      FMTINDX = FMTINDX + 2 
C 
C        BRANCH IF A LOAD ADDRESS IS NOT REQUIRED.
C 
  30  ADDR = AND(MODTABL(1,INDEX1),LDADMSK) 
      IF (BASEPAG .AND. ADDR .GT. PGAREAE)
     X      GO TO 22
      DO 21 J=1,HIPAGE
      IF (ADDR .EQ. FRSTPGA(J)) GO TO 24
   21 CONTINUE
      IF (.NOT. NEEDAD) GO TO 35
      GO TO 24
C 
C        IF NEEDED, CONVERT THE ADDRESS TO ASCII AND INSERT IT
C        INTO THE FORMAT ARRAY. 
C 
   22 BASEPAG = .FALSE. 
   24 FMTARAY(FMTINDX) = ADDRHOL
      ADDR = AND(MODTABL(1,INDEX1),LDADMSK) 
      CALL HEXCNVT(ADDR,FMTARAY(FMTINDX+1),5) 
      FMTINDX = FMTINDX + 2 
C 
C        BRANCH IF WE DO NOT NEED TO SPECIFY A PAGE REGISTER. 
C 
      IF (.NOT.PGREGD) GO TO 35 
      DO 26 J=1,HIPAGE
      IF (ADDR.EQ.FRSTPGA(J)) GO TO 28
   26 CONTINUE
      GO TO 35
C 
C        OTHERWISE, INCLUDE IT TOO. 
C 
   28 FMTARAY(FMTINDX) = PGRGHOL
      FMTARAY(FMTINDX+1) = HEXPGRG
      FMTINDX = FMTINDX + 2 
      IF (J .EQ. 1) BASEPAG = .TRUE.
C 
C        END THE FORMAT, AND OUTPUT IT. 
C 
   35 FMTARAY(FMTINDX) = ENDFMT 
      IF (OUTDIRD) WRITE (DIRUNIT,FMTARAY) MODTABL(1,INDEX1)
C 
C        IF A LISTING IS REQUIRED, OUTPUT IT. 
C 
      FMTARAY(1) = CRCNTRL
      IF (DIRRPT) WRITE (LIST,FMTARAY) MODTABL(1,INDEX1)
C 
C        WE NEED AN ADDRESS TO BE INSERTED NEXT TIME IF WE HAD
C        A NON-CONTIGUOUS MODULE THIS TIME. 
C 
      NEEDAD = .NOT.CONTIG
C 
C        IF THERE ARE MORE TO LOAD, GO TO IT. 
C 
      IF (I2.LE.RPTCNTR) GO TO 15 
C 
C        OTHERWISE, END THIS PHASE. 
C 
      IF (OUTDIRD) WRITE (DIRUNIT,40) 
   40 FORMAT (5H*END.)
      IF (DIRRPT) WRITE (LIST,45) 
   45 FORMAT (6H *END.) 
C 
C        BRANCH IF THERE ARE NO OVERLAYS. 
C 
  100 IF (OVLYCTR.EQ.0) GO TO 200 
C 
C        OTHERWISE, OUTPUT THE COMMAND TO RESERVE THE AREA. 
C 
      IF (OUTDIRD) WRITE (DIRUNIT,105) OVLYBGN,OVLYEND
  105 FORMAT (17H*OVLY,OVLYAR,AA,$,Z5,2H,$,Z5,1H.)
      IF (DIRRPT) WRITE (LIST,110) OVLYBGN,OVLYEND
  110 FORMAT (18H *OVLY,OVLYAR,AA,$,Z5,2H,$,Z5,1H.) 
      OVLYNDX = 0 
C 
C        POINT TO THE NEXT OVERLAY. 
C 
  115 OVLYNDX = OVLYNDX + 1 
C 
C        BRANCH IF ALL OVERLAYS DONE. 
C 
      IF (OVLYNDX.GT.OVLYCTR) GO TO 200 
      SWITCH = 1
      ADDR = 0
      OVNAME = AND(OVLYTBL(OVLYNDX),OVNMASK)
C 
C        BUILD THE OVERLAY COMMANDS.
C 
      DO 150 I3=I2,RPTCNTR
      I = SRTDADR(I3) 
C 
C        DO NOT LOAD IF THIS HAS NO DEFINED APPLICATIONS OR IF
C        THIS DOES NOT BELONG TO AN OVERLAY.
C 
      IF (AND(MODTABL(3,I),DEFMASK).EQ.0) GO TO 150 
      IF (AND(MODTABL(5,I),OVNMASK).NE.OVNAME) GO TO 150
C 
C        INSERT THE LOAD ADDRESS RELATIVE TO THE OVERLAY. 
C 
      MODTABL(1,I) = OR(AND(MODTABL(1,I),MODNAME),ADDR) 
      ADDR = ADDR + MODTABL(2,I) - 1
C 
C        SWITCH IS 1 IF WE ARE STARTING A NEW OVERLAY.
C 
      GO TO (120,135), SWITCH 
C 
C        GENERATE A DIRECTIVE TO START A NEW OVERLAY. 
C 
  120 SWITCH = 2
      IF (OUTDIRD) WRITE (DIRUNIT,125) MODTABL(1,I) 
  125 FORMAT (3H*L,,A6,8H,OVLYAR.)
      IF (DIRRPT) WRITE (LIST,130) MODTABL(1,I) 
  130 FORMAT (4H *L,,A6,8H,OVLYAR.) 
      GO TO 150 
C 
C        FOR A CONTINUING OVERLAY, GENERATE A REGULAR LOAD DIRECTIVE. 
C 
  135 IF (OUTDIRD) WRITE (DIRUNIT,140) MODTABL(1,I) 
  140 FORMAT (3H*L,,A6,1H.) 
      IF (DIRRPT) WRITE (LIST,145) MODTABL(1,I) 
  145 FORMAT (4H *L,,A6,1H.)
  150 CONTINUE
      GO TO 115 
C 
C 
  200 RETURN
      END 
