*DECK EXRQTSB 
      PROC REQTSB ( (TSBSIZE), TSBADDR , TSBN );
      BEGIN # REQTSB #
*IF DEF,IMS 
 #
**
* 
*     1. PROC NAME           AUTHOR              DATE 
*        REQTSB              M. D. PICKARD       76/11/20 
* 
*     2. FUNCTIONAL DESCRIPTION 
*        REQTSB WILL ASSIGN A TASK SEQUENCE BLOCK (TSB) OF THE
*        REQUESTED SIZE AS A FIXED POSITION BLOCK.
* 
*     3. METHOD USED
*        THE VALIDITY OF THE CALLING PARAMETERS IS CHECKED. GETTSBN 
*        IS CALLED TO GET AN ENTRY IN THE TSBIT TO BE USED FOR THIS 
*        BLOCK, THIS ALSO ASSIGNS A TSBN. GETTSB IS CALLED TO FIND A
*        BLOCK AND RESERVE IT. OVENTER IS CALLED TO ADD THE TIME-OUT
*        OVERLAY TO THE OEL, IF NECESSARY. THE ADDRESS AND IDENT ARE
*        RETURNED TO THE USER.
* 
*     4. ENTRY PARAMETERS 
*        TSBSIZE (FORMAL)    SIZE OF TSB BEING REQUESTED
*                            MUST BE GREATER THAN ZERO AND LESS 
*                            THAN MAXTSBL 
* 
*     5. EXIT PARAMETERS
*        TSBADDR (FORMAL)    ADDRESS OF BLOCK ASSIGNED, RETURNED TO 
*                            USER. IF NEGATIVE, THE REQUEST WAS 
*                            REJECTED, THE ERROR CODE WILL BE IN TSBN 
*        TSBN (FORMAL)       TSB NUMBER, BLOCK IDENTIFIER. IF TSBADDR 
*                            IS NEGATIVE, THEN A REQUEST ERROR CODE 
*                            IS HERE
*                                BADSIZE, ILLEGAL TSB SIZE
*                                BADTO, ILLEGAL TO
* 
*     6. COMDECKS USED
*        TSBBASE             TSB MANAGER BASED ARRAY DEFINITIONS
*        TSBDATA             TSB MANAGER DATA AREA DEFINITIONS
*        TSBDEFS             TSB MANAGER SYMPL DEFS 
*        CYBERDEFS           CYBER DEPENDENT VALUES 
* 
*     7. ROUTINES CALLED
*        GETTSB              GETS A TSB 
*        GETTSBN             GETS TSBN AND ENTRY IN TSBIT 
* 
*     8. DAYFILE MESSAGES 
*        NONE.
* 
 #
*ENDIF
*CALL CYBERDEFS 
*CALL TSBDEFS 
*CALL TSBBASE 
      ITEM
           TSBSIZE U,        # SIZE OF BLOCK BEING REQUESTED           #
           TSBADDR U,        # ADDRESS OF ASSIGNED BLOCK               #
           TSBN U;           # TSB IDENTIFIER                          #
      XREF
        BEGIN 
        PROC GETTSB;
        END 
*CALL TSBDATA 
      XREF PROC ABORT;
      ITEM
           RETFWA U,         # USED AS PARAMETER TO PASS TO GETTSB     #
           SIZE U,           # USED AS PARAMETER TO PASS TO GETTSB     #
           TEMP U,           # TEMPORY UNSIGNED INTEGER                #
           TEMPB B;          # TEMPORARY BOOLEAN                       #
      CONTROL EJECT;
      PROC GETTSBN ( TSBN );
      BEGIN # GETTSBN # 
*IF DEF,IMS 
 #
**
* 
*     1. PROC NAME           AUTHOR              DATE 
*        GETTSBN             M. D. PICKARD       76/11/23 
* 
*     2. FUNCTIONAL DESCRIPTION 
*        GETTSBN WILL ASSIGN A POSITION IN THE TSB INFORMATION TABLE
*        (TSBIT), THE ORDINAL OF THE POSITION IS THE TSBN. GETTSBN
*        WILL INCREASE THE SIZE OF THE TSBIT AS NEEDED. 
* 
*     3. METHOD USED
*        IF THERE ARE AVAILABLE ENTRIES, ASSIGN LOWEST VALUE IN 
*        CHAIN OF AVAILABLE ENTRIES.  IF NOT, GET ANOTHER TSB, MOVE 
*        THE DATA, BUILD THE CHAIN OF NEW AVAILABLE ENTRIES, ASSIGN 
*        THE LOWEST VALUE AVAILABLE ENTRY.
* 
*     4. ENTRY PARAMETERS 
*        TSBIT (TSBMGR GLOBAL)  BASED ARRAY IS SET TO TSB CONTAINING
*                               TSBIT, TSB IS NOT MOVEABLE
* 
*     5. EXIT CONDITIONS
*        TSBN                ORDINAL IN TSBIT ASSIGNED, IDENTIFIES
*                            BLOCK TO USER AND TSBMGR 
* 
*     6. COMDECKS CALLED
*        NONE.
* 
*     7. ROUTINES CALLED
*        GETTSB              GET A TSB FROM FREE SPACE
*        GIVETSB             GIVES BACK A TSB 
*        MOVEI               MOVES CENTRAL MEMORY WORDS IN BLOCK
* 
*     8. DAYFILE MESSAGES 
*        NONE.
* 
 #
