* 12/18/75 -- 13:00
* MODULE NAME: FIOSM
* NUMBER: 27B
* PURPOSE: PERFORM FILE I/O SERVICES
*
* ENTRY POINTS:
*
 DEF  S27WHDR,S27WTXT,S27WCPY,S27WFILE         *WRITE LINE TO FILE
 DEF  S27RHDR,S27RTXT,S27RCPY,S27RFILE         *READ LINE FROM FILE
 DEF  S27OHDR,S27OTXT,S27OCPY,S27OPEN         *OPEN FILE
 DEF  S27CHDR,S27CTXT,S27CCPY,S27CLOSE         *CLOSE FILE
 DEF S27DREC,S27DRHDR,S27DRTXT,S27DRCPY  *DELETE FILE RECORDS
 DEF  S27TXTFL,S27TXTLL             * FIND FIRST AND LAST LINES
 DEF  S27PFILE                      * POSITION FILE
         DEF      S27MTOPN,S27MTLST OPEN,POSITION MAG TAPE
         DEF      S27RDMT,S27WRMT   READ,WRITE MAG TAPE
         DEF      S27RNA            READ NAME/ADDRESS FILE
         DEF      S27ONA            OPEN NAME/ADDRESS FILE
         DEF      S27WNA            WRITE NAME/ADDRESS FILE
         DEF      S27CNA            CLOSE NAME/ADDRESS FILE
         DEF      S27OVPG           OPEN XGP FILE FOR 'GO'
         DEF      XGPFID            XGP FILE IDENTIFICATION
         DEF      KEYEDFLG          FILE KEYED FLAG
*
         SYSTEM   TEXTDEF
         SYSTEM   ITEMDEF
         INVDCBTBL
         INVCMDSTA
*
         REF      F:HDR,F:TXT,F:CPY   FILE I/O DCB'S
         REF      F:NA              NAME/ADDRESS FILE DCB
         REF      F:VP              XGP FILE DCB
         REF      F:MT              MAG TAPE DCB
         REF      S27EJLP           EJECT LINE PRINTER PAGE
         REF      S60XBAN           WRITE XGP BANNER
         REF      S36WFKEY,S36RFKEY,S36RFSEQ
         REF      S36PREC,S36DREC,S36OPEN,S36CLOSE
         REF      S36PFILE          POSITION FILE AT BOF OR EOF
*
         REF      S36MTOPN,S36MTNXT OPEN MAG TAPE
         REF      S36CLNXT          CLOSE MAG TAPE
         REF      PRECFPT,OPNFPT,CLSFPT,PFILEFPT
         REF      MTOPNFPT,MTNXTFPT MAG TAPE FPT'S
         REF      ARGSAVE,MODE,BUFSZ,RECKEY
         REF      J:PTIME           PROCESSOR EXECUTION TIME
         REF      J:UTIME           USER EXECUTION TIME
         PAGE
*
*
*
         DEF      27BP,27BD
*
27BP     EQU      %
         DATA     X'27B'            MODULE NUMBER
         DATA     X'121875'         DATE
         DATA     X'1300'           TIME
*
*
         TITLE    '** FIOSM(27B) **'
*
*
* FILE I/O ROUTINES
*
* WRITE FILE: BUF3 = BYTE ADDR OF OUTPUT BUFFER
*             AC1  = NUMBER OF CHARS TO WRITE
*             AC2  = RECORD KEY
*             AC3  = DCB ADDRESS
*
*
S27WFILE EQU      %
         SAVRTN
         LCI      3
         STM,AC1  ARGSAVE           SAVE INPUT PARAMETERS
*
         LW,D1    BUF3              GET BUFFER ADDR
         SLD,D1   -2                WORD ADDR IN D1
         SLS,DX1  -30               BYTE DISPLACEMENT IN DX1
*
         BAL,SRTN S36WFKEY          GO WRITE FILE
*
         RETURN
*
*
         PAGE
*
* WRITE HEADER, TEXT, COPY FILES
*
* ENTRY PARAMS SAME AS S27WFILE, EXCEPT AC3 NOT REQUIRED
*
*
S27WHDR  EQU      %
         LI,AC3   F:HDR             HEADER FILE DCB ADDR
         B        S27WFILE
