*DECK,NP$SENF 
*IF,DEF,XFR 
USETEXT NX$ACBF 
USETEXT AIPDEF
USETEXT HEADER
USETEXT NP$STAT 
USETEXT NP$DB 
USETEXT NP$NWL
USETEXT NP$MODE 
USETEXT NP$GETS 
USETEXT NX$ACBX 
      PROC NP$SENF(NBACKTRIG);
      BEGIN 
# 
*1DC  NP$SENF 
* 
*     1. PROC NAME         AUTHOR               DATE
*        NP$SENF           Y. C. YIP            02/19/1985
* 
*     2. FUNCTIONAL DESCRIPTION 
*        NP$SENF PERFORMS THE SENDING ACTION OF A FILE IN 
*        CHARACTER MODE TO THE RECEIVER. THE SAME MODULE IS 
*        USED IN INBTRAHOST FILE TRANSFER.
* 
*     3. METHOD USED
* 
*        LEGEND: CHECKMARK WINDOW SIZE REFERS TO THE
*                MAX NUMBER OF DATA BLOCKS THAT CAN BE NETPUT 
*                BEFORE A CHECKMARK MUST BE SENT IF MFACIL USED 
* 
*                MAX-CHARK REACHED REFERS TO THE MAXIMUM NUMBER 
*                OF CHECKMARKS THAT CAN BE SENT BEFORE A MR IS
*                RECEIVED FROM THE RECEIVER.
* 
*        UNTIL ABL WINDOW CLOSED OR MAX CHECKMARKS REACHED OR 
*              EOI REACHED
*              PERFORM: 
*              IF CHECKMARK WINDOW OPEN 
*                 READ FROM DISKBUFF
*                 TEST FOR DISK FET STATUS AND UPDATE 
*                 FTTEOR, FTTEOI AND FTTLEV ACCORDINGLY.
*                IF RESTART PENDING FLAG SET
*                  SET CHECKMARK RESTART INDEX
*                  SET DISK OUTFET ACCORDING TO THE 
*                  OFFSET CONTAINED IN THE CHECKMARK BUFFER ASSOCIATED
*                  WITH RESTART INDEX 
*                  CLEAR RESTART PENDING FLAG 
*                ENDIF
*                SAVE CURRENT DISK FETOUT IN DISKOLDOUT 
*                IF TRANSLATION FLAG SET
*                THEN 
*                  CALL TRANSLATION SERVICE 
*                ELSE 
*                  COPY CONTENTS OF DISK BUFF INTO NETWORK BUFFER 
*                  AS A INTRAHOST FILE TRANSFER ACTION. 
*                ENDIF
*                IF MFACIL SET (ONLY FOR INTERHOST) 
*                THEN 
*                  CALL NP$UPRU TO UPDATE FTTWORD, FTTDBIT AND FTTPRU.
*                ENDIF
*                IF NETWORK BUFFER FULL OR EOR REACHED
*                THEN 
*                  SET LOC$HA AND LOC$TA
*                  SET ACN AND TLC
*                  IF DISK BUFFER ALSO EMPTY
*                    UPDATE TBH$TBC 
*                  ENDIF
*                  IF FTTEOI SET
*                    SET NBACKTRIG TO TRIG-EOI
*                    EXIT LOOP
*                  ENDIF
*                  SET TBH IN THE HEADER
*                  NEPUT BLOCK. 
*                  RESET NETBUF FET POINTERS
*                  RESET CMB$NBYTE, CMB$NCOUNT AND CMB$NBUF FLAG
*                  IF MFACIL USED (ONLY FOR INTERHOST)
*                    DECREMENT CHECKMARK WINDOW SIZE BY 1 
*                  ENDIF
*                ELSE 
*                  PERFORM A SHORT TIME RECALL
*                  SET BACKTRIG TO SEND TRIGGER AGAIN 
*                ENDIF
*              ELSE          (MS WINDOW CLOSED) 
*                IF ABL WINDOW OPEN 
*                  SEND CHECKMARK 
*                  UPDATE CHECKMARK STATUS BUFFER FROM FTT
*                ENDIF
*             ENDIF 
*           END-LOOP         (END OF UNTIL) 
*         IF ABL WINDOW CLOSED
*         THEN
*           SET FTTSTATE TO ABL-CLOSED-STATE
*         ENDIF 
*         IF MAX-CHECKMARK REACHED
*           SET FTTSTATE TO MAX-CHECKMARK-REACHED STATE 
*         ENDIF 
*         RETURN
* 
*     4. ENTRY CONDITIONS 
*        FTTINDEX SET TO THE CURRENT FILE TRANSFER INDEX. 
* 
*     5. EXIT CONDITONS 
*        FTTLEV UPDATED.
*        DISKFET UPDATED
*        NBACKTRIG SET TO EOI=TRIGGER IF EOI REACHED
* 
*     6. COMDECKS CALLED AND SYMPL TEXTS USED.
*        NP$NWL, NX$ACBX
* 
*     7. ROUTINES CALLED
*        NP$CIO - CALLS CIO FUNCTIONS TO PERFORM READ 
*        NP$RCL - PERFORMS TIME RECALL
*        NP$D2N - PERFORMS DISK TO NETBUF TRANSLATION 
*        NP$PUT - PERFORMS NETPUT 
*        NP$UPRU - PERFORMS UPDATING OF PRU NUMBER, WORD AND DBIT 
*                  IN THE FTT.
*        NP$BT
*                  NUMBERS. 
*     8. DAYFILE MESSAGES 
*          NONE 
* 
# 
  
