*DECK BDELINK 
USETEXT NIPDEF
USETEXT AHEADER 
USETEXT DEQCOM
USETEXT DRHDR 
USETEXT KDIS
USETEXT KHDRX 
USETEXT AT
USETEXT ACB 
USETEXT ACNB
 PROC BDELINK(ACNBADDR,BUFADDR,TLW);
 STARTIMS;
 #
 *    NETWORK PRODUCTS DOCUMENTATION        PAGE
 *    NAM INTERNAL SPECIFICATION            DATE. 
 *    5.0 NIP DETAILED DESCRIPTION
*1DC  BDELINK 
* 
*     1. PROC NAME           AUTHOR              DATE 
*        BDELINK             E. GEE              77/07/20 
* 
*     2. FUNCTIONAL DESCRIPTION.
*          DELINK DATA BLOCK FROM DATA RING.
* 
*     3. METHOD USED. 
*          CHECK ACNB DATA RING POINTER 
*          DETERMINE THE CHARACTER TYPES: IF THE MESSAGE IS A DATA BLOCK
*        (QUEUED ON THE ACNB) OR A SUPERVISORY MESSAGE OF BLOCK TYPE
*        APPCMD, THEN THE MESSAGE IS TRANSPARENT. 
*          CHECK THAT CHARACTER TYPE IS A VALID TYPE. 
*          CONVERT CHARACTERS IF NECESSARY
*          DELINK BLK FROM DATA RING
* 
*     4. ENTRY PARAMETERS 
*          ACNBADDR          ADDR OF ACNB/ACB TO DELINK DATA BLK FROM 
*          ACNBDRFP          ADDRESS OF THE DATA RING TO BE DELINKED
*          ACT               INPUT CHAR TYPE FOR DATA BLOCK 
*          NEXTPTR           ADDRESS OF THE NEXTBLOCK IN THE DATA RING
*          ABHTLC            TEXT LENGTH IN CHARACTERS
*          TLW               SIZE OF DATA BLOCK IN NUMBER OF WORDS
* 
*     5. EXIT PARAMETERS
*          BUFADDR           ADDR OF DELINKED DATA BLOCK
*          ACNBDRBP          DATA RING BACKWARD POINTER 
*          ACNBBLKSQ         COUNT OF BLOCKS QUEUED IN ACNB 
*          ACNBDRFP          DATA RING FORWARD POINTER
* 
*     6. COMDECKS CALLED AND SYMPL TEXTS USED.
*        AHEADER   DEQCOM    DRHDR     DUMPFLG
*        AT   FREETAB   MSGIDX    NIPDEF
*        OVERLAY   PARAMS    ACB     ACNB 
*        KDIS 
* 
*     7. ROUTINES CALLED. 
*          BCONV             CONVERT DATA FROM ONE CHAR TYPE TO ANOTHER 
*          DELCDR            DELINK ACNB FROM CONNECTION DATA RING
*          HUPDDAW           UPDATE DATA AVAILABLE WORD 
*          HWRAVAL           WRITE DATA AVAILABLE WORD TO UCP 
*          KPUT              UPDATE K-DISPLAY STATUS BUFFER 
*          MGETS             ALLOCATE EMPTY BUFFER
*          MRELS             RELEASE BUFFER SPACE 
*          OVLCALL           LOAD AND EXECUTE OVERLAYS
*          RDUMP             DUMP NIP-S FIELD LENGTH
*          XERRMSG    OVL    ISSUE DAYFILE MESSAGE (AND ABORT)
*          XTRACE            RECORD PROCEDURE CALLS 
* 
*     8. DAYFILE MESSAGES AND OTHER IMPORTANT INFORMATION.
*          NIP FATAL ERROR PROC=BDEL.   (DEBUG MODE MESSAGE INDICATES 
*        EITHER A BAD DATA RING OR THE CHARACTER TYPES ARE ILLEGAL.)
*          SECURITY VIOLATION APP XXXX   . (THE CHARACTER TYPE OF THE 
*        DATA BLOCK IS BAD.)
* 
* 
 #
 STOPIMS; 
# 
      INPUT PARAMETERS
# 
      ITEM ACNBADDR;         # FWA OF ACB/ACNB TO DELINK DATA BLOCK    #
      ITEM TLW;              # SIZE OF DATA BLOCK IN NUMBER OF WORDS   #
# 
      OUTPUT PARAMETERS 
# 
      ITEM BUFADDR;          # FWA OF DELINKED DATA BLOCK              #
# 
      EXTERNAL VARIABLES
