.TITLE MVD - Mounted Volume Display .IDENT /1.03/ .ENABL LC .NLIST BEX ; Description: MVD lists for each user, all mounted volumes, sorted by user ; and by device. Information displayed includes volume label or ; "Foreign", ACP name, and "Private", "Nowrite", and ; "Marked_dismount" if so. Public devices are included if the ; symbol PUBDEV is defined below. ; ; Author: Steve Jobes, Mayo Clinic ; September, 1984 ; ; Maintenance: 28-SEP-84 SLJ V1.01 Added "Foreign", "Private", "Nowrite", ; "Marked_dismount", and ACP name ; 02-OCT-84 SLJ V1.02 Added Public devices ; 10-OCT-84 SLJ V1.03 Added file name for virtual disks ; ; Note: V1.03 was an attempt to display the file name of each virtual ; disk. It is conditionalized on the symbol VENAME but should ; NOT be defined at this time as VEDRV does not keep track of ; file names associated with virtual disks beyond the first unit. .MCALL JEQ,JNE,POP,PUSH .MCALL ALUN$S,EXIT$S,QIOW$S .MCALL DCBDF$,F11DF$,NBOFF$,UCBDF$ DCBDF$ F11DF$ NBOFF$ DEF$L UCBDF$ .MACRO MVMSG A MOV #'A,R1 ; Description addr MOVB (R1)+,(R0)+ ; Copy byte by byte BNE .-2 ; til done .ENDM PUBDEV = 0 ; If defined, include public devices ;VENAME = 0 ; If defined, display VE: file names MAXCNT = 32. ; Maximum mount entries .PAGE MVD: ALUN$S #1,"TI,#0 ; Assign LUN MOV #SRTBL,R0 ; Sort table CLR CNT ; Init count .if df PUBDEV ; Pass through the device list to find public mounted devices. MOV $DEVHD,R5 ; 1st DCB 1$: MOVB D.UNIT+1(R5),R3 ; Calc number MOVB D.UNIT(R5),R2 ; of units SUB R2,R3 ; for INC R3 ; this DCB MOV D.UCB(R5),R4 ; 1st UCB BIT #DV.MNT,U.CW1(R4) ; Is it mountable ? BEQ 4$ ; No, next DCB 2$: BITB #US.PUB,U.ST2(R4) ; Is it public ? BEQ 3$ ; No, next UCB BITB #US.MNT,U.STS(R4) ; Is it mounted ? BNE 3$ ; No, next UCB CLR (R0)+ ; Zero user UCB in sort CLRB (R0)+ ; table means public JSR PC,SUB1 ; Device name/unit in output MOV R4,(R0)+ ; UCB addr in output INC CNT ; Bump count CMP CNT,#MAXCNT ; Full yet ? BGE SORT ; Yes, quit early 3$: ADD D.UCBL(R5),R4 ; Offset to next UCB SOB R3,2$ ; If another 4$: MOV (R5),R5 ; Point to next DCB BNE 1$ ; Another .endc ; Pass through the mount list to find non-public mounted devices. MOV #$MOULS,R5 ; Mounted volume listhead 11$: CMPB #MT.MLS,M.TYPE(R5) ; Mount list entry ? BNE 12$ ; No, forget it MOV M.TI(R5),R4 ; User UCB JSR PC,SUB1 ; User name/unit in output MOV M.DEV(R5),R4 ; Device UCB JSR PC,SUB1 ; Device name/unit in output MOV R4,(R0)+ ; UCB addr in output INC CNT ; Bump count CMP CNT,#MAXCNT ; Full yet ? BGE SORT ; Yes, quit early 12$: MOV (R5),R5 ; Link BNE 11$ ; Next ... ; Perform a "bubble sort" on the entries we have found. SORT: MOV CNT,R4 ; Number of entries JEQ QUIT ; None DEC R4 ; Outer loop counter BEQ OUTP ; No need to sort 1$: MOV R4,R3 ; Inner loop counter MOV #SRTBL,R0 ; Sort table 2$: MOV R0,R1 ; Here too ADD #8.,R1 ; Point to next entry PUSH R1 ; Save it MOV #6,R2 ; Six bytes to compare 3$: CMPB (R0)+,(R1)+ ; Compare BLT 6$ ; Already in order BGT 4$ ; Need to reverse them SOB R2,3$ ; Must check next BR 6$ ; Entries match 4$: MOV (SP),R1 ; Saved addr MOV #4,R2 ; Four words to swap 5$: PUSH -8.(R1) ; Exchange with MOV (R1),-8.(R1) ; previous POP (R1)+ ; entry SOB R2,5$ ; Next ... 6$: POP R0 ; Point to next pair SOB R3,2$ ; Dec inner loop SOB R4,1$ ; Dec outer loop ; Display the sorted entries. OUTP: MOV #SRTBL,R5 ; Sort table 1$: MOV #OBUFR,R0 ; Output bufr TST (R5) ; Public ? BNE 2$ ; No MVMSG PUBLIC ; Yes, "Public" ADD #3,R5 ; Point past user BR 3$ 2$: JSR PC,SUB2 ; User device 3$: MOVB #11,(R0)+ ; Tab JSR PC,SUB2 ; Mounted device MOV (R5)+,R4 ; Device UCB BITB #US.FOR,U.STS(R4) ; Foreign ? BEQ 4$ ; No, get volume label MVMSG FOREIG ; Yes, "Foreign" BR 7$ ; No label or ACP 4$: MOV U.VCB(R4),R1 ; Device VCB ADD #V.LABL,R1 ; Offset to volume label MOV #12.,R2 5$: MOVB (R1)+,(R0)+ ; Label BEQ 6$ ; Quit early SOB R2,5$ 6$: MVMSG ACPEQU ; Get ACP name MOV U.ACP(R4),R3 ; ACP TCB MOV T.NAM(R3),R1 ; RAD50 ACP taskname CALL $C5TA ; ASCII MOV T.NAM+2(R3),R1 ; 2nd half RAD50 CALL $C5TA ; ASCII 7$: .if df VENAME CMPB #'V,-5(R5) ; Is it a virtual disk ? BNE 8$ ; No CMPB #'E,-4(R5) ; Maybe BNE 8$ ; No MOV 70(R4),R3 ; (U.NXT) Virtual control block ADD #122,R3 ; (X.FNB) Offset to filename block MVMSG FILEEQ ; "File=" MOVB N.DVNM(R3),(R0)+ ; Device name MOVB N.DVNM+1(R3),(R0)+ MOV N.UNIT(R3),R1 ; Binary unit number CLR R2 ; Zero suppression CALL $CBOMG ; Make it ASCII MOVB #72,(R0)+ ; Colon MOV #ARGEDM,R2 ; Addr argument block MOV N.FNAM(R3),(R2)+ ; RAD50 file name MOV N.FNAM+2(R3),(R2)+ MOV N.FNAM+4(R3),(R2)+ MOV N.FTYP(R3),(R2)+ ; RAD50 file type MOV N.FVER(R3),(R2)+ ; Binary version MOV #INPEDM,R1 ; Addr input string MOV #ARGEDM,R2 ; Addr argument block CALL $EDMSG ; Format .endc 8$: TST U.OWN(R4) ; Allocated ? BEQ 9$ ; No MVMSG PRIVAT ; Yes, "Private" 9$: BIT #DV.SWL,U.CW1(R4) ; Read only ? BEQ 10$ ; No MVMSG NOWRIT ; Yes, "Nowrite" 10$: BITB #US.MDM,U.STS(R4) ; Marked for dismount ? BEQ 11$ ; No MVMSG MARKED ; Yes, "Marked_dismount" 11$: SUB #OBUFR,R0 ; Calc length QIOW$S #IO.WVB,#1,#1,,,,<#OBUFR,R0,#40> DEC CNT JNE 1$ QUIT: EXIT$S ; Done ; Subroutines. SUB1: MOV U.DCB(R4),R2 ; Device DCB MOVB D.NAM(R2),(R0)+ ; Device name MOVB D.NAM+1(R2),(R0)+ ; 2nd character PUSH R0 ; Save Reg 0 CLR R0 ; Prepare for divide MOV R4,R1 ; This UCB SUB D.UCB(R2),R1 ; minus 1st UCB DIV D.UCBL(R2),R0 ; divided by length ADD D.UNIT(R2),R0 ; plus low unit number MOV R0,R1 ; is unit number POP R0 ; Restore Reg 0 MOVB R1,(R0)+ ; Put it bufr RTS PC SUB2: MOVB (R5)+,(R0)+ ; Device name MOVB (R5)+,(R0)+ ; 2nd character CLR R1 BISB (R5)+,R1 ; Binary unit number CLR R2 ; Zero suppression CALL $CBOMG ; Make it ASCII MOVB #72,(R0)+ ; Colon RTS PC SRTBL: .BLKB MAXCNT*8. ; Eight bytes per entry CNT: .WORD 0 ; Count OBUFR: .BLKB 100. ; Output bufr .if df VENAME ARGEDM: .BLKW 5 ; $EDMSG argument block INPEDM: .ASCIZ /%X/ ; $EDMSG input string FILEEQ: .ASCIZ /, File=/ .endc ACPEQU: .ASCIZ /, ACP=/ FOREIG: .ASCIZ /Foreign/ MARKED: .ASCIZ /, Marked_dismount/ NOWRIT: .ASCIZ /, Nowrite/ PRIVAT: .ASCIZ /, Private/ PUBLIC: .ASCIZ /Public/ .END MVD