*DECK HPRUON
USETEXT NIPDEF
USETEXT ACB 
USETEXT ACNB
USETEXT APPSTAT 
USETEXT AT
USETEXT INPARUT 
USETEXT NBT 
USETEXT NCNB
USETEXT ACNT
USETEXT NCNT
USETEXT LLCB
USETEXT PARAMP
USETEXT PRUBUFF 
USETEXT SYSTIME 
USETEXT OVERLAY 
USETEXT PARAMS
USETEXT PCNB
USETEXT PIT 
USETEXT PT
USETEXT SUPMSG
 PRGM HPRUON;                # PROCESS A PRU/ON/R FROM APPLICATION     #
 STARTIMS;
 #
*1DC  HPRUON
*     1. PROC NAME           AUTHOR              DATE 
*        HPRUON              J.C. LEE            80/04/01 
* 
*     2. FUNCTIONAL DESCRIPTION.
*          PROCESS A PRU/ON/R SUPERVISORY MESSAGE FROM AN APPLICATION.
* 
*     3. METHOD USED. 
*          VALIDATE PRU/ON/R SUPERVISORY MESSAGE, 
*          GET EMPTY BUFFER FOR A PCNB, 
*          FORMAT A PCNB FROM THE NCNB, 
*          INITIALIZE CONNECTION TABLE ENTRY IN LLCB, 
*          RELEASE THE NCNB,
*          UPDATE PCNB/NCNB POINTER OF ACNB,
*          LINK PCNB TO PCNB RING, UPDATE PQR POINTERS IN NBTE. 
* 
*     4. ENTRY PARAMETERS.
*          ACBADDR           APPLICATION ACB ADDRESS
*          WLADDR            WORKLIST ENTRY ADDRESS 
* 
*     5. EXIT PARAMETERS. 
*          PARAMP1           0 IF COMPLETED, 1 IF NOT 
*          PARAMP2           NEW PCNB ADDRESS 
* 
*     6. COMDECKS CALLED AND SYMPL TEXTS USED.
*        ACB       ACNB      APPSTAT   AT 
*        NBT       NCNB      NIPDEF    OVERLAY
*        PARAMS     PCNB     PT     SUPMSG
*        INPARUT     ACNT     NCNT
*        LLCB     PARAMP
*        PIT
* 
*     7. ROUTINES AND OVERLAYS CALLED.
*          HLGLERR    OVL    SEND ERR/LGL SM TO APP 
*          HPRUONX    OVL    SEND PRU/ON/N-A TO APPL
*          LOCLLCB           LOCATE LLCB USING HN AND TN
*          LOCNCNT           LOCATE NCNT ENTRY USING LLCB AND CN
*          MGETS             GET AN EMPTY BUFFER
*          MRELS             RELEASE BUFFER 
*          OVLCALL           LOAD AND EXECUTE AN OVERLAY
*          XTRACE            TRACE CALLS
* 
*     8. DAYFILE MESSAGES.   NONE 
* 
*        THIS PROGRAM IS A PRIMARY OVERLAY LOADED BY SUBROUTINE OVLCALL.
*        WHEN EXECUTION HAS COMPLETED, A JUMP IS MADE TO LOCATION RJMAIN
*        TO RETURN TO THE CALLING PROGRAM.
* 
*        W A R N I N G - THIS PROGRAM CANNOT EXCEED THE PRIMARY 
*CALL OPSIZE
* 
*        THIS OVERLAY IS CALLED BY HPPUT. 
* 
 #
 STOPIMS; 
# 
      EXTERNAL VARIABLES
# 
 XREF 
   BEGIN
   PROC LOCLLCB;             # LOCATE LLCB                             #
   PROC LOCNCNT;             # LOCATE NCNT                             #
   PROC MGETS;               # GET AN EMPTY BUFFER                     #
   PROC MCLRIL ;
   PROC MSETIL ;
   PROC MRELS;               # RELEASE BUFFER                          #
   PROC OVLCALL;             # LOAD AND EXECUTE AN OVERLAY             #
   PROC XTRACE;              # TRACE CALLS                             #
   LABEL RJMAIN;             # RETURN ADDRESS IN OVLCALL               #
   END
# 
      INTERNAL VARIABLES
