*DECK,FIN$CON 
USETEXT IP$COM
USETEXT MISC$ 
USETEXT TCH$COM 
USETEXT TSB$COM 
USETEXT ABH$COM 
USETEXT ACN$COM 
USETEXT  QAC$COM
USETEXT  QAB$COM
USETEXT  QCB$COM
USETEXT GLOBALI 
USETEXT TCB$COM 
      PROC FIN$CON; 
      BEGIN # FIN$CON # 
*IF DEF,IMS 
 #
*1DC  FIN$CON 
* 
*     1. PROC NAME           AUTHOR              DATE 
*        FIN$CON             B. M. WEST          CINCO DE MAYO 1977 
* 
*     2. FUNCTIONAL DESCRIPTION.
* 
*        TO CLEAN UP A CONSOLE CONNECTION AFTER IT HAS ENDED. 
* 
*     3. METHOD USED. 
* 
*        SO LONG AS THERE ARE BATCH CONNECTIONS NOT ENDED ON THIS 
*        CONSOLE ITS TCB WILL BE MAINTAINED ON A PSEUDO ACN,
*        THAT IS AN ACN GREATER THAN THE LARGEST ACCEPTABLE ACN.
*        SUCH A PSEUDO ACN IS CHECK BY THIS MODULE PERIODICALLY 
*        FOR BATCH DEVICES. ONCE NO DEVICE IS CONNECTED THE 
*        TCB WILL BE FREED AND THE PSEUDO ACN WORD CLEARED. 
* 
*        IF UPON FIRST ENTRY NO BATCH DEVICES EXISTS, THE 
*        TCB IS FREED.
* 
*     4. ENTRY PARAMETERS.
*        ACN OF CONSOLE CONNECTION
*        TCB OF CONSOLE CONNECTION
* 
*     5. EXIT PARAMETERS. NONE. 
* 
*     6. COMDECKS CALLED. 
* 
*        RBF$COM
*        ABH$COM
*        TSBMDEFS 
*        TSBMBASE 
*        TCB$COM
* 
*     7. ROUTINES USED. 
* 
*        LINK                LINK CONNECTION TO NEXT MODULE 
*        RETTSB              RETURNS FREED BUFFER 
*        TIMEOUT             TIMEOUT EVENT PROCESSOR
* 
*     8. DAYFILE MESSAGES. NONE.
* 
 #
*ENDIF
  
      XREF PROC LINK;        # LINK MODULE TO ACN                      #
      XREF PROC ACKED;
      XREF PROC FREEBUFFER;  # FREE QUEUED UP CONSOLE OUTPUT BUFFERS.  #
      XREF PROC RETTSB;      # FREE BUFFER                             #
      XREF PROC SETUPACN;                      # SET UP CONTROL BLOCKS #
      ITEM I I;              # INDEX VARIABLE                          #
      ITEM K I;              # INDEX VARIABLE                          #
      CONTROL EJECT;
      PROC FIX$QAB(OLDACN,NEWACN,NEWCAN); 
      BEGIN  # FIX$QAB #
      ITEM OLDACN;           # PREVIOUS ACN OF CONTROLLING CONSOLE #
      ITEM NEWACN;           # NEW ACN OF CONTROLLING CONSOLE      #
      ITEM NEWCAN B;         # NEW STATUS OF QAB$CANCEL IF FOUND   #
      ITEM J,NEXT, QUEUE;    # TEMPORARY VARIABLE                  #
      P<QCB> = ADDRESS[ACN$CB[QCBACN]]; 
      FOR QUEUE = 0 STEP 1 UNTIL 1
      DO                     # SEARCH EACH EXTENDED DIVERT QUEUE   #
        BEGIN 
        IF QUEUE EQ 0 
        THEN
          BEGIN 
          NEXT = QCB$EXTSUBF;  # ALREADY SUBMITTED QUEUE           #
          END 
        ELSE
          BEGIN 
          NEXT = QCB$EXTTBSF;  # TO BE SUBMITTED QUEUE             #
          END 
        FOR J = J WHILE NEXT NQ 0 
        DO                     # LOOK AT EACH QAB IN THE QUEUE     #
          BEGIN 
          P<QAB> = ADDRESS[NEXT]; 
          NEXT = QAB$NEXT;
          IF QAB$ACN EQ OLDACN
          THEN
            BEGIN 
            QAB$ACN = NEWACN; 
            QAB$CANCEL = NEWCAN;
            END 
          END 
        END 
      END  # FIX$QAB #
CONTROL EJECT;
#                                                                      #
#     TEST FOR NUMBER OF BATCH DEVICES STILL ASSOCIATED WITH CONSOLE   #
#     AND THE CON/END/N RECEIVED                                       #
#                                                                      #
#     TRACE CODE                                                       #
#     TRACE CODE                                                       #
      IF TCB$NDEVICE EQ 0 
      THEN
        BEGIN  # FREE TCB AND ACN$TABLE ENTRY # 
        FREEBUFFER(LOC(TCB$OUTPUT)); # RELEASE QUEUED OUTPUT BUFFERS.  #
        IF TCB$EXTDIVS NQ 0 
        THEN
          BEGIN 
          FIX$QAB(ACN,0,TRUE);   # CANCEL EXTENDED DIVERTS   #
          END 
        RETTSB (ACN$CB[ACN]); 
        SETUPACN (ACN); 
        ACN$WORD [ACN] = 0; 
        ACN$STATE [ACN] = S"NON$EXISTENT";
        END   # FREE TSB AND ACN$WORD ENTRY # 
      ELSE
        BEGIN # BATCH DEVICE STILL ASSOCIATED WITH THIS CONSOLE # 
        IF ACN LQ TOTDEV + STATIONS 
        THEN
          BEGIN # MOVE ACN TO A PSEUDO ACN #
          FOR I = TOTDEV + STATIONS + 1 STEP 1 WHILE ACN$WORD [I] NQ 0
            DO TEST;
          IF I LQ TOTDEV + STATIONS + STATIONS
          THEN
            BEGIN # TRANSFER ACN TO PSEUDO ACN I #
            ACN$WORD [I] = ACN$WORD [ACN];
            ACN$STATE[I] = S"PRE$CONNECT";
            ACN$MODE [I] = CONSOLESTATE"CON$ACTIVE";
            TCB$TIME = CLOCK; 
            FOR K = 1 STEP 1 UNTIL TCB$NDEVICE DO 
              BEGIN # RESET DEVICES" CONSTROLLING CONSOLE ACN # 
              ACN$CTLR [ TCB$DEVACN [K]] = I; 
              END   # RESET DEVICES" CONSTROLLING CONSOLE ACN # 
            IF TCB$EXTDIVS NQ 0 
            THEN                   # RESET DEVICE'S CONTROLLING ACN   # 
              BEGIN 
              FIX$QAB(ACN,I,FALSE); 
              END 
            ACN$WORD[ACN] = 0;
            ACN = I;
            END   # TRANSFER ACN TO PSEUDO ACN I #
          END   # MOVE ACN TO A PSEUDO ACN #
        END   # BATCH DEVICE STILL ASSOCIATED WITH THIS CONSOLE # 
      RETURN; 
      END   # FIN$CON # 
      TERM; 
