*DECK NS$MKD
USETEXT COM$NS
USETEXT DEF$NS
USETEXT KDS$NS
USETEXT LIN$NS
USETEXT PFC$NS
USETEXT SMB$NS
  
      PROC NS$MKD; # MANAGE K DISPLAY OUTPUT DATA                      #
  
# TITLE NS$MKD - MANAGE K DISPLAY OUTPUT DATA.                         #
  
      BEGIN    # NS$MKD # 
# 
**    NS$MKD - MANAGE K-DISPLAY OUTPUT DATA.
* 
*     J.C. LEE    1981
* 
*     THIS ROUTINE MANAGES K-DISPLAY OUTPUT DATA. 
* 
*     PROC NS$MKD 
* 
*     ENTRY:  
*       - FWA OF FIRST K-DISPLAY LINE WHICH MAY BE FIRST OF 
*         MANY CONSECUTIVELY ADDRESSED LINES FROM ONE OF THE
*         FOLLOWING BUFFERS: HISTORY BUFFER, PAGE-WAIT BUFFER,
*         STATUS BUFFER, OR DISPLAY CONTROL BLOCK.
*       - K-DISPLAY OUTPUT LINE COUNT.
*       - K-DISPLAY OUTPUT WORD COUNT.
* 
*     EXIT: 
*       NONE. 
* 
*     METHOD: 
*       CALL SEND-K-DISPLAY-OUTPUT TO SEND K-DISPLAY OUTPUT LINES 
*       UNTIL K-DISPLAY OUTPUT LINE COUNT IS EXHAUSTED OR 
*       K-DISPLAY IS FULL, WHICHEVER HAPPEN FIRST.
*       IF REMAINING K-DISPLAY OUTPUT LINES NOT ZERO, ADD THE 
*       REMAINING LINES TO PAGE-WAIT BUFFER.
* 
# 
  
      $BEGIN
      XREF
        BEGIN 
        PROC NS$DBG;         # TRACE PROC CALL   #
        END 
      $END
  
      XREF
        BEGIN 
        PROC EXINCSZ;        # INCREASE SIZE     #
        PROC EXREDUC;        # REDUCE SIZE       #
        PROC MOVEI;          # MOVE LINE TO SM BUFFER                  #
        PROC MOVEOK;         # ALLOW MOVES       #
        PROC NETPUT;         # SEND HOP MSG      #
        PROC NS$TKD;         # TRANSFER LINES TO K DISPLAY BUFFER      #
        PROC TSBINFO;        # LOCATE K-DISPLAY BUFFER                 #
        END 
  
      DEF L$HOPDIS   # 58 #; # LENGTH OF HOP-DIS-SM                    #
      DEF MDLC       # 4 #;  # ENTRY SIZE FOR MORE DATA .. ARRAY       #
  
      ITEM ADDR       U;     # FWA OF 1ST LINE TO SEND                 #
      ITEM BLKLC      U;     # KDB CURRENT LINE COUNT                  #
      ITEM BLKWC      U;     # KDB CURRENT WORD COUNT                  #
      ITEM I          I;     # LOOP VARIABLE                           #
      ITEM KDBTSBN    U;     # TSB NUMBER OF K DISPLAY BUFFER          #
      ITEM KDLC       U;     # LINES THAT CAN BE SENT OUT              #
      ITEM LC         U;     # LINE COUNT                              #
      ITEM LNSIZE     U;     # CURRENT LINE SIZE #
      ITEM TEMP       U;     # TEMP STORAGE FOR PWB SIZE               #
      ITEM TLW        U;     # TEXT LENGTH OF HOP/DIS                  #
      ITEM TSBFWA     U;     # FIRST WORD ADDRESS OF TSB               #
      ITEM TSBSIZE    U;     # SIZE OF TSB                             #
  
      ARRAY MORDATA [0:0] S(MDLC);
        BEGIN # MORE DATA .. K DISPLAY LINE                            #
        ITEM MDWD1      U(00,00,60); # PFC/SFC WORD                    #
        ITEM MD$PFCSFC  U(00,00,16) = [HOPDIS]; # PFC/SFC CODE         #
        ITEM MD$F1      U(00,16,44) = [0];
        ITEM MDWD2      U(01,00,60);
        ITEM MORDAT     C(01,00,11) = ["MORE DATA.."];
        ITEM MDZERO     U(02,06,54) = [0];
        ITEM MD$RES     U(03,00,60) = [0]; # LAST RESERVED WORD FOR NIP#
        END 
  
      ARRAY ABH [0:0] S(1); 
        BEGIN # APPLICATION BLOCK HEADER WORD FOR HOP/DIS/SM           #
        ITEM ABH$ABT    U(00,00,06) = [APPCMD]; 
        ITEM ABH$ADR    U(00,06,12) = [0];
        ITEM ABH$ABN    U(00,18,18) = [0];
        ITEM ABH$ACT    U(00,36,04) = [CT60TRANS];
        ITEM ABH$DBC    U(00,40,08) = [0];
        ITEM ABH$TLC    U(00,48,12);
        END 
  
      ARRAY SM$HOPDIS [0:0] S(64);
        BEGIN # HOP/DIS/SM BUFFER                                      #
        ITEM SM$PFCSFC  U(00,00,16) = [HOPDIS]; 
        ITEM SM$HOPI    B(00,59,01); # INPUT ALLOWED FLAG              #
        ITEM SM$F1      U(00,16,44) = [0];
        END 
  
      CONTROL EJECT;
  
      $BEGIN
      NS$DBG("MKD");         # TRACE CALL        #
      $END