# 
      XREF
        BEGIN 
        PROC BCONV;          # PERFORM DATA CONVERSION                 #
        PROC DELCDR;         # DELINK ACNB FROM CONNECTION DATA RING   #
        PROC HUPDDAW;        # UPDATE DATA AVAILABLE WORD              #
        PROC HWRAVAL;        # WRITE DATA AVAILABILITY WORD IN UCP     #
        PROC KPUT;           # UPDATE K DISPLAY DATA BUFFER            #
        PROC MGETS;          # GET BUFFER                              #
        PROC MRELS;          # RELEASE BUFFER                          #
        PROC XTRACE;         # TRACE SUBROUTINE CALLS                  #
        END 
# 
      LOCAL VARIABLES 
# 
      ITEM NEXTBLK;          # FWA OF NEXT DATA BLOCK IN DATA RING     #
      ITEM TEMP1;            # TEMPORARY VARIABLE                      #
      ITEM TEMP2;            # TEMPORARY VARIABLE                      #
  
      CONTROL EJECT;
  
  
      BEGIN # BDELINK # 
  
      CONTROL IFEQ DEBUG,1; 
      XTRACE("BDELI");       # TRACE CALLS                             #
      CONTROL FI; 
  
      P<DRHDRWD> = 0; 
      P<ACNB> = ACNBADDR; 
      P<ACB> = ACNBADDR;
      TEMP1 = ACNBDRFP[0];   # FWA OF DATA BLOCK TO DELINK             #
      P<AHEADER> = TEMP1 + BLKHSIZE;
      CHARCNT = ABHTLC[0]; # TEXT LENGTH IN CHARACTERS                 #
      BUFADDR = TEMP1;
  
      IF TEMP1 EQ ACNBDRBP[0] 
      THEN # ONLY DATA BLOCK IN RING                                   #
        ACNBDRPTRS[0] = 0;
      ELSE
        BEGIN # MORE DATA QUEUED IN RING                               #
        NEXTBLK = NEXTPTR[TEMP1]; 
        ACNBDRFP[0] = NEXTBLK;
        BACKPTR[NEXTBLK] = LOC(ACNBDRFP[0]);
        END 
  
      IF ACNBID[0] EQ ACNBIDVALUE 
      THEN # ITS AN ACNB                                               #
        BEGIN 
        P<ACB> = ATACBA[ACNBAN[0]]; # RESET ACB ADDRESS                #
  
        IF ACT NQ ABHACT[0] 
          AND CHARCNT NQ 0 # NOT A NULL BLOCK                          #
          AND ABHABT[0] NQ APPNULL # BT NQ 0                           #
        THEN # DATA NEED TO BE CONVERTED TO ICT FOR APP                #
          BEGIN 
          MGETS(TLW+BLKHSIZE+ABHSIZE,BUFADDR,FALSE);  # GET NEW BUFFER #
          CMWORD[BUFADDR+BLKHSIZE] = CMWORD[P<AHEADER>];
          DRPTR = P<AHEADER> + ABHSIZE; 
          BUFFIN = BUFADDR + BLKHSIZE + ABHSIZE;
          BCONV; # CONVERT DATA TO INPUT CHARACTER TYPE                #
          MRELS(TEMP1); # RELEASE OLD BUFFER                           #
          END 
  
        HUPDDAW(P<ACB>,P<ACNB>,-1,-1);  # UPDATE DATA AVAILABLE WORD   #
        IF ACNBBLKSQ[0] EQ 0
        THEN                       # NO MORE DATA QUEUED ON CONNECTION #
          BEGIN 
          DELCDR(P<ACNB>);         # DELINK ACNB FROM CONN DATA RING   #
          END 
        ELSE                           # NEED TO UPDATE CDR PTR IN ACB #
          BEGIN 
          ACBCDRP[0] = ACNBCDRFP[0];   # NEXT ACNB TO EXTRA DATA FROM  #
          END 
        TEMP1 = KPAPNDM;
        TEMP2 = ACBBLKSQ[0];
  
        END 
  
      ELSE # ITS AN ACB                                                #
        BEGIN 
        ACBSMQ[0] = ACBSMQ[0] - 1; # DECREMENT SM QUEUED COUNT         #
        TEMP1 = KPAPNSM;
        TEMP2 = ACBSMQ[0];
        IF TEMP2 EQ 0 
        THEN                 # NO MORE SUP MSGS QUEUED FOR APP         #
          BEGIN 
          HWRAVAL(P<ACB>,TRUE);  # UPDATE AIP-S DATA AVAILABLE WORD    #
          END 
        END 
  
      BLKID[BUFADDR] = MOUTIDVALUE; # RESET NON-MOVABLE ID             #
  
      IF KDIS$RT
        AND ACBKNDX[0] NQ 0 
        AND ACBKNDX[0] GQ KDAPPST[0]
        AND ACBKNDX[0] LQ KDAPPND[0]
      THEN # REAL TIME UPDATE FOR STATUS DISPLAY                       #
  
        KPUT(KHDRNP[0],ACBKNDX[0]-KDAPPST[0],TEMP1,TEMP2);
  
  
      RETURN; 
      END # BDELINK # 
      TERM
