*DECK S$GEN 
          IDENT  S$GEN
          TITLE  S$GEN -  GENERATE AN INSTRUCTION 
          COMMENT  GENERATE AN INSTRUCTION
          SPACE  4
**        GEN -  GENERATE INSTRUCTION                                    KEYCMP 
*                                                                        KEYCMP 
*     CALLING SEQUENCE-                                                  KEYCMP 
*         GEN    (INSTR),MOD           (SEE MACRO FOR DETAILS)           KEYCMP 
*       OR                                                               KEYCMP 
*         RJ     S$GEN
* +       VFD    30/INSTRUCTION, (LEFT-JUSTFIED)                         KEYCMP 
*         VFD    1/1 IFF INSTRUCTION IS 30 BITS,                         KEYCMP 
*         VFD    11/0,                                                   KEYCMP 
*         VFD    18/MODIFIER:                                            KEYCMP 
*                       0 MEANS NO MODIFICATION                          KEYCMP 
*                      <0 MEANS TO ADD REGISTER B7                       KEYCMP 
*                      >0 MEANS LOCAL LABEL REFERENCE                    KEYCMP 
*                                                                        KEYCMP 
*     GIVEN-
*         S$LOC = ADDRESS WHERE NEXT INSTRUCTION WILL BE STORED AND 
*          LATER EXECUTED.
*         S$POS = POSITION WITHIN WORD AT S$LOC WHERE INSTRUCTION WILL
*          BE STORED.  (VALUE IS 45, 30, 15 OR 0) 
*         S$ACODE = ORIGINAL VALUE OF S$LOC.
*         S$LCODE = NUMBER OF AVAILABLE WORDS STARTING AT S$ACODE.
* 
*     DOES-                                                              KEYCMP 
*         INSTRUCTIONS ARE GENERATED AT ADDRESS S$LOC AND 
*          POSITION S$POS (CORRESPONDING TO *P IN COMPASS). 
*         GENERATES A 15-BIT *NO* IF NECESSARY.                          KEYCMP 
*         GENERATES THE MODIFIED INSTRUCTION.                            KEYCMP 
*                                                                        KEYCMP 
*     USES-      B    * - - - - 6 7    *B1=1                             KEYCMP 
*                X  0 1 2 3 - - 6 -                                      KEYCMP 
*                A  - 1 2 3 - - 6 -                                      KEYCMP 
                                                                         KEYCMP 
                                                                         KEYCMP 
          ENTRY  S$GEN
 S$GEN    SUBR               (USED TO REFERENCE PARAMETERS) 
                                                                         KEYCMP 
*     IF LAST GENERATED INSTRUCTION FILLED A WORD, CLEAR (S$LOC)
                                                                         KEYCMP 
          SA1    S$LOC       ADDRESS FOR THIS INSTRUCTION 
          SA2    S$POS       POSITION = 45, 30, 15 OR 0 
          IFTHEN X2=0        IF JUST FILLED AN INSTRUCTION WORD          KEYCMP 
            MX6    0           CLEAR NEW WORD                            KEYCMP 
            SA6    X1                                                    KEYCMP 
            SX2    60          SET POSITION COUNTER                      KEYCMP 
            ENDIF.                                                       KEYCMP 
*         X1 = ADDRESS FOR THIS INSTRUCTION                              KEYCMP 
*         X2 = POSITION COUNTER (60, 45, 30 OR 15)                       KEYCMP 
*         B7 = POSSIBLE MODIFIER                                         KEYCMP 
                                                                         KEYCMP 
*     EXAMINE PARAMETERS                                                 KEYCMP 
                                                                         KEYCMP 
          SA3    S$GEN
          LX3    30                                                      KEYCMP 
          SA3    X3          30/INSTR, 1/L, 11/0, 18/MOD                 KEYCMP 
          SB6    X3                                                      KEYCMP 
          IFTHEN B6\0        IF NO MODIFICATION BY REGISTER B7           KEYCMP 
            SB7    B0          MODIFICATION VALUE IS ZERO                KEYCMP 
            ENDIF.                                                       KEYCMP 
          LX3    30          1/L, 29/, 30/INSTRUCTION                    KEYCMP 
          IFTHEN X3\0        IF 15-BIT INSTRUCTION                       KEYCMP 
            AX3    15          RIGHT-JUSTIFY INSTRUCTION                 KEYCMP 
            MX0    -15         MASK TO STRIP JUNK                        KEYCMP 
            SX6    X2-15       NEW POSITION COUNTER                      KEYCMP 
          ELSE-              IF 30-BIT INSTRUCTION                       KEYCMP 
            MX0    -30         MASK TO STRIP JUNK                        KEYCMP 
            SX6    X2-30       NEW POSITION COUNTER                      KEYCMP 
            ENDIF.                                                       KEYCMP 
          BX3    -X0*X3      STRIP JUNK FROM INSTRUCTION                 KEYCMP 
  
          ENTRY  S$GEN1 
 S$GEN1   BSS    0           ENTER FROM S$GEN15, S$GEN30
