!Modified   28/August/84   10.00





!   History of FILEOP401S:
            !                                                         %C
           (i). Change to INREC so that the last character in a       C 
                       character file is not ignored if it is not     C 
                       a newline character                            C 
                            (see bug report KB97)            AGRK


!   History of FILEOP02S:
            !                                                         %C
           (i). Change to NEW FILE OP to inhibit Fortran from writing C 
                       more than 160 characters per record on a unit  C 
                       that is connected to a character file.



!
!***********************************************************************
!*                                                                     *
!*                  Conditional compilation constants                  *
!*                                                                     *
!***********************************************************************
!
!
INCLUDE  "SS0302S_SSOWNF"
!
!***********************************************************************
!*                                                                     *
!*                           Record formats                            *
!*                                                                     *
!***********************************************************************
!
RECORDFORMAT  DAHF(INTEGER  DATAEND,DATASTART,SIZE,FILETYPE,DATE,TIME,FORMAT,
   RECORDS)
! %RECORDFORMAT FDF(%INTEGER LINK,DSNUM, %BYTEINTEGER STATUS,ACCESSROUTE,
!    VALID ACTION,CUR STATE, %BYTEINTEGER MODE OF USE,MODE,FILE ORG,DEV CODE,
!     %BYTEINTEGER REC TYPE,FLAGS,LM,RM, %INTEGER ASVAR,AREC,RECSIZE,MINREC,
!    MAXREC,MAXSIZE,LASTREC,CONAD,CURREC,CUR,END,TRANSFERS,DARECNUM,CURSIZE,
!    DATASTART, %STRING(31) IDEN, %INTEGER KEYDESC0,KEYDESC1,RECSIZEDESC0,
!    RECSIZEDESC1, %BYTEINTEGER F77FLAG,F77FORM,F77ACCESS,F77STATUS,
!     %INTEGER F77RECL,F77NREC,IDADDR, %BYTEINTEGER F77BLANK,F77UFD,SPARE1,
!    SPARE2)
!
!***********************************************************************
!*                                                                     *
!*                              Constants                              *
!*                                                                     *
!***********************************************************************
!
CONSTINTEGER  EM=25
CONSTINTEGER  FORTRANINDEFAULT=5
CONSTINTEGER  FORTRANOUTDEFAULT=6

! %CONSTINTEGER Stream MAXREC= 160
            ! Stream MAXREC is set to the longest record that         %C
                            Fortran is expected to handle if a        C 
                            unit is connected to a character          C 
                            file
!
!***********************************************************************
!*                                                                     *
!*                     %SYSTEM Routine/fn/map spec                     *
!*                                                                     *
!***********************************************************************
!
SYSTEMINTEGERFNSPEC  CLOSE(INTEGER  AFD)
SYSTEMINTEGERFNSPEC  FDMAP(INTEGER  C)
SYSTEMINTEGERFNSPEC  FORTRANDF(INTEGER  DSNUM,NUMBLOCKS,BLKSIZE, C 
   ASVARDESCAD)
SYSTEMINTEGERFNSPEC  IOCP(INTEGER  EP,PARM)
SYSTEMINTEGERFNSPEC  NEWMTFILEOP(INTEGER  AFD,ACT)
SYSTEMINTEGERFNSPEC  OPEN(INTEGER  AFD,MODE)
!
SYSTEMINTEGERMAPSPEC  COMREG(INTEGER  I)
!
SYSTEMROUTINESPEC  CHANGEACCESS(STRING (31) FILE, INTEGER  MODE,
    INTEGERNAME  FLAG)
SYSTEMROUTINESPEC  EXTEND(RECORD (FDF) NAME  R, INTEGERNAME  F)
SYSTEMROUTINESPEC  MAGIO(INTEGER  AFD,OP, INTEGERNAME  FLAG)
!
!***********************************************************************
!*                                                                     *
!*               External/internal routine/fn/map specs                *
!*                                                                     *
!***********************************************************************
!
!
!***********************************************************************
!*                                                                     *
!*                            Own variables                            *
!*                                                                     *
!***********************************************************************
!
! %OWNBYTEINTEGERARRAY STINBUFF  (1:Stream MAXREC  )     {for stream input }
! %OWNBYTEINTEGERARRAY STOUTBUFF (1:Stream MAXREC+2)     {for stream output}
        !
   !NOTE:
   !  In theory, only one buffer is required for input and output
   !     since Fortran handles a complete record at a time. However
   !     the distinction between input and output is maintained for
   !     clarity.
   !  The output buffer allows for format effector conversion for
   !     units connected to .OUT or for files defined as containing
   !     format effectors.

