.TITLE VTL - VT100 File Listing Utility .IDENT /1.7/ .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: VTL.MAC ; Author: Robin Miller ; Date: June 31, 1983 ; ; Description: ; ; This program is used to list files to a VT100 family terminal. ; ;- .ENABL AMA .NLIST BEX .MCALL ALUN$S, DIR$, EXIT$S, EXST$S, GTSK$, QIO$, QIOW$, QIOW$S .MCALL CSI$, GCMLB$, GCML$, RCML$, CLOSE$, GCMLD$, FINIT$, FDOFF$ .SBTTL Modification History ;+ ; ; Modification History: ; ; October 3, 1984 by Robin Miller. Edit (05), Version 1.7 ; After reporting an open file error, see if the user wants to ; exit. This prevents us from having to get an error on a whole ; list of files which we may not have access to. ; ; June 7, 1984 by Robin Miller. Edit (04), Version 1.6 ; On VMS, if there are no VMS wildcard characters in the filespec, ; use the normal RSX open routines because they are faster. ; ( Removed this edit ... didn't seem that much faster. ) ; ; June 6, 1984 by Robin Miller. Edit (03), Version 1.5 ; Adjust line count properly when there is no advanced video. ; ; June 2, 1984 by Robin Miller. Edit (02), Version 1.4 ; Use commmon routine to GET/MARK the next input record. ; ; June 2, 1984 by Robin Miller. Edit (01), Version 1.3 ; Initialize the total records skipped count. ; ;- ; Local equates: DEPTH = 2 ; Depth of command files. ; ASCII Messages: PRADR: .ASCII "[24;1HFile(s): ""[0K" PRLEN = .-PRADR ; 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. .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. ; Globalize bit definitions for DDT debugging. ; Bit definitions for SWMASK: .GLOBL B.NAR, B.WIDE, B.BELL, B.FE, B.FF, B.AVO, B.HDR, B.WAIT .GLOBL B.GBL, B.XACT, B.PROT, B.SCRB, B.NATV, B.STUP ; Bit definitions for STATUS: .GLOBL B.CMNT, B.IFIL, B.OFIL, B.132, B.EXIT, B.NEXT, B.AUX .GLOBL B.SRCH, B.ATTR, B.DOPR, B.BACK, B.2FIL, B.MSG, B.FERR, B.CTRC ; The switch mask and the status word: SWMASK::.WORD DEFSWM ; The switch mask. STATUS::.WORD 0 ; The status word. ; Get Command Line control block. GCLBLK::GCMLB$ DEPTH,,CMDBUF,TILUN,,CMDSIZ ATTACH: QIOW$ IO.ATA!TF.ESQ,TOLUN,TOEFN,,TIOSB,,<,,CTRLC> 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 VTL - Start Of Program ;+ ; ; VTL - Start of program. ; ;- .ENABL LSB VTL:: 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$: BIS #B.STUP,SWMASK ; Show doing startup code. 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. BIS #B.NATV,SWMASK ; Enable native mode routines. ; Open the input device (TI0: or SYS$INPUT). 20$: MOV #TIFILE,R5 ; Terminal file entry address. MOV O.FDB(R5),R0 ; Copy the FDB address. 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 device (TI0: or SYS$OUTPUT). MOV #TOFILE,R5 ; Terminal file entry address. MOV O.FDB(R5),R0 ; Copy the FDB address. 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. BITB #FD.TTY,F.RCTL(R0) ; Are we outputting to a terminal ? BEQ 90$ ; If EQ, no (this is bad news). ; ; On VAX/VMS, the sub-function bit TF.ESQ which is ignored, must be ; cleared so the attach of the CTRL/C AST will go into effect. ; TST VAXFLG ; Are we running on VAX/VMS ? BEQ 45$ ; If EQ, no - continue ... BIC #TF.ESQ,ATTACH+Q.IOFN ; Yes, disable escape sequence. 45$: 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. CLOSE$ #TOFDB ; Close the terminal output file ; since we're using QIO's to write. 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 PRFILE ; And continue ... 90$: ERRMSG NOTTY,<%VTL-F-NOTTY, program must run on a terminal.> BR 110$ ; Exit with severe error. ; We've had an error openning 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::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 ...) 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 ; 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. BNE 10$ ; If NE, we got one. ; On VAX/VMS, a CR/LF pushes the prompt string to the message line. CALL CLRMSG ; Else, clear the message line. BR PRFILE ; And prompt for another file name. 10$: 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. CALL DOOPEN ; Do the parse and file open. BCC LOOK ; If CC, a file is open. JMP PRFILE ; Else, prompt for another file. .SBTTL LOOK - Look at the contents of the file. ; Create the file name for display at top of screen. LOOK:: MOV IENTRY,R5 ; Copy the file entry address. CALL DOINIT ; Do the initial file setup. BIT #B.HDR,SWMASK ; Should we display the header ? BEQ 10$ ; If EQ, no. CALL SHOHDR ; Yes, display the file header. BIT #B.EXIT!B.NEXT,STATUS ; Time to exit or go to next file ? BNE 100$ ; If NE, yes. BR 30$ ; Else, go display the first page. 10$: CALL WRTHDR ; Now, write the file name, etc. CALL WRTACT ; Show which file is active. ; Main line file read loop. 20$: CALL DOBOTH ; Display pages for both files. ; End of screen / end of file processing. 30$: CALL CHKCMD ; Get/check/execute the command. MOV IENTRY,R5 ; Copy entry incase it was swapped. BIT #B.EXIT!B.NEXT,STATUS ; Time to exit or go to next file ? BNE 100$ ; If NE, yes. BIT #S.EOF,(R5) ; Are we still at the end of file ? BEQ 40$ ; If EQ, no (continue ...). BIT #B.FE,SWMASK ; Did the user specify force exit ? BEQ 100$ ; If EQ, no (time for the next file). 40$: BR 20$ ; And display the next page. ; End of file or display the next file, display next file (if any). 100$: CALL CLOFIL ; Close the input file (if open). BIT #B.EXIT,STATUS ; Does the user want to exit ? BNE 130$ ; If NE, yes. ; See if there is another file to display. CALL GETNXT ; Else, get the next file (if any). BCC LOOK ; If CC, go look at this file. (05) BIT #B.EXIT,STATUS ; Does the user want to exit ? (05) BEQ 140$ ; If EQ, no (no more files). (05) ; The user wants to exit. 130$: MOV #GCLBLK,R0 ; Address of the control block. BITB #FD.TTY,F.RCTL(R0) ; Input from the terminal ? BNE 140$ ; If NE, yes. RCML$ R0 ; Else, close the command file. 140$: CMP IENTRY,#IFILE2 ; Are we finishing second file ? BNE 150$ ; If NE, no (must be first file). CALL SWAPEM ; Else, swap back to the top file. BIC #^C,STATUS ; Initialize program status bits. CALL ADJTOP ; Adjust the top file entry. MOV IENTRY,R5 ; Set the top file entry address. BR 30$ ; And prompt the user. 150$: CALL WRTEOF ; Write the end of file sequence. JMP PRFILE ; Prompt for the next file name. .SBTTL DISPAG - Display a page on the screen. ;+ ; ; DISPAG - Display a page on the screen. ; ; This routine loops reading input records and formatting and writing ; them to the screen until the screen is full. ; ; Implicit inputs: ; IENTRY = The active file entry address. ; ; Outputs: ; All registers are preserved. ; ; Implicit outputs: ; O.LCNT = Reinitialized to zero. ; O.LSAV = The current page line count. ; O.RCNT = The current page record count. ; ;- DISPAG::CALL $SAVAL ; Save all registers. MOV IENTRY,R5 ; Copy the file entry address. CALL SETTOP ; Setup the top of page record. 10$: TST O.BADR(R5) ; Finishing a continuation record ? BNE 15$ ; If NE, yes (go do it). CALL GETM ; Get/Mark the next record. (02) BCS 20$ ; If CS, error or end of file. 15$: CALL WRTBUF ; Now format and display the record. CMP O.LCNT(R5),O.LMAX(R5) ; Have we filled up the screen yet ? BLT 10$ ; If LT, no (do another record). 20$: MOV O.LCNT(R5),O.LSAV(R5) ; Save the last page line count. CLR O.LCNT(R5) ; Clear the current line count. MOV O.CREC+2(R5),R0 ; Copy the current record number. SUB O.TOPR+2(R5),R0 ; Calculate the number of INC R0 ; records on the screen. MOV R0,O.RCNT(R5) ; Save the record count. BIS #S.STOP,(R5) ; Set to save top of page record. RETURN .SBTTL DOBOTH - Display page for both files. ;+ ; ; DOBOTH - Display pages for both files if in split screen mode. ; ; Inputs: ; R5 = The active file entry address. ; ; Outputs: ; All registers are preserved. ; ;- DOBOTH::CALL $SAVAL ; Save all registers. MOV O.LCNT(R5),R2 ; Save the current line count. CALL DISPAG ; Display a page on the screen. BIT #B.2FIL,STATUS ; Are we displaying two files ? BEQ 100$ ; If EQ, no. BIT #B.SCRB,SWMASK ; Should we scroll both files ? BEQ 100$ ; If EQ, no. CALL SWACMD ; Swap entrys via a SWAP command. MOV IENTRY,R5 ; Copy the file entry address. MOV R2,O.LCNT(R5) ; Save previous file line count. CALL DONEXT ; Prepare to write the next page. CALL DISPAG ; Display page for this file. CALL SWACMD ; Swap entrys via a SWAP command. 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 active file entry address. ; ; Outputs: ; R0 = The FDB address. ; C bit clear/set = another file/no more file. ; ; All other registers are preserved. ; ;- .ENABL LSB GETNXT::JSR R5,.SAVR1 ; Save R1 - R5. 10$: MOV O.FDB(R5),R0 ; Copy the FDB address. .IFNDF RSX11M TST VAXFLG ; Are we running on VAX/VMS ? BEQ 20$ ; If EQ, no. BIT #B.NATV,SWMASK ; Native mode routine disabled ? BEQ 20$ ; If EQ, yes (use normal routine). ;*** BIT #S.RSX,(R5) ; Use RSX open for this file ? (04) ;*** BNE 20$ ; If NE, yes. (04) CALL DOVMS ; Yes, do the VMS wildcard lookup. BCS 40$ ; If CS, we've had an error. MOV O.FNAM(R5),R1 ; Set address of expanded file name. CALL OPENR ; Try to open the file. BR 30$ ; Use common error checking ... .ENDC ;RSX11M 20$: CALL OPNEXT ; Open the next file (if any). 30$: BCC 100$ ; If CC, a file was opened. 40$: 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. BIT #B.EXIT,STATUS ; Does the user want to exit ? (05) BNE 90$ ; If NE, yes (return failure). (05) BCC GETNXT ; If CC, non-fatal error. 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 DOINIT - Do the initial file setup. ;+ ; ; DOINIT - Do the initial file setup. ; ; This routine is called once after each file is opened to make the ; ASCII file name, reinitialize various counters and status bits, and ; to setup the display parameters. ; ; Implicit inputs: ; IENTRY = The file entry address. ; ; Outputs: ; All registers are preserved. ; ;- C.BITS = ; Status bits to save. DOINIT::CALL $SAVAL ; Save all registers. MOV IENTRY,R5 ; Copy the file entry address. CALL MAKNAM ; Make the expanded file name. BIC #^C,STATUS ; Initialize program status bits. .IFDF T$SKIP CLR TSKIPS ; Clear the high and (01) CLR TSKIPS+2 ; low total records skipped. (01) .ENDC ; T$SKIP CLR O.CREC(R5) ; Initialize the current CLR O.CREC+2(R5) ; record number. CLR O.HREC(R5) ; Initialize the highest CLR O.HREC+2(R5) ; record number. CLR O.TOPR(R5) ; Setup the top of MOV #1,O.TOPR+2(R5) ; page record number. CLR O.LCNT(R5) ; Initialize the page line count. ;*** ;*** I prefer to retain the margin for the next file. ;*** ;*** CLR O.MARG(R5) ; Initialize the margin indent. CLRB O.STAT(R5) ; Clear the volitile status bits. BISB #S.FORW,(R5) ; Always start listing forward. ; Initialize the mark buffer fields. MOV O.MRKB(R5),R4 ; Copy the mark buffer address. CLR (R4)+ ; Setup to MOV #1,(R4)+ ; point to CLR (R4)+ ; first record. MOV R4,O.MRKP(R5) ; Save updated mark buffer pointer. CLR O.MRKC(R5) ; Initialize the mark counter. CLR O.LREC(R5) ; Set last record marked MOV #1,O.LREC+2(R5) ; to the first record. CALL CALMRK ; Calculate the mark buffer count. CALL SETUP ; Setup the display parameters. RETURN .SBTTL SETUP - Setup the display parameters. ;+ ; ; SETUP - Setup the display parameters. ; ; This routine is called to setup the display parameters after the file ; is first opened and also from the refresh routine. The refresh routine ; is called by routines which change the display parameters. ; ; Inputs: ; None. ; ; Outputs: ; All registers are preserved. ; ;- SETUP:: CALL $SAVAL ; Save all registers. MOV IENTRY,R5 ; Copy the file entry address. CALL SETWID ; Setup the screen width. ; Calculate the maximum number of lines to display. CALL CALMAX ; Calculate the maximum lines. ; ; If no advanced video option, we can only display 14 lines of ; 132 column lines. Thus, the maximum line count and bottom line ; numbers must be adjusted if we're on a wide screen. ; BIT #B.AVO,SWMASK ; VT100 with advanced video ? BNE 60$ ; If NE, yes (allowed max lines). BIT #B.2FIL,STATUS ; Are we displaying two files ? BNE 60$ ; If NE, yes (presume lines setup). BIT #B.132,STATUS ; Are we in 132 column mode ? BNE 10$ ; If NE, yes (adjust line count). MOV O.DBOT(R5),O.BOT(R5) ; Reset the maximum bottom line. CALL CALMAX ; Calculate the maximum lines. BR 60$ ; Maximum lines on narrow screen. ; On a wide screen, a maximum of 10 lines can be displayed. 10$: CMP R1,#10. ; Is the current line count OK ? (03) BLE 60$ ; If LE, yes (presuming file name).(03) MOV O.DBOT(R5),O.BOT(R5) ; Reset the maximum bottom line. CALL CALMAX ; Calculate the maximum lines. SUB #10.,R1 ; Adjust the maximum line count. (03) MOV R1,R2 ; Copy it. ADD O.TOP(R5),R2 ; Calculate the new bottom line. DEC R2 ; Adjust for top line number. MOV R2,O.BOT(R5) ; Save the new bottom line number. 60$: MOV R1,O.LMAX(R5) ; And save it in the table. CALL ADJSEC ; Calculate the section size. RETURN .SBTTL SETWID - Setup the screen width. ;+ ; ; SETWID - Setup the screen width. ; ; This routine is called to determine the screen width. By default, the ; screen width is determined by the maximum record size. This can be ; overridden with either a user specified screen width or by specifying ; a narrow or wide screen. The width is not changed if displaying two ; files in split screen mode. ; ; Inputs: ; None. ; ; Outputs: ; All registers are preserved. ; ;- SETWID::CALL $SAVAL ; Save all registers. MOV IENTRY,R5 ; Copy the file entry address. BIT #B.2FIL,STATUS ; Are we displaying two files ? BNE 50$ ; If NE, yes (don't change width). BIC #B.132,STATUS ; Presume 80 column mode. ; Check for user specified line width. MOV O.UWID(R5),O.LWID(R5) ; Did the user specify a width ? BEQ 10$ ; If EQ, no. CMP #80.,O.LWID(R5) ; Should we go into wide mode ? BGE 40$ ; If GE, no (leave narrow mode). BR 30$ ; Else, set for wide mode. ; Determine the screen width. 10$: MOV #80.,O.LWID(R5) ; Set the maximum line width. BIT #B.WIDE,SWMASK ; Does user want a wide screen ? BNE 20$ ; If NE, yes (132 column mode). BIT #B.NAR,SWMASK ; Does user want a narrow screen ? BNE 40$ ; If NE, yes (80 column mode). MOV O.FDB(R5),R0 ; Copy the FDB address. CMP #80.,F.RSIZ(R0) ; Should we go to wide mode ? BGE 40$ ; If GE, no (leave narrow mode). ; Set up for 132 column mode. 20$: MOV #132.,O.LWID(R5) ; Set the maximum line width. 30$: BIS #B.132,STATUS ; Show in 132 column mode. ; Copy the line width to the other file entry for two file display. 40$: MOV AENTRY,R4 ; Copy the non-active file entry. MOV O.LWID(R5),O.LWID(R4) ; Copy the active line width. 50$: RETURN .SBTTL CALMAX - Calculate the maximum lines. ;+ ; ; CALMAX - Calculate the maximum line for display. ; ; Inputs: ; R5 = The file entry address. ; ; Outputs: ; R1 = The maximum number of lines. ; ;- CALMAX::MOV O.BOT(R5),R1 ; Copy the bottom line number. SUB O.TOP(R5),R1 ; Calculate the number of lines. INC R1 ; Adjust the count for top line. RETURN .SBTTL CALMRK - Calculate the mark record count. ;+ ; ; CALMRK - Calculate the mark buffer record count. ; ; This routine calculates how often the record position should be marked. ; ; ((blocks_used * records/block)/mark_entrys) = mark_count. ; ; The worst case records/block is based upon the maximum record size. ; ; max_record > 256 use (512/32) = 16 records/block. ; max_record > 100 use (512/16) = 32 records/block. ; max_record > 32 use (512/8) = 64 records/block. ; max_record > 16 use (512/4) = 128 records/block. ; max_record < 16 use (512/2) = 256 records/block. ; ; The mark count is limited to a maximum of 50 records unless overridden. ; The calculation is overridden with the "/MARK=n" switch. ; ; Inputs: ; R5 = The file entry address. ; ; Outputs: ; All registers are preserved. ; ; Implicit outputs: ; O.MARK = The mark buffer record count. ; ;- CALMRK::CALL $SAVAL ; Save all registers. MOV O.UMRK(R5),O.MARK(R5) ; Copy the user specified count. BNE 100$ ; If NE, there is one. MOV #HDRBUF,R4 ; Set address of the header buffer. MOV V.EFBK(R4),R1 ; Copy the high order bits MOV V.EFBK+2(R4),R0 ; and the low order bits. MOV V.RSIZ(R4),R3 ; Copy the maximum record size. MOV #<512./32.>,R2 ; Presume maximum record > 256. CMP R3,#256. ; Did we presume correct ? BGT 10$ ; If GT, yes. MOV #<512./16.>,R2 ; Presume maximum record > 100. CMP R3,#100. ; Did we presume correct ? BGT 10$ ; If GT, yes. MOV #<512./8.>,R2 ; Presume maximum record > 32. CMP R3,#32. ; Did we presume correct ? BGT 10$ ; If GT, yes. MOV #<512./4.>,R2 ; Presume maximum record > 16. CMP R3,#16. ; Did we presume correct ? BGT 10$ ; If GT, yes. MOV #<512./2.>,R2 ; Else, set for very small records. 10$: MUL R2,R0 ; Calculate worst case record count. ; R0 = The high order bits. ; R1 = The low order bits. DIV #MRKLEN,R0 ; Divide by maximum mark entrys. ; R0 = The quotient. ; R1 = The remainder. INC R0 ; Adjust the record count by one. CMP R0,#DEFMOD ; Is the count larger than default ? BLOS 20$ ; If LOS, no (use calculated count). MOV #DEFMOD,R0 ; Else, set the default mark count. 20$: MOV R0,O.MARK(R5) ; Save the mark buffer record count. 100$: RETURN .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 #IN2FDB,R0 ; Address of the 2nd input file. TST F.BDB(R0) ; Is the input file open ? BEQ 20$ ; If EQ, no. CLOSE$ R0 ; Close the second input file. 20$: MOV #OUTFDB,R0 ; Address of the output FDB. TST F.BDB(R0) ; Is an output file open ? BEQ 30$ ; If EQ, no CALL .TRNCL ; Yes, close & truncate it. 30$: RETURN .SBTTL CLOFIL - Close a file (if open). ;+ ; ; CLOFIL - Close a file if it is open. ; ; Inputs: ; R5 = The active file entry address. ; ; Outputs: ; All registers are preserved. ; ;- CLOFIL::JSR R2,$SAVVR ; Save R0 - R2. BIC #S.EOF,(R5) ; Reset the end of file flag. MOV O.FDB(R5),R0 ; Copy the FDB address. 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 WCLOSE ; Close the output file (if any). CALL WRTEOF ; Write the end of file sequence. CALL CLOALL ; Close the input & output files. CLOSE$ #TIFDB ; Now close the CLOSE$ #TOFDB ; terminal input & output CALL DISESC ; Disable the escape sequences. ; And exit with success code. MOV #EX$SUC,R0 ; Set the success status code. ; Exit with the status code in R0. EXST:: EXST$S R0 ; Exit with the status. EXIT$S ; In case EXST$S fails. .END VTL ; Transfer address.