*         X1 = ADDRESS FOR THIS INSTRUCTION                              KEYCMP 
*         X3 = THIS INSTRUCTION, RIGHT-JUSTIFIED, ZERO-FILLED            KEYCMP 
*         A3+1 = RETURN ADDRESS                                          KEYCMP 
*         X6 = NEW POSITION COUNTER                                      KEYCMP 
*         B6 = NEGATIVE, 0 OR LBLPTR                                     KEYCMP 
*         B7 = VALUE TO ADD TO INSTRUCTION                               KEYCMP 
                                                                         KEYCMP 
*     PAD OLD WORD WITH *NO* IF NECESSARY                                KEYCMP 
                                                                         KEYCMP 
          IFTHEN X6<0        IF 15 BITS LEFT FOR 30-BIT INSTRUCTION      KEYCMP 
            SA1    X1          OLD INSTRUCTION WORD                      KEYCMP 
            SX6    46000B      *NO*                                      KEYCMP 
            BX6    X1+X6       INSERT *NO*                               KEYCMP 
            SA6    A1          STORE                                     KEYCMP 
            MX6    0           CLEAR NEXT WORD                           KEYCMP 
            SA6    A1+B1                                                 KEYCMP 
            SX6    A1+B1       SET NEW S$LOC
            SA6    S$LOC
            SX1    A1+B1       RETAIN S$LOC IN REGISTER X1                KEYCMP
            SX6    60-30       NEW POSITION COUNTER                      KEYCMP 
            ENDIF.                                                       KEYCMP 
                                                                         KEYCMP 
*     MODIFY INSTRUCTION WITH MODIFICATION CONSTANT                      KEYCMP 
                                                                         KEYCMP 
          SX2    B7                                                      KEYCMP 
          IX3    X3+X2       ADD TO INSTRUCTION                          KEYCMP 
                                                                         KEYCMP 
*     SAVE THE NEW POSITION COUNTER                                      KEYCMP 
                                                                         KEYCMP 
          SB7    X6                                                      KEYCMP 
          SA6    S$POS
                                                                         KEYCMP 
*         X1 = ADDRESS FOR THIS INSTRUCTION                              KEYCMP 
*         X3 = THIS INSTRUCTION, RJZF, WITHOUT LABEL MODIFICATION        KEYCMP 
*         A3+1 = RETURN ADDRESS                                          KEYCMP 
*         X6 = NEW POSITION COUNTER (45, 30, 15 OR 0)                    KEYCMP 
*         B6 = MODIFICATION TYPE                                         KEYCMP 
*         B7 = NEW POSITION COUNTER                                      KEYCMP 
                                                                         KEYCMP 
*     HANDLE POSSIBLE LABEL REFERENCE                                    KEYCMP 
                                                                         KEYCMP 
          IFTHEN B6>0        IF LABEL REFERENCE                          KEYCMP 
            SA2    S$DFLBL-1+B6  X2 = LINK OR LABEL VALUE 
            MX0    1           WORD=*DEFINE*, VALUE OF 0
            IX0    X2-X0
            IFTHEN X0=0        IF WORD IS DEFINED WITH VALUE OF 0,
              SX1    =7HS$GEN-1  DIAGNOSE INTERNAL ERROR
              CALL   S$ABORT
              ENDIF.
            MX0    -18         77777777777777000000B
            BX0    -X0*X3      EXAMINE INSTR WHERE LINK WILL GO 
            IFTHEN X0"0        IF FIELD IS NON-ZERO 
             ANDIF X2\0         AND ENTRY IS UNDEFINED, 
              SX1    =7HS$GEN-3  DIAGNOSE INTERNAL ERROR
              CALL   S$ABORT
              ENDIF.
            MX0    -18
            BX0    -X0*X2      STRIP FLAG BIT FROM LINK/LABEL VALUE 
                                WITHOUT EXTENDING PARCEL NUMBER 
            MX0    -18         STRIP FLAG BIT                            KEYCMP 
            BX0    -X0*X2        WITHOUT EXTENDING PARCEL NUMBER         KEYCMP 
            IX3    X3+X0       ADD LINK/ADDRESS TO INSTRUCTION           KEYCMP 
            IFTHEN X2\0        IF LABEL IS LINKED 
              AX6    3           0/8 = 0,  15/8=1,  30/8=3               KEYCMP 
              LX6    16          MAKE ROOM FOR BIASED ADDRESS            KEYCMP 
              SA2    S$ACODE     SUBTRACT START-OF-CODE FROM ADDRESS
              SX2    X2-1        ENSURE LINK IS NON-ZERO
              IX2    X1-X2                                               KEYCMP 
              IX6    X6+X2       2/PARCEL, 16/BIASED ADDRESS             KEYCMP 
              SA6    S$DFLBL-1+B6  STORE NEW LINK 
              ENDIF.             DONE WITH LINKING LABEL                 KEYCMP 
            ENDIF.             DONE WITH LABEL                           KEYCMP 
                                                                         KEYCMP 