! %OWNINTEGER CURRENT FD
! %OWNINTEGER IRGAP; !INTER-RECORD GAP
!
!***********************************************************************
!*                                                                     *
!*                         Extrinsic variables                         *
!*                                                                     *
!***********************************************************************
!
! %EXTRINSICINTEGER INDEFAULT
! %EXTRINSICINTEGER OUTDEFAULT
!
!***********************************************************************
!*                                                                     *
!*                         External variables                          *
!*                                                                     *
!***********************************************************************
!
!
!***********************************************************************
!*                                                                     *
!*                         End of declarations                         *
!*                                                                     *
!***********************************************************************
!
!
SYSTEMINTEGERFN  NEWFILEOP(INTEGER  DSNUM,ACTION,TYPE, INTEGERNAME  AFD)
INTEGERFNSPEC  SPECIAL ACTION
CONSTBYTEINTEGERARRAY  SIMPLE VALID ACTION(0:7)= C 
 0, x'73', x'7D', x'76', x'71', x'7D', 0, 0
RECORD (DAHF) NAME  HEAD
RECORD (FDF) NAME  F
INTEGER  I,J,K,FLAG,DARECNUM
!*
DARECNUM=AFD; !PASSED FOR FORTRAN WRITE DA CALLS
UNLESS  0<DSNUM<100 THENRESULT =164
 ! INVALID CHANNEL NUMBER
LOOK:

I=FDMAP(DSNUM)
IF  I=0 THENSTART 
   IF  DSNUM=FORTRAN IN DEFAULT THEN  DSNUM=SSOWN_INDEFAULT AND  ->LOOK
   IF  DSNUM=FORTRAN OUT DEFAULT THEN  DSNUM=SSOWN_OUTDEFAULT AND  ->LOOK
   RESULT =151; !CHANNEL NOT DEFINED
FINISH 
F==RECORD(I)
IF  F_ACCESSROUTE=1 THEN  DSNUM=SSOWN_INDEFAULT AND  ->LOOK
 !MAPPED ONTO PRIMARY INPUT
IF  F_ACCESSROUTE=2 THEN  DSNUM=SSOWN_OUTDEFAULT AND  ->LOOK
 !MAPPED ONTO PRIMARY OUTPUT
AFD=I
SSOWN_CURRENT FD=I
IF  F_ACCESSROUTE=5 THENRESULT =NEWMTFILEOP(AFD,ACTION)
 !MAGNETIC TAPE FILE
IF  F_RECTYPE=1 THEN  SSOWN_IRGAP=0 ELSE  SSOWN_IRGAP=2
 !INTER-RECORD GAP
!*
J=F_CUR STATE
UNLESS  0<=J<=7 THENRESULT =1008
 ! CORRUPT DESCRIPTOR
IF  F_ACCESS ROUTE=6 THEN  DSNUM=F_ASVAR AND  ->LOOK
IF  ACTION&F_VALID ACTION=0 AND  F_STATUS#0 THENSTART 
 !Invalid action and already OPEN
 ! INVALID I/O OP
   IF  ACTION=2 OR  ACTION=16 START ; !WRITE or ENDFILE
      CHANGEACCESS(F_IDEN,3,FLAG); !CHANGE TO WRITE MODE
      IF  FLAG#0 THENRESULT =162; !FAILURE
      F_VALIDACTION=F_VALIDACTION!2; !PUT IN WRITE BIT
      HEAD==RECORD(F_CONAD)
      F_END=F_CONAD+HEAD_SIZE
   FINISHELSERESULT =171; !SOME OTHER INVALID ACTION