# 
****
# 
      XREF
        BEGIN 
        PROC NP$CIO;               # PROCEDURE TO PERFORM CIO FUNCTIONS#
        PROC NP$D2N;               # TRANSLATION SERVICE FROM DISK TO  #
                                   # NETWORK BUFFER                    #
        PROC NP$RCL;               # PROCEDURE TO PERFORM THE RECALL   #
        PROC NP$PUT;               # INTERNAL PROCEDURE TO NETPUT BLOCK#
        PROC NETPUT;               # PROCEDURE TO NETPUT BLOCKS        #
        PROC NP$UPRU;              # PROCEDURE TO UPDATE PRU,WORD AND  #
                                   # DBIT IN FTT                       #
        PROC NP$BTO8;              # PROC TO TRANSLATE INTEGER TO ASCII#
        PROC NP$SHRK;              # PROC TO SHRINK CHECKMARK TABLE    #
        END 
# 
****
# 
      DEF COLON # O"072"#;        # DEFINITIONS FOR COLON 64 CHARSET   #
      DEF COLON3 # 3 #;           # HALF BYTE OF 072                   #
      DEF COLON10 # 10 #;         # LOWER HALF BYTE OF 072             #
      ITEM NBACKTRIG;              # BACK TRIGGER                      #
      ITEM INDEX;                  # LOOP INDEX                        #
      ITEM DONE B;                 # DONE FLAG                         #
      ITEM CHKINDEX;               # TEMPORARY CHECKMARK INDEX         #
      ITEM DISKOLDOUT;             # OLD OUT POINTER OF DISK           #
      ITEM CONT B;                 # CONTINUATION FLAG                 #
      ITEM INDEX1;                 # LOOP INDEX                        #
      BASED ARRAY COPYAREA[0:0] S(1); 
        BEGIN 
        ITEM WORD U(00,00,60);     #  TEMPLATE FOR CHANGING MEMORY     #
        END 
  
  
      CONTROL EJECT;
