*DECK S$GNFMG 
          PROC  S$GNFMG(FMTBL$, REC$, SPEC$, WSAF$, CODE$); 
  
#**       S$GNFMG -  GENERATE FINAL-MERGE-CODE                         #
#                                                                      #
#     CALLING SEQUENCE-                                                #
#         S$GNFMG(FMTBL$, REC$, SPEC$, WSAF$, CODE$):                  #
#                                                                      #
#     GIVEN-                                                           #
#         FMTBL$ = FORMAT OF FINAL MERGE TABLE                         #
#         REC$ = FORMAT OF INTERNAL RECORD.                            #
#         SPEC$ = USER SPECIFICATION.                                  #
#         WSAF$ = ALLOCATION OF WSA$ FOR FNLMRG-CODE                   #
#         CODE$ = LOCATION FOR GENERATED CODE.                         #
#                                                                      #
#     DOES-                                                            #
#         GENERATES FINAL-MERGE-CODE  INTO CODE$.                      #
  
  
          BEGIN 
  
*CALL A 
  
*CALL FMTBL$
  
*CALL REC$
  
*CALL SPEC$ 
  
*CALL WSAF$ 
  
*CALL CODE$ 
  
          XREF
              BEGIN 
              PROC  S$CMSLF;           # SHRINK MEMORY BLOCK AT LWA    #
              PROC  S$ABORT;           # HANDLE INTERNAL ABORT         #
              PROC  S$GNCMP;           # GEN- COMPARE CODE             #
              PROC  S$GNGIR;           # GEN- GET RECORD FROM FILE     #
              PROC  S$GNGIV;           # GEN- GET VAR-LEN REC FROM FILE#
              PROC  S$GNFM1;           # GEN- FNLMRG-CODE , PART 1     #
              PROC  S$GNFM2;           # GEN- FNLMRG-CODE , PART 2     #
              PROC  S$GNFM3;           # GEN- FNLMRG-CODE , PART 3     #
              PROC  S$GNFM4;           # GEN- FNLMRG-CODE , PART 4     #
              PROC  S$GNFET;           # GEN- FETS FOR FNLMRG FILES    #
              PROC  S$GNPRU;           # GEN- PUT RECORD TO USER       #
              PROC  S$GNSUM;           # GEN- SUMMING CODE             #
              PROC  S$INITL;           # INITIALIZE  LABELS            #
              PROC  S$LOAD;            # LOAD A MODULE                 #
              PROC  S$ULOAD;           # UNLOAD A MODULE               #
              END 
  
          XREF
              BEGIN                    # USED BY S$GNREV               #
              ITEM  S$IRRL   I;        # REC$IRRL                      #
              ITEM  S$LK     I;        # NUMBER OF USED KEY BITS       #
              ITEM  S$LR     I;        # NUMBER OF BITS FOR REC. NUM.  #
              ITEM  S$OREC   I;        # WSA$ OFFSET TO EXTERNAL REC   #
              ITEM  S$ORSA   I;        # WSA$ OFFSET TO REC STOR AREA  #
              END 
  
           XREF 
              BEGIN 
              ITEM  S$LOC    I;        # ABSOLUTE ADDRESS FOR NEXT INST#
              ITEM  S$POS    I;        # NEXT FREE BIT FOR INST, 0=LEFT#
              ITEM  S$ACODE  I;        # ABS. ADDRESS OF FIRST CODE WD #
              ITEM  S$LCODE  I;        # LENGTH OF CODE$               #
              END 
  
          ITEM  LF           I;        # FOR S$GNGIV                   #
          ITEM  LL           I;        # FOR S$GNGIV                   #
          ITEM  OFFSET       I;        # FOR S$GNGIV                   #
          ITEM  UNUSED       I;        # PARAMETER TO S$CMSLF          #
  
          ITEM  BUFREC       B;        # TRUE IF REMAINDER OF REC. IN  #
                                       #   BUFFER RATHER THAN IN RSA   #
  
          ITEM  I            I; 
  
          CONTROL DISJOINT ;
  
          CONTROL INERT ; 
  
CONTROL EJECT ; 
  
              S$INITL;                 # INITIALIZE LABELS             #
          S$ACODE = LOC(CODE$WORD[1]);           # FOR S$GEN, S$GNLBL  #
          S$LCODE = CODE$LENGTH;                 # FOR S$GEN           #
          S$LOC = S$ACODE;                       # FOR S$GEN, S$GNLBL  #
          S$POS = 0;                             # FOR S$GEN, S$GNLBL  #
  
  
#     SET GLOBALS USED BY LOW-LEVEL CODE GENERATORS                    #
  
          S$IRRL = REC$IRRL;
          S$LK = 0; 
          S$LR = REC$LR;
          S$OREC = WSAF$OREC; 
          S$ORSA = WSAF$ORSA; 
  
          S$GNFM1(WSAF$LTRN, REC$LR,SPEC$OUTFIT,WSAF$OREC,SPEC$FASTOUT);
  
          S$LOAD("S$GNPRU");
          S$GNPRU(SPEC$, WSAF$OREC, WSAF$ORSA, REC$); 
          S$ULOAD("S$GNPRU"); 
  
          S$GNFM2(WSAF$LTRN, WSAF$ORSA, REC$LR, REC$IRRL);
  
          IF SPEC$FIXED THEN
              S$GNGIR(REC$IRRL, REC$LR);
          ELSE
              BEGIN 
              OFFSET = 1 + 1 + REC$LR + REC$LK1 + REC$LK2 
                       + REC$LO1 + REC$LO2 + REC$LS1 + REC$LS2; 
              LL = REC$LL1 + REC$LL2; 
          LF = REC$LF1 + REC$LF2; 
              S$GNGIV(REC$LR, OFFSET, LL, REC$IRRL, LF);
              END 
  
          S$GNFM3;
  
          BUFREC = FALSE; 
  
  
          $BEGIN
          IF REC$LO1+REC$LO2 NQ 0 AND SPEC$1STSUM NQ 0 THEN 
              S$ABORT("S$GNFMG"); 
          $END
  
          S$GNCMP(WSAF$ORSA, REC$IRRL, REC$LR, REC$LK1, REC$LK2,
                  REC$LO1, REC$LO2, BUFREC, SPEC$1STSUM); 
  
          IF SPEC$1STSUM NQ 0 THEN
              S$GNSUM(SPEC$, WSAF$ORSA, REC$IRRL, REC$LR, BUFREC);
  
  
          S$GNFM4;
  
          FOR I=1  STEP 1 UNTIL WSAF$LTRN DO
              BEGIN 
              S$GNFET(FMTBL$FILE[I], WSAF$LIBUF[I], WSAF$OIBUF[I],
                                     FMTBL$PRUNUM[I]);
              END #FOR# 
  
          CODE$USED = S$LOC - S$ACODE + 1;       # (+1 FOR PART WORD)  #
  
          UNUSED = CODE$LENGTH - CODE$USED; 
          S$CMSLF(CODE$, UNUSED); 
  
          END  # S$GNFMG #
          TERM