FINISH 
IF  ACTION&SIMPLE VALID ACTION(J)=0 THENSTART 
 ! INVALID OR DETAILED PROCESSING
   K=SPECIAL ACTION
   IF  K>0 THENRESULT =K
   IF  K<0 THENRESULT =0
FINISH 
!*
IF  ACTION=1 THENSTART ; ! READ
   F_CUR STATE=2
   RESULT =0
FINISH 
!*
IF  ACTION=2 THENSTART ; !WRITE
!*
!*EMAS  ENSURE THAT F_AREC=ADDRESS OF OUTPUT BUFFER
!*EMAS              F_MAXREC=MAX RECORD SIZE
!*EMAS              F_REC TYPE=1 OR 2  (F OR V)
   IF  F_MODEOFUSE=1 START ; !STREAM OUTPUT

       F_AREC    = ADDR(SSOWN_STOUTBUFF(1))
   IF  F_DSNUM   = SSOWN_OUTDEFAULT OR                                      C 
       F_FLAGS&16= 16         THEN  F_MAXREC= Stream MAXREC+1         C 
                              ELSE  F_MAXREC= Stream MAXREC

   FINISHELSEIF  F_MODEOFUSE=2 START ; !SEQUENTIAL
      WHILE  F_CUR+F_MAXREC+SSOWN_IRGAP>F_END CYCLE 
         EXTEND(F,FLAG)
         IF  FLAG#0 THENRESULT =169
 !OUTPUT EXCEEDED
      REPEAT 
      F_AREC=F_CUR+SSOWN_IRGAP; !READY FOR DATA TO BE STUFFED IN
   FINISHELSESTART ; !FORTRAN DIRECT ACCESS
      IF  TYPE=8 THENRESULT =119; ! F77 SEQ/DA CONFLICT.
      F_AREC=F_CONAD+F_DATASTART+F_RECSIZE*(DARECNUM-1)
   FINISH 
   F_CURSTATE=3
   RESULT =0
FINISH 
!*
IF  ACTION=4 THENSTART ; !REWIND
!ACTION HERE IS AS FOLLOWS:
!IF FILE OPEN FOR READING THEN RESET F_CUR AND F_CURREC
!IF FILE OPEN FOR WRITING THEN CLOSE IT
   IF  F_VALIDACTION&2=0 START ; !OPEN FOR READING
      IF  F_CONAD#0 START 
         F_CUR=F_CONAD+INTEGER(F_CONAD+4)
         F_CURREC=F_CUR
         F_CURSTATE=4
         F_TRANSFERS=0; !IN CASE WRITE DONE LATER
      FINISH 
   FINISHELSE  FLAG=CLOSE(AFD); !IF OPEN FOR WRITING CLOSE IT
   RESULT =0
FINISH 
!*
IF  ACTION=8 START ; !BACKSPACE
   IF  F_MODEOFUSE=1 START ; !CHAR FILE -LOOK BACK
      IF  F_CUR<=F_DATASTART+1 THEN  F_CUR=F_DATASTART ANDRESULT =0
!AT BEGINNING OF FILE
      FOR  I=F_CUR-2,-1,F_DATASTART CYCLE ; !LOOKBACK
         IF  BYTEINTEGER(I)=NL THEN  I=I+1 ANDEXIT 
 !START OF LAST RECORD
      REPEAT 
      F_CUR=I
      F_CURREC=I
      RESULT =0
   FINISH 
 !DATA FILE
   IF  SSOWN_IRGAP=0 THENSTART 
      F_CUR=F_CUR-F_RECSIZE
   FINISHELSESTART 
      IF  F_LASTREC=0 THENRESULT =268; !DOUBLE BACKSPACE NOT ALLOWED
      F_CUR=F_LASTREC
      F_LASTREC=0; !TO PREVENT DOUBLE BACKSPACE
   FINISH 
   F_TRANSFERS=F_TRANSFERS-1
   RESULT =0
FINISH 
!*
IF  ACTION=16 THENSTART ; !ENDFILE
!*
!*EMAS  SET 'END OF DATA' TO CURRENT PTR
   F_CUR STATE=6
   RESULT =0