#                                                                      #
#            CODE OF NP$SENF BEGINS HERE                               #
#                                                                      #
      P<CMB> = FTTCMV$BLK[FTTINDEX]; # SET CMB TEMPLATE TO CHARACTER   #
                                    # CONVERSION ADDRESS FROM FTT      #
      P<FET$CIO> = FTTFETADR[FTTINDEX];  # SET FET$CIO TEMPLATE TO     #
                                         # FET ADDRESS FROM FTT        #
      P<FET$WORK> = FTTFETW[FTTINDEX];  # SET NETWORK FET TO ADDRESS   #
                                        # FROM FTT                     #
      P<CHK> = FTTCKTBL[FTTINDEX]; # CHECK MARK TABLE ADDRESS          #
      DONE = FALSE;                # SET DONE FLAG TO FALSE            #
      P<TBH$HDR> = FETWFIRST[0];   # SET TBH TEMPLATE TO FIRST WORD    #
                                   # OF THE NETWORK BUFFER             #
      FOR INDEX = 0 WHILE (FTTCURBLK[FTTINDEX] GR 0) AND
                          ( FTTOUTCWS[FTTINDEX] NQ FTTCWS[FTTINDEX]) AND
                          NOT DONE
      DO                           # LOOP WHILE ABL WINDOW OPEN AND    #
        BEGIN                      # MAX CHECKMARKS NOT REACHED AND    #
                                   # EOI NOT YET READ FROM DISK        #
        IF FTTBLK$MS[FTTINDEX] GR 0  # IF MS WINDOW OPEN               #
        THEN
          BEGIN 
          IF FETCOMP[0] AND FTTEORI[FTTINDEX] EQ 0 # IF CIO COMPLETE   #
          THEN                     # AND LAST STATUS FROM DISK NOT EOR #
            BEGIN                  # OR EOI                            #
                                   # GET DATA IS REQUIRED              #
            FETCODE[0] = 0;        # CLEAR FETCODE                     #
            NP$CIO(CIO$READ);      # PERFORM CIO READ                  #
            IF FETEC[0] NQ 0 AND FETSTATUS[0] NQ CIO$EOI
            THEN                   # IF AT NQ 0 AND STATUS = 741031B   #
              BEGIN 
              NBACKTRIG = NSCTERR; #  SET BACKTRIG TO CIO ERROR        #
              GOTO NPEXIT;         # EXIT LOOP AND RETURN              #
              END 
            ELSE
              BEGIN 
              IF FETCODE[0] EQ CIO$NORMAL  # IF RETURN CODE = 11B      #
              THEN
                BEGIN 
                FTTTBC[FTTINDEX] = 0;    # CLEAR TBC FROM FTT          #
                END 
              ELSE
                BEGIN 
                IF FETCODE[0] EQ CIO$EOR OR FETCODE[0] EQ CIO$EOF 
                THEN                     # IF EOR OR EOF FOUND IN CODE #
                  BEGIN 
                  FTTEOR[FTTINDEX] = TRUE;  # SET EOR FLAG IN FTT      #
                  FTTLEV[FTTINDEX] = FETLEVEL[0];  # SAVE LEVEL NUMBER #
                  END 
                IF FETEC[0] EQ 1         # EOI IS FOUND                #
                THEN
                  BEGIN 
                  FTTEOI[FTTINDEX] = TRUE;  # SET EOI FLAG IN FTT      #
                  FETEC[0] = 0;          # CLEAR ERROR CODE            #
                  END 
                END 
              END 
            END                    # GET DATA IS REQUIRED              #
          IF FTTRPND[FTTINDEX]     # IF RESTART PENDING                #
          THEN
            BEGIN 
            IF CHK$IDX[0] EQ CHK$START  # IF A NON-ZERO CHECKMARK EXIST#
            THEN
              BEGIN 
              CHKINDEX = CHK$START;  # SAVE POINTER TO CHECKMARK TABLE #
              FETOUT[0] = FETOUT[0] + CHK$WORD[CHKINDEX]; 
              END 
            ELSE
              BEGIN 
              CHKINDEX = 1;              # START FROM RR(0)            #
              END 
            FTTRPND[FTTINDEX]= FALSE;    # CLEAR RESTART PENDING FLAG  #
            END                          # ENTRY                       #
          DISKOLDOUT = FETOUT[0];        # SAVE OLD FET OUT POINTER    #
          IF NOT FTTNOTRAN[FTTINDEX]     # IF TRANSLATION NEEDED       #
          THEN
            BEGIN 
            NP$D2N(LOC(FETWFIRST[0]),LOC(FETFIR[0]),P<CMB>);  # CALL TS#
            END 
          ELSE
            BEGIN                        # TRANSLATION NOT NEEDED      #
            P<COPYAREA> = 0;
            IF FETWIN[0] EQ FETWFIRST[0] # BEGINNING OF BLOCK          #
            THEN
              BEGIN 
              FETWIN[0] = FETWIN[0] + 1; # RESERVE ONE WORD FOR TBH    #
              END 
            IF (FTTEOI[FTTINDEX] OR      # IF EOI SET                  #
               FTTEOR[FTTINDEX]) AND
              (FETIN[0] EQ FETOUT[0])    # DISK BUFFER EMPTIED         #
            THEN
              BEGIN 
              CONT = FALSE;              # DO NOT COPY FROM DISK BUFFER#
              CMB$DBUF[0] = 1;           # SET DISKBUF EMPTY FLAG      #
              END 
            ELSE
              BEGIN 
              CONT = TRUE;               # COPY FROM DISK BUFFER       #
              END 
            FOR INDEX1 = 0 WHILE CONT    # COPY DATA INTO NETBUF       #
            DO
              BEGIN 
              WORD[FETWIN[0]] = WORD[FETOUT[0]];  # COPY DISK DATA     #
                                         # INTO NETBUF                 #
              FETWIN[0] = FETWIN[0] + 1; # BUMP IN PTR OF NETBUF       #
              FETOUT[0] = FETOUT[0] + 1; # BUMP OUT PTR OF DISK BUF    #
              IF FETOUT[0] EQ FETLIM[0]  # WRAP AROUND DISKBUF         #
              THEN
                BEGIN 
                FETOUT[0] = FETFIR[0];   # SET OUT PTR TO FIRST PTR    #
                END 
              IF FETIN[0] EQ FETOUT[0]   # DISKBUF EMPTIED             #
              THEN
                BEGIN 
                CMB$DBUF[0] = 1;         # DISK BUFFER EMPTY           #
                FETIN[0] = FETFIR[0]; 
                FETOUT[0] = FETFIR[0];
                CONT = FALSE;            # EXIT LOOP                   #
                END 
              IF FETWIN[0] EQ FETWLIMIT[0]  # NETBUF FILLED            #
              THEN
                BEGIN 
                CONT = FALSE;            # EXIT LOOP                   #
                CMB$NBUF[0] = 1;         # SET NETBUF TO BE FULL       #
                END 
              END                        # END FOR LOOP                #
            END                          # END IF                      #
          IF FTTMFACIL[FTTINDEX]         # IF MFACIL SPECIFIED         #
          THEN
            BEGIN 
            NP$UPRU(DISKOLDOUT,FETOUT[0]);#UPDATE PRU NUMBER WITH OLD  #
            END                          # AND NEW DISK OUT PTR        #
          IF CMB$NBUF[0] EQ 1  OR        # IF NET BUFFER IS FULL       #
             FTTEOR[FTTINDEX]            # OR EOR IS TRUE FROM FTT     #
          THEN                           # PUT MSG PROCESSING BEGINS   #
            BEGIN 
            IF NOT FTTNOTRAN[FTTINDEX]   # IF TRANSLATION NEEDED       #
            THEN
              BEGIN 
              LOC$HA = LOC(OUT$DATA);    # SET HEADER TO DATA HEADER   #
              LOC$TA = FETWFIRST[0];     # TA SET TO FIRST WORD ADDRESS#
                                         #   OF NETWORK BUFFER         #
              OUT$DAACN[0] = FTTACN[FTTINDEX];  # SET ADR IN HEADER    #
              OUT$DATLC[0] = CMB$NCOUNT[0]; 
              END 
            ELSE
              BEGIN                      # INTRHOST BINARY FILE XFR    #
              LOC$HA = LOC (OUT$INTRA); 
                                         # SET HEADER TO INTRHOST HDR  #
              LOC$TA = FETWFIRST[0];     # SET TEXT ADDRESS TO FIRST   #
              OUT$INTACN[0] = FTTACN[FTTINDEX]; # SET ADR              #
              OUT$INTTLC[0] = (FETWIN[0] - FETWFIRST[0])*15/2;
              END                        # FOR ACT = 2                 #
            TBH$WRD[0] = 0;              # CLEAR TBH                   #
            IF CMB$DBUF[0] EQ 1          # IF DISK BUFFER EMPTY        #
            THEN
              BEGIN 
              TBH$TBC[0] = FTTTBC[FTTINDEX];  # UPDATE TBC OF TBH      #
                                         # USING TBC FROM FTT          #
              FTTEOR[FTTINDEX] = FALSE;  # CLEAR EOR BIT IN FTT        #
              P<COPYAREA> = 0;
              IF CMB$STATE[0] NQ 0       # IF DAGGLING 00 OCCUR        #
              THEN
                BEGIN 
                OUT$DATLC[0] = OUT$DATLC[0]  + 1;  # ADD 072B :        #
                CMB$NCOUNT[0] = CMB$NCOUNT[0] + 1;
                IF CMB$NBYTE  LS 0       # IF  HALF BYTE AVAILABLE     #
                THEN
                  BEGIN 
                  B<56,04>WORD[FETWIN[0]] = COLON3; 
                  B<00,04>WORD[FETWIN[0] + 1] = COLON10;
                  END 
                ELSE
                  BEGIN                  # COMPLETE BYTE               #
                  B<52 - CMB$NBYTE[0],8>WORD[FETWIN[0]] = COLON;
                  END 
                END 
              CMB$STATE[0] = 0;          # CLEAR STATE FROM POSSIBLE   #
                                         # REMAINING GARBAGE           #
              IF FTTEOI[FTTINDEX]        # EOI TRUE FROM FTT           #
              THEN
                BEGIN 
                DONE = TRUE;             # SET DONE FLAG TO TRUE       #
                NBACKTRIG = NSCTEOI;     # SET BACK TRIG TO EOI TRIGGER#
                END 
              END 
            TBH$TBN[0] = FTTTBN[FTTINDEX];    # SET SERIAL BLOCK NUMBER#
            FTTTBN[FTTINDEX] = FTTTBN[FTTINDEX] + 1;  # BUMP TBN IN FTT#
            IF NOT FTTNOTRAN[FTTINDEX]   # IF TRANSLATION NEEDED       #
            THEN
              BEGIN 
              TBH$OLEN[0] = CMB$NCOUNT - TBH$LEN;  # UPDATE OLEN IN TBC#
              END 
            ELSE                         # INTRAHOST BINARY            #
              BEGIN 
              CMB$DBUF[0] = 0;           # READY FOR NEXT READ AND SO  #
                                         # SET DISK BUFFER NOT EMPTY   #
              TBH$OLEN[0] = OUT$INTTLC[0];  # OLEN ACCORDING TO ACT =4 #
              END 
            OPCODE = OP$PUT;             # SET OPCODE IN NETPUT        #