*     INSERT INSTRUCTION INTO CORE                                       KEYCMP 
                                                                         KEYCMP 
          SA2    X1          GET OLD INSTRUCTION WORD                    KEYCMP 
          LX3    X3,B7       POSITION NEW INSTRUCTION PROPERLY           KEYCMP 
          IX6    X2+X3       COMBINE                                     KEYCMP 
          SA6    X1          STORE                                       KEYCMP 
  
*    IF INSTRUCTION WAS *RJ*, FORCE UPPER 
  
          SA2    S$GEN
          LX2    30 
          SA2    X2          30/INSTR, 1/L, 11/0, 18/MOD
                             OR 30/<RJ S$GEN15>, 15/INSTR, 15/0 
                             OR 30/<RJ S$GEN30>, 30/INSTR 
          BX0    X2 
          AX0    30 
          SB6    A3          SAVE NORMAL EXIT ADDRESS 
          SA3    RJGEN30     30/0, 30/<RJ S$GEN30>
          IX3    X0-X3
          IFTHEN X3=0        IF X2 = 30/<RJ S$GEN30>,30/INSTR,
            LX2    30          LEFT-JUSTIFY INSTR 
          ELSE- 
            SA3    RJGEN15     30/0, 30/<RJ S$GEN15>
            IX3    X0-X3
            IFTHEN X3=0        IF X2 = 30/<RJ S$GEN15>,15/INSTR,15/0, 
              LX2    30          LEFT-JUSTIFY INSTR 
              ENDIF.
            ENDIF.
          AX2    54          54/+-0, 6/OPCODE 
          SX2    X2-1        VS. *RJ* 
          IFTHEN X2=0        IF *RJ*, 
            SX6    0           S$POS := 0 
            SA6    S$POS
            SB7    B0 
            ENDIF.
                                                                         KEYCMP 
*     UPDATE S$LOC IF NECESSARY 
                                                                         KEYCMP 
          IFTHEN B7=0        IF NEW POSITION COUNTER IS ZERO             KEYCMP 
            SX6    X1+B1       INCREMENT S$LOC
            SA6    S$LOC
            SA1    S$ACODE     ADDRESS OF CODE$ BLOCK 
            SA2    S$LCODE     LENGTH OF CODE$ BLOCK
            IX1    X1+X2       LWA+1 OF CODE$ BLOCK 
            IX0    X6-X1       S$LOC - LWA+1
            IFTHEN X0\0        IF NEW S$LOC IS BEYOND CODE$,
              SX1    =10HS$GEN-2
              CALL   S$ABORT
              ENDIF.
            ENDIF.           THE WORD AT (S$LOC) IS NOT CLEARED 
                             IN CASE THIS INSTRUCTION IS THE LAST        KEYCMP 
                             GENERATED INSTRUCTION.                      KEYCMP 
                                                                         KEYCMP 
*     EXIT                                                               KEYCMP 
  
          JP     B6+1        EXIT TO WORD FOLLOWING DESCRIPTOR
          SPACE  4
 RJGEN15  VFD    30/0,12/0100B,18/=XS$GEN15 
  
 RJGEN30  VFD    30/0,12/0100B,18/=XS$GEN30 
 S$ACODE  EXTERNAL           ORIGINAL VALUE OF S$LOC
  
 S$DFLBL  EXTERNAL           ADDRESS FOR DEFINITIONS OF LABELS
  
 S$LCODE  EXTERNAL           NUMBER OF AVAIL. WORDS STARTING AT S$ACODE 
  
 S$LOC    EXTERNAL           ADDRESS WHERE NEXT INSTRUCTION WILL BE 
                             STORED AND LATER EXECUTED
  
 S$POS    EXTERNAL           POSITION WITHIN WORD AT S$LOC WHERE
          SPACE  4
          END 
