; ; TITLE DU ; ; Disk usage by PPn for a device ; ; THIS PROGRAM MAY BE FREELY DISTRIBUTED TO AMUS MEMBERS ; COURTESY OF WHITE HOUSE SOFTWARE, INC. ; ; Note: to get a sorted listing of disk usage, do the following ; DU X.LST=DSK2: ; SORT X.LST ; record length = 80 ; key size = 11 ; key position = 11 ; order = d (descending) ; Press RETURN on next key size question ; ;Edit History: ; ; 5/30/86 1.0(0) - David Greene ; Written ; VEDIT=0. SEARCH SYS SEARCH SYSSYM ; Define TAB and Carriage Return TAB=9. CR=13. ; Define Version Information VMAJOR=1. VMINOR=0. VSUB=0. VWHO=0. ; Start of program PHEAD: PHDR -1,0,PH$REE!PH$REU TYPECR BYP ; skip blanks and tabs LIN ; end of string? JNE DU10 DU0: TYPECR TYPECR < DU =Dev: - Print listing to DU.LST> TYPECR < DU outfil=Dev: - Pring listing to specified output file> TYPECR < (Default extention is .LST)> CRLF EXIT ; ; get command string file specifications ; DU10: GETIMP IMPSIZ,A5 ; get impure area CLR TOTCNT(A5) ; no kilobytes yet SETB FILOUT(A5) ; assume output is to a file CMPB @A2,#'= ; output to file.LST? BEQ DU30 ; yup MOV A2,D4 ; save A2 for a second FSPEC DDBOUT(A5),LST ; output file specification BYP ; ignore spaces CMPB @A2,#'= ; was that the output file? BEQ DU20 ; yup MOV D4,A2 ; ->start of input file name CLRB FILOUT(A5) ; output is not to a file BR DU80 ; DU file.out=Dev: ; (full input and output specification) DU20: INC A2 ; bypass '=' BYP ; any device spec? LIN ; no - show user how to invoke JEQ DU0 BR DU80 ; done with file specifications ; DU =Dev: ; (output is to file.LST) DU30: INC A2 ; bypass '=' BYP ; LIN ; any device specification? JEQ DU0 ; no - show user how to invoke MOV A2,D4 ; ->start of input file name PUSH A2 ; save A2 a second LEA A2,OPNFIL ; index default output filename FSPEC DDBOUT(A5),LST ; DU.LST POP A2 BR DU80 ; Default filename when .DU =Dev#: OPNFIL: ASCII /DU/ BYTE 0 EVEN DU80: ; ; set up input device ; CLRW DDBIN(A5) ; not yet INITed INIT DDBIN(A5) ; get buffers SET D6 ; stop scanning after device spec FSPEC DDBIN(A5) ; process device spec ; ; open output file ; TSTB FILOUT(A5) ; output to a file? BEQ MAIN ; nope CLRW DDBOUT(A5) ; not yet INITed INIT DDBOUT(A5) ; get buffers LOOKUP DDBOUT(A5) ; look it up BNE 40$ DSKDEL DDBOUT(A5) ; delete existing file 40$: OPENO DDBOUT(A5) ; open for output ; output header for file LEA A2,DDBOUT(A5) ; A2 must point to output DDB OUTS OT$DDB, OFILE DDBIN(A5),OT$DDB OUTCR OT$DDB PAGE ;************* ;* MAIN * ;************* ; Main processing loop ; We go from PPn to PPn and call DOPPN which calculate disk usage ; for that account. MAIN: ; MFD starts with block number 1 MOV #1,DDBIN+D.REC(A5) ; block number 1 ; Main MFD loop 5$: READ DDBIN(A5) ; read MFD MOV DDBIN+D.BUF(A5),A2 ; A2->MFD buffer 10$: TSTW MF.PPN(A2) ; end of MFD? BEQ 20$ ; Yes ; process a PPn CTRLC EXIT$ ; allow CTRL-C CALL DOPPN ; process one PPn ; get next PPn for loop ADD #MF.SIZ,A2 ; Advance to next MFD entry MOV DDBIN+D.BUF(A5),A6 ; End of buffer? ADD DDBIN+D.SIZ(A5),A6 SUB #MF.SIZ,A6 CMP A2,A6 ; are we at the end of an MFD block? BLO 10$ ; no - continue ; we are past the last PPn in this block, get the next one ; if there is one MOVW MF.NXT(A6),DDBIN+D.REC+2(A5);Advance to next MFD record BNE 5$ ; And continue unless no more blocks ; no more PPns ; output total kilobytes used 20$: LEA A2,OUTLIN(A5) OUTSP OT$MEM, MOV TOTCNT(A5),D4 ROR D4,#1 ; divide by 2; N bit set if remainder CLR D1 MOVW D4,D1 ; get number of kilobytes ; output kilobytes used DCVT 0,OT$MEM ; output number of Kilobytes MOVB #'.,(A2)+ ; output decimal point MOVB #'0,D1 ; no remainder yet TST D4 ; any remaider from before? BPL 25$ ; no - finish MOVB #'5,D1 ; .5 remainder ; output remainder 25$: MOVB D1,(A2)+ ; yes - show user OUTS OT$MEM, ; show number is kilobytes MOVB #CR,(A2)+ ; output Carriage return CLRB @A2 ; we need null terminator ; print line to appropriate place CALL LINOUT ; output last line ; close output file if open TSTB FILOUT(A5) ; are we outputing to a file? BEQ EXIT$ ; no - no need to close CLOSE DDBOUT(A5) ; yes - wrap it up EXIT$: EXIT ; we're done PAGE ;************* ;* DOPPN * ;************* ; Entry: ; A2->PPN @ MFD ; Exit: ; A1,A3,A4,D1,D4 modified DOPPN: ; we have a PPn match PUSH A2 ; save MFD pointer PUSH D.REC+DDBIN(A5) ; save MFD block number PUSH D.BUF+DDBIN(A5) ; save buffer address ; Use a seperate buffer for the directory LEA A6,DIRBUF(A5) ; don't use any registers MOV A6,D.BUF+DDBIN(A5) ; set buffer for directory to use ; output PPn MOV A2,A3 ; yes - save PPn pointer ; set octal JOBIDX A4 ; get my job PUSHW JOBTYP(A4) ; save my type ANDW #^C,JOBTYP(A4) ; make sure we are octal ; output PPn to output line buffer LEA A2,OUTLIN(A5) ; A2-> output buffer CLR D1 MOVB #'[,(A2)+ MOVB 1(A3),D1 ; get project number OCVT 0,OT$MEM ; output it MOVB #',,(A2)+ MOVB @A3,D1 ; programmer number OCVT 0,OT$MEM ; output it MOVB #'],(A2)+ MOVB #40,(A2)+ ; followed by some blanks MOVB #40,(A2)+ MOVB #40,(A2)+ MOVB #40,(A2)+ MOVB #40,(A2)+ ; restore jobtyp POPW JOBTYP(A4) ; restore type MOV A3,A2 ; restore pointer ; set directory info and get space used in this UFD MOVW 2(A2),D.REC+2+DDBIN(A5) ; set directory block number ; SCNDIR returns D4 with number of blocks in directory CALL SCNDIR ; scan directory (D4) ; Now D4 contains number of blocks. After we rotate, (which will divide the ; number of blocks by 2, giving us kilobytes,) we will have the N-bit set if ; set if we have an extra half a kilobyte ; first accumulate total ADD D4,TOTCNT(A5) ; keep running total ; now calculate kilobytes ROR D4,#1 ; divide by 2; N bit set if remainder CLR D1 MOVW D4,D1 ; get number of kilobytes ; output kilobytes used PUSH A2 ; save pointer LEA A2,10.+OUTLIN(A5) ; allow exactly 10 spaces for [PPN] DCVT 5,OT$MEM!OT$ZER ; output number of Kilobytes MOVB #'.,(A2)+ ; output decimal point MOVB #'0,D1 ; no remainder yet TST D4 ; any remainder from before? BPL 25$ ; no - finish MOV #'5,D1 ; .5 remainder ; output remainder 25$: MOVB D1,(A2)+ ; yes - show user MOVB #'K,(A2)+ ; show number is kilobytes MOVB #CR,(A2)+ ; output Carriage return CLRB @A2 ; place at end of output buffer POP A2 ; Now print line CALL LINOUT ; output line to appropriate place ; Done with this PPn - restore info 100$: POP D.BUF+DDBIN(A5) ; restore MFD areas POP D.REC+DDBIN(A5) POP A2 RTN PAGE ;************* ;* SCNDIR * ;************* ; Entry: ; A2->PPn buffer[not used] ; DDBIN set up for directory reads ; ; Exit: ; D4 contains number of total blocks in this directory ; SCNDIR: SAVE A2,D1,D3 ; save work registers CLR D4 ; clear block count TST D.REC+DDBIN(A5) ; is there a directory ? JEQ RTNDIR ; no - just return ; This is the master loop DIRLOP: READ DDBIN(A5) ; get a directory block MOV D.BUF+DDBIN(A5),A2 ; A2 -> directory buffer MOVW (A2)+,D1 ; D1 -> next block number MOV #42.,D3 ; 42 entries per block ; This loop scans an entire block and checks for matches DIRLP2: TSTW @A2 ; are we at the end of the directory? BEQ RTNDIR ; yes - return CMPW @A2,#-1 ; empty slot ? BEQ NXTDIR ; yes - get the next one ADDW 6(A2),D4 ; get the next directory item, if end of block ; then set up for next block NXTDIR: ADD #14,A2 ; next directory item please SOB D3,DIRLP2 ; are we at the end of the block ? MOVW D1,D.REC+2+DDBIN(A5) ; yes - set next block number BNE DIRLOP ; if zero we're done RTNDIR: REST A2,D1,D3 RTN PAGE ;************* ;* LINOUT * ;************* ;Output OUTLIN(A5) to terminal or file ; Entry: ; FILOUT(A5) set if we want to output to file ; clear if we want output to terminal ; Exit: ; Line outputted LINOUT: PUSH A2 TSTB FILOUT(A5) ; are we outputting to a file ? BEQ 10$ ; no - output to screen ; output line to file LEA A2,DDBOUT(A5) ; A2->output DDB for OUTL call OUTL OUTLIN(A5),OT$DDB ; output line to file BR 20$ ; output line to terminal 10$: TTYL OUTLIN(A5) ; finish routine 20$: POP A2 RTN ;define impure area SAVDOT=. .=0 DDBIN: BLKB D.DDB ; input ddb DDBOUT: BLKB D.DDB ; output ddb DIRBUF: BLKB 512. ; disk buffer for UFD reads OUTLIN: BLKB 40. ; output file buffer TOTCNT: BLKL 1 ; total kilobytes used FILOUT: BLKB 1 ; output flag EVEN IMPSIZ=. .=SAVDOT END .