*IF DEF,STAT,1
            IAM = TYPE"PUT";             # SET TYPE OF EXECUTING       #
                                         # ROUTINE                     #
            NP$PUT;                      # NETPUT BLOCK                #
            FTTCURBLK[FTTINDEX] = FTTCURBLK[FTTINDEX] - 1;
                                         # DECREASE ABL WINDOW         #
            FETWIN[0] = FETWFIRST[0];    # RESET IN POINTER FOR NETBUF #
            FETWOUT[0] = FETWFIRST[0];   # RESET OUT POINTER FOR NETBUF#
            TBH$FWD[0] = 0;              # CLEAR FIRST WORD OF NETBUF  #
            CMB$NCOUNT[0] = TBH$LEN;     # RESET CMB$NCOUNT TO 6       #
            CMB$NBYTE[0] = INITNBYTE;    # RESET CMB$NBYTE TO 4        #
            CMB$NBUF[0] = 0;             # SET NETFUF EMPTY FLAG       #
            IF FTTMFACIL[FTTINDEX]       # IF MFACIL SPECIFIED         #
            THEN
              BEGIN 
              FTTBLK$MS[FTTINDEX] = FTTBLK$MS[FTTINDEX] - 1;
              END 
            END 
          ELSE
            BEGIN                        # NETBUF NOT FULL OR DISK     #
            NP$RCL(0);                   # DISK BUFFER NOT EMPTY       #
            NBACKTRIG = NSCTSND;         # AND NOT EOI                 #
                                         # SET SEND DATA AS BACK TRIG  #
            IF FTTNOTRAN[FTTINDEX]       # IF INTRAHOST BINARY XFR     #
            THEN
              BEGIN 
              CMB$DBUF[0] = 0;           # SET DISK BUFFER NOT EMPTY   #
              END 
            END                          # SET SEND TRIGGER AS BACKTRIG#
             # SEND SEND DATA AS BACKTRIG              #
          END 
        ELSE
          BEGIN 
                                         # MS WINDOW CLOSED  NETPUT(MS)#
          IF FTTMFACIL[FTTINDEX]         # IF M FACIL SPECIFIED        #
          THEN
            BEGIN 
            IF FTTCURBLK[FTTINDEX] GR 0  # IF ABL WINDOW OPEN          #
            THEN
              BEGIN 
              FTTBLK$MS[FTTINDEX] = MSWINDOWSZ;  #   RESET MS WINDOW   #
              FTTOUTCWS[FTTINDEX] = FTTOUTCWS[FTTINDEX] + 1;
                                         # BUMP OUTSTANDING CHECKMARK  #
                                         # COUNT                       #
              FTTLCKSNT[FTTINDEX] = FTTLCKSNT[FTTINDEX] + 1;
              NP$BTO8(FTTLCKSNT[FTTINDEX],CHKINDEX); # CONVERT TO ASCII#
              ABH$L7ADR = FTTACN[FTTINDEX];  # SET ADR IN ABH          #
              L7$PFC = LEV7$MS;          # SEND MS                     #
              L7$DD = B<STARTBIT,DDLEN>CHKINDEX;
              OPCODE = OP$PUT;
              LOC$HA = LOC(ABH$LEV7);    # SET HEADER ADDRESS          #
              LOC$TA = LOC(LV7$MSG);     # SET TEXT ADDRESS            #
