.TITLE DIRFMT - DIR Formatting Routines .IDENT /1.6/ .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: DIRFMT.MAC ; Author: Robin Miller ; Date: February 26, 1985 ; ; Description: ; ; Various formatting routines for the Directory program. ; ;- .ENABL AMA .NLIST BEX .MCALL FCSBT$, FDOFF$, FHDOF$, NBOFF$ FCSBT$ ; Define the FCS bits. FDOFF$ DEF$L ; Define the FDB offsets. FHDOF$ DEF$L ; Define the file header offsets. NBOFF$ DEF$L ; Define the FNB offsets. ;+ ; ; Modification History: ; ; May 16, 1985 by Robin Miller. Edit (06), Version 1.6 ; Add an extra space to the message "" in the ; make date routine so the next field is aligned properly. ; ; April 29, 1985 by Robin Miller. Edit (05), Version 1.5 ; o When selecting files by date, change the "No files found" message ; to "%DIR-W-NOFILES, no file(s) found" to identify our program. ; o Change test of for any files selected to get above message. ; ; April 25, 1985 by Robin Miller. Edit (04), Version 1.4 ; If only displaying the blocks used, then display whether the ; file is contiguous or not. ; ; April 25, 1985 by Robin Miller. Edit (03), Version 1.3 ; o Use the selected file count instead of the directory file count ; when checking for files selected in a directory. ; o Clear the various counters in the DOTAIL routine when no files ; have been selected to for format of the next directory header. ; ; April 11, 1985 by Robin Miller. Edit (02), Version 1.2 ; Add routine DOUFMT to format the user's format string. ; ; April 11, 1985 by Robin Miller. Edit (01), Version 1.1 ; Check for no date and/or time specified in the make date and time ; routines. On ANSI magtapes, the revision date and time is set to ; all zeros. ; ;- .SBTTL DOBREF - Format the brief directory. ;+ ; ; DOBREF - Format the brief directory. ; ; This routine format the file names for a brief directory. This directory ; is displayed in 4 columns by default. If the terminal width is set > 80. ; columns, then 6 columns is used. ; ; Inputs: ; R0 = The output buffer address. ; R5 = The file entry address. ; ; Outputs: ; R0 = The updated buffer address. ; ; All other registers are preserved. ; ;- DOBREF::JSR R5,.SAVR1 ; Save R1 - R5. MOV #M.BREF,FLDMAX ; Set the maximum brief field size. TST COLCNT ; Is this the first column ? BEQ 10$ ; If EQ, yes. PAD ; Pad the previous field with spaces. 10$: MOV O.FNAM(R5),R1 ; Set address of the file name. CALL MOVE ; Copy to the format buffer. INC COLCNT ; Adjust the column counter. CMP COLCNT,NUMCOL ; Reached the maximum column ? BLO 100$ ; If LO, no. CALL TYPMSG ; Yes, display these columns. CLR COLCNT ; Reset the column count to zero. 100$: RETURN .SBTTL DODATE - Format the desired dates. ;+ ; ; DODATE - Format the desired dates. ; ; Inputs: ; R0 = The output buffer address. ; ; Outputs: ; R0 = The updated buffer address. ; ; All other registers are preserved. ; ;- .ENABL LSB DODATE::JSR R5,.SAVR1 ; Save R1 - R5. MOV #HDRBUF,R2 ; Set the file header address. ; If we're displaying all dates and anything else, use a separate line. CMPB #D.ALL,DATESW ; Are we displaying all dates ? BNE 10$ ; If NE, no. BITB #^C,SWMASK ; Displaying anything with date ? BEQ 10$ ; If EQ, no (only the dates). CRLF MOV #M.BREF,FLDMAX ; Setup the maximum field size. PAD 10$: BIT #D.CDAT,DATESW ; Display the creation date ? BEQ 30$ ; If EQ, no. CMPB #D.ALL,DATESW ; Displaying all the dates ? BEQ 20$ ; If EQ, yes (no spacing). MOVB #SPACE,(R0)+ ; Separate fields with a space. 20$: CALL DOCDAT ; Yes, format creation date. 30$: BIT #D.MDAT,DATESW ; Display the modified date ? BEQ 50$ ; If EQ, no. MOVB #SPACE,(R0)+ ; Separate fields with a space. CMPB #D.ALL,DATESW ; Displaying all the dates ? BNE 40$ ; If NE, no. MVS < > 40$: CALL DORDAT ; Yes, format revision date. 50$: BIT #D.EDAT,DATESW ; Display the expiration date ? BEQ 70$ ; If EQ, no. MOVB #SPACE,(R0)+ ; Separate fields with a space. CMPB #D.ALL,DATESW ; Displaying all the dates ? BNE 60$ ; If NE, no. MVS < > 60$: CALL DOEDAT ; Yes, format expiration date. 70$: RETURN .DSABL LSB .SBTTL DOHEAD - Format the directory header. ;+ ; ; DOHEAD - Format the directory header. ; ; This routine is used to format the directory header to display. ; ; Inputs: ; R0 = The output buffer address. ; R5 = The file entry address. ; DIRCNT = The current directory count. ; ; Outputs: ; R0 = The updated buffer address. ; DIRCNT = The adjusted directory count. ; ; All other registers are preserved. ; ;- .ENABL LSB DOHEAD::JSR R5,.SAVR1 ; Save R1 - R5. TST FILCNT ; First file of this directory? (03) BNE 100$ ; If NE, no. INC DIRCNT ; Count the number of directorys. BIT #B.GTOT,SWMASK ; Displaying grand totals only ? BNE 100$ ; If NE, yes (inhibit heading). BIT #B.HEAD,SWMASK ; Should we display the heading ? BEQ 100$ ; If EQ, no. BIT #B.FF,STATUS ; Preceed heading with formfeed ? BEQ 10$ ; If EQ, no. MOVB #FF,(R0)+ ; Yes, add a formfeed character. 10$: CRLF MVS MOV O.DEVU(R5),R1 ; Copy address of device/UIC. CALL MOVEC ; Append it to the buffer. CRLF CRLF 100$: RETURN .DSABL LSB .SBTTL DONAME - Format the device/file name. ;+ ; ; DONAME - Format the device/file name. ; ; This routine is used to format the file name to be displayed. If the ; file header has been disabled, then the device/uic is also displayed. ; ; Inputs: ; R0 = The output buffer address. ; R5 = The file entry address. ; ; Outputs: ; R0 = The updated buffer address. ; ; All other registers are preserved. ; ;- DONAME::JSR R5,.SAVR1 ; Save R1 - R5. BIT #B.HEAD,SWMASK ; Has the heading been disabled ? BNE 10$ ; If NE, no. MOV O.DEVU(R5),R1 ; Yes, copy device/UIC address. CALL MOVEC ; And append to the buffer. 10$: MOV #M.FNAM,FLDMAX ; Set the maximum file name size. MOV O.FNAM(R5),R1 ; Set address of the file name. CALL MOVE ; Copy to the format buffer. TSTB SWMASK ; Are there any other fields ? BEQ 100$ ; If EQ, no (breif format). PAD ; Pad the file name field. 100$: RETURN .SBTTL DOPROT - Format the file protection. ;+ ; ; DOPROT - Format the file protection. ; ; Inputs: ; R0 = The output buffer address. ; ; Outputs: ; R0 = The updated buffer address. ; ; All other registers are preserved. ; ;- DOPROT::JSR R5,.SAVR1 ; Save R1 - R5. MOVB #SPACE,(R0)+ ; Separate fields with a space. MOV #HDRBUF,R2 ; Set the file header address. MOV V.PROT(R2),R3 ; Copy the protection code. ; Setup the system protection. MOVB #'[,(R0)+ ; Start with a left bracket. CALL SETPRO ; Move in the protection. ; Setup the owner protection. MOVB #COMMA,(R0)+ ; Separate with a comma. ASH #-4,R3 ; Shift bits into place. CALL SETPRO ; Move in the protection. ; Setup the group protection. MOVB #COMMA,(R0)+ ; Separate with a comma. ASH #-4,R3 ; Shift bits into place. CALL SETPRO ; Move in the protection. ; Setup the world protection. MOVB #COMMA,(R0)+ ; Separate with a comma. ASH #-4,R3 ; Shift bits into place. CALL SETPRO ; Move in the protection. MOVB #'],(R0)+ ; End with a right bracket. CLRB (R0) ; Terminate the output buffer. RETURN .SBTTL DOSIZE - Format the file size(s). ;+ ; ; DOSIZE - Format the file sizes. ; ; This routine is used to format the blocks used and/or blocks allocated ; by a file. ; ; Inputs: ; R0 = The output buffer address. ; ; Outputs: ; R0 = The updated buffer address. ; ; All other registers are preserved. ; ;- .ENABL LSB DOSIZE::JSR R5,.SAVR1 ; Save R1 - R5. MOVB #SPACE,(R0)+ ; Separate fields with a space. CLF ; Clear the current field size. ; Field format: blocks_used/blocks_allocated MOV #M.FSIZ,FLDMAX ; Set the maximum field width. MOV #HDRBUF,R2 ; Set the file header address. ; If the file is locked, don't display the block sizes. BITB #UC.DLK,V.UCHA(R2) ; Is the file deaccess-locked ? BEQ 10$ ; If EQ, no. DEC R0 ; Overwrite the first space. MVS <*** LOCKED ***> BR 50$ ; And use common code ... ; Format the number of blocks used. 10$: BIT #B.SIZU,SWMASK ; Both size used and allocated ? BEQ 30$ ; If EQ, no (allocated only). MOV R2,R1 ; Copy the header record address. ADD #V.EFBK,R1 ; Point to the end of file block. CALL CVTDBL ; Convert double decimal number. BIT #B.SIZA,SWMASK ; Format size allocated also ? BNE 20$ ; If NE, yes. (04) CALL ADDCON ; Check/add contiguity flag. (04) BR 50$ ; And continue ... (04) ; Format the number of blocks allocated. 20$: MVS ; Separate used from allocated. 30$: MOV R2,R1 ; Copy the header record address. ADD #V.HIBK,R1 ; Point to the high block number. BIT #B.SIZU,SWMASK ; Both size used and allocated ? BNE 40$ ; If NE, yes. CALL CVTDBL ; No, allocated blocks only. CALL ADDCON ; Check/add contiguity flag. (04) BR 50$ ; And continue ... 40$: CALL CVTDTD ; Convert double decimal number. 50$: BITB #^C,SWMASK ; Displaying any other fields ? BEQ 60$ ; If EQ, no. PAD ; Yes, pad the file size field. 60$: RETURN .DSABL LSB .SBTTL ADDCON - Add contiguity flag after size. ;+ ; ; ADDCON - Add contiguity flag after the file size. ; ; This routine checks for and adds the contiguity flag following the ; file size if other fields are being displayed. ; ; Inputs: ; R0 = The output buffer address. ; R2 = The header buffer address. ; ; Outputs: ; R0 = The updated output buffer address. ; ; All other registers are preserved. ; ;- .ENABL LSB ADDCON: JSR R5,.SAVR1 ; Save R1 - R5. Added for edit (04) BITB #^C,SWMASK ; Displaying any other fields? BEQ 100$ ; If EQ, no. BITB #,V.UCHA(R2) ; Is the file contiguous ? BEQ 100$ ; If EQ, no. MVS < C> ; Show file is contiguous. 100$: RETURN .DSABL LSB .SBTTL DOTAIL - Format/write the directory trailer. ;+ ; ; DOTAIL - Format/write the directory trailer. ; ; This routine is used to format and write the directory trailer. ; ; Inputs: ; R0 = The output buffer address. ; ; Outputs: ; R0 = The starting buffer address. ; ; All other registers are preserved. ; ;- .ENABL LSB DOTAIL::JSR R5,.SAVR1 ; Save R1 - R5. TST SELCNT ; Any files in this directory ? (03) BNE 10$ ; If NE, yes. TST FILCNT ; First file of this directory? (03) BEQ 70$ ; If EQ, yes (leave CR/LF). (03) ; ; If no files were selected in this directory, reset the starting ; buffer address to prevent the directory header from being displayed. ; MOV BUFADR,R0 ; Reset the starting address. BR 70$ ; Use common return ... 10$: TSTB SWMASK ; Is this a brief directory ? BNE 20$ ; If NE, no. TST COLCNT ; Partial columns formatted ? BEQ 20$ ; If EQ, no. CRLF CLR COLCNT ; Yes, clear the column count. 20$: BIT #B.GTOT,SWMASK ; Displaying grand totals only ? BNE 60$ ; If NE, yes (skip trailing). BIT #B.TAIL,SWMASK ; Should we display trailer ? BEQ 60$ ; If EQ, no (user disabled). CRLF MVS MOV SELCNT,R1 ; Copy the selected file count. (03) CALL CVTDEC ; Convert it to decimal. MVS < files> CMP SELCNT,#1 ; More than one file ? (03) BHI 30$ ; If HI, yes. DEC R0 ; Else, set to overwrite the "s". ; If we read any file headers, format blocks used/allocated. 30$: TST HREADS ; Did we read any file headers ? BEQ 50$ ; If EQ, no. MVS <, > MOV #DIRUBK,R1 ; Set address of blocks used. CALL CVTDTD ; Convert it to decimal ASCII. MVS MOV #DIRABK,R1 ; Set address of blocks allocated. CALL CVTDTD ; Convert it to decimal ASCII. MVS < blocks> CMP DIRABK+2,#1 ; More than one block allocated ? BHI 40$ ; If HI, yes. DEC R0 ; Else, set to overwrite the "s". 40$: MVS < used/allocated> 50$: MVS <.> CRLF CALL VTYPE ; Write trailer to the terminal. ; Accumulate the total file/block counts. 60$: ADD SELCNT,TOTCNT ; Accumulate total file count. (03) ADD DIRABK+2,TOTABK+2 ; Accumulate total blocks allocated. ADC TOTABK ; Add the overflow (if any). ADD DIRABK,TOTABK ; Now add the high bits. ADD DIRUBK+2,TOTUBK+2 ; Accumulate total blocks used. ADC TOTUBK ; Add the overflow (if any). ADD DIRUBK,TOTUBK ; Now add the high bits. ; Clear the directory counters. 70$: CLR FILCNT ; Clear directory file count. CLR SELCNT ; Clear selected files count. CLR DIRUBK ; Clear blocks used CLR DIRUBK+2 ; for the next directory. CLR DIRABK ; Clear block allocated CLR DIRABK+2 ; for the next directory. RETURN .DSABL LSB .SBTTL DOUFMT - Format the users' format string. ;+ ; ; DOUFMT - Format the users' format string. ; ; This routine is used to decode and format the users' format string. ; The following characters get expanded as followes: ; ; $F The expanded file name. ; $D The device name field. ; $N The file name field. ; $T The file type field. ; $U The file UIC field. ; $V The file version field. ; ; Inputs: ; R0 = The output buffer address. ; ; Outputs: ; R0 = The updated buffer address. ; ; All other registers are preserved. ; ; *** This routine added for edit number (02) *** ;- DOUFMT::JSR R5,.SAVR1 ; Save R1 - R5. MOV SOFFMT,R2 ; Copy starting format address. 10$: TSTB (R2) ; At end of the format string ? BEQ 100$ ; If EQ, yes (all done). MOVB (R2)+,(R0) ; Copy the next character. CMPB (R0)+,#'$ ; Is this a special character ? BNE 10$ ; If NE, no (check the next). MOVB (R2)+,(R0) ; No, copy the next character. BEQ 100$ ; If EQ, end of format string. CALL CUCHAR ; Convert character to uppercase. MOVB (R0),R3 ; Copy the uppercase character. DEC R0 ; Point to the dollar sign. ; Check for $D for the device name field. CMPB R3,#'D ; Want the device name ? BNE 20$ ; If NE, no. MOV O.DEVU(R5),R1 ; Copy the device name address. 15$: CMPB (R1),#"[ ; Start of the owner UIC ? BEQ 10$ ; If EQ, yes (end of device). MOVB (R1)+,(R0)+ ; No, copy the device name. BR 15$ ; And check the next character. ; Check for $F for the expanded file name. 20$: CMPB R3,#'F ; Want the expanded file name ? BNE 30$ ; If NE, no. MOV O.DEVU(R5),R1 ; Yes, copy device/UIC address. CALL MOVEC ; And append to the buffer. MOV O.FNAM(R5),R1 ; Copy address of the file name. CALL MOVEC ; And append to the buffer. BR 10$ ; Check the next character. ; Check for $N for the file name field. 30$: CMPB R3,#'N ; Want the file name ? BNE 40$ ; If NE, no. MOV O.FNAM(R5),R1 ; Copy address of the file name. 35$: CMPB (R1),#'. ; Start of the file type ? BEQ 10$ ; If EQ, yes (end of file name). MOVB (R1)+,(R0)+ ; No, copy the file name. BR 35$ ; And check the next character. ; Check for $T for the file type field. 40$: CMPB R3,#'T ; Want the file type ? BNE 50$ ; If NE, no. MOV SOFTYP,R1 ; Set start of file type field. 45$: CMPB (R1),#'; ; Start of the version number ? BEQ 10$ ; If EQ, yes (end of file type). MOVB (R1)+,(R0)+ ; No, copy the file type. BR 45$ ; And check the next character. ; Check for $U for the file UIC field. 50$: CMPB R3,#'U ; Want the file UIC field. BNE 60$ ; If NE, no. MOV SOFUIC,R1 ; Set start of file UIC field. CALL MOVEC ; Append to the output buffer. BR 10$ ; And check the next character. ; Check for $V for the file version number field. 60$: CMPB R3,#'V ; Want the file version field ? BNE 70$ ; If NE, no. MOV SOFVER,R1 ; Set start of version # field. CALL MOVEC ; Append to the output buffer. BR 10$ ; And check the next character. ; Not a valid string to expand, so just copy it. 70$: INC R0 ; Point past the dollar sign. MOVB -1(R2),(R0)+ ; Copy original input character. BR 10$ ; Now, check the next character. 100$: RETURN .SBTTL GTOTAL - Format/write the grand totals. ;+ ; ; GTOTAL - Format and write the grand totals. ; ; This routine is used to format and write the grand totals. These totals ; are only displayed if there was more than one directory displayed. ; ; Inputs: ; R0 = The output buffer address. ; ; Outputs: ; R0 = The starting buffer address. ; ; All other registers are preserved. ; ;- .ENABL LSB GTOTAL::JSR R5,.SAVR1 ; Save R1 - R5. ; ; If we were selecting files by a date and we did not find any, ; let the user know that no files were found. ; TST TOTCNT ; Were any files selected ? (05) BNE 10$ ; If NE, yes. (05) MOV BUFADR,R0 ; Yes, set starting address. BIT #B.OFIL,STATUS ; Writing to an output file ? BNE 5$ ; If NE, yes. CRLF ; No, add carriage control. 5$: MVS <%DIR-W-NOFILES, no file(s) found> ; (05) BR 20$ ; Use common code ... ; If more than one directory searched, display grand totals. 10$: CMP DIRCNT,#1 ; More than one directory ? (05) BLOS 100$ ; If LOS, no. (05) BIT #B.TAIL,SWMASK ; Should we display trailer ? BEQ 100$ ; If EQ, no (user disabled). CRLF MVS MOV DIRCNT,R1 ; Copy the directory count. CALL CVTDEC ; Convert it to decimal. MVS < directories, > MOV TOTCNT,R1 ; Copy the total file count. CALL CVTDEC ; Convert it to decimal. MVS < files> ; If we read any file headers, format blocks used/allocated. TST HREADS ; Did we read any file headers ? BEQ 20$ ; If EQ, no. MVS <, > MOV #TOTUBK,R1 ; Set address of blocks used. CALL CVTDTD ; Convert it to decimal ASCII. MVS MOV #TOTABK,R1 ; Set address of blocks allocated. CALL CVTDTD ; Convert it to decimal ASCII. MVS < blocks> CMP TOTABK+2,#1 ; More than one block allocated ? BHI 20$ ; If HI, yes. DEC R0 ; Set to overwrite the "s". 20$: MVS <.> CALL TYPMSG ; Write it to the terminal. 100$: RETURN .DSABL LSB .SBTTL MAKDAT - Make the ASCII date. ;+ ; ; MAKDAT - Make the ASCII date. ; ; This routine is used to format the ASCII date read from the file header. ; ; Inputs: ; R0 = The output buffer address. ; R1 = The date buffer address. ; ; Outputs: ; R0 = The updated output buffer address. ; ; All other registers are preserved. ; ;- .ENABL LSB MAKDAT::JSR R5,.SAVR1 ; Save R1 - R5. MOV R0,-(SP) ; Save the buffer address. ; If the first byte is zero, presume no date. TSTB (R1) ; Is the first byte zero ? (01) BNE 10$ ; If NE, no (presume date). (01) MOVB #'<,(R0)+ ; Put in left angle bracket. (01) ; dd-mmm-yyyy hh:mm ; Format of the date/time field.(06) MVS ; (06) MOVB #'>,(R0)+ ; End with right angle bracket. (01) MOVB #SPACE,(R0)+ ; Pad the field with a space. (06) BR 30$ ; And use common code ... (01) ; Format the date: dd-mmm-yy or yyyy for VMS. 10$: MOVB (R1)+,(R0)+ ; Move in the MOVB (R1)+,(R0)+ ; day of month. MOVB #'-,(R0)+ ; Separate with minus sign. MOVB (R1)+,(R0)+ ; Move in the MOVB (R1)+,(R0)+ ; month of MOVB (R1)+,(R0)+ ; the year. MOVB #'-,(R0)+ ; Separate with a minus sign. ; ; I like the VMS date format better. ; ;*** TSTB VAXFLG ; Are we running on VAX/VMS ? ;*** BEQ 20$ ; If EQ, no (must be RSX-11M). MOVB #'1,(R0)+ ; Make system MOVB #'9,(R0)+ ; default date. 20$: MOVB (R1)+,(R0)+ ; Move in the MOVB (R1)+,(R0)+ ; year of decade. 30$: MOV R0,R1 ; Copy the buffer address. SUB (SP)+,R1 ; Calculate the field width. ADD R1,FLDSIZ ; Adjust the current field size. CLRB (R0) ; Terminate the output buffer. RETURN .DSABL LSB .SBTTL MAKTIM - Make the ASCII time. ;+ ; ; MAKTIM - Make the ASCII time. ; ; This routine is used to format the ASCII time read from the file header. ; ; Inputs: ; R0 = The output buffer address. ; R1 = The time buffer address. ; ; Outputs: ; R0 = The updated output buffer address. ; ; All other registers are preserved. ; ;- MAKTIM::JSR R5,.SAVR1 ; Save R1 - R5. ; If the first byte is zero, presume no time. TSTB (R1) ; Is there a valid time ? (01) BEQ 100$ ; If EQ, presume no. (01) ; Format the time: hh:mm:ss MOV R0,-(SP) ; Save the buffer address. MOVB #SPACE,(R0)+ ; Space between date and time. MOVB (R1)+,(R0)+ ; Move in the MOVB (R1)+,(R0)+ ; hour of the day. MOVB #':,(R0)+ ; Separate with a colon. MOVB (R1)+,(R0)+ ; Move in the MOVB (R1)+,(R0)+ ; minute of the hour. ; ; Don't display the seconds field. ; ;*** MOVB #':,(R0)+ ; Separate with a colon. ;*** MOVB (R1)+,(R0)+ ; Move in the ;*** MOVB (R1)+,(R0)+ ; second of the minute. MOV R0,R1 ; Copy updated buffer address. SUB (SP)+,R1 ; Calculate the field count. ADD R1,FLDSIZ ; Adjust the current field size. CLRB (R0) ; Terminate the output buffer. 100$: RETURN .END