# 
 ITEM 
   BUFADDR,                  # BUFFER ADDRESS                          #
   LLCBAD,                   # LLCB ADDRESS                            #
   NCNTEAD,                  # NCNT ENTRY ADDRESS                      #
   INDEX,                    # FRONT-END INDEX                         #
   ACNBADDR,                 # ACNB ADDRESS                            #
   PITIDX,                   # PIT ENTRY INDEX                         #
   PRUBS,                    # PRU BLOCK SIZE                          #
   PTR, 
   NEXT,
   CURRENT, 
   I,J,N, 
   TWIN;                     # TWIN QCB ADDRESS                        #
  
 BASED ARRAY PRUNIPWD  S(1);           # TEMPLATE FOR NIP WORD IN PIT  #
   BEGIN
   ITEM PRUNIPMFB   U(0,00,06);        # MINIMUM NO OF PRU BUFS        #
   ITEM PRUNIPMAB   U(0,06,06);        # MAXIMUM NO OF PRU BUFS        #
   ITEM PRUNIPNCA   U(0,12,12);        # CURRENT NO OF BUFFERS ASSIGNED#
   ITEM PRUNIPNC    U(0,24,12);        # CURRENT NO OF PRU CONNECTIONS #
   ITEM PRUNIPFPB   U(0,42,18);        # ADR OF FIRST BUF IN FREE CHAIN#
   END
  
 BASED ARRAY PRUPIPWD  S(1);           # TEMPLATE FOR PIP WORD IN PIT  #
   BEGIN
   ITEM PRUPIPNFB   U(0,00,12);        # NO OF BUFS IN FREE CHAIN      #
   ITEM PRUPIPNRA   U(0,12,12);        # NO OF BUS NEEDED BY PIP       #
   ITEM PRUPIPRPB   U(0,42,18);        # ADDR OF BUF TO RELEASE        #
   END
  
# ******************************************************************** #
      BEGIN 
  
      CONTROL IFEQ DEBUG,1; 
        XTRACE("HPRON") ; 
      CONTROL FI; 
  
      P<ACB> = ACBADDR;                # APPLICATION ACB ADDRESS       #
      P<SUPMSG> = WLADDR + AIPHSIZE + ABHSIZE; # ADDRESS OF PRU/ON/R   #
      PARAMP1 = 1 ; # INITIAL ERROR STATE # 
      PARAMS1 = RPRU"N" ; 
# 
      CHECK IF A VALID PRU/ON/R SUPERVISORY MESSAGE 
# 
      IF ATPRU[ACBAN[0]]
      THEN                   # LEGAL PRU APPLICATION SEND PRU/ON/R     #
        BEGIN 
  