*IF DEF,STAT,1
              IAM = TYPE"PUT";
*IF DEF,DEBUG,1 
              DB$CALL = LOC(NETPUT);     # COLLECT STATISTICS          #
              NP$PUT;                    # NETPUT MS                   #
              FTTCURBLK[FTTINDEX] = FTTCURBLK[FTTINDEX] - 1;
              CHK$IDX = CHK$IDX + 1;     # BUMP LAST ENTRY OF CHECKMARK#
                                         # TABLE                       #
              CHK$MARK[CHK$IDX] = FTTLCKSNT[FTTINDEX];
              CHK$WORD[CHK$IDX] = FTTWORD[FTTINDEX]; # CHECKMARK TABLE #
              CHK$DBIT[CHK$IDX] = FTTDBIT[FTTINDEX];
              CHK$PRUNO[CHK$IDX] = FTTCURPRU[FTTINDEX];#CURPRU UPDATED #
              CHK$TBN[CHK$IDX] = FTTTBN[FTTINDEX]; # TBN SAVED         #
              END 
            END 
          END                            # TRANSLATION                 #
        END                        # END WHILE                         #
      IF FTTCURBLK[FTTINDEX] EQ 0  # IF ABL WINDOW CLOSED              #
      THEN
        BEGIN 
        FTTSTATE[FTTINDEX] = NSCCABL;  # NEW STATE IS ABL-CLOSED STAE  #
        END 
      IF FTTOUTCWS[FTTINDEX] EQ FTTCWS[FTTINDEX]
      THEN
        BEGIN                      # IF MAX CHECKMARKS REACHED         #
        NBACKTRIG = NSCTMCM;       # SET BACK TRIGGER TO MAX CHECKMRKS #
        END                        # REACHED TRIGGER                   #
NPEXIT:  RETURN;                   # RETURN TO CALLER                  #
      END                          # END OF PROC NP$SENF               #
TERM
*ENDIF
