.TITLE DIROPE - Open Files for Read/Write .IDENT /1.1/ .ENABL LC ;+ ; ; Free software BY ; Project Software & Development, Inc. ; ; This software is furnished for free and may be used and copied as ; desired. This software or any other copies thereof may be provided ; or otherwise made available to any other person. No title to and ; ownership of the software is hereby transferred or allowed. ; ; The information in this software is subject to change without notice ; and should not be construed as a commitment by PROJECT SOFTWARE ; AND DEVELOPMENT, INC. ; ; PROJECT SOFTWARE assumes no responsibility for the use or reliability ; of this software on any equipment whatsoever. ; ; Project Software & Development, Inc. ; 14 Story St. ; Cambridge, Ma. 02138 ; 617-661-1444 ; ; ; Title: DIROPE ; Author: Robin Miller ; Date: February 19, 1985 ; ; Description: ; ; This module is called to open a file for read or write. It ; does all the neccessary syntax checking using the CSI routines, parsing ; of the file specification, and opening of the file. It presumes the FDB ; is setup with all the required information such as the LUN, the EFN, the ; record attributes, and the access mode. ; ; Modification History: ; ; March 8, 1985 by Robin Miller. Edit (01), Version 1.1 ; If looking up file by file ID, check for CTRL/C being typed. ; ;- .ENABL AMA ; DEBUG = 0 ; Define for DDT debugging. .MCALL CSI$, CLOSE$, FCSBT$, FDOFF$, NBOFF$ ; Bit and offset definitions: CSI$ ; Define the CSI offsets. .IF NDF DEBUG FCSBT$ ; Define the FCS bits locally. FDOFF$ DEF$L ; Define the FDB offsets locally. NBOFF$ DEF$L ; Define the FNB offsets locally. .IFF FCSBT$ DEF$G ; Define the FCS bits globally. FDOFF$ DEF$G ; Define the FDB offsets globally. NBOFF$ DEF$G ; Define the FNB offsets globally. .ENDC ; .IF NDF DEBUG ; Define offsets for the dataset descriptor block: N.DEVD == 0 ; The device name descriptor. N.DIRD == 4 ; The directory descriptor. N.FILD == 10 ; The file name descriptor. .SBTTL Command String Interpreter (CSI) block. ; ; Scratch storage for wild UIC logic consists of a file name block ; followed by the following extra words. Also defined in PARSE.MAC. ; ; N.WNM1 = S.FNB ; 2 words for RAD50 non wild card ; ; project or programmer name. ; N.WNM2 = N.WNM1+4 ; 6 words of string storage for ; ; ASCII form of current directory name. S.WUIC = S.FNB+16. ; NO. OF BYTES IN SCRATCH AREA NB.SFL = NB.SD1!NB.SD2!NB.SNM!NB.STP!NB.SVR ; All wildcard bits. WILDCH = 124300 ; Radix-50 for wildcard "$ ". INCSI1::.BLKB C.SIZE ; CSI buffer for input OUTCSI::.BLKB C.SIZE ; & one output file. INFNB1::.BLKB S.FNB+S.WUIC ; FNB for wildcard UIC's. INDSD1::.BLKW 6 ; Wildcard dataset descriptor. .SBTTL OPEN - Open a file for read or write access. ;+ ; ; OPEN - Open a file for read or write access. ; ; This routine is used to open a single file for either read or write. If ; the file is already open on entry, it will be closed automatically. If ; the file access offset (F.FACC) in the FDB is not setup, it will be filled ; with either shared read (FO.RD!FA.SHA) or write without supercede ; (FO.WRT!FA.NSP). The Command String Interpreter (CSI) routines are used ; to check for syntax errors. If no error is returned from the CSI routines, ; then the file is openned for either read or write. ; ; The error code IE.BNM (bad file name) is returned if errors are encountered ; by the CSI routines. ; ; Inputs: ; R0 = The FDB address. ; R1 = The file specification address. ; R5 = The file entry address. ; ; Outputs: ; C bit clear/set = success/failure. ; All registers are preserved. ; ;- OPENR:: TSTB F.FACC(R0) ; Is the file access setup ? BNE OPEN ; If NE, yes. MOVB #FO.RD!FA.SHR,F.FACC(R0) ; No, setup for shared read. BR OPEN ; Continue ... OPENW:: TSTB F.FACC(R0) ; Is the file access setup ? BNE OPEN ; If NE, yes. MOVB #FO.WRT!FA.NSP,F.FACC(R0) ; No, setup for write/no supercede. BR OPEN ; Continue ... .ENABL LSB OPEN: CALL $SAVAL ; Save all registers. CALL CKOPEN ; If the file is open, close it. CALL CLNAME ; Clear the file name from the FNB. CALL CHKCSI ; Check the command syntax. BCS 20$ ; If CS, illegal syntax. ; Parse the file name and open the file for read or write. AOPEN:: ; Alternate open entry point. MOV O.FNB(R5),R1 ; Copy the FNB address. MOV O.CSI(R5),R3 ; Copy the CSI block address. ; ; When opening files for a read operation, specified we use the ; wildcard parsing routine. ; BITB #FO.RD,F.FACC(R0) ; Opening a file for read access ? BNE OPWILD ; If NE, yes (do wildcard parse). SEC ; Presume wildcards or mulitple files. BITB #CS.MOR!CS.WLD,C.STAT(R3) ; Wildcards or multiple files ? BNE 20$ ; If NE, yes (illegal for write). 10$: MOV F.DSPT(R0),R2 ; Address of dataset descriptor. MOV F.DFNB(R0),R3 ; Address of the default FNB. CALL .PARSE ; Parse the file specification. BCS 20$ ; If CS, we had an error. CALL .OPFNB ; Open the file for read/write. 20$: RETURN .DSABL LSB .SBTTL OPWILD - Setup for wildcard parsing. ;+ ; ; OPWILD - Setup for wildcard parsing. ; ; This routine is used to setup for wildcard parsing. The dataset descriptor ; pointed to by the FDB is first copied to the wildcard dataset descriptor. ; This is used when wildcards are specified in the project or programmer ; number (UIC). On subsequent calls to the OPNEXT routine, either the next ; file specification is returned, or the carry bit is set to indicate an FCS ; failure (only error expected is IE.NSF). ; ; Inputs: ; R0 = The FDB address. ; R1 = The FNB address. ; R5 = The file entry address. ; ; Outputs: ; C bit clear/set = success/failure. ; Presumes registers saved by OPEN routine. ; ;- OPWILD: MOV #6,R2 ; Size of the dataset descriptor. MOV F.DSPT(R0),R3 ; Addess of the dataset descriptor. MOV O.WDSD(R5),R4 ; Copy the wildcard dataset address. ; Copy the dataset descriptor to the wildcard descriptor. 10$: MOV (R3)+,(R4)+ ; Copy the dataset descriptor. SOB R2,10$ ; Loop until done. MOV O.WDSD(R5),R4 ; Restore the dataset address. MOV N.DIRD(R4),R2 ; Copy the directory string size. BEQ 30$ ; If EQ, none was specified. MOV N.DIRD+2(R4),R3 ; Copy the directory string address. MOV O.WFNB(R5),-(SP) ; Copy the wildcard FNB address. ADD #N.WNM2,(SP) ; Set address for directory string. MOV (SP),N.DIRD+2(R4) ; Save the new directory string addr. MOV (SP)+,R4 ; Address to store directory string. ; Copy the directory descriptor. 20$: MOVB (R3)+,(R4)+ ; Copy directory string to scratch. SOB R2,20$ ; Loop until done. 30$: MOV F.DSPT(R0),R2 ; Address of the dataset descriptor. MOV F.DFNB(R0),R3 ; Address of the default FNB. MOV O.WFNB(R5),R4 ; Copy the wildcard FNB address. CALL .WPARS ; Do the wildcard file parsing. BCS 40$ ; If CS, failure. CALL CKWILD ; Check for wildcard selection. CALL SVNAME ; Save the Radix-50 file name. MOV N.FVER(R1),O.WVER(R5) ; Save the original version number. BR OPNXTA ; Now go look up the first file. 40$: RETURN .SBTTL OPNEXT - Open the next wildcard file. ;+ ; ; OPNEXT - Alternate entry to open next file for wildcards. ; OPNXTA - Alternate entry to open after calling .PARSE routine. ; ; Inputs: ; R0 = The FDB address. ; R5 = The file entry address. ; ; Outputs: ; C bit clear/set = sucess/failure. ; ;- .ENABL LSB OPNEXT::CALL $SAVAL ; Save all registers. CALL CKOPEN ; If the file is open, close it. 10$: MOV O.FNB(R5),R1 ; Copy the FNB address. MOVB #IE.NSF,F.ERR(R0) ; Presume "No such file" error. BIT #NB.SFL,N.STAT(R1) ; Are there any wildcards ? BEQ 90$ ; If EQ, no (we're all done). CALL RSNAME ; Restore the Radix-50 file name. OPNXTA::MOV O.WFNB(R5),R2 ; Copy the wildcard FNB address. MOV N.FVER(R1),N.FID+4(R1) ; Copy the old version number. MOV O.WVER(R5),N.FVER(R1) ; Restore original version number. CALL .FNDNX ; Go find the next file. BCS 90$ ; If CS, we failed. ; If a file ID was specified, go compare with current. BIT #B.BFID,STATUS ; Was the file ID specified ? BEQ 20$ ; If EQ, no. BIT #B.CTRC,STATUS ; Does the user want to exit ? (01) BNE 90$ ; If NE, yes (return failure). (01) CALL CHKFID ; Yes, check for the file ID. BCS 10$ ; If CS, wrong file ID. 20$: BIT #S.FIND,O.STAT(R5) ; Should we find the file only ? BNE 100$ ; If NE, yes (skip the open). CALL .OPFNB ; Open the file for read access. BR 100$ ; Use common return ... 90$: SEC ; Show failure. 100$: RETURN .DSABL LSB .SBTTL OPMORE - Open the next file specification. ;+ ; ; OPMORE - Open the next file specification. ; ; This routine is called when there is another file specification to be ; parsed. If parsed successfully, we open the file(s), otherwise failure ; status is returned. ; ; Inputs: ; R0 = The FDB address. ; R5 = The file entry address. ; ; Outputs: ; C bit set if syntax error from parsing. ; ; All registers are preserved. ; ;- OPMORE::CALL $SAVAL ; Save all registers. CALL SETDNB ; Setup the new default name block. CALL DOCSI2 ; Parse next file specification. BCS 10$ ; If CS, syntax error. JMP AOPEN ; Else, try to open the file(s). 10$: RETURN .SBTTL DOCSI2 - Call command semantic parser. ;+ ; ; DOCSI2 - Call the command semantic parser. ; ; Inputs: ; R0 = The FDB address. ; R5 = The file entry address. ; ; Outputs: ; C bit clear/set = success/failure. ; ; All registers are preserved. ; ;- DOCSI2::JSR R2,$SAVVR ; Save R0 - R2. CLR F.ERR(R0) ; Initialize the FCS error code. BISB #IE.BNM,F.ERR(R0) ; Preset to "Bad file name" error. MOV O.CSI(R5),R0 ; Copy the CSI block address. CALL .CSI2 ; Parse the file specification. RETURN .SBTTL CHKFID - Check for specified file ID. ;+ ; ; CHKFID - Check for specified file ID. ; ; This routine compares the current file ID with the specified file ID ; using the /FID qualifier. ; ; Inputs: ; R0 = The file descriptor address. ; R1 = The file name block address. ; ; Outputs: ; C bit clear/set = match/no match. ; ; All registers are preserved. ; ;- CHKFID::JSR R2,$SAVVR ; Save R0 - R2. MOV #TMPFID,R0 ; Set address of file ID. MOV R1,R2 ; Copy the FNB address. CMP (R0)+,(R2)+ ; Compare the first word. BNE 90$ ; If NE, no match. CMP (R0)+,(R2)+ ; specified FID BNE 90$ ; If NE, no match. CMP (R0)+,(R2)+ ; into the FNB. BNE 90$ ; If NE, no match. BIC #NB.SFL,N.STAT(R1) ; Don't need to look further. BR 100$ ; Use common return ... 90$: SEC ; Show no file ID match. 100$: RETURN .SBTTL CKOPEN - Check for open file. ;+ ; ; CKOPEN - Check for open file and close it if open. ; ; Inputs: ; R0 = The FDB address. ; ; Outputs: ; All registers are preserved. ; ;- CKOPEN: TST F.BDB(R0) ; Is the file already open ? BEQ 10$ ; If EQ, no. CLOSE$ R0 ; Yes, close it. 10$: RETURN .SBTTL CKWILD - Check for wild card selection. ;+ ; ; CKWILD - Check for wild card selection. ; ; This routine is used to fill in wildcards for any part of file name ; which was not specified. ; ; Inputs: ; R0 = The file descriptor address. ; R1 = The file name block address. ; ; Outputs: ; All registers are preserved. ; ;- CKWILD: JSR R2,$SAVVR ; Save R0 - R2. MOV R1,R2 ; Copy the FNB address. ADD #N.STAT,R2 ; Point to the status word. BIT #NB.VER,(R2) ; Was an version specified ? BNE 10$ ; If NE, yes (use it). BIS #NB.SVR,(R2) ; No, select all versions. 10$: BIT #NB.TYP,(R2) ; Was a file type specified ? BNE 20$ ; If NE, yes (use it). BIS #NB.STP,(R2) ; No, select all file types. MOV #WILDCH,N.FTYP(R1) ; Set the type field to "*". 20$: BIT #NB.NAM,(R2) ; Was a file name specified ? BNE 30$ ; If NE, yes. BIS #NB.SNM,(R2) ; No, select a file names. MOV #WILDCH,N.FNAM(R1) ; Set the name field to "*". 30$: RETURN .SBTTL CLNAME - Clear the file name in the FNB. ;+ ; ; CLNAME - Clear the file name in the FNB. ; ; This routine clears the file name (if any) in the FNB so that old file ; name information is not used when constructing an ASCII file name for ; error messages if a syntax error occurs in the CSI routines. ; ; Inputs: ; R0 = The FDB address. ; ; Outputs: ; All registers are preserved. ; ;- CLNAME: JSR R2,$SAVVR ; Save R0 - R2. ADD #F.FNB+N.FNAM,R0 ; Set address of the file name. MOV #5.,R1 ; Set size in words of file name. 10$: CLR (R0)+ ; Clear the file name. SOB R1,10$ ; And loop until done. RETURN .SBTTL CHKCSI - Check file name using CSI routines ;+ ; ; CHKCSI - Use CSI routines to check the filspc syntax. ; ; Inputs: ; R0 = The FDB address. ; R1 = File specification address. (terminated by NULL or ). ; R5 = The file entry address. ; ; Outputs: ; C bit clear/set = success/failure. ; All registers are preserved. ; ;- CHKCSI::CALL $SAVAL ; Save all registers. ;*** CLR F.DSPT(R0) ; Clear the dataset pointer. CLR F.ERR(R0) ; Initialize the FCS error code. BISB #IE.BNM,F.ERR(R0) ; Preset to "Bad file name" error. MOV O.CSI(R5),R3 ; Copy the CSI block address. MOV R3,F.DSPT(R0) ; Setup the dataset ADD #C.DSDS,F.DSPT(R0) ; descriptor address. ; Clear the CSI block so old information isn't used. MOV #C.SIZE/2,R2 ; SET THE CSI SIZE IN WORDS 10$: CLR (R3)+ ; CLEAR THE CSI BLOCK SOB R2,10$ ; BR UNTIL DONE MOV O.CSI(R5),R0 ; Set the CSI block address. MOV R1,C.CMLD+2(R0) ; Save the filspc address. ; Find the end of the file specification (either CR or NULL). 20$: CMPB (R1),#CR ; End of the file name ? BEQ 30$ ; If EQ, yes. TSTB (R1)+ ; End of the file name ? BNE 20$ ; If NE, nope (loop). DEC R1 ; Adjust for the null byte. ; Calculate the length of the file specification. 30$: SUB C.CMLD+2(R0),R1 ; Calculate the byte count. BEQ 50$ ; If EQ, don't do CSI parsing. MOV R1,C.CMLD(R0) ; Now save it. ; Check the syntax of the file specification. CALL .CSI1 ; Check the string syntax. BCS 60$ ; If CS, bad syntax. MOVB #CS.OUT,(R0) ; Set for output file parsing. CALL .CSI2 ; Parse the file specification. BCS 60$ ; If CS, syntax error. 50$: CLC ; Show success. RETURN 60$: SEC ; Show syntax error. RETURN .SBTTL RSNAME - Restore the Radix-50 file name. ;+ ; ; RSNAME - Restore the Radix-50 file name. ; ; Inputs: ; R1 = The FNB address. ; R5 = The file entry address. ; ; Outputs: ; All registers are preserved. ; ;- RSNAME::CALL $SAVAL ; Save all registers. ADD #N.FNAM,R1 ; Point to the file name. ADD #O.RNAM,R5 ; Point to area to save name. MOV #4,R0 ; Set the loop count. 10$: MOV (R5)+,(R1)+ ; Copy the radix-50 name/type. SOB R0,10$ ; Loop until we're done. RETURN .SBTTL SVNAME - Save the Radix-50 file name. ;+ ; ; SVNAME - Save the Radix-50 file name. ; ; This routine is used to save the file name block when doing special ; wildcard lookup (* and/or %). The file name block must be reset before ; doing the next wildcard lookup. ; ; Inputs: ; R1 = The FNB address. ; R5 = The file entry address. ; ; Outputs: ; All registers are preserved. ; ;- SVNAME::CALL $SAVAL ; Save all registers. ADD #N.FNAM,R1 ; Point to the file name. ADD #O.RNAM,R5 ; Point to area to save name. MOV #4,R0 ; Set the loop count. 10$: MOV (R1)+,(R5)+ ; Copy the radix-50 name/type. SOB R0,10$ ; Loop until we're done. RETURN .SBTTL SETDNB - Setup the default name block. ;+ ; ; SETDNB - Setup the default name block. ; ; This routine is used to copy the radix-50 file name and file type ; to the default file name block so that multiple file specifications ; will default properly (i.e., DIR.MAC, DIRNAM). ; ; Inputs: ; R0 = The FDB address. ; R5 = The file entry address. ; ; Outputs: ; All registers are preserved. ; ;- SETDNB: JSR R2,$SAVVR ; Save R0 - R2. MOV O.FNB(R5),R1 ; Copy file name block address. ADD #N.FNAM,R1 ; Point to the file name field. MOV F.DFNB(R0),R2 ; Copy default file name address. ADD #N.FNAM,R2 ; Point to the file name field. MOV #4,R0 ; Set the number of words to copy. 10$: MOV (R1)+,(R2)+ ; Copy the radix-50 name/type. SOB R0,10$ ; Loop until we're done. RETURN .END