.NLIST TOC,SYM .TITLE $OPEN .SBTTL ULBLIB 007 - Open File .IDENT \V01.01\ .PSECT .LIBC. .ENABL LC,GBL ; Copyright (c) 1998 by Mentec, Inc., Nashua, NH. ; All rights reserved ; ; This software is furnished under a license for use only on a ; single computer system and may be copied only with the ; inclusion of the above copyright notice. This software, or ; any other copies thereof, may not be provided or otherwise ; made available to any other person except for use on such ; system and to one who agrees to these license terms. Title ; to and ownership of the software shall at all times remain ; in Mentec, Inc. ; ; The information in this document is subject to change without ; notice and should not be construed as a commitment by Digital ; Equipment Corporation, or Mentec, Inc. ; ; Digital and Mentec assume no responsibility for the use or ; reliability of its software on equipment which is not supplied ; by Digital or Mentec, and listed in the Software Product ; Description. ; CG01 03-Mar-79 Add buffer size checks for random access I/O with user ; specified buffers. ; CG02 04-Mar-79 Add file protection check to .ENTER code. ; ; V01.01 29-Aug-91 MBG Added check for invalid directory following ; .LOOKUP or .ENTER ;+ ; $OPEN ; The Open File routine takes whatever action is neccessary to open a file ; for input or output (handler fetches and such). A call to $INIDM must have ; been made prior to the first call to $OPEN. ; ; R0 -> File Descriptor Block (FDB) ; R1 -> free memory listhead ; ; CALL $OPEN ; ; C-bit = 0 => success ; R0, R1 = random ; ; C-bit = 1 => failure ; Offset F.ERR in the FDB contains the error code. ;- .MCALL .DSTAT, .FETCH, .HERR, .SERR, .PURGE S$EERB = 52 $OPEN:: JSR R5,$SAVRG ;Save non-volatile registers MOV R1,R4 ;Copy -> free memory listhead MOV R0,R1 ;Copy -> FDB MOV R0,R5 ; " ADD #F.DS.,R1 ;Point to the .DSTATUS return block .DSTAT R1,F.OPNM(R5) ;Do the .DSTATUS BCC 1$ ;Branch if no error MOV #FE.ILD,R0 ;Illegal device BR 10$ ; 1$: TST F.DHEP(R5) ;Is the handler in core? BNE 4$ ;Branch if so MOV R4,R0 ;Point to free memory listhead MOV F.DVHS(R5),R1 ;Get the size of the handler CALL $RQCB ;Request a core block for the handler BCC 3$ ;Got it. 2$: MOV #FE.NOM,R0 ;Insufficient memory BR 10$ ; 3$: MOV R0,F.HNLD(R5) ;Save the handler load address MOV R1,F.HSIZ(R5) ; and the actual amout of memory allocated .SERR ;Do soft error .FETCH F.HNLD(R5),F.OPNM(R5) ;Fetch the handler BCC 4$ ;Branch if no error MOV #FE.FER,R0 ;Fetch error BR 10$ ; 4$: .SERR ;Soft errors please MOV R5,R0 ;Copy -> FDB EMT 375 ;Issue .ENTER or .LOOKUP BCC 11$ ;Branch if no error MOVB @#S$EERB,R0 ;Copy the error byte (with sign extension) BPL 7$ ;Branch if normal error CMP #-3,R0 ;Directory io error? BNE 5$ ;Branch if not MOV #FE.DIO,R0 ;Remember it BR 10$ ; 5$: CMP #-6,R0 ;Directory full? BNE 6$ ;Branch if not MOV #FE.DFL,R0 ;Remember the error BR 10$ ;Go give it 6$: CMP R0,#-14 ;Invalid directory? BNE 65$ ;Nope... MOV #FE.IVD,R0 ;Yes, remember the error BR 10$ 65$: MOV #FE.SYS,R0 ;Must be a system error BR 10$ ; 7$: BNE 8$ ;Not sure what it is yet MOV #FE.CIU,R0 ;Channel in use BR 10$ ; 8$: CMPB #F.OPIN,F.OPCD(R5) ;Was this a lookup? BNE 9$ ;Branch if not MOV #FE.FNF,R0 ;File not found BR 10$ ; 9$: CMP #3,R0 ;Output file protected? ;CG02+ BEQ 99$ ;Branch if so MOV #FE.DVF,R0 ;Else device full BR 10$ ; 99$: MOV #FE.OFP,R0 ;Set protected error ;CG02+ 10$: MOVB R0,F.ERR(R5) ;Save the error byte MOVB F.OPCH(R5),R1 ;Get the channel .PURGE R1 ;Purge it. SERR sometimes leaves channels open .HERR ;Reset hard error BR 15$ 11$: .HERR ;Reset hard error MOV R4,R0 ;Point to free memory listhead MOV F.BFSZ(R5),R1 ;Get the size of the buffer BEQ 115$ ;Branch if zero. ;CG01 CALL $RQCB ;Request the core block BCS 2$ ;Branch if not there MOV R0,F.IOBF(R5) ;Save its starting address MOV R1,F.IOBS(R5) ;Save the actual size allocated 115$: CMPB #F.IOOUT,F.IOCD(R5) ;Is this an output file? BEQ 12$ ;Branch if so... No record buffer neccessary MOV R4,R0 ;Point to free memory listhead MOV F.RSIZ(R5),R1 ;Get its size BEQ 12$ ;Branch if zero. ;CG01 CALL $RQCB ;Request a core block BCS 2$ ;None to get MOV R0,F.URBA(R5) ;Save the buffer address MOV R1,F.URBS(R5) ; and its actual size 12$: CLR F.IOBK(R5) ;Clear the current block number CLR F.IOCR(R5) ;Clear completion routine address CMPB #F.OPIN,F.OPCD(R5) ;Is this an input file? BNE 13$ ;Branch if not MOV F.IOBF(R5),R4 ;Point to the input buffer ADD F.IOBS(R5),R4 ;Point at the end INC R4 ; to force a read MOV R4,F.BPTR(R5) ;Save it BR 14$ ; 13$: MOV F.IOBF(R5),F.BPTR(R5) ;Set up output buffer pointer 14$: CLR F.ERR(R5) ;No errors TST (PC)+ ;Indicate it 15$: SEC ;Indicate failure RETURN .END