.TITLE DIR - File Directory Utility .IDENT /1.9/ .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: DIR.MAC ; Author: Robin Miller ; Date: February 19, 1985 ; ; Description: ; ; This program is used to get directorys in different formats. ; ;- .ENABL AMA .NLIST BEX .MCALL ALUN$S, DIR$, EXIT$S, EXST$S, GMCR$, GTSK$, QIO$, QIOW$, QIOW$S .MCALL CSI$, GCMLB$, GCML$, RCML$, CLOSE$, GCMLD$, FINIT$, FDOFF$ ;+ ; ; Modification History: ; ; April 86, modify to detach terminal before exiting for IAS F. Borger ; o And make brief the default mode ; ; July 22, 1985 by Robin Miller. Edit (09), Version 1.9 ; o Add support for appending to an existing output file. ; o If /DETACHed is specified, do not open an output file. ; ; June 25, 1985 by Robin Miller. Edit (08), Version 1.8 ; o After reporting a "No such file" error in routine OPERR, ; don't look for another file via OPNEXT to prevent the ; directory(s) from being searched a second time. ; o If we had an error reading the file header, count the file as ; being selected to prevent the "No files found" message from ; being displayed if this is the only file (looks cleaner). ; ; April 25, 1985 by Robin Miller. Edit (07), Version 1.7 ; Always re-attach the after reprompting to ensure CTRL/C can ; be detected for the next directory display. ; ; April 25, 1985 by Robin Miller. Edit (06), Version 1.6 ; o Adjust the directory file count and selected file counts in ; the appropriate places. ; o Increase the maximum file name size from 17 to 19 since the ; version number field can be a maximum of 5 octal digits. ; ; April 11, 1985 by Robin Miller. Edit (05), Version 1.5 ; Re-attach the terminal before prompting for another file ; specification if CTRL/C was previously typed. ; ; April 11, 1985 by Robin Miller. Edit (04), Version 1.4 ; Add bit definition for /FORMAT qualifier and call to format ; the user specified format string. ; ; April 10, 1985 by Robin Miller. Edit (03), Version 1.3 ; Add support for ANSI magtapes. ; ; March 7, 1985 by Robin Miller. Edit (02), Version 1.2 ; Check for use of an ANSI magtape. If we're using a magtape, ; force to a brief directory since the File Name Block format ; is so different than a disk FNB (See I/O Operation Manual). ; ; March 7, 1985 by Robin Miller. Edit (01), Version 1.1 ; Check for CTRL/C being typed when skipping over files due to ; file header read error and/or not valid date selection. ; ;- ; Local equates: DEPTH = 1 ; Depth of command files. M.FNAM == 19. ; Maximum file name width. M.FSIZ == 13. ; Maximum file size width. M.BREF == 20. ; Maximum brief field width. ; ASCII Messages: PRADR: .ASCII "File(s): " PRLEN = .-PRADR .EVEN ; Define offsets and bit definitions: CSI$ ; Define the CSI offsets. FDOFF$ DEF$L ; Define the FDB offsets. GCMLD$ DEF$L ; Define the GCML offsets. ; ; Switch definitions (SWMASK): ; ; Bits which require the reading of the file header are in ; the low byte. If all these butes are zero, we presume a ; brief directory. ; B.DATE == 1 ; Display the file date(s). B.FID == 2 ; Display the file ID. B.FULL == 4 ; Display full directory. B.BOWN == 10 ; Display by specific UIC. B.OWNR == 20 ; Display the owner UIC. B.PROT == 40 ; Display the protection. B.SIZU == 100 ; Display the size used. B.SIZA == 200 ; Display the size allocated. ; B.HEAD == 400 ; Display the header lines. B.TAIL == 1000 ; Display the trailer lines. B.CDAT == 2000 ; Display the creation date. B.MDAT == 4000 ; Display the modified date. B.EDAT == 10000 ; Display the expiration date. B.TOT == 20000 ; Display the directory totals. B.GTOT == 40000 ; Display the grand totals. ; == 100000 ; ; DEFSWM = B.HEAD!B.TAIL!B.SIZU!B.DATE!B.CDAT DEFSWM = B.HEAD!B.TAIL!B.CDAT ; Define bits for /ALL switch (all my favorites). B.ALL == B.SIZU!B.SIZA!B.DATE!B.CDAT!B.OWNR!B.PROT ; ; Status bit definitions (STATUS): ; ; These are the bits modified by the program. ; B.CMNT == 1 ; Comment line encountered. B.IFIL == 2 ; An input file was specified. B.OFIL == 4 ; An output file was specified. B.DET == 10 ; Terminal should be detached. B.PRI == 20 ; Output directed to line printer. B.SPOL == 40 ; Spool output file to the printer. B.FF == 100 ; Preceed heading with form feed. B.BFID == 200 ; User specified a file ID. B.STUP == 400 ; Executing the startup code. B.GMCR == 1000 ; Started by MCR command line. B.FMT == 2000 ; Format string was specified. (04) B.APND == 4000 ; Append to existing output file.(09) ; == 10000 ; B.FERR == 20000 ; There has been a file error. B.CTRO == 40000 ; Control/O has been typed. B.CTRC == 100000 ; Control/C was typed to abort. ; ; Date switch definitions (DATESW): ; ; These bits are used control which dates get displayed. The date ; switches defined for SWMASK above are used to control selection ; of dates when using the /BEFORE or /SINCE switches (same as VMS). ; D.CDAT == 1 ; Display the creation date. D.MDAT == 2 ; Display the revision date. D.EDAT == 4 ; Display the expiration date. D.BEF == 400 ; Select files before date. D.SIN == 1000 ; Select files since date. D.ALL == 7 ; Display all the dates. DEFDAT == D.CDAT ; Default date to display. ; The switch mask and the status word: SWMASK::.WORD DEFSWM ; The switch mask. STATUS::.WORD B.STUP ; The status word. DATESW::.WORD DEFDAT ; The date switch mask. ; Get Command Line control block. G.MCRS = 80. ; Size of an MCR buffer. GCLBLK::GCMLB$ DEPTH,,CMDBUF,TILUN,,CMDSIZ GMCR:: GMCR$ ; Get MCR command line. CMDBUF == GMCR+G.MCRB ; The command buffer address. .BLKB ; Allocate more buffer space. .EVEN ATTACH::QIOW$ IO.ATA,TOLUN,TOEFN,,TIOSB,,<,,CTRLC> DETACH::QIOW$ IO.DET,TOLUN,TOEFN,,,, ; Detach the terminal. GETTSK: GTSK$ TSKBUF ; Get task parameters TSKBUF: .BLKW 16. ; and the buffer. VAXFLG::.WORD 0 ; Running on VAX/VMS -1 = TRUE TIOSB:: .BLKW 2 ; Terminal I/O status block. .SBTTL DIR - Start Of Program ;+ ; ; DIR - Start of program. ; ;- .ENABL LSB DIR:: ALUN$S #TOLUN,#"TI,#0 ; Assign a LUN to TI0:. MOV @#.FSRPT,R0 ; Get pointer to the FSR. TST A.DFUI(R0) ; Has .FINIT been done (DDT) ? BNE 10$ ; If NE, yes (do it only once) FINIT$ ; Initialize the file storage. ; Determine what system we're running on. 10$: dir$ #GETTSK ; Get our task parameters. CALL CHKDIR ; Check/report directive error. BCS 110$ ; If CS, we had an error. CLR VAXFLG ; Presume not on VAX/VMS. CMPB #5,TSKBUF+G.TSSY ; Are we running on VAX/VMS ? BNE 20$ ; If NE, no. MOV #-1,VAXFLG ; Yes, set the flag true. ; Attach the terminal and get terminal information. 20$: DIR$ #ATTACH ; Attach the output device. ; CALL CHKERR ; Check for any errors. ; BCS 110$ ; If CS, we had an error. CALL CTTYPE ; Check the terminal type. BCS 110$ ; If CS, we've had an error. CALL GETDAT ; Get and setup the current date. MOV #GCLBLK,R0 ; Address of the control block. BISB #GE.CON,G.MODE(R0) ; Set for continuation lines. ; If we can get a command line then use it, otherwise prompt. DIR$ #GMCR ; Try to get an MCR command line. BCS PRFILE ; If CS, prompt the user. BIS #B.GMCR,STATUS ; Show we started by MCR line. MOV #CMDBUF,R1 ; Set the input buffer address. MOV $DSW,R2 ; Copy the command byte count. MOV R1,R3 ; Copy the buffer address. ADD R2,R3 ; Point to end of the buffer. CLRB (R3) ; Overwrite the terminator. ; Now find the end of the task name. 50$: CMPB (R1),#SPACE ; End of the task name ? BEQ 60$ ; If EQ, yes. CMPB (R1),#HT ; End of the task name ? BEQ 60$ ; If EQ, yes. CMPB (R1),#'/ ; Start of a switch ? BEQ 70$ ; If EQ, yes. INC R1 ; Bump the buffer address. SOB R2,50$ ; And check the next character. BR 70$ ; Must be "DIR" by itself. 60$: INC R1 ; Point past the delimiter. DEC R2 ; Adjust the byte count. 70$: MOV R1,G.CMLD+2(R0) ; Set the command buffer address. MOV R2,G.CMLD(R0) ; Set the command byte count. JMP GOTFIL ; Now, parse and execute it. ; We've had an error opening the input or output LUNs. 100$: CALL FCSERR ; Report the FCS error message. 110$: MOV #EX$SEV,R0 ; Set severe status code. JMP EXST ; And exit with the status. .DSABL LSB ; Prompt for file name(s) to display. .ENABL LSB PRFILE::BIS #B.STUP,STATUS ; Show doing startup code. BIT #B.GMCR,STATUS ; Start by an MCR command line ? BNE 5$ ; If NE, yes (time to exit). ;*** BIT #B.CTRC,STATUS ; Was CTRL/C typed to abort ? (07) ;*** BEQ 3$ ; If EQ, no (continue ...) (07) DIR$ #ATTACH ; Attach the output device. (05) 3$: MOV #GCLBLK,R0 ; Address of the control block. GCML$ R0,#PRADR,#PRLEN ; Get a command line. BCC GOTFIL ; If CC, got a command. CMPB #GE.EOF,G.ERR(R0) ; End of file detected ? BNE 10$ ; If NE, no (continue ...) 5$: JMP EXIT ; And exit ... ; For the errors GE.IOR & GE.OPR, F.ERR in the FDB has the error code. 10$: CMPB #GE.IOR,G.ERR(R0) ; I/O error detected ? BEQ 20$ ; If EQ, yes. CMPB #GE.OPR,G.ERR(R0) ; File open error ? BEQ 20$ ; If EQ, yes. CMPB #GE.BIF,G.ERR(R0) ; Syntax error ? BEQ 30$ ; If EQ, yes. CMPB #GE.MDE,G.ERR(R0) ; Maximum @ depth exceeded ? BNE 20$ ; If NE, no (try fcs error) ERRMSG TOOMNY, JMP EXIT ; Consider this fatal. ; Report an error message. 20$: CALL FCSERR ; Report the FCS error message. BR PRFILE ; And prompt for another file. ; Report a syntax error. SYNERR:: 30$: ERRMSG SYNMSG, BR PRFILE ; Prompt for a another file name. .DSABL LSB .SBTTL GOTFIL - Got a command line to parse. ; Got a command line, now parse it. GOTFIL::MOV #GCLBLK,R0 ; Address of the control block. MOV G.CMLD(R0),R1 ; Copy the string byte count. MOV G.CMLD+2(R0),R0 ; Copy the input buffer address. MOV R0,R2 ; Copy the buffer address. ADD R1,R2 ; Point to end of input string. CLRB (R2) ; Terminate the string with null. CALL CUPPER ; Convert the string to upper case. ; Setup to parse the input file specification. MOV IENTRY,R5 ; Copy the file entry address. MOV O.FPTR(R5),INPTR ; Copy address of the input buffer. ; Parse the command line using the table parser. CALL DOINIT ; Initialize counters and flags. MOV #START,R5 ; Set the starting state address. CALL DOPARS ; Now parse the command line. BCS 100$ ; If CS, we had an error parsing. ; The command line has been successfully parsed. BIT #B.CMNT,STATUS ; Did we encounter a comment line ? BNE 100$ ; If NE, yes. ; Detach terminal if /DETACH or output file was specified. BIT #B.OFIL!B.DET,STATUS ; Output file or detach ? BEQ 10$ ; If EQ, no (skip file open). DIR$ #DETACH ; Detach the local terminal. ; Open the output file if one was specified. BIT #B.OFIL,STATUS ; Creating an output file ? (09) BEQ 10$ ; If EQ, no. (09) MOV OENTRY,R5 ; Copy the file entry address. MOV O.FDB(R5),R0 ; Copy the FDB address. MOV O.FNAM(R5),R1 ; Copy the file name address. BIT #B.APND,STATUS ; Open existing file for append?(09) BEQ 5$ ; If EQ, no (create new file). (09) CALL OPENA ; Yes, append to existing file. (09) BR 7$ ; Use common error check ... (09) 5$: CALL OPENW ; Open the file for write. 7$: BCC 10$ ; If CC, the file is open. ; Report the open file error. CALL MAKNAM ; Make the ASCII file name. CALL FILERR ; Else, report the error. BIC #B.OFIL,STATUS ; Don't try to open this again. BR 100$ ; Prompt for input again ... ; Open the first input file. 10$: MOV IENTRY,R5 ; Reset the file entry address. MOV O.FDB(R5),R0 ; Copy the FDB address. MOV O.FPTR(R5),R1 ; Copy address of the input buffer. CALL OPENR ; Try to open the input file. BCC DOFMT ; If CC, format the file name. BIT #B.CTRC,STATUS ; Does the user want to exit ? BNE 100$ ; If EQ, no (don't report error). CALL OPERR ; Report error/get the next file. BCC DOFMT ; If CC, format the file name. 100$: JMP PRFILE ; Else, prompt for another file. .SBTTL DOFMT - Format the file specification. ;+ ; ; DOFMT - Create the file name for display at top of screen. ; ; Inputs: ; R0 = The FDB address. ; R5 = The file entry address. ; ;- DOFMT:: BIC #B.STUP,STATUS ; Show done with startup code. ;(03) BITB #CH.AND,F.CHR(R0) ; Are we using an ANSI magtape? (02) ;(03) BEQ 10$ ; If EQ, no. (02) ;(03) CLRB SWMASK ; Yes, force to brief directory.(02) 10$: MOV BUFADR,R0 ; Copy the output buffer address. BIT #B.OFIL,STATUS ; Are we writing to output file ? BNE 25$ ; If NE, yes. CALL NEWLIN ; Add a carriage-return/line-feed. ; The buffer address should always be in R0 at this point. 25$: CALL MAKNAM ; Make the expanded file name. ; Check for end of a directory. CALL CHKDID ; Are we going to new directory ? BCC 50$ ; If CC, no (still same directory). CALL DOTAIL ; Format and write the trailer. CALL SAVDID ; Save this directorys' ID. ; Check for start of a directory. 50$: CALL DOHEAD ; Format the directory header. INC FILCNT ; Adjust directory file count. (06) ; If the switch specified needs header information, then go read it. TSTB DATESW+1 ; Selection of file by a date ? BNE 60$ ; If NE, yes (must read header). TSTB SWMASK ; Do we need header information ? BEQ 65$ ; If EQ, no. 60$: MOV R0,BUFPTR ; Save address incase of error. CALL RDHDR ; Yes, go read the file header. BCC 65$ ; If CC, successful read. MOV BUFADR,R0 ; Else, set starting address. TSTB DATESW+1 ; Selection of file by a date ? (08) BNE 63$ ; If NE, yes (presume no select)(08) INC SELCNT ; Adjust files selected count. (08) 63$: BR 200$ ; And try for the next file. (01) ; Check for selection of a file BEFORE a specific date. 65$: BIT #D.BEF,DATESW ; Select files /BEFORE a date ? BEQ 70$ ; If EQ, no. CALL CHKBEF ; Yes, check for before date. BCS 200$ ; If CS, date not in range. (01) ; Check for selection of a file SINCE a specific date. 70$: BIT #D.SIN,DATESW ; Select files /SINCE a date ? BEQ 80$ ; If EQ, no. CALL CHKSIN ; Yes, check for since date. BCS 200$ ; If CS, date not in range. (01) ; Adjust the file selected and file header read counts. 80$: INC SELCNT ; Adjust files selected count. (06) TSTB SWMASK ; Did we read the file header ? BEQ 85$ ; If EQ, no. INC HREADS ; Count number of header reads. ; Adjust the blocks used/allocated counters. 85$: MOV #HDRBUF,R2 ; Set the file header address. ADD V.EFBK+2(R2),DIRUBK+2 ; Count number of blocks used. ADC DIRUBK ; Add in any overflow (carry). ADD V.EFBK(R2),DIRUBK ; Now add in the high bits. ADD V.HIBK+2(R2),DIRABK+2 ; Count number of blocks allocated. ADC DIRABK ; Add in any overflow (carry). ADD V.HIBK(R2),DIRABK ; Now add in the high bits. ; Check for a format string being specified. BIT #B.FMT,STATUS ; Was format string specified ? (04) BEQ 90$ ; If EQ, no. (04) CALL DOUFMT ; Format the user's string. (04) BR 180$ ; Write the formatted string. (04) ; Check for display of totals only (/TOTAL or /GRANDTOTAL). 90$: BIT #B.TOT!B.GTOT,SWMASK ; Does the used want totals only ? BNE 200$ ; If NE, yes (don't display). ; Check for a full directory display. BIT #B.FULL,SWMASK ; User want a full directory ? BEQ 100$ ; If EQ, no. CALL DOFULL ; Display a full directory. BR 200$ ; And continue ... ; Check for a brief directory display. 100$: BIT #B.HEAD,SWMASK ; Has the heading been disabled ? BEQ 110$ ; If EQ, yes (single file/line). TSTB SWMASK ; Is this a brief directory ? BNE 110$ ; If NE, no. CALL DOBREF ; Format a brief directory. BR 200$ ; And continue ... 110$: CALL DONAME ; Format the device/file name. ; Check for display of size used and/or allocated. BIT #B.SIZU!B.SIZA,SWMASK ; Display size used/allocated ? BEQ 150$ ; If EQ, no. CALL DOSIZE ; Format the used/allocated size. ; Check for display of any dates. 150$: BIT #B.DATE,SWMASK ; Display any of the dates ? BEQ 155$ ; If EQ, no. CMPB #D.ALL,DATESW ; Are we displaying all dates ? BEQ 155$ ; If EQ, format these last. CALL DODATE ; Yes, format the desired dates. ; Check for display of the file owner UIC. 155$: BIT #B.OWNR,SWMASK ; Display the file owner UIC ? BEQ 160$ ; If EQ, no. MOV #HDRBUF,R2 ; Set the file header address. MOVB #SPACE,(R0)+ ; Separate fields with a space. CALL DOUIC ; Format the file owner UIC. ; Check for display of file protection. 160$: BIT #B.PROT,SWMASK ; Display the file protection ? BEQ 165$ ; If EQ, no. CALL DOPROT ; Yes, format the protection. ; Check for display of the file ID. 165$: BIT #B.FID,SWMASK ; Display the file ID ? BEQ 175$ ; If EQ, no. MOVB #SPACE,(R0)+ ; Separate fields with a space. CALL DOFID ; Yes, format the file ID. ; If displaying all dates, we format them last. 175$: CMPB #D.ALL,DATESW ; Are we displaying all dates ? BNE 180$ ; If NE, no. CALL DODATE ; Yes, format all the dates. 180$: CALL TYPMSG ; Write it to the terminal. ; Exit if the user typed CTRL/C. 200$: BIT #B.CTRC,STATUS ; Does the user want to exit ? BNE 250$ ; If NE, yes. ; Go to the next directory if the user typed CTRL/O. BIT #B.CTRO,STATUS ; Did the user type CTRL/O ? BEQ 225$ ; If EQ, no. MOV O.FNB(R5),R1 ; Copy the FNB address. BIS #NB.NXD,N.STAT(R1) ; Set the next directory bit. ; See if there is another file to display. 225$: CALL GETNXT ; Else, get the next file (if any). BCS 250$ ; If CS, no more files. JMP 25$ ; Else, format this file. ; The user wants to exit. 250$: CALL DOTAIL ; Format and write the trailer. CALL GTOTAL ; Format and write grand totals. CALL WAITIO ; Wait for any outstanding I/O. BIT #B.CTRC,STATUS ; Does the user want to exit ? BEQ 275$ ; If EQ, no (no more files). MOV #GCLBLK,R0 ; Address of the control block. BITB #FD.TTY,F.RCTL(R0) ; Input from the terminal ? BNE 275$ ; If NE, yes. RCML$ R0 ; Else, close the command file. 275$: CALL CLOALL ; Close all the open files. JMP PRFILE ; Prompt for the next file name. .SBTTL DOINIT - Initialize counters and flags. ;+ ; ; DOINIT - Initilaize the counters and flags. ; ; Inputs: ; R5 = The input file entry address. ; ; Outputs: ; All registers are preserved. ; ;- DOINIT::JSR R2,$SAVVR ; Save R0 - R2. CALL CLRDID ; Clear the saved directory ID. CLRB @O.FPTR(R5) ; Clear first byte of file name. BIC #^C,STATUS ; Clear all but startup flags. MOV #DEFSWM,SWMASK ; Setup the default switch mask. MOV #DEFDAT,DATESW ; Setup the default date switch mask. MOV #CLRBUF,R0 ; Set address to start clearing. MOV #CLRSIZ,R1 ; Set number of words to clear. 10$: CLR (R0)+ ; Clear counters and flags. SOB R1,10$ ; Loop until we're done. RETURN .SBTTL DOPARS - Parse the command line. ;+ ; ; DOPARS - Parse the command line. ; ; Use .TPARS to parse the command line. ; ; Inputs to DOPARS: ; R0 = The buffer address. ; R1 = The buffer byte count. ; R5 = The starting state address. ; ; Inputs to .TPARS: ; R1 = Bit 0 in the low byte controls processing of blanks/tabs: ; if 0, ignore blanks, if 1 then pass blanks and tabs. ; The high byte contains the number of characters that ; keywords are alloewed to be abbreviated (0 = exact). ; R2 = The keyword table address. ; R3 = The input string byte count. ; R4 = The input buffer address. ; R5 = The starting state address. ; ; Outputs from .TPARS: ; C bit clear/set = success/failure. ; ; R3 = Zero on success or ; remaining byte count on syntax error. ; R4 = End of input string or ; updated buffer address on syntax error. ; ; All other registers from .TPARS are preserved. ; ;- DOPARS::CALL $SAVAL ; Save all registers. MOV R0,R4 ; Copy the buffer address. MOV R1,R3 ; Copy the buffer byte count. MOV #<<400*1>+0>,R1 ; Ignore blanks, match 1 character. MOV #KEYWRD,R2 ; Address of the keyword table. CALL .TPARS ; Now parse the command line. BCC 100$ ; If CC, success. CALL WRTSYN ; Write the syntax error. 100$: RETURN .SBTTL GETNXT - Open the next input file. ;+ ; ; GETNXT - Open the next input file (if any). ; OPERR - Report error and check for more files. ; ; This routine is called to open the next input file (if any). The next ; input file may come from either a wildcard file specification, or from ; specifying multiple input files. ; ; Inputs: ; R5 = The file table address. ; ; Outputs: ; C bit clear/set = another file/no more files. ; ; All registers are preserved. ; ;- .ENABL LSB GETNXT::CALL $SAVAL ; Save all registers. 10$: MOV O.FDB(R5),R0 ; Copy the FDB address. CALL OPNEXT ; Open the next file (if any). BIT #B.CTRC,STATUS ; Does the user want to exit ? BNE 90$ ; If NE, yes (return failure). BCC 100$ ; If CC, a file was opened. CMPB #IE.NSF,F.ERR(R0) ; Did we get expected error ? BEQ 50$ ; If EQ, yes (don't flag error). OPERR:: CALL MAKNAM ; Make the ASCII file name. CALL FILERR ; And report the error message. CMPB #IE.NSF,F.ERR(R0) ; Was error "No such file" ? (08) BNE 10$ ; If NE, no (find next file). (08) 50$: MOV O.CSI(R5),R1 ; Copy the CSI block address. BITB #CS.MOR,C.STAT(R1) ; Any more file specifications ? BEQ 90$ ; If EQ, no (we're all finished). CALL OPMORE ; Parse and open next file spec. BCC 100$ ; If CC, another file open. BR OPERR ; Else, report the error message. 90$: SEC ; Show no more input files. 100$: RETURN .DSABL LSB .SBTTL CLOALL - Close all open files. ;+ ; ; CLOALL - Close all open files. ; ; Inputs: ; None. ; ; Outputs: ; All registers are preserved. ; ;- CLOALL: JSR R2,$SAVVR ; Save R0 - R2 MOV #INFDB,R0 ; Address of the 1st input file. TST F.BDB(R0) ; Is the input file open ? BEQ 10$ ; If EQ, no. CLOSE$ R0 ; Close the first input file. 10$: MOV #OUTFDB,R0 ; Address of the output FDB. TST F.BDB(R0) ; Is an output file open ? BEQ 100$ ; If EQ, no BIT #B.SPOL,STATUS ; Should we spool the output file ? BEQ 20$ ; If EQ, no. CALL .PRINT ; Send the file to the line printer. BR 100$ ; Use common return ... 20$: CALL .TRNCL ; Close and truncate the file. 100$: RETURN .SBTTL CLOFIL - Close a file (if open). ;+ ; ; CLOFIL - Close a file if it is open. ; ; Inputs: ; R0 = The FDB address. ; ; Outputs: ; All registers are preserved. ; ;- CLOFIL::JSR R2,$SAVVR ; Save R0 - R2. TST F.BDB(R0) ; Is the file open ? BEQ 20$ ; If EQ, no. BITB #FO.RD,F.FACC(R0) ; Is the file open for read ? BEQ 10$ ; If EQ, no (open for write). CLOSE$ R0 ; Yes, close the file normally. BR 20$ ; And use common return ... 10$: CALL .TRNCL ; For write, close & truncate file. 20$: RETURN .SBTTL EXIT - Close Open Files And Exit ;+ ; ; EXIT - Close any open files and exit to the system. ; ;- EXIT:: CALL CLOALL ; Close the input & output files. MOV #EX$SUC,R0 ; Set the success status code. ; Exit with the status code in R0. EXST:: DIR$ #DETACH ; detach before exiting EXST$S R0 ; Exit with the status. EXIT$S ; In case EXST$S fails. .END DIR ; Transfer address.