.TITLE REF - REFormat Files .IDENT /4.2/ .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: REF.MAC ; Author: Gary Larsen & Robin Miller ; Date: April 23, 1982 ; ; Description: ; ; This program is used to convert input files into variable length ; implied carriage control output files. These output files can then be ; printed, typed, or edited without difficulty. ; ; Modification History: ; ;- .ENABL AMA .NLIST BEX .MCALL CLOSE$, DIR$, FINIT$, GET$, GMCR$, NMBLK$, PUT$ .MCALL FSRSZ$, FDBDF$, FDAT$A, FDOP$A, FDRC$A, FDBF$A .MCALL ALUN$S, EXIT$S, EXST$S, GTSK$, QIOW$S .MCALL GCMLB$, GCML$ ; Local equates: BELL = 7 ; ASCII for 'BELL' LF = 10. ; ASCII for 'LINE FEED' FF = 12. ; ASCII for 'FORM FEED' CR = 13. ; ASCII for 'CARRIAGE RETURN' DEL = 127. ; ASCII for 'DELETE' DEPTH = 2 ; Depth of command files. CMDSIZ = 256. ; Size of command line buffer. BUFSIZ = 512. ; Input/Output buffer sizes. FILSIZ = 128. ; Maximum size of file names. ERRSIZ = 80. ; Maximum size of error messages. OUTSIZ = 80. ; Terminal output buffer size. INLUN == 2 ; Input file logical unit number. INEFN == 2 ; Input file event flag number. OUTLUN == 3 ; Output file logical unit number. OUTEFN == 3 ; Output file event flag number. TILUN == 4 ; Terminal input logical unit number. TIEFN == 4 ; Terminal input event flag number. TOLUN == 5 ; Terminal output logical unit number. TOEFN == 5 ; Terminal output event flag number. ERRLUN == 6 ; Error message logical unit number. ERREFN == 6 ; Error message logical unit number. ; Macro to generate error message. .MACRO ERRMSG LABEL,MSG .NCHR $$$, .PSECT $ERMSG,RO,D,REL,CON LABEL: .ASCII "MSG" .EVEN .PSECT MOV #LABEL,R1 MOV #$$$,R2 CALL OUTMSG .ENDM .SBTTL Status Bit Definitions ; Status bit definitions: B.CMNT == 1 ; Comment line. B.IFIL == 2 ; Input file specified. B.OFIL == 4 ; Output file specified. B.TOT == 10 ; Output total records and bytes. B.VFU == 20 ; Input file contains VFU bytes. B.WILD == 40 ; Wildcard "*" for output file. B.NAME == 100 ; Output name of reformatted file B.BACK == 200 ; Removal of backspace sequence B.ESC == 400 ; Breakup escape sequences B.ASC == 1000 ; Convert from ASCII to EBCDIC B.EBC == 2000 ; Convert from EBCDIC to ASCII ; == 4000 ; ; == 10000 ; ; == 20000 ; ; == 40000 ; ; == 100000 ; STATUS::.WORD 0 ; Status word for options. ; Storage area: EXSTAT::.WORD EX$SUC ; Setup the default exit status. TIOSB:: .BLKW 2 ; Terminal I/O status block. INREC:: .WORD 0 ; Number of input records. INCNT:: .WORD 0,0 ; Total input file byte count. INBYT:: .WORD 0 ; Current input record byte count. OUTBYT::.WORD 0 ; Current output record byte count. OUTREC::.WORD 0 ; Number of output records. OUTCNT::.WORD 0,0 ; Total output file byte count. INPTR:: .WORD INFIL ; Pointer to the input file name. OUTPTR::.WORD OUTFIL ; Pointer to the output file name. MCRFLG::.WORD 0 ; SHOW STARTED FROM AN MCR LINE CTRFLG::.WORD 0 ; FLAG FOR CARRIAGE CONTROL PRTFLG::.WORD 0 ; FLAG FOR VAX-11 PRINT FILE FORFLG::.WORD 0 ; Flag for Fortran carriage control .PSECT $$ZZZZ,RW,D,REL,CON ; Force buffers to end of task. INFIL:: .BLKB FILSIZ ; Storage for the input file name. .BYTE -1 ; Show end of input file buffer. OUTFIL::.BLKB FILSIZ ; Storage for the output file name. .BYTE -1 ; Show end of output file buffer. CMDBUF::.BLKB CMDSIZ ; Storage for command lines. ERRBUF::.BLKB ERRSIZ ; Storage for error messages. WRKBUF::.BLKB CMDSIZ ; Storage for work buffer. INBUF:: .BLKB BUFSIZ ; Input file buffer. OUTBUF::.BLKB BUFSIZ ; Output file buffer. .EVEN .PSECT ; RETURN TO ORIGINAL PSECT ; Get Command Line control block. GCLBLK::GCMLB$ DEPTH,REF,CMDBUF,TILUN,,CMDSIZ GETTSK: GTSK$ TSKBUF ; Get task parameters TSKBUF: .BLKW 16. ; and store them here. VAXFLG::.WORD 0 ; Running on VAX/VMS -1 = True. ; File Descriptor Blocks (FDB's): FSRSZ$ 4 ; Allocate file storage region. TIFDB:: FDBDF$ ; FDB FOR TERMINAL INPUT FDAT$A R.VAR,FD.CR,,, ; VARIABLE LENGTH / IMPLIED FDRC$A ,CMDBUF,CMDSIZ ; LOCATE MODE / MAX SIZE FDOP$A TILUN,,DEFNB,FO.RD ; OPEN FOR READ FDBF$A TIEFN,CMDSIZ,, ; INIT BLOCK BUFFER SECTION TOFDB:: FDBDF$ ; FDB FOR TERMINAL OUTPUT FDAT$A R.VAR,FD.CR,,, ; VARIABLE LENGTH / IMPLIED FDRC$A ,WRKBUF,OUTSIZ ; LOCATE MODE / MAX SIZE FDOP$A TOLUN,,OUTNB,FO.WRT ; OPEN FOR WRITE FDBF$A TOEFN,OUTSIZ,, ; INIT BLOCK BUFFER SECTION ERRFDB::FDBDF$ ; FDB FOR ERROR MESSAGES FDAT$A R.VAR,FD.CR,,, ; VARIABLE LENGTH / IMPLIED FDRC$A ,ERRBUF,ERRSIZ ; LOCATE MODE / MAX SIZE FDOP$A ERRLUN,,ERRNB,FO.WRT ; OPEN FOR WRITE FDBF$A ERREFN,OUTSIZ,, ; INIT BLOCK BUFFER SECTION INFDB:: FDBDF$ ; FDB FOR INPUT FILE FDAT$A R.VAR,FD.CR,,, ; VARIABLE LENGTH / IMPLIED FDRC$A ,INBUF,BUFSIZ ; BUFFER ADDR / MAX SIZE FDOP$A INLUN,,INPNB,FO.RD!FA.SHR ; OPEN FOR SHARED READ FDBF$A INEFN,BUFSIZ,, ; EFN / BUFFER SIZE OUTFDB::FDBDF$ ; FDB FOR THE OUTPUT FILE FDAT$A R.VAR,FD.CR,,-10.,-10. ; VARIABLE LENGTH / IMPLIED FDRC$A ,OUTBUF,BUFSIZ ; LOCATE MODE / MAX SIZE FDOP$A OUTLUN,,OUTNB,FO.WRT!FA.NSP ; OPEN FOR WRITE FDBF$A OUTEFN,BUFSIZ,, ; INIT BLOCK BUFFER SECTION ; Default name blocks: INPNB: NMBLK$ REF,LOG,,SY,0 ; Input file name. OUTNB: NMBLK$ REF,OUT,,SY,0 ; Terminal output. ERRNB: NMBLK$ REF,ERR,,SY,0 ; Error message output. DEFNB: NMBLK$ REF,DAT,,SY,0 ; Output file name. ; Terminal output devices: TISTR: .ASCIZ "TI0:" ; TI0: for RSX-11M SYSIN: .ASCIZ "SYS$INPUT:" ; Input for VAX/VMS. SYSOUT: .ASCIZ "SYS$OUTPUT:" ; Output for VAX/VMS SYSERR: .ASCIZ "SYS$ERROR:" ; Errors for VAX/VMS .EVEN .SBTTL REFormat - Main Line Code ;+ ; ; REFormat - Main line code. ; ;- REF:: ALUN$S #TILUN,#"TI,#0 ; ASSIGN LUN TO TI0: MOV @#.FSRPT,R0 ; GET POINTER TO FSR TST A.DFUI(R0) ; HAS .FINIT BEEN DONE (DDT) BNE 10$ ; IF NE, YES (DO ONLY ONCE) FINIT$ ; DO THE FINIT ; Determine what system we are running on. 10$: DIR$ #GETTSK ; GET TASK PARAMETERS CALL CHKDIR ; CHECK/REPORT DIRECTIVE ERROR CLR VAXFLG ; PRESUME NOT ON VAX/VMS CMPB #5,TSKBUF+G.TSSY ; ARE WE ON VAX/VMS ? BNE 20$ ; IF NE, NO MOV #-1,VAXFLG ; YES, SET THE FLAG TRUE ; Open the input, output, and error LUNS. For RSX-11M, these ; should be asssigned at TKB time to TI:. That way they can ; be reassigned using the REAssign MCR command to a disk. ; For VAX/VMS, SYS$INPUT, SYS$OUTPUT, and SYS$ERROR are used. ; These can be reassigned using the ASSIGN/USER file SYS$xxxxx. ; Do SYS$ERROR first incase we get errors on the others. 20$: MOV #ERRFDB,R0 ; Address of error message FDB. MOV #TISTR,R1 ; Use TI0: when on RSX-11M. TST VAXFLG ; Are we runnng on VAX/VMS ? BEQ 25$ ; If EQ, no. MOV #SYSERR,R1 ; Yes, write to SYS$ERROR. 25$: CALL OPENW ; Open the LUN for write. BCS 100$ ; If CS, we had an error. ; Now do the input LUN (SYS$INPUT). MOV #TIFDB,R0 ; Address of terminal input FDB. MOV #TISTR,R1 ; Use TI0: for RSX-11M. TST VAXFLG ; Are we running on VAX/VMS ? BEQ 30$ ; If EQ, no. MOV #SYSIN,R1 ; Yes, read from SYS$INPUT. 30$: CALL OPENR ; Open the LUN for read. BCS 100$ ; If CS, we had an error. CLOSE$ ; Now close it so GCML$ can open it. ; Open the output LUN (SYS$OUTPUT). MOV #TOFDB,R0 ; Address of terminal output FDB. MOV #TISTR,R1 ; Use TI0: for RSX-11M. TST VAXFLG ; Are we running on VAX/VMS ? BEQ 40$ ; If EQ, no. MOV #SYSOUT,R1 ; Yes, write to SYS$OUTPUT. 40$: CALL OPENW ; Open the LUN for write. BCS 100$ ; If CS, we had an error. 50$: MOV #GCLBLK,R0 ; Address of the control block. BISB #GE.CON,G.MODE(R0) ; Set for continuation lines. ; On VAX, change the default file name extension to .COM TST VAXFLG ; Are we running on VAX/VMS ? BEQ 60$ ; If eq, no (default to .CMD) MOV F.DFNB(R0),R1 ; Get the file name block address. MOV #^RCOM,N.FTYP(R1) ; Change the extension to .COM 60$: BR GETCMD ; And continue ... ; We've had an error openning the input or output LUNs. 100$: CALL FILERR ; Report the error message. JMP EXISEV ; And exit with severe error. ; Get the command line and check for errors. .ENABL LSB GETCMD::MOV #GCLBLK,R0 ; Address of the control block. GCML$ R0,, ; Get a command line. BCC GOTCMD ; If CC, got a command. CMPB #GE.EOF,G.ERR(R0) ; End of file detected ? BNE 10$ ; If NE, no. JMP EXISUC ; Yes, 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,<%REF-F-TOOMANY, maximum @ file depth exceeded.> JMP EXISEV ; Consider this fatal. ; Report an error message. 20$: CALL FILERR ; Report the error message. BR GETCMD ; And get the next command. ; Report a syntax error. SYNERR:: 30$: ERRMSG SYNMSG,<%REF-E-SYNERR, syntax error in command line.> BR GETCMD ; Get the next command. .DSABL LSB ; Got a command line. GOTCMD::MOV #GCLBLK,R0 ; Address of the control block. MOV G.CMLD(R0),R3 ; Copy the string byte count. BEQ GETCMD ; If EQ, empty record. MOV G.CMLD+2(R0),R4 ; Copy the input buffer address. MOV R4,R0 ; Copy the buffer address. ADD R3,R0 ; Point to end of input string. CLRB (R0) ; Now, terminate with a null. ; Initialize various flags, counters, and storage. MOV #INFIL,INPTR ; Pointer to the input file name. MOV #OUTFIL,OUTPTR ; Pointer to the output file name. CLR STATUS ; Clear the output status BIS #B.BACK!B.ESC!B.NAME,STATUS ; Set up output defaults. CLR INREC ; Clear the input record count CLR INCNT ; and the input byte count. CLR INCNT+2 ; Double precision number. CLR OUTREC ; Clear the output record count CLR OUTCNT ; and the output byte count. CLR OUTCNT+2 ; Double precision number. ; ; Use TPARS to parse the command line. ; ; Inputs: ; 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). ; R3 = the input string byte count, ; R4 = the input buffer address. ; ; Outputs: ; R3 = zero on success or ; remaining byte count on syntax error. ; R4 = end of input string or ; updated buffer address on syntax error. ; MOV #<<400*1>+1>,R1 ; Pass blanks, match 1 character. MOV #KEYWRD,R2 ; Address of the keyword table. MOV #START,R5 ; Starting transition address. CALL .TPARS ; Now parse the command line. BCC GOGO ; If CC, parse successful. JMP SYNERR ; Else, report a syntax error. ; The command line has been successfully parsed. GOGO:: BIT #B.CMNT,STATUS ; Did we encounter a comment line ? BEQ 10$ ; If EQ, no. JMP GETCMD ; Yes, get the next command. ; Open the input file. 10$: MOV #INFDB,R0 ; Address of input file FDB. MOV #INFIL,R1 ; Address of input file name. CALL OPENR ; Try to open the input file. BCC 20$ ; If CC, success. CALL FILERR ; Else, report the error. JMP GETCMD ; And get the next command. ; See if we have an output file. 20$: BIT #B.WILD,STATUS ; Specify "*" for output file ? BNE 22$ ; If NE, yes (use input file name) BIT #B.OFIL,STATUS ; Do we have an output file name ? BNE 30$ ; If NE, yes 22$: MOV #INFIL,R0 ; No, so use the input file. MOV #OUTFIL,R1 ; Storage for output file name. 25$: CLRB (R1) ; Terminate file name with NULL. CMPB (R0),#'; ; Was a version number specified ? BEQ 30$ ; If EQ, yes (don't copy it). MOVB (R0)+,(R1)+ ; Copy the input file name. BNE 25$ ; If NE, more to go. ; Now open the output file. 30$: MOV #OUTFDB,R0 ; Address of output file FDB. MOV #OUTFIL,R1 ; Address of output file name. CALL OPENW ; Open the file for write. BCC DOIT ; If CC, we're ready to go. ; Report a file error and close the input file. CALL FILERR ; Else, report the error. 40$: CALL CLOFIL ; Close the input file. JMP GETCMD ; And get the next command. ; Now, reformat the input file. DOIT:: MOV #INFDB,R0 ; Address of the input FDB. CLR CTRFLG ; Presume no carriage control. CLR PRTFLG ; Presume no VAX print file. CLR FORFLG ; Presume no fortran carriage control BITB #2,F.RATT(R0) ; Is there carriage control ? BEQ 80$ ; If EQ, no MOV #-1,CTRFLG ; Yes, show that it does. 80$: BITB #1,F.RATT(R0) ; Is there Fortran carriage control ? BEQ 90$ ; If EQ, no MOV #-1,FORFLG ; Yes, show that it does. 90$: BITB #4,F.RATT(R0) ; Vax-11 Print file BEQ 100$ ; If EQ, no MOV #-1,PRTFLG ; Yes, show that it is. 100$: MOV #OUTBUF,R3 ; Address of output buffer. ; Get the record from the logfile until an error or end-of-file. LOOP:: MOV #INBUF,R4 ; ADDRESS OF INPUT BUFFER MOV #INBUF,INBYT ; SET UP THE CHECK FOR END OF RECORD GET$ #INFDB,#INBUF,#BUFSIZ ; GET THE NEXT RECORD BCC 5$ ; If CC, OK JMP 190$ ; else report the error 5$: INC INREC ; Count the number of input records. ADD F.NRBD(R0),INCNT+2 ; Accumlate the input bute count. ADC INCNT ; And the high bits (if any). ADD F.NRBD(R0),INBYT ; POINTER TO END OF INPUT BUFFER TST FORFLG ; Fortran carriage control ? BGE 10$ ; If GE, no CALL FORMAN ; Else convert the carriage control BR 20$ ; and continue with the record 10$: TST PRTFLG ; IS FILE A PRINT FILE ? BGE 20$ ; IF GE, NO MOV F.SEQN(R0),R5 ; PRINT CONTROL BYTE FIELD CALL PRINTR ; NOW CONVERT IT ; Check for the end of the input record ; Register usage: ; R3 = address of output buffer. ; R4 = address of input buffer. 20$: CMP OUTBYT,#BUFSIZ ; IS THE OUTPUT BUFFER FULL ? BLT 22$ ; IF LT, NO (CONTINUE) CALL WRTBUF ; YES, OUTPUT THE BUFFER ; TOO PREVENT RUN-AWAY 22$: CMP INBYT,R4 ; END OF THE INPUT BUFFER ? BHI 30$ ; IF HI, NO (CONTINUE) TST PRTFLG ; INPUT FILE VAX-11 PRINT FILE ? BLT 27$ ; IF LT, YES TST FORFLG ; INPUT FILE A FORTRAN FILE ? BLT 25$ ; IF LT, YES TST CTRFLG ; INPUT FILE HAVE CARRIAGE CONTROL ? BEQ LOOP ; IF EQ, NO (DON'T WRITE RECORD) 25$: CALL WRTBUF ; ELSE FLUSH THE OUTPUT BUFFER BR LOOP ; and get the next input record 27$: MOVB F.SEQN+1(R0),R5 ; THE PRINT CONTROL FIELD CALL PRINTR ; and call Print routine BR LOOP ; And get the next input record. ; Check the input record for nulls and strip them 30$: BIT #B.VFU,STATUS ; Does file have VFU in it ? BNE 35$ ; If NE, yes BIT #B.EBC,STATUS ; Are we converting from EBCDIC ? BNE 35$ ; If NE, yes BICB #200,(R4) ; No, strip the parity bit. 35$: TSTB (R4) ; IS THIS CHARACTER A NULL BNE 40$ ; IF NE, NO INC R4 ; GO TO THE NEXT CHARACTER BR 20$ ; AND CHECK IT ; Check the input record for delete characters and strip them 40$: CMPB (R4),#DEL ; IS THIS THE DELETE CHARACTER ? BNE 50$ ; IF NE, NO INC R4 ; GO TO THE NEXT CHARACTER BR 20$ ; AND CHECK IT ; Check the input record for sequences and convert them to 50$: CALL CHKVFU ; CHECK FOR VFU CHARACTER BVS 20$ ; IF VS, VFU FOUND CMPB (R4),#LF ; IS THE CHARACTER A LINE FEED BNE 60$ ; IF NE, NO CMPB 1(R4),#CR ; IS THE NEXT CHARACTER A RETURN BEQ 90$ ; IF EQ, YES INC R4 ; ADJUST THE INPUT BUFFER POINTER BR 110$ ; ELSE PUT THE IN THE BUFFER ; Check the input to see if the character is a 60$: CMPB (R4),#CR ; IS THE CHARACTER A RETURN ? BNE 140$ ; IF NE, NO ; Check the input character to see if we have a sequence 70$: CMPB 1(R4),#CR ; IS IT A SEQUENCE ? BNE 80$ ; IF NE, NO INC R4 ; ELSE IGNORE THE FIRST BR 70$ ; AND SEE IF THERE IS ANOTHER ONE ; Check the input character to see if it is a 80$: CMPB 1(R4),#LF ; IS IT A SEQUENCE ? BEQ 90$ ; IF EQ, YES INC R4 ; ELSE POINT PAST THE BR 20$ ; AND CHECK THE NEXT CHARACTER ; Upon reaching a write the output record 90$: ADD #2,R4 ; POINT PAST THE CALL WRTBUF ; WRITE THE RECORD BCS 200$ ; IF CS, ERROR ENCOUNTERED CMP INBYT,R4 ; END OF THE INPUT BUFFER ? BLOS LOOP ; If LOS, yes (Next record) ; Check for a sequence 100$: CMPB (R4),#LF ; IS IT A SEQUENCE ? BNE 120$ ; IF NE, NO INC R4 ; ADUJUST THE INPUT BUFFER POINTER ; Convert a to write a blank record on second 110$: CALL WRTBUF ; AND WRITE ANOTHER BLANK RECORD BCS 200$ ; IF CS, REPORT ERROR & EXIT BR 20$ ; AND SEE IF THERE ARE MORE () ; Check the input string for a string 120$: CMPB (R4),#CR ; IS IT A SEQUENCE BEQ 130$ ; IF EQ, YES BR 20$ ; AND CHECK THE NEXT ONE ; Make sure it isn't a if not ignore the second 130$: CMPB 1(R4),#LF ; WAS IT BEQ 90$ ; IF EQ, YES INC R4 ; ELSE POINT PAST THE BR 20$ ; AND CONTINUE CHECKING ; Check for the delete a character string and strip it and the ; character(s) to delete from the input buffer. 140$: BIT #B.BACK,STATUS ; DISABLE BACKSPACE DELETE ? BEQ 150$ ; IF EQ, YES CALL BAKSPC ; CHECK FOR BACKSPACE STRING BCS 20$ ; IF CS, WE HAD SEQUENCE ; Check for VT100 escape sequences 150$: BIT #B.ESC,STATUS ; CHECK FOR ESCAPE SEQUENCES ? BEQ 160$ ; IF EQ, NO CALL ESCAPE ; GO CHECK FOR ESCAPES BCS 20$ ; IF CS, GOT IT ; Move a character into the output buffer and go check the next one. 160$: MOVB (R4)+,(R3)+ ; MOVE IN THE CHARACTER INC OUTBYT ; ADJUST THE BYTE COUNT BR 20$ ; AND CONTINUE ; Got an error reading the input file. 190$: CMPB F.ERR(R0),#IE.EOF ; Was the error "End of file" ? BEQ 195$ ; If EQ, yes (expected error). CALL FILERR ; Else, report the error message. 195$: TST OUTBYT ; Is there anything to write ? BEQ 200$ ; If EQ, no. CALL WRTBUF ; Yes, write the last buffer. 200$: CALL CLOFIL ; Close the input/output files. CALL WRTTOT ; Write the total records/bytes. BIT #B.NAME,STATUS ; Output the reformatted filename BEQ 210$ ; IF EQ, NO CALL NAMWRT ; ELSE WRITE OUT THE FILENAME 210$: JMP GETCMD ; And get the next command. .SBTTL Common Exit Routines ; Common exit routines: EXISUC::MOV #EX$SUC,R0 ; Set success status. BR EXST ; And exit with status. EXIWAR::MOV #EX$WAR,R0 ; Set warning status. BR EXST ; And exit with status. EXIERR::MOV #EX$ERR,R0 ; Set error status. BR EXST ; And exit with status. EXISEV::MOV #EX$SEV,R0 ; SET SEVERE STATUS ; Exit with status in R0. EXST:: MOV R0,EXSTAT ; Save the exit status. ; And fail through to exit. .SBTTL EXIT - Close Open Files And Exit ;+ ; ; EXIT - Close any open files and exit to the system. ; ;- EXIT:: CALL CLOFIL ; Close the input & output files. CLOSE$ #TIFDB ; Now close the CLOSE$ #TOFDB ; terminal input & output CLOSE$ #ERRFDB ; and error files. EXST$S EXSTAT ; Exit with the status. EXIT$S ; In case EXST$S fails. .END REF