# 
      DETERMINE NUMBER OF LINES TO SEND TO K DISPLAY
# 
      KDBTSBN = DCW$KDBTSB[0]; # TSB NUMBER OF K DISPLAY BUFFER        #
      TSBINFO(TSBSIZE,TSBFWA,KDBTSBN);       # LOCATE K-DISPLAY BUFFER #
      P<KDS$BUFFER> = TSBFWA; # FWA OF K DISPLAY BUFFER                #
      BLKLC = KDB$LC[0];     # KDB CURRENT LINE COUNT                  #
      BLKWC = KDB$WC[0] - KDB$HDRL; # WORD COUNT OF ALL KDB LINES      #
      LC = BLKLC; 
  
      IF DCW$F$PWM[0] 
      THEN # PAGE WAIT MODE IS ON                                      #
        BEGIN 
        KDLC = MAX$PW - DCW$LC[0];     # LINES THAT CAN BE SENT OUT    #
        IF LC GR KDLC 
        THEN # BUFFER CONTAINS MORE LINES THAN NAM K DISPLAY CAN HOLD  #
          LC = KDLC;
        END 
# 
        FORMAT HOP/DIS/SM TO CARRY AS MANY LINES AS CAN BE FIT INTO THE 
        SMB$BUFFER, MULTIPLE HOP/DIS/SM(S) MAY BE SENT