*
S27WTXT  EQU      %
         LI,AC3   F:TXT             TEXT FILE DCB ADDR
         B        S27WFILE
*
S27WCPY  EQU      %
         LI,AC3   F:CPY             COPY FILE DCB ADDR
         B        S27WFILE
*
S27WNA   EQU      %
         LI,AC3   F:NA              NAME/ADDRESS FILE DCB ADDR
         B        S27WFILE
*
*
         PAGE
*
* READ FILE: BUF2 = BYTE ADDR OF INPUT BUFFER
*            AC1  = MAX. SIZE OF INPUT BUFFER
*            AC2  = KEY OR OFFSET (BYTE 0 = 3 FOR KEY, OTHERWISE
*                                  OFFSET IS IN 2ND HALFWORD AND
*                                  BYTE 0 = 0). SET TO KEY AFTER READ.
*            AC3  = DCB ADDRESS
*
* RETURN: SR3=0   NO ERROR
*            =1   KEY NOT FOUND
*            =2   BOF FOUND
*            =3   EOF FOUND
*            =-1  DATA LOST
*
*
S27RFILE EQU      %
         SAVRTN
         LCI      3
         STM,AC1  ARGSAVE           SAVE INPUT PARAMETERS
         CI,AC1   0                 TEST FOR ZERO-SIZE READ
         BG       NTZRO                NO, SKIP ADDRESS SET
         LI,BUF2  0                    YES, SET ADDRESS TO 0
NTZRO    EQU      %
*
*
         LI,SR3   0
         STW,SR3  ERRFLG            INITIALIZE ERROR FLAG
         LW,D1    BUF2              GET BUFFER ADDR
         SLD,D1   -2                WORD ADDR IN D1
         SLS,DX1  -30               BYTE DISPLACEMENT IN DX1
*
         LB,AC1   RECKEY            TEST BYTE ZERO OF KEY
         CI,AC1   3                 FIRST BYTE OF KEY = 3
         BNE      SEQREAD             NOT KEY, MUST BE SEQ. READ
*
         BAL,SRTN S36RFKEY          GO READ FILE
         CI,SR3   0                 TEST FOR ERROR RETURN
         BNE      CHKERR               YES, GO CHECK ERROR
         B        CHKSZ                NO, GO CHECK SIZE
*
         PAGE
*
*
SEQREAD  EQU      %
         LI,X1    1
         LH,AC1   RECKEY,X1         TEST 2ND HALFWORD FOR OFFSET
         BEZ      RDNXT                 ZERO, READ NEXT SEQUENTIAL REC.
         BGZ      FWDPREC               POSITIVE, MUST POSITION FILE
*
         LCH,AC1  RECKEY,X1             NEGATIVE, POSITION BACKWARD
         LI,D2    1                 SET UP M:PREC FPT WORD FOR REV
         B        PREC
*
FWDPREC  EQU      %
         LI,D2    0                 SET M:PREC FPT FOR FORWARD
*
PREC     EQU      %
         LI,AC3   WA(PRECFPT)       ADDR OF PREC FPT
         STW,AC3  FPTADDR
         PUT,D2   *#PRECFR          STORE FWD-REV FLAG IN FPT
*
         BAL,SRTN S36PREC           GO POSITION FILE RECORDS
         CI,SR3   0                 TEST ERROR FLAG
         BNE      CHKERR               SET, GO CHECK ERROR
*
*
         PAGE
*
RDNXT    EQU      %
         BAL,SRTN S36RFSEQ          READ FILE SEQUENTIALLY
         CI,SR3   0                 TEST FOR ERROR RETURN
         BNE      CHKERR               YES, GO CHECK ERROR
*
*
GETKEY   EQU      %
*
         GET,D2   *#KBUF            GET KBUF FROM DCB
         LW,AC2   *D2               GET ACTUAL KEY
         STW,AC2  RECKEY            STORE IN KEY VALUE
*
CHKSZ    EQU      %
         GET,D2   *#ARS             GET ARS FROM DCB(READ SIZE)
         STW,D2   BUFSZ
