.TITLE DIRLST-LIST THE DIRECTORY .IDENT /V2.0/ ;FORMERLY SRDLST ; SRD**UPDATE AUDIT CONTROL-13 NOV 1979 12:08:30 ;**V5.0 ; EDIT # 0057 5 Dec 1979 9:44:04 DR1:[300,3]SRDLST.MAC;75 ; PREVIOUS EDIT 2 NOV 1979 14:44:46 DK1:[300,3]SRDLST.MAC;72 ;**V5.0 ;+ ;**-1 ; ;**SRD--SORT DIRECTORY ; ;THIS MODULE CREATS A SELECTIVE LISTING OF THE FILE ; ; ; THIS TASK WILL SORT A RSX11 DIRECTORY ;**V5.0 ;THEN CREATE A LISTING WITH MANY SELECTION OPTIONS ;**-1 ; ;******************************************************************************* ; ; DIRLST; FORMERLY SRDLST. SEVERAL DIFFERENCES FROM SRDLST INCLUDE ; DEFINING THE PURGE OPERATION FOR DELETION OF ALL BUT HIGHEST ; VERSION NUMBER (DEFAULT) OR EVEN ALL BUT LOWEST VERSION NUMBER ; IF SELECTED VERSION = -1. ; ; LISTING OPTIONS : LISW =BRIEF ; LISW!MISW =MIDDLE ; LISW!FUSW =FULL ; ; THIS VERSION ALTERED TO OUTPUT DIRECTORY LISTINGS IN MORE STANDARD ; RSX11M "PIP" FORMAT. ; ; PAUL SORENSON ; PULMONARY RESEARCH ; S3, MAYO CLINIC ; ROCHESTER, MN 55904 ; ;***** ; ; LAST UPDATE 8/80--PRS ; ; UPDATE 2/10/82 -- PRS; MOVE CODE FOR HEADER/TRAILER MESSAGES AND ; PUTTING LINES INTO LISTING FILE TO SEPARATE SUBROUTINES. ; ADD SUPPORT FOR [Y/N/G/Q] SELECTIVE DELETE OPITONS LIKE NEWER ; SRD'S. ; ; UPDATE 3/82 -- PRS; ADD SUPPORT FOR "/NULL", "/LOCKED" AND "/EXP" ; SWITCHES TO SELECT NULL LENGTH, LOCKED, AND EXPIRED FILES. ; EXPIRATION DATE SELECTION IS NOT CURRENTLY SUPPORTED ; (SEE COMMENTS IN DIRPRE.MAC). ; ; UPDATE 4/82 -- PRS; CHANGED SELECTIVE LISTING OPTIONS AND SWITCH ; MASK WORDS TO MAKE CHECKING ALL DESIRED OPTIONS EASIER. ; ;***** ; ; ;THIS IS THE MAIN ROUTINE, AND IS PURE. ; ; ;- ; ;SYSTEM MACRO CALLS ; .MCALL FHDOF$,DIR$,QIOW$S,WTSE$S FHDOF$ DEF$L .PSECT $IDATA,RW,D,LCL,REL,CON ENDTBL: .WORD 0 ;SET TO END OF TABLE ADDRESS FOR DESIRED ; LISTING FORMAT SETMSK: ;SET APPROPRIATE BITS IN THIS WORD ; AS AN ENTRY PASSES SELECTION CRITERIA ENDFIL: .WORD 0 ; ONCE SELECT ENTRY, KEEP POINTER TO END OF ; ASCII FILE NAME STRING FOR ERROR MESSAGES ; ; OUTPUT FORMAT TABLES: 1ST BYTE=FIELD LENGTH, 2ND BYTE=OFFSET ; SPECIFIER, 3RD AND 4TH BYTE=JUMP ADDRESS ; .PSECT $PDATA,RO,D,LCL,CON,REL FULTBL: .BYTE 16.,H.FNUM ;FULL LIST, OUTPUT FILE ID FIRST .WORD FIDCV MIDTBL: .BYTE 14.,H.UFAT+F.EFBK+2 ;OUTPUT USED/ALLOCATED BLOCKS .WORD SIZECV .BYTE 3.,H.UCHA ;SHOW CONTIGUOUS AND LOCKED STATUS .WORD CONTIG .BYTE 10.,I.CRDT ;SHOW CREATION DATE/TIME .WORD DATE .BYTE 7.,I.CRTI .WORD TIME ENDMID: .BYTE 10.,H.PROG ;SHOW OWNER .WORD UICCV .BYTE 23.,H.FPRO ;SHOW PROTECTION STATUS .WORD FPROCV .BYTE 10.,I.RVDT ;SHOW REVISION DATE/TIME .WORD DATE .BYTE 6.,I.RVTI .WORD TIME .BYTE 10.,I.RVNO ; AND REVISION # .WORD REVNUM .IF DF EX$DAT .BYTE 15.,I.EXDT ;OUTPUT EXPIRATION DATE .WORD EXPDAT ; IF SUPPORTED .ENDC ENDFUL: .WORD 0 ; ; DEFINE DEFAULT EXPIRATION DATE FOR FILES THAT HAVEN'T HAD EXP. ; DATE SETUP YET ; .IF DF EX$DAT DEFEXP: .ASCIZ /31DEC99/ EXPSTR: .ASCIZ /EXP: / .ENDC ;EX$DAT DATSTR: .BYTE 2,'-,3,'-,2,0 TIMSTR: .BYTE 2,':,2,0 .EVEN .ENABL LC ; ; DELETE MESSAGE ; DELMSG: .ASCIZ /Delete / DELASK: .ASCIZ % [Y/N/G/Q] ? % .EVEN .DSABL LC .PSECT $CODE1,RO,I,LCL,CON,REL ; ;***** ; ; DIRECTORY IS SORTED,NOW GENERATE LISTING ; ; LISTING RECORDS ARE ALL BUILT IN "LINBUF" BUFFER ; SELECTIVE DELETE PROMPTS ARE BUILT IN "PRMPT" BUFFER ; ;***** ; .DRLST:: ;ENTRY POINT MOV #LINBUF,LSTFDB+F.NRBD+2 ;SET START ADDRESS OF LISTING RECORDS ; INTO LISTING FDB MOV DIRBF$,R5 ;SET START OF DIRECTORY BUFFER ; ;***** ; UNPACK: TST (R5) ;ANY THING REMAINING TO UN-PACK? BNE 10$ ;YES, CONTINUE CLC ;ALL DONE, SIGNAL SUCCESS RETURN ; AND EXIT 10$: CLR SETMSK ;CLEAR MASK WORD FOR THIS ENTRY MOV R5,READHD+Q.IOPL ;SAVE POINTER TO FILE ID IN CASE ; HEADER IS NEEDED .IF DF ST$DAT ;INCLUDE IF SUPPORT SETTING FILE DATES MOV R5,WRITHD+Q.IOPL ;SAVE FID IN CASE NEED TO WRITE ; ATTRIBUTES .ENDC ;ST$DAT MOV #LINBUF,R0 ;FETCH POINTER TO START OF LISTING REC ; ;***** ; ; SETUP FILE NAME-TYPE FIELDS IN LISTING RECORD, CHECK IF ; ENTRY MATCHES DESIRED FILE SPEC. ; ; NOTE: KEEP R5 POINTING TO START OF FILE ENTRY UNTIL ALL ; THROUGH WITH THE ENTRY. ; ;***** ; CKFILE: MOV R5,R4 ;COPY FILE ENTRY POINTER ADD #D.FNAM,R4 ;POINT AT FILE-NAME PORTION MOV #3,R3 ;NUMBER OF WORDS IN NAME 20$: MOV (R4)+,R1 ;GET A RADIX-50 WORD CALL $C5TA ;CONVERT TO ASCII DEC R3 ;COUNT NUMBER OF ENTRIES DONE BGT 20$ ;BR IF STILL DOING NAME BMI 30$ ;BR IF JUST DID TYPE MOVB #'.,(R0)+ ;SEPARATE NAME AND TYPE BR 20$ ;---AND DO TYPE 30$: MOVB #';,(R0)+ ;SEPARATE TYPE AND VERSION BIT #SESW,SWMS1$ ;IS THIS A SELECTIVE LIST? BEQ 40$ ;BR IF NO MOV #SEBUF$,R2 ;SET SELECTION STRING ADDRESS MOV #LINBUF,R1 ;SET START OF NAME CALL .DRTST ;SEE IF MATCHES DESIRED FILE SPEC. BCS 40$ ;BRANCH IF NO BIS #SESW,SETMSK ;YES, FLAG IT 40$: ; ;***** ; ; CHECK FILE VERSION ; ; HANDLE PURGE OPERATION-- SELECTING VERSION "0" (NORMAL MODE) WILL ; DELETE ALL BUT NEWEST VERSION OF A FILE, WHICH MEANS ALL OLDER ; VERSIONS SHOULD BE FLAGGED AS MATCHING DESIRED VERSION #. ; SELECTING VERSION "-1" WILL DELETE ALL BUT OLDEST VERSION OF A FILE, ; WHICH MEANS ALL NEWER VERSIONS SHOULD BE FLAGGED AS MATCHING DESIRED ; VERSION #. ; ;***** ; CKVER: MOV D.VER(R5),R1 ;FETCH ENTRY'S VERSION # BIT #PUSW,SWMSK$ ;PURGE SELECTED ? BNE 1$ ;YES, LOOK AT WHICH VERSION BIT #SVSW,SWMS1$ ;SELECTED VERSION SEARCH ? BEQ 40$ ;NO, DONE 1$: MOV #-D.SIZ,R3 ;ANTICIPATE CHECKING PREVIOUS ENTRY MOV SVNUM$,R2 ;FETCH VERSION NUMBER SELECTED BGT 25$ ;BRANCH IF > 0, CHECK VERSION #'S BEQ 10$ ;BRANCH IF = 0, LOOK FOR NEWEST ;USING FACT THAT IF PREVIOUS ENTRY HAS ;SAME NAME, THIS ENTRY CAN'T BE NEWEST TST D.SIZ(R5) ;IF < 0, LOOK FOR OLDEST USING FACT ;THAT IF NEXT ENTRY HAS SAME NAME, ;THIS ENTRY CAN'T BE OLDEST. BEQ 20$ ;BR ON END-OF-LIST, CAN'T MATCH NAME NEG R3 ;READJUST OFFSET TO LOOK AT NEXT ENTRY 10$: MOV R5,R2 ;COPY CURRENT POINTER ADD #D.FNAM,R2 ;POINT IT TO FILENAME ADD R2,R3 ;SET R3 TO POINT AT PREV/NEXT FILENAME MOV #4,R4 ;SET # WORDS IN NAME 15$: CMP (R3)+,(R2)+ ;NAMES MATCH ? BNE 20$ ;NO, GET OUT SOB R4,15$ ;YES, DO ALL FOUR WORDS BIT #PUSW,SWMSK$ ;IF HERE NAMES MATCH, DOING PURGE ? BNE 30$ ;SAME NAME AND PURGE, CORRECT VERSION BR 40$ ;NOT PURGING, INCORRECT VERSION 20$: BIT #PUSW,SWMSK$ ;IF HERE NAMES DON'T MATCH, ; DOING PURGE ? BNE 40$ ;YES, INCORRECT VERSION BR 30$ ;NO, CORRECT VERSION ; ;***** ; 25$: ;CHECK EXPLICIT VERSION # CMP R1,R2 ;IS THIS THE RIGHT VERSION ? BNE 40$ ;NO, DON'T FLAG IT 30$: BIS #SVSW,SETMSK ;SET BIT, MATCHED DESIRED VERSION # 40$: CLR R2 ;SET ZERO SUPPRESSION FLAG CALL $CBOMG ;PUT VERSION # INTO LISTING RECORD ; ;***** ; ; TIME TO SEE IF ENTRY MAKES FIRST CUT OR NOT ; ; CURRENTLY SUPPORT NEGATED SELECTION OPTION FOR FILE NAME-TYPE ; AND VERSION ONLY, E.G. "/EXCLUDE" SWITCH SELECTS ALL FILES THAT ; DON'T MATCH THE ENTERED FILE SPEC. ; ;***** ; CKEXC: ;CHECK IF SHOULD EXCLUDE ENTRY ADD #D.SIZ,R5 ;SET R5 TO NEXT ENTRY NO MATTER WHAT MOV SWMS1$,R1 ;FETCH SELECTED LISTING OPTIONS BIC #^C,R1 ;GRAB ONLY SESW AND SVSW BITS CMP R1,SETMSK ;COMPARE WHAT'S BEEN FLAGGED SO FAR BEQ 10$ ;BRANCH IF IDENTICAL ; BIT #NESW,SWMSK$ ;FILE NOT SELECTED, EXCLUDING SELECTED ; FILES ? BEQ UNPACK ;BRANCH IF NO, SKIP ENTRY BR 20$ ;ELSE, INCLUDE FILE IN OPERATION 10$: BIT #NESW,SWMSK$ ;FILE SELECTED, EXCLUDING SELECTED ; FILES ? BNE UNPACK ;BRANCH IF YES, SKIP ENTRY 20$: ;ELSE, INCLUDE FILE IN OPERATION MOV R1,SETMSK ;FORCE LOCAL MASK WORD = SESW!SVSW OF ; SELECTION MASK WORD .PAGE ; ;***** ; ; CHECK IF NEED TO READ FILE'S HEADER ; ;***** ; CKHDR: BIT #,SWMSK$ ;FULL/MIDDLE LISTING ? BNE 10$ ;BRANCH IF YES, NEED FILE HEADER BIT #,SWMS1$ ;SELECTED LISTING ; OPTIONS ? BNE 10$ ;BRANCH IF YES, NEED FILE HEADER BIT #,SWMS2$ ;ANY OTHER ; DATE STUFF BNE 10$ ;BRANCH IF YES, NEED FILE HEADER JMP LSTENT ;NO, SKIP READING FILE HEADER 10$: CLR HDBUF$ ;ZERO THIS WORD FOR FCP DIR$ #READHD ;READ THE FILE HEADER BCC 20$ CALL $ALERR BR 10$ 20$: WTSE$S #DSKEFN CMPB IOSB$,#IS.SUC ; OKAY? BEQ 40$ CMPB IOSB$,#IE.SQC ; FILE ID/SEQ NUMBER CHECK BNE 25$ DIAG SQCHK BR 35$ 25$: CMPB IOSB$,#IE.PRI ; PRIV BEQ 30$ DIAG HDRE ; SOME OTHER ERROR BR 35$ 30$: DIAG HDPRV ; ;***** ; ; IN EVENT OF SOME PROBLEM READING FILE HEADER, SEND FILE ; NAME TO TERMINAL ALONG WITH DIAGNOSTIC ; ;***** ; 35$: CALL TYPEIT ;TYPE FILE NAME JMP UNPACK ;MOVE ON TO NEXT ENTRY 40$: ; ;***** ; ; CHECK FILE DATES ; ;***** ; CKDATE: BIT #,SWMS1$ ;DOING ANY DATE SELECTIONS ? BEQ 40$ ; BRANCH IF NO MOVB HDBUF$+H.IDOF,R1 ;GET WORD OFFSET TO IDENT AREA ASL R1 ;MAKE IT A BYTE OFFSET ADD #HDBUF$,R1 ;POINT AT IDENT AREA ADD #I.CRDT,R1 ;POINT TO CREATION DATE BIT #CDSW,SWMS2$ ;USE CREATION DATE ?? BNE 20$ ; BRANCH IF YES BIT #RDSW,SWMS2$ ;USE REVISION DATE ?? BEQ 10$ ; BRANCH IF NO TST (R1) ;EVER REVISED ?? BEQ 20$ ;NO--USE CREATION DATE ADD #,R1 ;YES -- POINT R1 AT REVISION DATE BR 20$ 10$: .IF DF EX$DAT BIT #EDSW,SWMS2$ ;USE EXPIRATION DATE ? BEQ 20$ ;BRANCH IF NO ADD #,R1 ; YES -- POINT R1 AT EXPIRATION DATE TSTB (R1) ;CHECK ENTRY-SHOULD BE IN ASCII BNE 20$ ;BRANCH IF DEFINED MOV #DEFEXP,R1 ;ELSE, USE A DEFAULT EXPIRATION DATE .ENDC 20$: MOV R0,-(SP) ;FREE UP R0 MOV R1,R0 ;MOVE DATE POINTER TO R0 CALL .DRCDI ;CONVERT DATE TO INTEGER MOV (SP)+,R0 ;RESTORE LISTING LINE POINTER BCC 30$ ;BRANCH ON GOOD DATE FERR BADD ;FATAL ERROR ON BAD DATE ; ;***** ; ; CHECK THREE DATE SELECTION VALUES; SPECIFIC DATE, BEFORE A ; SPECIFIC DATE, AND AFTER A SPECIFIC DATE. ; BEFORE AND AFTER DATES ARE NOW EXCLUSIVE (!!!) OF DATE SPECIFIED. ; ; DATE VALUES MUST BE DEFINED OR SET TO FOLLOWING "DISABLED" STATES ; (HANDLED BY MODULE "INIT2"): ; DAVAL$=-1, BEVAL$=0, AFVAL$=-1 ; AND ARE HANDLED AS 16 BIT UNSIGNED INTEGERS ; ;***** ; 30$: CMP R1,DAVAL$ ;CHECK IF DATE MATCHES SELECTED VALUE BNE 33$ ;BRANCH IF NO BIS #DASW,SETMSK ;YES, FLAG MATCH 33$: CMP R1,BEVAL$ ;CHECK IF DATE VALUE LESS THEN BEFORE VALUE BHIS 36$ ;BRANCH IF NO BIS #BESW,SETMSK ;YES, FLAG MATCH 36$: CMP R1,AFVAL$ ;CHECK IF DATE VALUE GREATER THEN AFTER VALUE BLOS 40$ ;BRANCH IF NO, DONE BIS #AFSW,SETMSK ;YES, FLAG MATCH 40$: ; ;***** ; ; CHECK FOR MISC. OTHER SELECTION OPTIONS ; ;***** ; CKMISC: MOVB HDBUF$+H.UCHA,R1 ;FETCH USER CHARACTERISTICS BYTE BIT #LKSW,SWMS1$ ;CHECKING FOR LOCKED FILES ? BEQ 5$ ;BRANCH IF NO BIT #UC.DLK,R1 ;IS FILE LOCKED? BEQ 5$ ;BRANCH IF NO BIS #LKSW,SETMSK ;YES, FLAG IT 5$: BIT #COSW,SWMS1$ ;CHECKING FOR CONTIGUOUS FILES ? BEQ 10$ ;BRANCH IF NO BIT #UC.CON,R1 ;IS FILE CONTIGUOUS ? BEQ 10$ ;BRANCH IF NO BIS #COSW,SETMSK ;YES, FLAG IT 10$: BIT #NLSW,SWMS1$ ;CHECKING FOR NULL LENGTH FILES ? BEQ 20$ ;BRANCH IF NO MOV HDBUF$+H.UFAT+F.EFBK+2,R2 ; FETCH USED BEQ 19$ TST HDBUF$+H.UFAT+F.FFBY ; 1ST FREE BYTE = 0? BNE 15$ DEC R2 ; YES--DON'T COUNT THE BLOCK 15$: TST R2 ;CHECK FILE LENGTH BNE 20$ ;BRANCH IF NON-0 19$: BIS #NLSW,SETMSK ;FLAG NULL LENGTH FILE 20$: ; ;***** ; ; TIME TO CHECK WHAT WAS SELECTED AGAINST THIS ENTRIES CHARACTERISTICS ; ; MULTIPLE SELECTION OPTIONS ARE EFFECTIVELY "AND'ED" WHEN DECIDE ; WHETHER TO INCLUDE A FILE OR NOT, E.G. MUST MATCH FILE NAME ; AND VERSION AND ALL SPECIFIED DATE OPTIONS ; ;***** ; CKMASK: ;CHECK MASK WORDS CMP SWMS1$,SETMSK ;DID WE MEET ALL CRITERIA ? BEQ LSTENT ;BRANCH IF YES, LIST ENTRY JMP UNPACK ;ELSE, GET NEXT ENTRY .PAGE LSTENT: BIT #HDSW,SWMSK$ ;HAS HEADER BEEN LISTED? BNE LSTE1 ;BR IF YES CALL .DRHDR ;OUTPUT DIRECTORY HEADER BIS #,SWMSK$ ;FLAG BOTH HEADER PRINTED AND FILE LISTED LSTE1: ; .IF DF ST$DAT ;INCLUDE ONLY IF SUPPORT SETTING FILE DATES BIT #,SWMS2$ ;SETTING ANY FILE DATES ? BEQ 10$ ;BRANCH IF NO CALL .DRSFD ;YES, CALL ROUTINE TO DO IT BCC 10$ ;BRANCH ON SUCCESS CALL TYPEIT ;FOLLOW UP ERROR MESSAGE WITH JMP UNPACK ; FILE NAME -- SKIP ENTRY ON FAILURE 10$: .ENDC ;ST$DAT ; MOV R0,ENDFIL ;SAVE CURRENT RECORD POINTER, MAY BE ; NEEDED FOR ERROR MESSAGE BIT #,SWMSK$ ;FULL OR MIDDLE LISTING ? BEQ LSTE2 ;BR IF NEITHER ; ;***** ; ; SETUP LISTING RECORD; NEW FORMAT, 8/80 ; ;***** ; MOV #LINBUF+20.,R1 ;SET R1 TO POINT PAST FILENAME BIT #FUSW,SWMSK$ ;DOING FULL LISTING? BNE 13$ ;YES, FIND CORRECT OUTPUT FORMAT MOV #MIDTBL,R4 ;SET UP MIDDLE FORMAT STARTING ADDRESS MOV #ENDMID,ENDTBL ;SET UP MIDDLE FORMAT ENDING ADDRESS BR 15$ 13$: MOV #FULTBL,R4 ;SET UP FULL FORMAT START ADDRESS MOV #ENDFUL,ENDTBL ;SET UP FULL FORMAT ENDING ADDRESS 15$: CALL PADIT ;PAD FIELD (UP TO R1) WITH TRAILING SPACES MOVB (R4)+,R1 ;PICK UP NEXT FIELD LENGTH ADD R0,R1 ;POINT R1 TO NEW END OF LINE CALL LNLNGT ;WILL THIS FIELD EXCEED RECORD LENGTH ? MOVB (R4)+,R3 ;FETCH OFFSET FROM HEADER BLOCK ADD #HDBUF$,R3 ;ADJUST FOR START OF HEADER BLOCK MOV R1,-(SP) ;PUSH NEW END OF LINE POINTER ONTO STACK CALL @(R4)+ ;CALL CORRECT OUTPUT ROUTINE MOV (SP)+,R1 ;RESTORE R1-NEW END OF LINE CMP R4,ENDTBL ;AT END OF FORMAT TABLE ? BLO 15$ ;BRANCH IF NO, GET NEXT FIELD ; LSTE2: BIT #SDSW,SWMSK$ ;SELECTIVE DELETE ? BNE 10$ ;YES, LIST FILE USING READ-AFTER-PROMPT BIT #,SWMSK$ ;DOING DELETE OR PURGE ? BNE 40$ ;BRANCH IF YES, PROCEED WITH DELETION CALL LOGIT ;MUST BE "DIRECTORY", COUNT FILE IN TOTALS BIT #LISW,SWMSK$ ;LISTING INDIVIDUAL FILE NAMES ? BEQ 5$ ;BRANCH IF NO CALL .DRPUT ;OUTPUT LINE 5$: JMP UNPACK ;GET NEXT ENTRY 10$: MOV #PRMPT,R1 ;++003 INITIALIZE PROMPT BUFFER MOV (PC)+,(R1)+ ;++003 .BYTE 15,12 ;++003 PROMPT ON NEW LINE MOV #DELMSG,R2 ;SET UP WORD "DELETE" 15$: MOVB (R2)+,(R1)+ ;AND MOVE TO PROMPT BUFFER BNE 15$ DEC R1 ;BACK UP OVER 0 MOV #LINBUF,R2 ;FETCH START ADDRESS OF FILE NAME RECORD SUB R2,R0 ;++003 CALC. LENGTH 20$: MOVB (R2)+,(R1)+ ;++003 COPY PROMPT SOB R0,20$ ;++003 TILL END MOV #DELASK,R2 ;FETCH TRAILING QUESTION STRING 23$: MOVB (R2)+,(R1)+ ;MOVE IT TO PROMPT BUFFER BNE 23$ ;TIL DONE SUB #PRMPT+1,R1 ;++003 CALC LENGTH (+1 ADJUSTS FOR NULL) CLRB HDBUF$ ;ERASE ANY PREVIOUS YES'S, USE HEADER BUFFER QIOW$S #IO.RPR,#TILUN,#TIEFN,,#IOSB$,,<#HDBUF$,#80.,,#PRMPT,R1,#0> TSTB IOSB$ ;ANY ERROR ? BGT 30$ ;BR IF NO ERR CMPB IOSB$,#IE.EOF ;CHECK FOR EOF ERROR BNE ERR ;ANYTHING BUT EOF = ERROR, TIME TO QUIT 30$: MOVB HDBUF$,R4 ;FETCH RESPONSE BICB #40,R4 ;FORCE RESPONSE TO UPPERCASE CMPB #'Y,R4 ;ANSWER YES ? BEQ 40$ ;BRANCH IF YES CMPB #'Q,R4 ;ANSWER QUIT ? BEQ QUIT ;BRANCH IF YES CMPB #'G,R4 ;ANSWER GO ? BNE 50$ ;NO-DON'T DELETE IT 40$: ;CONTINUE WITH DELETION OF THIS ENTRY MOV R5,R0 ;COPY PLACE IN DIRECTORY BUFFER MOV #UFDFDB+F.FNB+N.FVER+2,R1 ;POINT AT FILE NAME BLOCK END MOV #8.,R2 ;SET NUMBER OF WORDS IN DIRECTORY ENTRY 45$: MOV -(R0),-(R1) ;COPY THE DATA SOB R2,45$ ;DO ALL MOV #UFDFDB,R0 ;POINT AT FDB PROPER MOV SAVFNB+N.FID,F.FNB+N.DID(R0) ;RESTORE MOV SAVFNB+N.FID+2,F.FNB+N.DID+2(R0) ;DIRECTORY FILE ID MOV SAVFNB+N.UNIT,F.FNB+N.UNIT(R0) ;DEVICE UNIT NUMBER MOV SAVFNB+N.DVNM,F.FNB+N.DVNM(R0) ;---AND FINALLY NAME CALL .DLFNB ;TRY TO DELETE BY FILENAME BLOCK MOV ENDFIL,R0 ;RESTORE POINTER PAST FILE NAME BCC 49$ ;BR IF DELETE WORKED DIAG FDEL ;ISSUE DIAGNOSTIC MESSAGE CALL TYPEIT ;FOLLOW UP DIAGNOSTIC WITH FILE NAME BIT #SDSW,SWMSK$ ;DOING SELECTIVE DELETE ? BNE 52$ ;BRANCH IF YES, CHECK FOR "GO" OR EOF JMP UNPACK ;ELSE, MOVE ON TO NEXT ENTRY 49$: CALL LOGIT ;DELETE WORKED, COUNT FILE IN TOTALS ; ;***** ; ; DELETION SUCCESSFUL OR NOT SPECIFIED, TAKE CARE OF A FEW MISC. THINGS ; ;***** ; 50$: BIT #SDSW,SWMSK$ ;DOING SELECTIVE DELETE ? BEQ 57$ ;BRANCH IF NO 52$: CMPB #'G,R4 ;WAS RESPONSE A "GO" ? BNE 55$ ;BRANCH IF NO, CHECK FOR EOF BIC #SDSW!HDSW!MISW!FUSW,SWMSK$ ;RESET SELECTIVE DELETE, ; DO BRIEF LISTING, AND FLAG HEADER ; NOT PRINTED BIS #LISW,SWMSK$ ;SET FOR DELETE/PURGE WITH LISTING MOV #LINBUF,R0 ;FETCH ADDRESS OF LINE BUFFER BR 58$ ;BRANCH TO SEND NULL LINE FOR SPACING 55$: TSTB IOSB$ ;CHECK QIO STATUS AGAIN BLT QUIT ;BR IF -VE = EOF BR 59$ ;ELSE, CONTINUE 57$: BIT #LISW,SWMSK$ ;DELETE/PURGE WITH LISTING ? BEQ 59$ ;BRANCH IF NO 58$: CALL .DRPUT ;LIST FILE 59$: JMP UNPACK ;GET NEXT ENTRY ; ; QUIT: CLR NXUIC$ ;CLEAR WILD CARD UFD INDICATOR CLR UFDFDB+F.BDB ;FAKE UFD FILE CLOSED, DON'T GO ON TO NEXT ; PIECE IF DOING IN PIECES CLC ;FLAG SUCCESSFUL EXIT RETURN ; AND LEAVE ; ; ERR: MOV #EX$ERR,EXSTAT ;PROBLEMS, EXIT THIS RUN WITH ERROR STATUS SEC ; SET CARRY BIT RETURN ; AND LEAVE .PAGE ; ;************************************************************************* ; ; LOCAL SUBROUTINES SECTION ; ;************************************************************************* ; ; TYPEIT - PUTS CURRENT STRING STARTING @LINBUF, ENDING @ R0 ; TO TERMINAL ; TYPEIT: MOV R0,-(SP) ;SAVE REGISTERS NEEDED MOV R1,-(SP) MOV R0,R1 ;COPY CURRENT POSITION IN STRING MOV #LINBUF,R0 ;RESTORE R0 TO TOP OF OUTPUT STRING SUB R0,R1 ;FIND LENGTH OF STRING BLE 5$ ;BRANCH IF NOTHING THERE QIOW$S #IO.WVB,#TILUN,#TIEFN,,,, ;OUTPUT STRING AND WAIT TILL DONE 5$: MOV (SP)+,R1 ;RESTORE REGISTERS MOV (SP)+,R0 RETURN ; ;***** ; ; SUBROUTINE TO ACCUMULATE # FIELS LISTED, USED/ALLOCATED BLOCKS ; ;***** ; LOGIT: MOV R0,-(SP) ;SAVE REGISTERS MOV R1,-(SP) INC $TFILS+2 ;COUNT # FILES LISTED ADC $TFILS MOV #HDBUF$+H.UFAT,R0 ; ADDR OF USER ATTRIBUTES MOV F.EFBK+2(R0),R1 ; USED BEQ 5$ TST F.FFBY(R0) ; 1ST FREE BYTE = 0? BNE 5$ DEC R1 ; YES--DON'T COUNT THE BLOCK 5$: ADD R1,$TBLKU+2 ; ACCUMULATE # BLOCKS USED ADC $TBLKU ADD F.HIBK+2(R0),$TBLKA+2 ; ACCUMULATE # BLOCKS ALLOCATED ADC $TBLKA ADD F.HIBK(R0),$TBLKA MOV (SP)+,R1 ;RESTORE REGISTERS MOV (SP)+,R0 RETURN ; ;************************************************************************* ; ; WHEN CALLED, THE FOLLOWING ROUTINES EXPECT: ; 1) R0=POINTER TO CURRENT POSITION IN LINE BUFFER ; 2) R1=FREE REGISTER (EXCEPT FOR LNLNGT:) ; 3) R2=FREE REGISTER ; 4) R3=POINTER TO CORRECT ELEMENT OF DIRECTORY HEADER INFORMATION ; 5) R4=USED ; ;************************************************************************ ; ; ; ; CHECK TO MAKE SURE CURRENT FIELD WON'T EXCEED LISTING'S RECORD LENGTH ; R1=END OF LINE POINTER LNLNGT: MOV LINSZ$,R2 ;FETCH LINE LENGTH ADD LSTFDB+F.NRBD+2,R2 ;ADJUST FOR START OF BUFFER CMP R1,R2 ;IS NEW END OF LINE (R1) OK? BLO 10$ ;YES, EXIT SUB R0,R1 ;NO, FIND FIELD LENGTH WORKING WITH CALL .DRPUT ;OUTPUT CURRENT LINE MOV LSTFDB+F.NRBD+2,R0 ;RESTORE START OF RECORD POINTER MOV (PC)+,(R0)+ ;INSERT 2 LEADING SPACES .BYTE 40,40 ADD R0,R1 ;RESTORE NEW END OF LINE INDICATOR 10$: RETURN ;AND EXIT ; ; ; ; SPACE FILL FIELD (ALWAYS INSERTS AT LEAST 1 SPACE BETWEEN FIELDS) PADIT: MOVB #' ,(R0)+ ;INSERT TRAILING SPACE CMP R0,R1 ;AT END OF NEW FIELD YET ? BLO PADIT ;NO, DO IT AGAIN MOV R0,R1 ;YES, SET R1 TO CURRENT POINTER POSITION 10$: RETURN ;AND EXIT ; ; ; ; OUTPUT USED/ALLOCATED BLOCKS SPECIFICATION SIZECV: MOV (R3)+,R1 ;FETCH ELEMENT FROM HEADER BLOCK CLR R2 ;SET ZERO SUPPRESS FLAG TST -2>(R3) ;FIRST FREE BYTE 0 ? BNE 10$ ;NO, PROCEED TST R1 BEQ 10$ DEC R1 ;YES, DON'T COUNT THIS BLOCK 10$: CALL $CBDMG ;CONVERT TO ASCII BIT #FUSW,SWMSK$ ;CHECK IF FULL LISTING? BNE 12$ ;IF YES, FIND ALLOCATED BLOCKS SUB #6.,2(SP) ;IF NO, SHORTEN OUTPUT FIELD BY 6 CHARACTERS BR 15$ ;AND EXIT 12$: MOVB #'.,(R0)+ ;INSERT SEPARATORS MOVB #'/,(R0)+ MOV >(R3),R1 ;GET HIGHEST ALLOCATED CLR R2 ;ZERO SUPPRESS CALL $CBDMG ;CONVERT 15$: MOVB #'.,(R0)+ ;INSERT TERMINATOR RETURN ;AND RETURN ; ; ; ; OUTPUT FILE #,SEQUENCE # FIDCV: MOVB #'(,(R0)+ ;INSERT LEADING CHARACTER MOV (R3)+,R1 ;FETCH FILE ID INFORMATION CLR R2 ;SUPPRESS ZEROS CALL $CBOMG ;CONVERT TO OCTAL MOVB #',,(R0)+ ;INSERT SEPARATOR MOV (R3),R1 ;GET SEQ NUMBER CLR R2 ;ZERO SUPRESS AGAIN CALL $CBOMG ;CONVERT THAT MOVB #'),(R0)+ ;INSERT TRAILING CHARACTER RETURN ; ; ; ; OUTPUT STATE OF "CONTIGUOUS" AND "LOCKED" BITS IN FILE HEADER CONTIG: MOVB (R3),R1 ;FETCH USER CHARACTERISTICS BYTE BITB #UC.CON,R1 ;CONTIGUOUS ? BEQ 5$ ;BRANCH IF NO MOVB #'C,(R0)+ ;YES, INSERT "C" INTO LINE BR 6$ 5$: MOVB #40,(R0)+ ;PUT SPACE INTO STRING 6$: BITB #UC.DLK,R1 ;LOCKED ? BEQ 10$ ;BRANCH IF NO MOVB #'L,(R0)+ ;YES, INSERT "L" INTO LINE ; "PADIT" WILL PUT SPACE INTO LINE IF ; FILE NOT LOCKED 10$: RETURN ; ; ; ; OUTPUT DATE AND TIME INFORMATION TIME: MOV #TIMSTR,R2 ;FETCH TIME FORMAT BR DATTIM ; BRANCH TO COMMON CODE ; .IF DF EX$DAT ;INCLUDE IF SUPPORT EXPIRATION DATES EXPDAT: MOV #EXPSTR,R2 ;FETCH PREFIX STRING FOR EXPIRATION DATE 1$: MOVB (R2)+,(R0)+ ;COPY STRING TO OUTPUT RECORD BNE 1$ DEC R0 ;BACKUP OVER NULL AND OUTPUT DATE .ENDC ;EX$DAT ; DATE: MOV #DATSTR,R2 ;FETCH DATE FORMAT DATTIM: MOVB HDBUF$+H.IDOF,R1 ;CREATION AND REVISION DATES - ASL R1 ;ARE RELATIVE TO ID BLOCK - ADD R1,R3 ;NOT HEADER BLOCK 5$: MOVB (R2)+,R1 ;FETCH FORMAT-# OF CHARACTERS TO OUTPUT 7$: MOVB (R3)+,(R0)+ ;MOVE "R1" CHARACTERS TO OUTPUT RECORD BEQ 10$ ;BRANCH ON NULL IN DATE STRING, SHOULD ; ONLY OCCUR WITH EXPIRATION DATES SOB R1,7$ ;MORE TO GO ? MOVB (R2)+,(R0)+ ;NO, OUTPUT SEPARATOR BNE 5$ ;FETCH NEXT FORMAT STRING LENGTH 10$: DEC R0 ;BACK UP OVER TERMINATING NULL RETURN ; ; ; ; OUTPUT FILE UIC UICCV: MOV (R3)+,R1 ;FETCH UIC INFORMATION MOV R1,-(SP) ;AND SAVE IT ON STACK CLRB R1 ;REMOVE PROGRAMMER NUMBER SWAB R1 ;GET PROJECT NUMBER INTO LO BYTE CLR R2 ;SET ZERO SUPPRESSION MOVB #'[,(R0)+ ;INSERT LEADING CHARACTER CALL $CBOMG ;CONVERT THAT MUCH MOVB #',,(R0)+ ;INSERT SEPARATOR CLR R1 ;GET READY FOR UNSIGNED-- BISB (SP)+,R1 ;MOVE OF PROGRAMMER NUMBER CLR R2 ;SET ZERO SUPPRESSION CALL $CBOMG ;CONVERT AND OUTPUT MOVB #'],(R0)+ ;OUTPUT TERMINATOR RETURN ;AND EXIT ; ; ; ; OUTPUT FILE PROTECTION PROTEC: .ASCIZ /RWED/ .EVEN FPROCV: MOVB #'[,(R0)+ ;INSERT LEADING CHARACTER MOV (R3),R1 ;FETCH PROTECTION STATUS MOV #4,R3 ;SET # OF TIMES TO SCAN PROTECTION FORMAT 10$: MOV #PROTEC,R2 ;START OF PROTECTION FORMAT 20$: ASR R1 ;MOVE 1 BIT INTO C BCS 30$ ;BR IF NOT ACTIVE MOVB (R2),(R0)+ ;INSERT A DESRIPTOR CHAR 30$: INC R2 ;ADJ FORMAT STRING TSTB (R2) ;END OF FORMAT ? BNE 20$ ;BR IF NO MOVB #',,(R0)+ ;INSERT A SEPARATOR SOB R3,10$ ;LOOP? DEC R0 ;NO-BACK UP OVER LAST COMMA MOVB #'],(R0)+ ;INSERT TERMINATOR RETURN ; ; ; ; OUTPUT REVISION NUMBER IF > 1; IF REV # 1, PRINT IT SUB #17.,R0 ;REV # = 1, RESET LINE POINTER TO START OF BR 10$ ; REV DATE/TIME AND SKIP LISTING IT 5$: MOVB #'(,(R0)+ ;OUTPUT LEADING CHARACTER CLR R2 ;SET ZERO SUPPRESSION CALL $CBDMG ;CONVERT AND OUTPUT # MOVB #'.,(R0)+ ;OUTPUT TERMINATOR MOVB #'),(R0)+ 10$: RETURN .END