FINISH 
!*
IF  ACTION=32 THENSTART ; ! CLOSE
   I=CLOSE(AFD)
   IF  I>0 THENRESULT =I
   RESULT =0
FINISH 
!*
IF  ACTION=64 THENSTART ; ! FIND
   RESULT =0
FINISH 
!*
RESULT =1013; ! INVALID ACTION REQUESTED
!*

INTEGERFN  SPECIAL ACTION
   INTEGER  I,J
   SWITCH  S(0:7)
   ->S(F_CUR STATE)
!*
!******  CLOSED
S(0):IF  ACTION=4 OR  ACTION=8 THENRESULT =-1
 !IGNORE REWIND AND BACKSPACE IF CLOSED
   IF  (ACTION=2 OR  ACTION=16) AND  F_MODEOFUSE<12 THEN  J=2 ELSE  J=1
 ! SQ WRITE ELSE SQ READ OR DA
   IF  F_MODEOFUSE=0 THEN  F_MODEOFUSE=2
 !FORCE DATA TYPE IF NOT SET
   IF  TYPE=7 THEN  RESULT =301;  ! FORTRANG - Chan not open
   IF  TYPE=9 THEN  START 
      ! FORTRAN77 DA access request
      IF  13#F_MODEOFUSE#3 THEN  RESULT =119;  ! Conflicting access
      RESULT =FORTRANDF(DSNUM,0,0,0)
   FINISH 
   I=OPEN(SSOWN_CURRENT FD,J)
   IF  F_RECTYPE=1 THEN  SSOWN_IRGAP=0 ELSE  SSOWN_IRGAP=2
   IF  I<=0 START 
      F_LASTREC=F_CUR; !FOR BACKSPACE
      F_CUR STATE=1
      RESULT =0
   FINISH 
   RESULT =I
!*
!******  AFTER OPEN
S(1):RESULT =-1; ! NO ACTION REQUIRED FOR
 ! REWIND/BACKSPACE
!*
!****** AFTER READ
S(2):
   RESULT =0
!*
!******   AFTER WRITE
S(3):IF  F_MODEOFUSE<12 THENSTART 
      IF  ACTION=8 START ; !BACKSPACE
         HEAD==RECORD(F_CONAD)
         HEAD_DATAEND=F_CUR-F_CONAD
         HEAD_RECORDS=F_TRANSFERS
         F_VALIDACTION=F_VALIDACTION&x'FD'; !REMOVE WRITE VALID BIT
 ! TO AVOID LOOSING LAST RECORD IF NEXT ACTION IS REWIND OR CLOSE
         F_CURSTATE=2
         RESULT =0
      FINISH 
      RESULT =156; !READ AFTER WRITE ERROR
   FINISHELSERESULT =0
!*
!******  AFTER REWIND
S(4):IF  ACTION=4 OR  ACTION=8 THENRESULT =-1
!*
!****** AFTER BACKSPACE
S(5):IF  ACTION=2 THENSTART 
!*
!*EMAS  SET 'END OF DATA' TO CURRENT PTR
   FINISH 
   RESULT =0
!*
!******  AFTER ENDFILE
S(6):IF  ACTION=1 THENRESULT =156
 !READ AFTER WRITE
   IF  ACTION=2 THENRESULT =157
 !WRITE AFTER END FILE
   IF  ACTION=4 THENRESULT =0
 !NORMAL REWIND PROCESSING
   IF  ACTION=8 THENSTART 
 ! AFTER BACKSPACE
      F_CUR STATE=3; ! IN WRITE MODE AFTER LAST RECORD
      RESULT =-1
   FINISH 
   IF  ACTION=16 THENRESULT =-1
 ! IGNORE MULTIPLE ENDFILE
   RESULT =1013; ! INVALID ACTION
!*
!******  AFTER END OF FILE DETECTED ON READ
S(7):IF  ACTION=1 THENRESULT =153
 !REPEAT END OF FILE CONDITION
   IF  ACTION=2 THEN  ->S(2)
 !TO SET WRITE MODE
   IF  ACTION=8 THEN  F_CURSTATE=2 ANDRESULT =-1
 !BACKSPACE - JUST SKIPS BACK OVER IMAGINARY END OF FILE
   IF  ACTION=16 THENRESULT =-1
 !ENDFILE ALREADY
   RESULT =0