#     SEARCH FOR ACNB                                                  #
        BEGIN 
        P<ACNT> = ACBACNT[0]; 
        ACNBADDR = 0; 
        IF PRUACN[0] LQ ACNTHCN[0] AND PRUACN[0] GQ ACNTMINACN[0] 
        THEN
        ACNBADDR = ACNTACNB[PRUACN[0] + ACNTHSIZE - ACNTMINACN[0]]; 
        IF ACNBADDR EQ 0
        OR PRUACN[0] EQ 0 
          THEN
          BEGIN 
          PARAMS1 = RPRU"CNV" ; 
          GOTO HEXIT; 
          END 
        END 
  
        P<ACNB> = ACNBADDR;            # ACNB ADDRESS                  #
        TWIN = ACNBNCNB[0];            # NCNB ADDRESS                  #
  
          P<NCNB> = TWIN;              # NCNB ADDRESS                  #
        IF NCNBNBO[0] NQ 0
        THEN
          BEGIN            # STILL OUTSTANDING BLOCK COUNT             #
          PARAMS1 = RPRU"COB" ;    # RC = 5                            #
          GOTO HEXIT ;
          END 
  
        IF NCNBHN[0] EQ 0 
           OR NCNBTN[0] EQ 0
        THEN
          BEGIN                    # PRU/ON/R ON INTRA A-A             #
          PARAMS1 = RPRU"CNB" ;    # REJECT WITH REASON CODE 4         #
          GOTO HEXIT ;             # GOTO SEND PRU/ON/A                #
          END 
        LOCLLCB(NCNBHN[0],NCNBTN[0],LLCBAD);
        P<LLCB> = LLCBAD ;
        PITIDX = LLCBPITIDX[0];        # PIT ENTRY INDEX               #
        LOCNCNT(LLCBAD,NCNBCN[0],NCNTEAD);
        P<NCNT> = NCNTEAD ; 
        PRUBS = PRUUPS[0] ; 
        IF PRUBS EQ 0 
        THEN
          PRUBS = PRUDPS[0] ; 
        IF PRUBS EQ 0 OR INPPRU[PRUBS] EQ 0 
        THEN
          BEGIN 
          PARAMS1 = RPRU"CNB" ; 
          GOTO HEXIT ;
        END 
          IF NCNBID[0] EQ NCNBIDVALUE AND   # NCNB                     #
              NCNBDT[0] NQ DT$CONS
          THEN
            BEGIN 
            P<PRUNIPWD> = LOC(PITW5[PITIDX])-1; # 1 PRU BUF NIP WORD   #
            P<PRUPIPWD> = LOC(PITW8[PITIDX])-1; # 1 PRU BUF PIP WORD   #
            PRUNIPNC[PRUBS] = PRUNIPNC[PRUBS] + 1;  # INCR NO OF PRU CN#
            IF PRUNIPNCA[PRUBS] EQ 0
            THEN                       # NO PRU BUFS CURRENTLY ASSIGNED#
              BEGIN                    # ALLOCATE DYNAMIC PRU BUFFERS  #
              MSETIL(0) ;              # SET INTER LOCK BIT            #
              FOR I = PRUBS STEP -1 UNTIL 1 
              DO
                BEGIN                  # LOOP FOR EACH TYPE OF PRU     #
                IF PRUNIPNCA[I] EQ 0
                THEN
                  BEGIN                # NEEDS BUUFFERS                #
                  NEXT = 0;            # LAST BUF HAS ZERO POINTER     #
                  N = PRUNIPMFB[PRUBS];  # MIN NO OF BUFS TO ALLOCATE  #
                  FOR J = 1 STEP 1 UNTIL N
                  DO
                    BEGIN              # FIND MERPRU[I] BUFFER         #
                  MGETS(PBHSIZE + I*PRUSIZE + I,CURRENT,TRUE);
                                       # ALLOCATE BUFFER FOR EACH SIZE #
                                       # FOR 1 PRU BUFFER SIZE = 102   #
                                       # FOR 2 PRU BUFFER SIZE = 204   #
                                       # FOR 3 PRU BUFFER SIZE = 306   #
  
                    P<PRUBUFF> = CURRENT ;     # SET UP THE BUF HEADER #
                    PRUBDLFP[0] = NEXT;  # PTR TO NEXT BUF IN FREE CHN #
                    NEXT = CURRENT ;
                    PRUBID[0] = PRUBIDVALUE ; 
                    PRUBPBS[0] = I - 1 ; # BUFFER SIZE IN PRU - 1      #
                    PRUBTBA[0] = MSECS[0] ; 
                    PRUBUP[0] = TRUE;  # SET USER PROCESSING BIT       #
                    PRUBEP[0] = TRUE;  # SET ERROR PROCESSING BIT      #
                    PRUBFETL[0] = 2 ; 
                    PTR = P<PRUBUFF> + PBHSIZE - 1 ;
                    PRUBFIRST[0] = PTR ;
                    PRUBIN[0] = PTR ; 
                    PRUBOUT[0] = PTR ;
                    PRUBLIMIT[0] = P<PRUBUFF> + PRUBBS[0] ; 
                    END                # FIND BUFFERS                  #
                  PRUNIPFPB[I] = CURRENT;  # ADDR OF 1ST BUF IN CHAIN  #
                  PRUNIPNCA[I] = N;    # CUR NO OF PRU BUFS ASSIGNED   #
                  PRUPIPNRA[I] = N;    # CUR NO OF PRU BUFS NEEDED     #
                  END                  # BUFFER NEEDED                 #
                END 
              MCLRIL ;
              END                      #                               #
  
# 
            GET EMPTY BUFFER FOR A PCNB 
# 
            MGETS(PCNBSIZE, BUFADDR, TRUE); 
              P<PCNB> = BUFADDR;       # PCNB ADDRESS                  #
# 
              FORMAT A PCNB FROM THE NCNB 
# 
              PCNBID[0] = LCNBIDVALUE ;  # SET TO INTERMED IDVALUE     #
              PCNBR0[0] = NCNBR0[0] ; 
              PCNBR1[0] = NCNBR1[0] ; 
              PCNBSTS[0]= NCNBSTS[0]; 
              PCNBNBTE[0] = NCNBNBTE[0] ; 
              PCNBTNAM[0] = NCNBTNAM[0] ; 
              PCNBPBS[0] = PRUBS ;
              PCNBACNB[0] = ACNBADDR;  # ACNB ADDRESS                  #
              IF PRUFL1[0]
              THEN
                BEGIN             # MSG FROM FILE TRANSFER APPLICATION #
                PCNBXFR[0] = PRUFL1[0] ;
                PCNBCWS[0] = PRUCWS[0] ;
                PCNBKVL[0] = PRUICKVAL[0] ; 
                PCNBXDD[0] = PRUDD[0] ; 
                END               # MSG FROM FILE TRANSFER APPLICATION #
# 
              UPDATE NCNT ENTRY FOR THIS NEW PCNB 
# 
              NCNTNCNB[0] = BUFADDR ;  # RESET PCNB ADDRESS IN NCNT    #