*
RFRTN    EQU      %
         LCI      3
         LM,AC1   ARGSAVE           RESTORE ARGUMENTS
         LW,SR3   ERRFLG            GET ERROR FLAG
         RETURN
         PAGE
*
* ERROR AND ABNORMAL CONDITIONS
*
CHKERR   EQU      %
         CI,SR3   40                TEST FOR ERROR OR ABN RETURN
         BGE      DCBERR            ERROR RETURN
*
         CI,SR3   7
         BE       DATALOST          BUFFER TOO SMALL
         CI,SR3   4
         BE       BOFERR            BOF HIT
*
EOFERR   EQU      %                 EOF FOUND
         LI,SR3   3
         B        ERTN
*
DATALOST EQU      %
         LI,SR3   -1
         STW,SR3  ERRFLG            SAVE ERROR CODE
         B        GETKEY            GET KEY ANYWAY
*
BOFERR   EQU      %
         LI,SR3   2
*
ERTN     EQU      %
         LI,AC1   0                 READ SIZE ZERO
         LI,AC2   0                 KEY NOT FOUND
         RETURN
*
*
DCBERR   EQU      %                 KEY NOT FOUND
         LI,SR3   1
         B        ERTN              GET NEXT KEY
*
*
         PAGE
*
* READ HEADER, TEXT, COPY FILES
*
* ENTRY PARAMS SAME AS S27RFILE, EXCEPT AC3 NOT REQUIRED
*
*
S27RHDR  EQU      %
         LI,AC3   F:HDR             HEADER FILE DCB ADDR
         B        S27RFILE
*
S27RTXT  EQU      %
         LI,AC3   F:TXT             TEXT FILE DCB ADDR
         B        S27RFILE
*
S27RCPY  EQU      %
         LI,AC3   F:CPY             COPY FILE DCB ADDR
         B        S27RFILE
*
S27RNA   EQU      %
         LI,AC3   F:NA              NAME/ADDRESS FILE DCB ADDR
         B        S27RFILE
*
*
         PAGE
*
*
* DELETE RECORD
*
* ENTRY: AC2=KEY
*        AC3=DCB ADDR
*
S27DREC  EQU      %
         SAVRTN
*
         LCI      2
         STM,AC2  RECKEY            SAVE INPUT PARAMS
         BAL,SRTN S36DREC           GO DELETE FILE RECORD
         RETURN
*
*
S27DRHDR EQU      %
         LI,AC3   F:HDR
         B        S27DREC
*
S27DRTXT EQU      %
         LI,AC3   F:TXT
         B        S27DREC
*
S27DRCPY EQU      %
         LI,AC3   F:CPY
         B        S27DREC
*
*
         PAGE
*
* OPEN DISK FILES
*
* ENTRY PARAMS:
*        AC1=MODE
*        AC3=DCB ADDR
*
*
S27OPEN  EQU      %
         SAVRTN
         LCI      3
         STM,AC1  ARGSAVE           SAVE ENTRY PARAMETERS
*
         LI,AC1   WA(OPNFPT)        ADDR OF FPT
         STW,AC1  FPTADDR           STORE
         LW,D1    MODE              GET MODE
         PUT,D1   *#FPTMODE         STORE IN FPT
*
         LI,D1    #KEYED            SET ORG TO KEYED
         LI,D2    #DIRECT           SET ACC TO DIRECT
         MTW,0    KEYEDFLG          IS FILE KEYED
         BNEZ     OPEN20            YES
         LI,D1    #CONSEC           SET ORG TO CONSECUTIVE
         LI,D2    #SEQUEN           SET ACC TO SEQUENTIAL
OPEN20   RES      0
         PUT,D1   *#FPTORG          STORE ORG
         PUT,D2   *#FPTACC          STORE ACC
         LI,D1    1
         STW,D1   KEYEDFLG          SET DEFAULT TO KEYED
         PAGE
