.TITLE VOL - MCR VOLUME DISPLAY TASK .IDENT /V02.0/ .NLIST ME,BEX,CND .ENABL LC .Sbttl Author's Credits ; Author: ?? ; Modified By: Henry R. Tumblin ; Date: 23-Jul-79 ; Version: 2.0 ; For: Systems -- Utilities ; Module Name: VOLUME ; Build File: VOLUME.DCL ; Residence: [311,33]VOLUME.MAC ; Machine/System: PDP-11/70 IAS V3.0 ; Type/Language: Main/Assembler ; Abstract: This program scans the Physical Unit Directory ; for all mountable devices and displays their ; status. ; ; Edits: ; ;No. Date By Reason ;--- --------- ------ -------------------------------------------- ;+01 23-Jul-79 HRT Re-write and other mods. ;+02 24-Jul-79 HRT IAS V03.0 mods .SBTTL LOCAL MACROS .MCALL QIOW$,DIR$,EXST$S ; MACROS USED ; .MACRO PUSH,LIST .IRP .I., .IF IDN,<.I.>,<*> CLR -(SP) .IFF MOV .I.,-(SP) .ENDC .ENDR .ENDM .MACRO POP,LIST .IRP .I., .IF IDN,<.I.>,<*> TST (SP)+ .IFF MOV (SP)+,.I. .ENDC .ENDR .ENDM .MACRO PRINT,.BUFF.,.LEN.,.CCW. MOV .BUFF.,-(SP) MOV .LEN.,-(SP) .IF B .CCW. CLR -(SP) .IFF MOV .CCW.,-(SP) .ENDC CALL $OUT .ENDM .SBTTL Equates and FDB's LUN = 1 ;DISPLAY LINE LUN FLAG = 10. ;DISPLAY LINE EVENT FLAG V.TRCT = 0 ; Count of users on volume V.IFWI = 2 ; Index file window address V.STD = 4 ; V.FCB = 6 ; V.IBLB = 12 ; Start LBN of Index File Bitmap(high) V.IBSZ = 13 ; Number of blocks in bitmap V.FMAX = 16 ; Maximum number of files on volume V.WISZ = 20 ; Window size V.SBCL = 21 ; Storage bitmap cluster size V.SBSZ = 22 ; Number of blocks in storage bitmap V.SBLB = 24 ; Start LBN of Storage File Bitmap V.FIEX = 25 ; Default file extension increment V.FPRO = 30 ; Default file protection V.FRBK = 34 ; Free blocks on device V.LRUC = 35 ; Count of entries in directory LRU V.LABL = 40 ; Volume label V.STAT = 54 ; VC.IFW=1 ; VC.BMW=2 ; V.FFNU = 55 ; V.LGTH = 56 ; V.LENG = 12. ;VOLUME LABEL LENGTH ; ; DIRECTIVES ; $WRT: QIOW$ IO.WLB,LUN,FLAG,100,,,<0,0,0> IOSTAT: .BLKW 2 ;I/O STATUS BLOCK FRBK: .BLKW 2 ; Free blocks on device .SBTTL MESSAGES MSGBUF: .BLKB 133. ; +01 Message buffer TMPBUF: .BLKB 80. ; String building buffer HEADR: .ASCII "Device"<11><11>"Status%N" .ASCII "======"<11> .ASCIZ <11>"============================================" BASE: .ASCIZ "%2S%2A%O:"<11><11>"%VA" REDR: .ASCIZ "is redirected to Device - %2A%O:" OFFL: .ASCIZ "- Device handler is%VAresident, Controller is offline" NOT: .ASCII " not " NOTS=.-NOT FOR: .ASCIZ "is mounted [FOREIGN]%VA" DMO: .ASCIZ " - Dismount pending" DMOS=.-DMO VOF: .ASCII "- Volume is off-line" VOFS=.-VOF BVCB: .ASCIZ "- Bad VCB extension detected" MOU: .ASCII "- Volume '%VE' is mounted,%N" .ASCIZ <11><11>"%4S%D users, %T blocks free" .EVEN .sbttl Sample Pud ; The following PUD is for test purposes only. This allows the ; program to be tested without having to be built priviledged ; and also prevents nasty system crashes. ;D$$BUG=1 .IF DF D$$BUG .even U.SZ=64 .PUDBA: .WORD PUD .PUDEA: .WORD PUD+ PUD: .WORD "HH .BYTE 0,200 .WORD 100000+40000+10 .BLKW 4. .WORD PUD .BLKW 7. .WORD VCB .BYTE 1,20 .BYTE 0,0 .BLKW 8. .WORD "HH .BYTE 1,200 .WORD 100000+40000+10 .BLKW 4 .WORD PUD+64 .BLKW 7 .WORD VCB .BYTE 1,20 .BYTE 200+100,0 .BLKW 8. VCB: .WORD 3 ; Number of users .BLKB 32 .BYTE 0,0 .WORD 5000. .ASCII "VOLUME LABEL" .WORD .ENDC .SBTTL START MAINLINE CODE ; ; INITIALIZATION ; VOLUME: ; Output the header line MOV #MSGBUF,R0 ; Point to output area MOV #HEADR,R1 ; Point to header line CLR R2 ; No argument list CALL $EDMSG ; Format it PRINT #MSGBUF,R1,#40 ; Output to screen ; Scan the PUD MOV .PUDBA,R4 ;SET THE START OF THE PUD TABLE BGIN: CMP .PUDEA,R4 ; +02 Are we at the end yet ? BNE CHKRED ; +02 NE - no, display volume msg EXST$S #EX$SUC ; +03 Exit with success ; CHECK FOR PUD REDIRECTION CHKRED: MOV R4,R5 ;SET THE CURRENT PUD ADDRESS 10$: CMP U.RP(R5),R5 ;IF THE PUD IS REDIRECTED TO ITSELF, BEQ CHKUC1 ;THAT'S THE END OF THE REDIRECTION MOV U.RP(R5),R5 ;OTHERWISE, SET THE REDIRECTED PUD BR 10$ ;ADDRESS AND CHECK IT FOR REDIRECTION ; CHECK CHARACTERISTICS WORD 1 CHKUC1: BIT #UC.DIR,U.C1(R5) ;CHECK IF DEV IS DIRECTORY-STRUCTURED BEQ 10$ ;EQ - then skip this pud BIT #UC.MNT,U.C1(R5) ;CHECK IF DEVICE IS MOUNTABLE BEQ 10$ ;EQ - then skip this pud BIT #UC.F11,U.C1(R5) ;CHECK IF DEV IS FILES-11 STRUCTURED BNE SETDV1 ;NE - then this is valid device 10$: JMP NXTPUD ;IF ANY CHECK FAILS => NEXT PUD ; ; SET THE DEVICE MESSAGE ; SETDV1: MOVB U.UN(R4),R1 ; +02 Get unit # -> R1 MOV R1,-(SP) ; +02 Set up as argument MOV R4,-(SP) ; +02 Point to device name ADD #U.DN,(SP) ; +02 Set up device name as arg. ; At this point, the argument list for the basline message ; has been initialized with the device name and unit number. ; this info will remain on the stack until the entire message ; has been built, then built via a final call to $EDMSG CMP R4,R5 ;CHECK FOR REDIRECTION BEQ CHKUFB ;EQ - then no redirection MOVB U.UN(R5),R1 ; +02 Get unit # -> R1 ; ; Here we have found that the device has been redirected. ; Display the device name to which it has been redirected. MOV R1,-(SP) ; +02 Set up as argument MOV R5,-(SP) ; +02 Point to device name ADD #U.DN,(SP) ; +02 Set up device name as arg. MOV #TMPBUF,R0 ; +02 Point to build area MOV #REDR,R1 ; +02 Point to format string MOV SP,R2 ; +02 Point to argument list CALL $EDMSG ; +02 Create substring CMP (SP)+,(SP)+ ; +02 Clean up the stack CALL OUTMSG ; +02 Output the message JMP NXTPUD ; +02 Go do next PUD .sbttl CHECK THE FLAGS BYTE CHKUFB: BITB #UF.OFL,U.FB(R4) ;CHECK IF THE CONTROLLER IS OFF-LINE BEQ CHKUCH ; EQ - then check characteristics ; At this point, the controller is either offline, with the ; device handler resident or non-resident. CLR R1 ; +02 Assume handler resident BITB #UF.RH,U.FB(R4) ; Is the device handler resident ? BNE 10$ ; NE - yup, MOV #NOTS,R1 ; +02 Set for NOT resident 10$: MOV #NOT,-(SP) ; +02 Set up message plist MOV R1,-(SP) ; +02 Set string length MOV #TMPBUF,R0 ; +02 Point to build area MOV #OFFL,R1 ; +02 Point to format string MOV SP,R2 ; +02 Point to argument list CALL $EDMSG ; +02 Format message CMP (SP)+,(SP)+ ; +02 Clean up the stack CALL OUTMSG ; +02 Build and output message JMP NXTPUD ; +02 Go check next device .sbttl CHECK THE CHARACTERISTIC FLAGS BYTE CHKUCH: BITB #CH.OFF,U.CH(R4) ;CHECK IF THE VOLUME IS OFF-LINE BEQ 10$ ; EQ - nope, check next bit MOV #VOFS,R1 ; Get message size -> R1 MOV #TMPBUF,R2 ; Point to destination -> R2 MOV #VOF,R0 ; Get message pointer MOV R1,-(SP) ; Save R1 5$: MOVB (R0)+,(R2)+ ; Move into place SOB R1,5$ ; Loop till thru MOV (SP)+,R1 ; Restore R1 CALL OUTMSG ; Output the message BR NXTPUD ; Go do next device 10$: BITB #CH.FOR,U.CH(R4) ;CHECK IF VOLUME IS MOUNTED AS FOREIGN BEQ CHKVCB ; EQ - no, check VCB CLR R1 ; Set no DMO pending BITB #CH.UNL,U.CH(R4) ;CHECK IF A DISMOUNT IS PENDING BEQ 12$ ; EQ - then no dismount pending MOV #DMOS,R1 ; Set string length -> R1 12$: MOV #DMO,-(SP) ; ... MOV R1,-(SP) ; Set up parameter list MOV #TMPBUF,R0 ; Set up substring MOV #FOR,R1 ; Point to format string MOV SP,R2 ; Point to parameter list CALL $EDMSG ; Edit the string CMP (SP)+,(SP)+ ; Clean up stack CALL OUTMSG ; Output message BR NXTPUD ; And do next pud .sbttl EXTRACT THE MOUNT INFORMATION FROM THE VCB EXTENSION AREA ; ; First make sure that the VCB is valid for this device CHKVCB: MOV U.VA(R4),R5 ;SET THE VCB EXTENSION ADDRESS BNE GVCB ; NE - then valid VCB CLR R1 ; Set string length BITB #CH.UNL,U.CH(R4) ; Is DMO pending ? BEQ 10$ ; EQ - then not pending MOV #DMOS,R1 ; Else set length 10$: MOV #DMO,-(SP) ; Point to the string MOV R1,-(SP) ; Set it's length MOV #TMPBUF,R0 ; Point to output area MOV #BVCB,R1 ; Point to format string MOV SP,R2 ; Point to parameter list CALL $EDMSG ; And output message CMP (SP)+,(SP)+ ; Clean up stack CALL OUTMSG ; Output the message BR NXTPUD ; And go check the next device ; Now display the number of users of this volume GVCB: MOVB V.FRBK(R5),FRBK ; Get total free blocks on device MOV V.FRBK+2(R5),FRBK+2 ; ... MOV #FRBK,-(SP) ; Point to doubleword MOV V.TRCT(R5),-(SP) ; Get # of users -> R1 MOV R5,-(SP) ; Get pointer to ADD #V.LABL,(SP) ; Volume Label MOV #V.LENG,-(SP) ; Get length of volume label MOV #TMPBUF,R0 ; Point to output area MOV #MOU,R1 ; Point to format string MOV SP,R2 ; Point to parameter list CALL $EDMSG ; And output message ADD #10,SP ; Clean up stack CALL OUTMSG ; Output the message BR NXTPUD ; And go do next pud ; ADVANCE TO THE NEXT PUD ; NXTPUD: ADD #U.SZ,R4 ;POINT AT THE NEXT PUD ENTRY JMP BGIN ; Go check next PUD .sbttl Support Subroutines .sbttl 1) OUTMSG -- Output Baseline Message ; This subroutine will build and output the baseline message ; string to TO:. ; Inputs: ; R1 -- Length of substring to insert in baseline string ; (SP)-- RETURN ADDRESS ; 2(SP)-- Device Name ; 4(SP)-- Device Unit Number ; TMPBUF-- The substring to insert OUTMSG: CMP -(SP),-(SP) ; +02 Create two entries on stack MOV 4(SP),(SP) ; +02 Correct return address MOV 10(SP),4(SP) ; +02 Get unit # MOV 6(SP),2(SP) ; +02 Get device name MOV R1,6(SP) ; +02 Set character count MOV #TMPBUF,10(SP) ; +02 Point to temp string MOV #MSGBUF,R0 ; +02 Point to output buffer MOV #BASE,R1 ; +02 Point to baseline message MOV SP,R2 ; +02 Point to parameter list ADD #2,R2 ; +02 ...+2 CALL $EDMSG ; +02 Format message PRINT #MSGBUF,R1,#40 ; +02 Output message MOV (SP),10(SP) ; +02 Restore return address ADD #10,SP ; +02 Clean up the stack RETURN ; +02 Return to calling proc. .sbttl 2) $OUT -- Output line to TO: ; This subroutine will output a string to the terminal ; that is currently assigned to TO: $OUT: MOV 4(SP),$WRT+Q.IOPL+2 ; Set buffer length BEQ 10$ ; EQ - then skip I/O MOV 2(SP),$WRT+Q.IOPL+4 ; Set CCW word MOV 6(SP),$WRT+Q.IOPL ; Set buffer address DIR$ #$WRT ; Perform I/O 10$: MOV (SP),6(SP) ; Restore return address ADD #6,SP ; Clean up stack RETURN ; Return to whom called us .END VOLUME