*ENDIF
      ITEM
           TSBN U;           # TSB NUMBER/IDENT ASSIGNED AND RETURNED  #
      XREF
        BEGIN 
        PROC GIVETSB; 
        PROC MOVEI; 
        END 
      ITEM
           ADDRESS U,        # ADDRESS PASSED TO MOVECM                #
           DONE B,           # COMPLETE FLAG                           #
           I U,              # LOOP INDUCTION VARIABLE                 #
           J U,              # LOOP INDUCTION VARIABLE                 #
           IDENT U,          # IDENT FOR GETTSB REQUEST                #
           SIZE U;           # SIZE FOR GETTSB REQUEST                 #
      DONE = FALSE; 
      FOR I=0 WHILE NOT DONE DO 
        BEGIN                # ASSIGN A TSBN                           #
        IF NUMFREE[0] NQ 0
        THEN                 # THERE IS A ENTRY TO ASSIGN              #
          BEGIN 
          NUMFREE[0] = NUMFREE[0] - 1; # DECREASE NUMBER OF FREE ENT.  #
          TSBN = LOWFREE[0]; # ASSIGN LOWEST FREE TSBN                 #
          LOWFREE[0] = FWDPTR[LOWFREE[0]]; # ASSIGN NEW LOWEST FREE    #
          TBUSY[TSBN] = TRUE; # SET ENTRY BUSY                         #
          FWDPTR[TSBN] = 0;  # CLEAR FORWARD POINTER IN ASSIGNED ENT.  #
          DONE = TRUE;       # SET COMPLETE FLAG                       #
          END 
        ELSE                 # GET SOME MORE SPACE                     #
          BEGIN 
          SIZE = LENGTH[0] + TSBITL + TSBHDRL; # NEW SIZE OF TSBIT TSB #
          IDENT = 1;         # TSBIT PERMANENT IDENT                   #
          GETTSB(SIZE,IDENT,ADDRESS); # GET A TSB OF NEW LENGTH        #
          TTSBFWA[1] = ADDRESS; # SET NEW ADDRESS IN TSBIT             #
          MOVEI(LENGTH[0],LOC(TSBIT),ADDRESS+TSBHDRL); # MOVE TSBIT    #
          GIVETSB(LOC(TSBIT) - TSBHDRL); # GIVE BACK OLD TSB FOR TSBIT #
          P<TSBIT> = ADDRESS + TSBHDRL; # RESET TSBIT BASED ARRAY      #
          NUMFREE[0] = TSBITL; # NUMBER OF FREE ENTRIES NOW            #
          LOWFREE[0] = LENGTH[0]; # NEW LOWEST FREE ORDINAL            #
          FOR J = LENGTH[0] STEP 1 UNTIL (SIZE - 1 - TSBHDRL) DO
            BEGIN            # SET UP NEW PART OF TSBIT                #
            TBUSY[J] = FALSE; # SET FREE                               #
            FWDPTR[J] = J + 1; # SET FORWARD POINTER FOR FREE CHAIN    #
            END 
          FWDPTR[SIZE - 1 - TSBHDRL] = 0; # SET END OF CHAIN POINTER   #
          LENGTH[0] = SIZE - TSBHDRL; # SET NEW SIZE OF TSBIT IN HEADER#
          P<BTSBHDR> = TTSBFWA[1]; # TSBIT TSB FIRST WORD ADDRESS      #
          BNOTMOV[0] = FALSE; # MAKE TSBIT MOVEABLE                    #
          END 
        END 
      RETURN; 
      END # GETTSBN # 
      CONTROL EJECT;         # *** REQTSB CODE STARTS HERE             #
      IF (TSBSIZE LQ 0) OR (TSBSIZE GR MAXTSBL) 
      THEN                   # BAD REQUEST SIZE                        #
        BEGIN 
        $BEGIN
        ABORT;
        $END
        TSBADDR = -1;        # NEGATIVE ADDRESS INDICATES REJECT       #
        TSBN = BADSIZE;      # ILLEGAL SIZE SPECIFIED ERROR CODE       #
        RETURN;              # ***** EXIT *****                        #
  
        END 
      GETTSBN(TEMP);         # GET A TSB IDENTIFIER                    #
      TSBN = TEMP;           # SET TSB NUMBER FOR USER                 #
      SIZE = TSBSIZE + TSBHDRL;  # REAL SIZE OF BLOCK WANTED           #
      GETTSB(SIZE,TEMP,RETFWA);  # GET THE BLOCK                       #
      TTSBFWA[TEMP] = RETFWA;  # SET ADDRESS OF TSB IN TSBIT           #
      TSBADDR = RETFWA + TSBHDRL;  # ADDRESS OF USER AREA              #
      END TERM  # REQTSB #