# 
      P<SMB> = LOC(SM$HOPDIS); # FWA OF HOP/DIS SM BUFFER              #
      P<LIN$HEADER> = 0;
      ADDR = P<KDS$BUFFER> + KDB$HDRL; # FWA OF 1ST LINE IN KDB TO SEND#
      TLW = 1;               # TEXT LENGTH OF HOP/DIS                  #
  
      IF LC NQ 0
      THEN                   # K-DISPLAY LINES TO SEND TO NIP          #
        BEGIN 
  
        FOR I=LC STEP -1 WHILE I GQ 0 
        DO # SEND LINES TO K DISPLAY                                   #
          BEGIN 
          LNSIZE = LIN$LNSIZE[ADDR] - LIN$HDRL;  # CURRENT LINE SIZE   #
  
          IF (I EQ 0 # ALL LINES ARE SENT                              #
            AND TLW NQ 1) # SM BUFFER  CONTAINS K DISPLAY LINES        #
            OR (TLW+LNSIZE) GR L$HOPDIS # LINE CANNOT FIT IN BUF       #
          THEN # SEND HOP/DIS/SM                                       #
            BEGIN 
            ABH$TLC[0] = TLW + 1; # SET TEXT LENGTH                    #
            SM$HOPI[0] = DCW$F$IA[0]; # SET INPUT-ALLOWED FLAG         #
            SMBWORD[TLW] = 0;# CLEAR TEXT LENGTH+1 WORD                #
            NETPUT(ABH,SM$HOPDIS); # SEND HOP/DIS/SM                   #
            TLW = 1;         # RESET TLW TO INITIAL VALUE              #
            END 
  
          IF I NQ 0 
          THEN # MOVE CURRENT LINE TO SMB$BUFFER                       #
            BEGIN 
            DCW$F$IA[0] = LIN$F$ENDR[ADDR]; 
            MOVEI(LNSIZE,ADDR+LIN$HDRL,LOC(SMBWORD[TLW]));
            BLKWC = BLKWC - LNSIZE - LIN$HDRL;
            TLW = TLW + LNSIZE; # UPDATE WORD COUNT IN SM BUFFER       #
            ADDR = ADDR + LNSIZE + LIN$HDRL;     # FWA OF NEXT LINE    #
            END 
  
          END   # I LOOP #
  
        BLKLC = BLKLC - LC;  # UPDATE REMAINING LINE COUNT             #
        DCW$LC[0] = DCW$LC[0] + LC;    # UPDATE NAM K-DISPLAY LINE CNT #
        END 
  
      IF BLKLC NQ 0 
      THEN                   # MORE K-DISPLAY LINES TO FOLLOW          #
        BEGIN 
        IF NOT DCW$F$PAGE[0]
        THEN # NAM K DISPLAY PAGE WAS NOT FULL                         #
          BEGIN # SEND MORE DATA .. TO NAM K DISPLAY                   #
          ABH$TLC[0] = MDLC; # SET TEXT LENGTH                         #
          NETPUT(ABH,MORDATA); # SEND MORE DATA.. TO K DISPLAY         #
          DCW$F$PAGE[0] = TRUE; # SET PAGE FULL FLAG                   #
          END 
# 
        TRANSFER REMAINING KDB LINES TO PAGE WAIT BUFFER
# 
        TEMP = DCW$PWBTSB[0]; 
        TSBINFO(TSBSIZE,TSBFWA,TEMP);  # LOCATE PAGE WAIT BUFFER       #
        P<PWB$BUFFER> = TSBFWA;        # FWA OF PAGE WAIT BUFFER       #
        IF PWB$LC[0] LS PWB$MAX$LN
        THEN                 # LINE CNT LESS THAN PAGE WAIT LINE LIMIT #
          BEGIN              # TRANSFER LINE TO PAGE WAIT BUFFER       #
          EXINCSZ(BLKWC,TSBFWA,TEMP);  # INCREASE PWB SIZE             #
          P<PWB$BUFFER> = TSBFWA; # RESET PWB FWA                      #
          P<LIN$HEADER> = TSBFWA + PWB$WC[0];    # FWA TO MOVE TO      #
          MOVEI(BLKWC,ADDR,P<LIN$HEADER>);
          PWB$LC[0] = PWB$LC[0] + BLKLC;# UPDATE PWB LINE COUNT        #
          PWB$WC[0] = PWB$WC[0] + BLKWC;# UPDATE PWB WORD COUNT        #
          MOVEOK(TEMP);      # ALLOW PWB TO MOVE #
          END 
  
        END 
# 
      REDUCE K DISPLAY BUFFER TO ITS HEADER ONLY
# 
      EXREDUC(KDB$WC[0]-KDB$HDRL,KDBTSBN,FALSE,TSBFWA); 
      P<KDS$BUFFER> = TSBFWA; 
      KDB$WC[0] = KDB$HDRL; # RESET KDB WORD COUNT AND LINE COUNT      #
      KDB$LC[0] = 0;
      DCW$F$SKD[0] = FALSE; 
      MOVEOK(KDBTSBN); # ALLOW K DISPLAY BUFFER TO MOVE                #
  
      RETURN; 
      END   # NS$MKD #
      TERM
