.TITLE OPEN - Open Files for Read/Write .IDENT /3.0/ .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: OPEN ; Author: Robin Miller ; Date: July 1, 1983 ; ; Description: ; ; This module is called to open a file for read or write. It ; will do all the neccessary syntax checking and parsing of the file ; specification into the File Descriptor Block (FDB). 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: ; ;- .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. CSIBLK::.BLKB C.SIZE ; Allocate a CSI buffer. .EVEN WLDFNB::.BLKB S.FNB+S.WUIC ; FNB for wildcard UIC's. WLDDSD::.BLKW 6 ; Wildcard dataset descriptor. WLDVER::.WORD 0 ; Save original verision # here. .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. ; ; 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. .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. 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. 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 R0,R1 ; Copy the FDB address. ADD #F.FNB,R1 ; Point to the FNB address. ; When opening files for a read operation, if no wildcards were ; specified we use the normal parsing, otherwise we use the ; wildcard parsing routine. BITB #CS.WLD,CSIBLK+C.STAT ; Any wildcards in file specification ? BEQ 10$ ; If EQ, no (use normal parse). 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,CSIBLK+C.STAT ; 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 ; Else, open the file for 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. ; ; 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 #WLDDSD,R4 ; Address of the wildcard dataset. ; Copy the dataset descriptor to the wildcard descriptor. 10$: MOV (R3)+,(R4)+ ; Copy the dataset descriptor. SOB R2,10$ ; Loop until done. MOV WLDDSD+N.DIRD,R2 ; Get the length of the descriptor. BEQ 30$ ; If EQ, none was specified. MOV WLDDSD+N.DIRD+2,R3 ; Set address of directory string. MOV #WLDFNB+N.WNM2,R4 ; Address to store directory string. MOV R4,WLDDSD+N.DIRD+2 ; Set the new string address. ; 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 #WLDFNB,R4 ; Address of the wildcard FNB. CALL .WPARS ; Do the wildcard file parsing. BCS 40$ ; If CS, failure. MOV N.FVER(R1),WLDVER ; Save the original version number. BR OPNEXT ; 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. ; ; Inputs: ; R0 = the FDB address. ; ; Outputs: ; C bit clear/set = sucess/failure. ; ;- OPNEXT::CALL $SAVAL ; Save all registers. CALL CKOPEN ; If the file is open, close it. MOV R0,R1 ; Copy the FDB address. ADD #F.FNB,R1 ; Set up 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 30$ ; If EQ, no (we're all done). MOV #WLDFNB,R2 ; Address of the wildcard FNB. MOV N.FVER(R1),N.FID+4(R1) ; Copy the old version number. MOV WLDVER,N.FVER(R1) ; Restore original version number. CALL .FNDNX ; Go find the next file. BCS 20$ ; If CS, we failed. CALL .OPFNB ; Open the file for read access. RETURN ; ; On a "Privilege violation" error, we presume no access to the directory ; file (UFD). We don't clear the wildcard bits to allow a find of the ; next directory. ; 20$: ;*** I hope this doesn't hurt me. *** ;*** ;*** CMPB #IE.PRI,F.ERR(R0) ; Is error "Privilege violation" ? ;*** BEQ 30$ ; If EQ, yes (presume no UFD access). ;*** BIC #NB.SFL,N.STAT(R1) ; Disable all the wildcard bits. 30$: SEC ; Show failure. RETURN .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. ; ; Outputs: ; C bit set if syntax error from parsing. ; ; All registers are preserved. ; ;- OPMORE::CALL $SAVAL ; Save all registers. CLR F.ERR(R0) ; Initialize the FCS error code. BISB #IE.BNM,F.ERR(R0) ; Preset to "Bad file name" error. MOV R0,R5 ; Copy the FDB address. MOV #CSIBLK,R0 ; Set address of the CSI block. CALL .CSI2 ; Parse the file specification. BCS 10$ ; If CS, syntax error. MOV R5,R0 ; Else, restore the FDB address. JMP AOPEN ; And try to open the file(s). 10$: 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 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: CALL $SAVAL ; Save all registers. 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 ). ; ; Outputs: ; C bit clear/set = success/failure. ; All registers are preserved. ; ;- CHKCSI: CALL $SAVAL ; Save all registers. MOV R0,R4 ; Copy the FDB address. MOV #CSIBLK+C.DSDS,F.DSPT(R4) ; Setup dataset descriptor address. ; Clear the CSI block so old information isn't used. MOV #C.SIZE/2,R2 ; SET THE CSI SIZE IN WORDS MOV #CSIBLK,R3 ; SET ADDRESS OF CSI BLOCK 10$: CLR (R3)+ ; CLEAR THE CSI BLOCK SOB R2,10$ ; BR UNTIL DONE MOV #CSIBLK,R0 ; ADDRESS OF CSI BLOCK 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 .END