# BATCH STREAM STATE AND BLOCK HANDLE STATE WILL BE SET TO PRU WHEN    #
# SPECIAL OUTBOUND BUFFER (ID=PRUSPECID) GETS RELEASED IN XEXEC        #
  
              IF PRUUPS[0] NQ 0 
              THEN
                PCNBREC[0]  = TRUE    ;  # RECEIVING MODE              #
  
              IF NCNBDBSN[0] LS 7 
              THEN
                NCNTNOB[0] = NCNBDBSN[0] + 1 ;   # NEXT OUTPUT BSN     #
              ELSE
                NCNTNOB[0] = 1 ;
                  NCNTOIB[0] = 0 ;
                  NCNTOOB[0] = 0 ;
# 
              RELEASE NETWORK-SIDE NCNB 
# 
              IF NCNBACKQ[0] NQ 0 
              THEN                     # ACKNOWLEDGMENT QUEUE EXISTS   #
                MRELS(NCNBACKQ[0]);    # RELEASE ACK-Q                 #
  
              MRELS(TWIN);             # RELEASE NCNB                  #
# 
              UPDATE NCNB/NCNT POINTER OF HOST-SIDE ACNB
# 
              P<ACNB> = ACNBADDR;      # ACNB ADDRESS                  #
              ACNBNCNB[0] = BUFADDR;   # SET TO PCNB ADDRESS           #
# 
              LINK PCNB TO PCNB RING. 
              UPDATE PQR POINTERS IN NBT
# 
              FOR INDEX = 0 STEP NBTFETNO UNTIL NBTMAXID
              DO
                BEGIN 
                IF NBTIUF[INDEX] AND
                   NBTHN[INDEX] EQ PCNBHN[0]
                THEN
                  BEGIN 
                  PCNBPCFP[0] = LOC(NBTFIRST[INDEX]); 
                             # SET PCNB FORWARD POINTER                #
  
                  IF NBTPCRF[INDEX] EQ 0
                  THEN                 # NO EXISTING PCNB RING         #
                    BEGIN 
                    PCNBPCBP[0] = LOC(NBTFIRST[INDEX]);# SET BACK PTR  #
                    NBTPCRF[INDEX] = BUFADDR; # SET PQR HEAD PTR IN NBT#
                    END 
  
                  ELSE                 # PCNB-RING ALREADY EXISTS      #
                    BEGIN 
                    PCNBPCBP[0] = NBTPCRB[INDEX]; # SET PQR BACK PTR   #
                    P<PCNB> = NBTPCRB[INDEX];# PREVIOUS LAST MEMBER PQR#
                    PCNBPCFP[0] = BUFADDR;  # LINK NEW PCNB TO PQR     #
                    END 
  
                  NBTPCRB[INDEX] = BUFADDR;# UPDATE PQR TAIL PTR IN HNT#
# 
              INCREMENT COUNT OF ACTIVE PRU CONNECTIONS 
# 
                  LLCBNPC[0] = LLCBNPC[0] + 1 ; 
                  ACBNPRU[0] = ACBNPRU[0] + 1 ; 
                  PARAMP1 = 0 ; # SIGNAL FOR COMPLETION                #
                  PARAMP2 = BUFADDR ; 
                  END 
                END 
            END 
          ELSE
            BEGIN 
            PARAMS1 = RPRU"CNV" ; 
            GOTO HEXIT ;
            END 
        END 
      ELSE
        BEGIN                # ILLEGAL APPLICATION SEND PRU/ON/R       #
        PARAMS1 = RPRU"CNS" ;# REASON IS 1 IN PRU/ON/A                 #
        GOTO HEXIT ;
        END                  # ILLEGAL APPLICATION SEND PRU/ON/R       #
HEXIT:  BEGIN 
        PARAMS2 = PRUACN[0];           # ADDRESS OF ACNB FOR CONNECTION#
        OVLNAME = HPRUONXP;            # NAME OF OVERLAY TO LOAD       #
        IF PARAMS1 NQ 0 
        THEN                           # PRU/ON/A IS BEING RETURNED    #
          BEGIN 
          IF ACBERCNT[0] LS MAXLGERR
          THEN                         # OKAY TO GENERATE PRU/ON/A     #
            BEGIN 
            OVLCALL;                   # LAOD AND EXECUTE OVERLAY      #
            END 
          ELSE                         # REACHED MAX NO OF ERR SUP MSG #
            BEGIN 
            IF ACBERCNT[0] EQ MAXLGERR
            THEN                       # REACHED MAX NO OF ERR SUP MSG #
              BEGIN 
              PARAMS1 = RLG"IAL";      # ERR/LGL RC FOR TOO MANY ERRORS#
              OVLNAME = HLGLERRP;      # NAME OF OVERLAY TO LOAD       #
              OVLCALL;                 # LAOD AND EXECUTE OVERLAY      #
              END 
            END 
          END 
        ELSE                           # PRU/ON/N BEING RETURNED       #
          BEGIN 
          OVLCALL;                     # LAOD AND EXECUTE OVERLAY      #
          END 
        END 
  
      GOTO RJMAIN;
      END 
TERM