*
MVFPTNM  EQU      %
         GET,D1   #NCDOCNM          GET NUMBER OF CHARS IN NAME
         PUT,D1   *#FPTNMNC         STORE IN FPT
         LW,AC1   D1
         AI,AC1   4
         SLS,AC1  -2                CALCULATE NUMBER OF WORDS USED
         PUT,AC1  *#FPTNMNW         STORE IN FPT
         GET,X1   #DOCNM            ADDR OF FIRST CHAR
         LI,X2    :EO(#FPTNMNC)     OFFSET OF NAME IN FPT
         AW,X2    FPTADDR           ADD WA OF FPT
         SLS,X2   2
         AI,X2    1                 CALCULATE BA OF FIRST CHAR
         STB,D1   X2                COUNT FOR MBS
         MBS,X1   0                 MOVE NAME TO FPT
*
*
         PAGE
*
         LI,X3    0                 INITIALIZE ACCT/PW COUNTER
         LW,AC1   L('    ')         GET BLANKS FOR ENTRIES
         LW,AC2   FPTADDR           ADDR OF FPT
         AI,AC2   :EO(#FPTAPNW)+2   ADD OFFSET FOR ACCT
*
MVACPW   EQU      %
         STW,AC1  *AC2              INITIALIZE 2ND WORD
         AI,AC2   -1
         STW,AC1  *AC2              INITIALIZE 1ST WORD
         JEZ,D1   (#NCACCT,X3),STWDS  TEST FOR ACCT/PW ENTRY
*
         GET,X1   #ACCT,X3          GET ADDR OF CHAR STRING
         LW,X2    AC2               WORD ADDR OF FPT ENTRY
         SLS,X2   2                 CALC BYTE ADDR
         STB,D1   X2                COUNT FOR MBS INST.
         MBS,X1   0                 MOVE ACCT/PW TO FPT
         LI,D1    2                 SET WORD COUNT TO 2
*
STWDS    EQU      %
         PUT,D1   *#FPTAPNW,X3      STORE WORD COUNT IN FPT
*
         CI,X3    0                 TEST ACCT/PW COUNTER
         BG       OFILE               >0, ACCT/PW DONE
         AI,X3    1                   =0, NOW DO PW
         AI,AC2   4                 SET TO WORD 2 OF PW
         B        MVACPW            REPEAT FOR PW
*
         PAGE
*
*
OFILE    EQU      %
*
         BAL,SRTN S36OPEN           GO OPEN FILE
*
OFRTN    EQU      %
         LCI      3
         LM,AC1   ARGSAVE           RESTORE INPUT PARAMETERS
         RETURN
*
*
*
* OPEN HEADER, TEXT, COPY FILES
*
*
S27OHDR  EQU      %
         LI,AC3   F:HDR             HEADER FILE DCB ADDR
         B        S27OPEN
*
S27OTXT  EQU      %
         LI,AC3   F:TXT             TEXT FILE DCB ADDR
         B        S27OPEN
*
S27OCPY  EQU      %
         LI,AC3   F:CPY             COPY FILE DCB ADDR
         B        S27OPEN
*
S27ONA   EQU      %
         LI,AC3   F:NA              NAME/ADDRESS FILE DCB ADDR
         B        S27OPEN
*
*
         PAGE
*
* CLOSE DISK FILES
*
* ENTRY PARAMS:
*        AC1=REL/SAVE CODE (1=REL,2=SAVE)
*        AC3=DCB ADDR
*
*
S27CLOSE EQU      %
         SAVRTN
         LI,AC2   WA(CLSFPT)        GET FPT ADDR
         STW,AC2  FPTADDR           SAVE FOR REL/SAVE STORE
         PUT,AC1  *#CRELSVE         STORE REL/SAVE CODE IN FPT
         STW,AC3  DCBADDR           STORE DCB ADDRESS
*
         BAL,SRTN S36CLOSE          GO CLOSE FILE
*
         RETURN
*
*
         PAGE
*
* CLOSE HEADER, TEXT, COPY FILES
*
*
S27CHDR  EQU      %
         LI,AC3   F:HDR
         B        S27CLOSE
*
S27CTXT  EQU      %
         LI,AC3   F:TXT
         B        S27CLOSE
*
S27CCPY  EQU      %
         LI,AC3   F:CPY
         B        S27CLOSE
*
S27CNA   EQU      %
         LI,AC3   F:NA
         B        S27CLOSE
*
*
         PAGE
*
* S27TXTFL,S27TXTLL -- FIND FIRST OR LAST LINE IN FILE
*
S27TXTFL EQU      %                 FIND FIRST LINE IN TEXT FILE
         SAVRTN
         LI,AC1   #BOFPFILE         SET PFILE WORD FOR BOF
         LI,AC3   F:TXT             DCB FOR TEXT FILE
         BAL,SRTN S27PFILE          POSITION FILE AT START
         LI,AC2   0                 SET READ FOR NEXT
         B        RDKEY             GO READ KEY
*
S27TXTLL EQU      %
         SAVRTN
         LI,AC1   #EOFPFILE         SET PFILE WORD FOR EOF
         LI,AC3   F:TXT             DCB FOR TEXT FILE
         BAL,SRTN S27PFILE          POSITION FILE AT END
         LI,AC2   -1                SET FOR READ PREVIOUS
*
RDKEY    EQU      %                 NOW READ TO GET KEY
         LI,AC1   0                 SET SIZE TO ZERO
         BAL,SRTN S27RTXT           READ TEXT FILE
         RETURN                     RETURN WITH KEY
*
*
         PAGE
*
* S27PFILE -- POSITION FILE AT EOF OR BOF
*
* ENTRY: AC1 = #BOFPFILE/#EOFPFILE FOR BOF/EOF
*        AC3 = DCB ADDRESS
*
S27PFILE EQU      %
         SAVRTN
*
         STW,AC3  DCBADDR           STORE DCB ADDRESS
         LI,AC3   PFILEFPT          GET PFILE FPT ADDR
         STW,AC3  FPTADDR           STORE FPT ADDR
         PUT,AC1  *FPT:PFILE        STORE EOF/BOF WORD IN FPT
         BAL,SRTN S36PFILE          POSITION FILE
*
         RETURN
*
*
         PAGE
*
*
* S27MTOPN -- OPEN MAG TAPE FILES
*
S27MTOPN EQU      %
         SAVRTN
*
         LI,AC3   MTOPNFPT          GET FPT ADDR
         STW,AC3  FPTADDR
         PUT,AC1  *#FPTMODE         SET FPT MODE
         LI,X2    :EO(FPT:MTSN)     GET OFFSET FOR INSN
         BAL,SRTN S27CHKSN          GO CHECK AND STORE SN
         CI,SR3   0                 TEST FOR ILLEGAL SN
         BNE      RTNMTOPN             YES, RETURN
*
         GET,X1   #DOCNM            GET ADDR OF FILE NAME
         LI,X2    :EO(FPT:MTNCLB)   GET OFFSET OF LABEL VLP
         AW,X2    FPTADDR           ADD FPT ADDR
         SLS,X2   2                 CONVERT TO BA
         AI,X2    1
         GET,AC1  #NCDOCNM          GET SIZE OF NAME
         STB,AC1  X2                COUNT FOR MBS
         MBS,X1   0                 MOVE NAME TO FPT
*
*
*
         PAGE
*
*
         PUT,AC1  *FPT:MTNCLB       STORE NAME SIZE
         SLS,AC1  -2                CONVERT SIZE TO WORDS
         AI,AC1   1
         PUT,AC1  *FPT:MTNWLB       STORE WORD COUNT
         BAL,SRTN S36MTOPN          OPEN MAG TAPE FILE
*
RTNMTOPN EQU      %
         RETURN
*
*
         PAGE
*
* S27MTLST -- POSITION MAG TAPE AT LAST FILE
*
*
S27MTLST EQU      %
         SAVRTN
*
         LI,AC3   MTNXTFPT          GET FPT ADDR
         STW,AC3  FPTADDR
         LI,AC1   1                 SET MODE FOR SN CHECK
         LI,X2    :EO(FPT:MTSN)     GET OFFSET FOR SN
         BAL,SRTN S27CHKSN          GO CHECK AND STORE SN
         CI,SR3   0                 TEST FOR ILLEGAL SN
         BNE      RTNMTLST             YES, RETURN
*
PSTNMTLP EQU      %
         BAL,SRTN S36MTNXT          OPEN NEXT FILE ON MT
         CI,SR3   0                 TEST FOR OPEN
         BNE      RTNMTLST             NO, RETURN
         BAL,SRTN S36CLNXT          CLOSE MT FILE
         B        PSTNMTLP          OPEN NEXT MT FILE
*
RTNMTLST EQU      %
         RETURN
*
*
         PAGE
*
* S27RDMT,S27WRMT -- READ, WRITE MAG TAPE
*
*
S27RDMT  EQU      %
*
         LI,AC3   F:MT              GET ADRR OF DCB
         LI,AC2   0                 SET KEY FOR READ NEXT
         B        S27RFILE          GO READ NEXT RECORD
*
*
S27WRMT  EQU      %
*
         LI,AC3   F:MT              GET ADDR OF DCB
         B        S27WFILE          GO WRITE RECORD
*
*
         PAGE
*
* S27CHKSN -- CHECK AND STORE MAG TAPE SN
*
*
S27CHKSN EQU      %
         SAVRTN
*
         GET,D1   #NCNM             GET SIZE OF SN
         CI,D1    4                 TEST FOR TOO BIG
         BG       SNERROR              YES, ERROR
         AW,X2    FPTADDR           CALC ADDR OF SN
         AI,AC1   -1                CALC INSN/OUTSN
         SLS,AC1  1
         AW,X2    AC1
         SLS,X2   2                 CONVERT TO BA
*
         INSCHAR  #BLANK,*X2,4      INITIALIZE SN
         GET,X1   #NM               GET BA OF SN
         STB,D1   X2                COUNT FOR MBS
         MBS,X1   0                 MOVE SN TO FPT
         LI,SR3   0                 RESET ERROR RETURN
         B        RTNCHKSN          RETURN
*
SNERROR  EQU      %
         LI,SR3   -1                SN ERROR
         LI,AC1   32                'ILLEGAL OPTION' MSG
*
RTNCHKSN EQU      %
         RETURN
*
         PAGE
*
*
* S27OVPG -- OPEN XGP PRINT FILE FOR 'GO'
*
S27OVPG  RES      0
         SAVRTN
         LW,AC1   J:PTIME           GET A 'UNIQUE' NUMBER
         AW,AC1   J:UTIME
         STW,AC1  XGPFID1           STORE AS PART OF FILE NAME
         LI,D1    8
         PUT,D1   #NCDOCNM          SET UP NUMBER OF CHAR IN NAME
         LI,D1    BA(XGPFID)
         PUT,D1   #DOCNM            SET UP BYTE ADDR OF NAME
         LI,D1    0
         PUT,D1   #NCACCT           SET UP NO ACCOUNT NUMBER
         PUT,D1   #NCGETPW          SET UP NO PASSWORD
OVPG10   RES      0
         LI,AC1   #INOUT            SET MODE = 'INOUT'
         LI,AC3   F:VP              SET UP DCB ADDRESS
         BAL,SRTN S27OPEN           TRY TO OPEN FILE
         CI,SR3   3                 DOES FILE ALREADY EXIST
         BE       OVPG20            NO
         LI,AC1   #SAVE             SET MODE = SAVE
         LI,AC3   F:VP              SET UP DCB ADDRESS
         BAL,SRTN S27CLOSE          CLOSE FILE WITH SAVE
         MTW,1    XGPFID1           GET A NEW FILE NAME
         B        OVPG10
OVPG20   RES      0
         LI,AC1   #OUT              SET MODE = OUT
         LI,AC3   F:VP              SET UP DCB ADDRESS
         BAL,SRTN S27OPEN           OPEN FILE IN 'OUT' MODE
         BAL,SRTN S60XBAN           WRITE XGP BANNER
         BAL,SRTN S27EJLP           EJECT LINE PRINTER PAGE
         RETURN
         PAGE
*
* LOCAL VARIABLES
*
27BD     CSECT    0
*
ERRFLG   RES      1                 SAVE ERROR FLAG
KEYEDFLG DATA     1                 DEFAULT = KEYED FILE
XGPFID   RES      0                 XGP FILE IDENTIFICATION
         GEN,24,8 'XGP',0
XGPFID1  RES      1
*
*
         USECT    #PLOC             CSECT FOR LITERALS
         END