END ; ! SPECIAL ACTION
!
!
!*
END ; !NEWFILEOP
!
!
SYSTEMINTEGERFN  INREC
INTEGERARRAY  IOCP PARM(1:3)
RECORD (FDF) NAME  F
INTEGER  ABFR
INTEGER  I,FLAG,CIST,ASVAR,L,R,START POS
INTEGER  LEN    ; !a savearea
INTEGER  CUR POS; !       for descriptors and the STD instruction

    {LEN,CUR POS are currently used for character input from}
    {            a file or alien data in background JCL     }

F==RECORD(SSOWN_CURRENT FD)
IF  F_ACCESSROUTE=5 START ; !MAGNETIC TAPE
   MAGIO(SSOWN_CURRENTFD,2,FLAG)
   RESULT =FLAG
FINISH 
IF  F_ACCESSROUTE=10 THENRESULT =153; !.NULL GIVES INPUT
 !ENDED
IF  F_CURSTATE=7 THENRESULT =153
 ! INPUT ENDED
!*
!*EMAS  SET F_AREC=ADDRESS OF NEXT RECORD
!*EMAS      F_RECSIZE=LENGTH OF RECORD
!*EMAS      %RESULT=153 FOR END OF FILE
!*
IF  F_MODEOFUSE=1 START ; !STREAM
   IF  (F_ACCESSROUTE=8 AND  F_DSNUM#90) OR  F_ACCESSROUTE=11 START 
 !READING FROM CHARACTERFILE OR ALIEN DATA
 !        %IF F_CUR # F_CURREC %START;    !SKIP REST OF PART-USED RECORD
!           I = F_CUR
!           %CYCLE
!              %IF BYTEINTEGER(I) = 10 %START
!                 F_CUR = I+1
!                 F_CURREC = I+1
!              %FINISH
!              %IF I >= F_END %THEN %RESULT = 153
!                                       !END OF FILE
!              I = I+1
!           %REPEAT
!        %FINISH
!        F_AREC = F_CUR
!        I = F_CUR
 !        %CYCLE;                         !NOW LOOK FOR END OF RECORD
 !           %IF BYTEINTEGER(I) = NL %START; !END OF RECORD
!              F_RECSIZE = I-F_AREC
 !              F_CUR = I+1;              !POINT TO START OF NEXT RECORD
!              F_CURREC = I+1
!              %RESULT = 0
!           %FINISH
 !           %IF I >= F_END %THEN %RESULT = 153; !END OF FILE
!           I = I+1
!        %REPEAT

!---Initialise
    !
    !
    cur pos= f_cur
        len= f_end - cur pos
unless  len> 0 then  -> report 153

       *ldtb_ x'58000000'; !load DR with
       *ldb_    len      ; !      a descriptor to
       *lda_    cur pos  ; !          the rest of the file

if  cur pos¬= f_cur rec thenstart 
    !
    !   First find the end of the current record
    !
       *swne_ l =dr ,0,10; !look for next NL
       *jcc_   8,<a>     ; !skip if one was not found
       *modd_  1         ; !skip DR over NL
a:     *std_   len       ; !save address in CUR POS

           if  len=x'58000000' then  -> report 153
    finish 

!Note: cur pos points to the start of the required record
     !     len is undefined
     !     DR  contains a descriptor from the required record to the end of the file

     f_arec= cur pos
           !
           !   Look for the end of the required record
           !
              *swne_ l =dr ,0,10
                 {if no NL is found then DR1 should equal F_END    }
                 {if a  NL is found then DR1 should point to the NL}

              *std_    len {and set CUR POS to the address}

     !
     !   Update the File Definition Table
     !
         f_recsize= cur pos - f_arec
           cur pos= cur pos + 1 unless  cur pos>= f_end
                                {unless no NL was found}
         f_cur rec= cur pos
         f_cur    = cur pos

     result =0

report 153: f_currec= cur pos
            f_cur   = cur pos
                    !
             result = 153
                     {153 => input ended}
finish 

 !NOT FILE INPUT SO MUST USE FULL CHARACTER INPUT ROUTE PROTEM
   CIST=COMREG(22)
   SELECTINPUT(F_DSNUM)
 !     %WHILE INPOS # 0 %THEN SKIPSYMBOL; !SKIP REST OF CURRENT RECORD
!     %FOR I=1,1,160 %CYCLE
!        NEXT = NEXTCH
!        %IF NEXTCH = EM %THEN SELECTINPUT(CIST {Current input stream}) !           %AND %RESULT = 153
!                                       !INPUT ENDED
!        %IF NEXT = 10 %THEN SKIPSYMBOL %AND %EXIT
!                                       !NL NOT NEEDED
!        READCH(SSOWN_STINBUFF(I))
!     %REPEAT
!     F_AREC = ADDR(SSOWN_STINBUFF(1))
!     F_RECSIZE = I-1
!     SELECTINPUT(CIST {Current input stream})
   ABFR=ADDR(SSOWN_STINBUFF(1))
   IOCP PARM(1)=ABFR
   IOCP PARM(3)=ADDR(L)
   I=NL
   CYCLE 
      START POS=F_CUR-F_CURREC
      R=IOCP(26,ADDR(IOCP PARM(1)))
      L=L-1
      IF  I>0 THEN  I=SSOWN_STINBUFF(L)
   REPEATUNTIL  START POS=0 OR  I=EM
   SELECT INPUT(CIST)
   IF  I=EM THENRESULT =153
   F_AREC=ABFR
   F_RECSIZE=L
FINISHELSESTART 
   IF  F_MODEOFUSE=2 START ; !SEQUENTIAL
      IF  F_CUR>=F_END THEN  F_CURSTATE=7 ANDRESULT =153
 !INPUT ENDED
      IF  SSOWN_IRGAP#0 START ; !V FORMAT
         F_RECSIZE=(BYTEINTEGER(F_CUR)<<8)!BYTEINTEGER(F_CUR+1)-SSOWN_IRGAP
 !TO AVOID ALIGNMENT PROBLEMS
      FINISH 
      F_AREC=F_CUR+SSOWN_IRGAP
      F_LASTREC=F_CUR; !FOR BACKSPACE
      F_CUR=F_AREC+F_RECSIZE
      F_TRANSFERS=F_TRANSFERS+1; !MUST KEEP COUNT IN CASE WRITE DONE LATER
   FINISHELSESTART ; !FORTRAN DIRECT ACCESS
      F_AREC=F_CONAD+F_DATASTART+F_RECSIZE*(F_DARECNUM-1)
      F_DARECNUM=F_DARECNUM+1; !NOW POINTS TO NEXT RECORD
!THE FOLLOWING CODE UPDATES THE ASSOCIATED VARIABLE. IF IT
!IS AN INTEGER*4 IT IS SIMPLE. IF IT IS AN INTEGER*2 IT IS HORRID
      ASVAR=F_ASVAR
      IF  F_FLAGS&4=0 THEN  INTEGER(ASVAR)=F_DARECNUM ELSESTART 
         BYTEINTEGER(ASVAR)=(F_DARECNUM>>8)&x'FF'
         BYTEINTEGER(ASVAR+1)=F_DARECNUM&x'FF'
      FINISH 
   FINISH 
FINISH 
RESULT =0
END ; ! INREC
!
!
SYSTEMINTEGERFN  OUTREC(INTEGER  LEN)
RECORD (FDF) NAME  F
INTEGER  COST,FE,FLAG,ASVAR,DR0,DR1
F==RECORD(SSOWN_CURRENT FD)
!*
!*EMAS  A RECORD OF LENGTH LEN IS IN THE BUFFER AT F_AREC
!*EMAS  AFTER DISPOSING OF THE RECORD ENSURE THAT F_AREC IS SET FOR
!*EMAS  THE NEXT OUTPUT RECORD
!*EMAS  %RESULT=169 IF THE OUTPUT FILE IS FULL
!*
IF  F_ACCESSROUTE=5 START ; !MAGNETIC TAPE OUTPUT
   F_RECSIZE=LEN
   MAGIO(SSOWN_CURRENTFD,3,FLAG)
   RESULT =FLAG
FINISH 
IF  F_ACCESSROUTE=10 THENRESULT =0; !NO ACTION FOR .NULL
IF  F_MODEOFUSE=1 START ; !STREAM OUTPUT
   COST=COMREG(23)
   SELECTOUTPUT(F_DSNUM)
 !FIRST DEAL WITH FORMAT
 ! EFFECTOR. CURRENTLY A
 ! NEWLINE IS PUT
 !OUT AT THE END OF EACH
 ! RECORD. ACTION ONLY
 ! REQUIRED FOR '0' ADD ANOTHER
 !NEWLINE AND '1' NEWPAGE.
   WHILE  LEN>1 AND  SSOWN_STOUTBUFF(LEN)=' ' CYCLE 
      LEN=LEN-1
   REPEAT 
!REMOVE TRAILING SPACES
 !MUST LEAVE AT LEAST ONE FOR NEWLINES
 !WITHIN FORMATS
   SSOWN_STOUTBUFF(LEN+1)=NL
   IF  F_DSNUM=SSOWN_OUTDEFAULT OR  F_FLAGS&16=16 START 
 !INTERPRET FE CHAS
      FE=SSOWN_STOUTBUFF(1)
      IF  FE='0' THEN  NEWLINE
      IF  FE='1' THEN  NEWPAGE
      IF  FE='+' THEN  FLAG=IOCP(24,13); !OVERWRITE LAST CHAR WITH RETURN
      DR0=LEN; !LENGTH OF TRANSFER
      DR1=ADDR(SSOWN_STOUTBUFF(2)); !ADDRESS OF FIRST BYTE TO BE SENT
   FINISHELSESTART ; !STRAIGHT TO FILE - DON'T INTERPRET FE
      DR0=LEN+1; !MUST INCLUDE NEWLINE
      DR1=ADDR(SSOWN_STOUTBUFF(1))
   FINISH 
   FLAG=IOCP(19,ADDR(DR0)); !PUT WHOLE RECORD
   SELECTOUTPUT(COST)
FINISHELSESTART 
   IF  F_MODEOFUSE=2 START ; !SEQUENTIAL OUTPUT
      IF  SSOWN_IRGAP#0 START ; !PUT IN RECORD LENGTH
         LEN=LEN+SSOWN_IRGAP; !RECORD LENGHT INCLUDES SSOWN_IRGAP
         BYTEINTEGER(F_CUR)<-LEN>>8
         BYTEINTEGER(F_CUR+1)=LEN&255
      FINISH 
      F_LASTREC=F_CUR; !FOR BACKSPACE
      F_CUR=F_CUR+LEN; !SSOWN_IRGAP ALREADY ADDED IN TO
 ! LEN ABOVE
      F_TRANSFERS=F_TRANSFERS+1
      WHILE  F_CUR+F_MAXREC+SSOWN_IRGAP>F_END CYCLE 
         EXTEND(F,FLAG)
         IF  FLAG#0 THENRESULT =169; !OUTPUT EXCEEDED
      REPEAT 
      F_AREC=F_CUR+SSOWN_IRGAP
   FINISHELSESTART ; !FORTRAN DIRECT ACCESS
      F_AREC=F_AREC+F_RECSIZE
!THE FOLLOWING CODE UPDATES THE ASSOCIATED VARIABLE. IF IT
!IS AN INTEGER*4 IT IS SIMPLE. IF IT IS AN INTEGER*2 IT IS HORRID
      F_DARECNUM=F_DARECNUM+1; !NOW POINTS TO NEXT RECORD
      ASVAR=F_ASVAR
      IF  F_FLAGS&4=0 THEN  INTEGER(ASVAR)=F_DARECNUM ELSESTART 
         BYTEINTEGER(ASVAR)=(F_DARECNUM>>8)&x'FF'
         BYTEINTEGER(ASVAR+1)=F_DARECNUM&x'FF'
      FINISH 
   FINISH 
FINISH 
RESULT =0
END ; ! OUTREC
!
ENDOFFILE