1 ! ! S T A T S 2! PROGRAM : STATS 5! VERSION : 6B 6! EDIT : 07 7! EDIT DATE : 17-FEB-77 8! 9! AUTHOR : MARTIN MINOW/MARK BRAMHALL 11 ! ! C O P Y R I G H T ! Copyright (C) 1974, 1975, 1976, 1977 ! Digital Equipment Corporation, Maynard, Massachusetts ! ! ! This software is furnished under a license for use only on a ! single computer system and may be copied only with the ! inclusion of the above copyright notice. This software, or ! any other copies thereof, may not be provided or otherwise ! made available to any other person except for use on such ! system and to one who agrees to these license terms. Title to ! and ownership of the software shall at all times remain in ! DIGITAL. ! ! The information in this software is subject to change without ! notice and should not be construed as a commitment by Digital ! Equipment Corporation. ! ! DIGITAL assumes no responsibility for the use or reliability ! of its software on equipment that is not supplied by DIGITAL. ! !******************************************************************** 20 ! ! M O D I F I C A T I O N H I S T O R Y 21! VER/ED EDIT DATE REASON ! 100 ! ! G E N E R A L D E S C R I P T I O N 110 ! PARAMETER LINE: OUTPUT ? FILE/FLAGS ! "FILE" DEFAULTS TO KB: AND FLAGS MAY BE AS FOLLOWS: ! TERMINAL TYPE: ! /VT05 /VT50 /VT52 /SPEC /TTY ! DEFAULT: /TTY 120 ! STATISTICS DESIRED: ! /JOB /DISK /BOTH /TOTAL /INCR ! DEFAULT: /BOTH (VT50 FLIPS DISPLAY) ! DEFAULT: INCREMENTAL STATISTICS 130 ! OTHER FLAGS: ! /SL:NN /DET ! DEFAULT: 60 SECONDS SLEEP, NO DETACHING ! /SL:0 MEANS "PRINT ONE STATS REPORT ! NOTE: YOU MUST BE PRIVILEGED TO DETACH. 210 ! CHANGE THE NEXT LINE TO CHANGE THE DEFAULT PARAMETER LINE ! 220 DATA "KB:STATS.LST/TTY/INCR/BOTH/SL:60" 300 ! ! I / O C H A N N E L S 301! CHANNEL # USED FOR ! 310! 1 STATISTICS OUTPUT 800 ! ! F U N C T I O N / S U B R O U T I N E D E S C . 801! FUNCTION/SUBROUTINE USE ! 810! FND(C%,U%,I%) GET DISK BUFFER DATA: C% WHICH BUFFER U% WHICH DISK DEV/UNIT I% WHAT TYPE OF TRANSFER FND$(L%) PRINT DISK DATA ENTRY: L% WHICH ENTRY FND1$(Q%) PRINT ACCESS/BLOCK INFORMATION Q% 1=BLOCK, 0=ACCESS FNN$(Q%) RETURN DATE STRING FROM LOW-CORE Q% WHERE IN LOW-CORE IT IS 820! FNP(Q%) GET 32-BIT STATISTICS BUFFER ENTRY: Q% OFFSET FROM BASE P% FNP0(Q%) GET 16-BIT UNSIGNED STATISTICS BUFFER ENTRY: Q% ADDRESS TO PEEK AT FNP$(T%,Q,D) PRINT PERCENTAGE DATA: T% WHERE TO TAB TO Q VALUE AS A PERCENT D WHAT IT'S A PERCENT OF FNR$(T%,V,S%) PRINT A NUMERIC VALUE: T% WHERE TO TAB TO V WHAT TO PRINT S% PRINTED RIGHT-JUSTIFIED IN THIS FIELD FNR1$(T%,V,S%) PRINT A VALUE WITH 2 DECIMAL PLACE T% WHERE TO TAB TO V WHAT TO PRINT S% PRINTED RIGHT-JUSTIFIED IN THIS FIELD 830! FNS%(K$,K%) COMMAND-LINE STRING SEARCH: K$ SWITCH NAME K% VALUE TO RETURN IF THERE FNS0%(K$,K%) COMMAND-LINE STRING SEARCH (VALUE ARG.) K$ SWITCH NAME K% DEFAULT IF NOT THERE FNT EXACT TIME OF DAY IN FLOATING SECONDS FNN$(Q%) DD-MMM-YY HH:MM:SS Q% STARTING PEEK ADDRESS FNV% TRUE IF PRINTING JOB STATISTICS NOW FNX(Q%) GET INCREMENTAL TABLE VALUE: Q% MONITOR TABLE ENTRY 900 ! ! D I M E N S I O N S T A T E M E N T S 910 DIM T(100), D(5,4), X(5,4), V%(5), D$(5), H0%(30%), H1%(30) !T() OLD CPU DATA FOR INCREMENTAL STATISTICS !D() OLD DISK DATA (AT LAST PROBE) !X() NEW DISK DATA (AT THIS PROBE) !V%() DISK REMAPPING VECTOR !D$() DISK OUTPUT LABELING !H0%() MONITOR TABLES, PART 1 !H1%() MONITOR TABLES, PART 2 999 ! ! M A I N C O D I N G A R E A 1000 ! ! G E T P A R A M E T E R S A N D S E T U P 1010 PRINT "STATS"; CHR$(9%); "V06B-07"; CHR$(9%); CVT$$(RIGHT(SYS(CHR$(6%)+CHR$(9%)+CHR$(0%)),3%),4%) !INITIAL SIGN-ON 1020 P7%=PEEK(PEEK(156%))\ U9%=PEEK(P7%) AND 255% \P8%=PEEK(PEEK(156%)+2%)\ P9%=PEEK(PEEK(156%)+6%)\ H=PEEK(P8%) !P7% -> DISK !P8% -> JOB !P9% -> CACHE !U9% := DISKS !H := TICKS/SECOND 1030 IF (P7% OR P8%) = 0% THEN PRINT "?No statistics configured on this system" \GOTO 32767 !MUST HAVE JOB, DISK BUFFERS SYSGEN'D IN 1040 RESTORE\ READ Q$\ PRINT "Output <";Q$;">"; \INPUT LINE O0$\ O0$=CVT$$(O0$,-1%)\ O0$=Q$ UNLESS LEN(O0$)<>0% !GET CONSOLE INPUT LINE, SET UP FOR DEFAULT IF ! WAS TYPED 1050 S%=FNS0%("SL",60%)\ K0%=FNS%("DET",1%) \I9%=FNS%("TOTAL",-1%) OR FNS%("INCR",0%) \T9%=FNS%("VT05",1%) OR FNS%("VT50",2%) OR FNS%("VT52",3%) OR FNS%("SPEC",4%) OR FNS%("TTY",0%) !GET SLEEP, DETACH, STATISTICS, AND OUTPUT TYPE 1060 T8%=FNS%("JOB",1%) OR FNS%("DISK",2%) OR FNS%("BOTH",3%) \ON T9%+1% GOSUB 20010,20020,20030,20030,20040 \T8%=3% UNLESS T8%\ T7%=0%\ T6%=(T8%=3%) AND (T9%=2%) !GET STATISTICS FLAGS AND VT52 FLAG. !SETUP AND 1070 X(V%,I%)=0.0 FOR I%=0% TO 4% FOR V%=0% TO 5% \READ V%(I%) FOR I%=0% TO 5%\ READ D$(I%) FOR I%=0% TO 5% !X() DISK STATS BUFFER !V%() MAPPING VECTOR !D$() TITLES 1080 DATA 2,0,3,3,1,3, "User data","Directory"," Swapping", "Other Sys"," All Sys"," All I/O" 1090 T(Q%)=0.0 FOR Q%=0% TO 100% \CHANGE SYS(CHR$(6%)+CHR$( -3%)) TO H0% \CHANGE SYS(CHR$(6%)+CHR$(-12%)) TO H1% \H0%(Q%)=H0%(Q%)+SWAP%(H0%(Q%+1%)) FOR Q%=5% TO 29% STEP 2% \H1%(Q%)=H1%(Q%)+SWAP%(H1%(Q%+1%)) FOR Q%=3% TO 29% STEP 2% \O%=1%\ O0$="KB:STATS.LST" UNLESS LEN(O0$)\ GOSUB 20050 !T() JOB STATS !H0%() -> STSTEM STUFF !H1%() -> SYSTEM STUFF !SET OUTPUT UNIT NUMBER AND OPEN IT 1100 IF K0%>0% THEN GOSUB 25000 \Q$=SYS(CHR$(6%)+CHR$(7%)) \GOSUB 25100 !DETACH !NOTE: DROP TEMP. PRIVILEGES FIRST 1110 PRINT #O%, Z0$; Z1$;\ S1%=-1% \ON ERROR GOTO 19000\ Q$=SYS(CHR$(6%)+CHR$(-7%)) !CLEAR SCREEN, SETUP ERROR HANDLER !AND TRAP CTRL/C'S 2000 ! ! D O T H E W O R K 2010 GOSUB 3000\ GOSUB 10000 \IF S1% THEN S0%=S% ELSE S0%=S%-(INT(S0+0.5)-S0%) !COLLECT STATISTICS AND PRINT THEM !S0% SLEEP TIME NEXT TIME 2020 GOSUB 2200 \IF S%=0% THEN CLOSE O%\ GOTO 32767 !ABSORB ANY TYPING !EXIT (AFTER PRINTING) IF NO SLEEPING 2030 T=FNT\ SLEEP S0%\ T=FNT-T-S0%\ T=0.0 IF T<0.15 \GOSUB 2200\ GOTO 2010 !WAIT A WHILE, THEN GO DO THE STATISTICS. !T "RESPONSE TIME". !NOTE: T WILL BE LESS THAN ZERO IF THE !JOB WAS AWAKENED EARLY (TERMINAL TYPED SOMETHING). !WE ALSO IGNORE VERY SMALL VALUES (ONE TICK) 2100 ! ! T R Y F O R T E R M I N A L I N P U T 2200 S1%=0% \IF O1%>=0% THEN GET#O%, RECORD 8192% \S1%=-1%\ T7%= NOT T7%\ T5%=T6% !TRY TO GET SOME INPUT, IF YOU DO, !SET "AWAKENED" FLAG, FLIP VT50 DISPLAY FLAG 2210 RETURN !RETURN HERE (FROM ERROR HANDLER, TOO) 3000 ! ! C O L L E C T J O B S T A T I S T I C S 3010 P%=P8% ! START WITH JOB STATISTICS 3020 ! H=PEEK(P%) ! TICKS PER SECOND 3030 U=FNX(2%) ! UPTIME (TICKS) 3040 B%=PEEK(P%+6%) ! SMALL BUFFERS MINIMUM COUNT 3050 S=FNX(8%) ! LEVEL 3 ACCOUNTED (TICKS) 3060 L=FNX(12%) ! LOST (TICKS) 3070 O=FNX(16%) ! LEVEL 3 UNACCOUNTED (TICKS) 3080 N=FNX(20%) ! NULL (TICKS) 3090 Q%=PEEK(H1%(13%)) \J0%=Q% AND 255% ! CURRENT NUMBER OF ACTIVE JOBS 3100 J1%=SWAP%(Q%) AND 255% ! CURRENT MAXIMUM NUMBER OF JOBS 3110 E1=FNP0(H1%(11%)) ! HUNG TERMINALS 3120 E2=FNP0(H1%(17%))-E1 ! REAL ERRORS (EXCLUDING HUNG TERMINALS) 3130 F0=FNX(24%) ! FIP DESIRED 3140 ! F1=FNX(28%) ! FIP NOT RUNNING 3150 F2=FNX(32%) ! FIP WAITING 3160 ! F3=FNX(36%) ! FOR CODE 3170 ! F4=FNX(40%) ! FOR DISK 3180 ! F5=FNX(44%) ! FOR SAT 3190 ! F6=FNX(48%) ! FOR OTHER 3200 L0=FNX(52%) ! PR0 3210 L1=FNX(56%) ! PR1 3220 L2=FNX(60%) ! PR2 3230 L3=FNX(64%) ! PR3 3240 L4=FNX(68%) ! PR4 3250 L5=FNX(72%) ! PR5 3255 REM K8%=PEEK(P%+102%) ! # TIMES AT PR6 OR PR7 (IN-HOUSE) 3260 K9%=PEEK(P%+76%) ! KW11P OVERRUNS 3270 ! C0=FNX(78%) ! PR0 CACHE CODE 3280 ! C1=FNX(82%) ! PR1 CACHE CODE 3290 ! C2=FNX(86%) ! PR2 CACHE CODE 3300 C3=FNX(90%) ! PR3 CACHE CODE 3310 C4=FNX(94%) ! PR4 CACHE CODE 3320 C5=FNX(98%) ! PR5 CACHE CODE 3330 P%=P9% \GOTO 4010 UNLESS P% ! DO IF CACHE CODE 3340 H0=FNP(0%) ! CACHE ATTEMPTS 3350 H1=FNP(8%) ! CACHE HITS 3360 H4=H0-H2 ! INCREMENTAL ATTEMPTS 3370 H5=H1-H3 ! INCREMENTAL HITS 3380 H2=H0\ H3=H1 ! GET NEW "PREVIOUS" VALUES 3390 ! H6%=PEEK(P%+16%) ! RESTARTS 3400 H7%=PEEK(P%+18%) ! SMALL BUFFER CACHE NODES 3410 H8%=PEEK(P%+20%) ! EXTENDED BUFFER CACHE NODES 4000 ! ! C O L L E C T D I S K S T A T I S T I C S 4010 GOTO 4050 UNLESS P7%\ P%=P7%+2% \IF I9% THEN D(V%,I%)=0.0 FOR I%=0% TO 4% FOR V%=0% TO 5% ELSE D(V%,I%)=X(V%,I%)FOR I%=0% TO 4% FOR V%=0% TO 5% !D() PREVIOUS TRIAL'S DATA 4020 X(V%,I%)=0.0 FOR I%=0% TO 4% FOR V%=0% TO 5% \X(V%(C%),I%)=X(V%(C%),I%)+FND(C%,U%,I%) FOR U%=0% TO U9%-1% FOR I%=0% TO 3% FOR C%=0% TO 5% !COLLECT DISK STATS !U% DISK UNIT NUMBER !I% ACCESS TYPE (READ/WRITE) !C% PROCESS TYPE (SWAP, ETC.) 4030 X(5%,I%)=X(5%,I%)+X(V%,I%) FOR I%=0% TO 3% FOR V%=0% TO 3% \X(4%,I%)=X(5%,I%)-X(0%,I%) FOR I%=0% TO 3% \D(V%,I%)=X(V%,I%)-D(V%,I%) FOR I%=0% TO 3% FOR V%=0% TO 5% !GET DISK GROUP DATA AND SUMS ! DISK DATA IS STORED IN D(V%,I%) WHERE ! V% I% ! 0 USER 0 READ ACCESSES ! 1 DIRECTORY 1 READ BLOCKS ! 2 SWAPS 2 WRITE ACCESSES ! 3 OTHER SYS ACTION 3 WRITE BLOCKS ! 4 TOTAL SYS I/O ! 5 TOTAL I/O 4050 RETURN ! END OF STATISTICS 10000 ! ! P R I N T F I R S T T E N L I N E S 10010 U1=U-N\ U3=L3+L4+L5\ U2=L0+L1+L2+U3\ U4=U-L-O-N\ S0=U/H !U1 TOTAL LESS NULL JOB !U2 TOTAL PRIORITY 0-5 !U3 TOTAL EXEC. PRIORITY 3-5 !U4 UNCHARGED (TOTAL-LOST-UNCH.MON-NULL) !S0 SECONDS = TICKS/HERTZ 10020 PRINT #O%, Z2$;FNN$(512%);FNR$(0%,S0,15%);" Seconds"; FNR$(0%,E2,7%);" Errors";FNR$(0%,E1,7%);" Hung TTY" 10030 GOSUB 22040 \PRINT #O%, SPACE$((11%-LEN(Q$))/2%);Q$;" Uptime"; " ";NUM1$(J0%)+"/"+NUM1$(J1%);" Jobs"; \PRINT #O%, ",";FNR1$(0%,T,6%);" Swap in"; UNLESS S1% \PRINT #O%,FNR$(42%,B%,6%);" Minimum Small Buffers" 10040 PRINT #O%, Z1$;CHR$(13%); IF T5%\ T5%=0% \GOTO 12010 UNLESS FNV% \PRINT #O%, TAB(13%);"System Operation Statistics"; TAB(49%);"Cache/Fip Statistics" 10050 PRINT #O%, TAB( 7%);"Including Idle Time Excluding Idle Time"; FNR$(47%,H7%,7%);" Monitor Nodes" 10060 PRINT #O%, TAB( 8%);"Charged Uncharged Charged Uncharged"; FNR$(47%,H8%,7%);" XBUF Nodes" 10070 PRINT #O%," Idle ";FNP$(18%,N,U); FNP$(47%,H5,H4);"Incremental Hits" 10080 PRINT #O%," Lost ";FNP$(18%,L,U);FNP$(38%,L,U1); FNP$(47%,H1,H0);"Running Sum Hits" 10090 PRINT #O%," User ";FNP$(0%,U4-S,U);FNP$(29%,U4-S,U1); FNP$(47%,C3+C4+C5,U);"Cache CPU Usage" 10100 PRINT #O%," System ";FNP$(0%,S,U);FNP$(18%,O,U);FNP$(29%,S,U1); FNP$(38%,O,U1);FNP$(47%,F0,U);"FIP Desired" 10110 PRINT #O%," Total ";FNP$(0%,U4,U);FNP$(18%,O+L+N,U);FNP$(29%,U4,U1); FNP$(38%,O+L,U1);FNP$(47%,F2,U);"FIP Waiting" 10120 REM IF K8%<>0% THEN PRINT #O%, FNR$(4%,K8%,7%);" Ticks at PR6/PR7"; !PRINT PR6/PR7 TICKS IF THERE ARE ANY IN-HOUSE ONLY 10130 IF K9%<>0% THEN PRINT #O%, FNR$(25%,K9%,7%);" KW11P Overruns"; ! PRINT #O%, " (";FNN$(P8%+104%);")"; IN-HOUSE ONLY !PRINT OVERRUNS ONLY IF THERE ARE ANY 10190 IF ((T8% AND 2%) = 0%) OR T6% THEN GOTO 13000 ELSE PRINT #O%\ PRINT #O% !END OF PART 1 12000 ! ! P R I N T L A S T N I N E L I N E S 12010 PRINT #O%, TAB(13%);"CPU Status"; TAB(29%);"Disk Status for all Disks"; TAB(59%);"Xfer Percent" 12020 PRINT #O%, TAB(11%);"Total Exec Process "; " Block/Sec Xfer/Sec Reads Total" 12030 PRINT #O%,"User Job ";FNP$(0%,L0,U2); FND$(0%) 12040 PRINT #O%,"CPU Idle ";FNP$(0%,L1,U2); FND$(1%) 12050 PRINT #O%,"(Unused) ";FNP$(0%,L2,U2); FND$(2%) 12070 PRINT #O%,"Monitor ";FNP$(0%,L3,U2);FNP$(0%,L3,U3); FND$(3%) 12080 PRINT #O%,"Slow I/O ";FNP$(0%,L4,U2);FNP$(0%,L4,U3); FND$(4%) 12090 PRINT #O%,"Fast I/O ";FNP$(0%,L5,U2);FNP$(0%,L5,U3); FND$(5%); 13000 PRINT #O%, Z1$;Z0$;\ RETURN !DONE, GO TO HOME AND EXIT 19000 ! ! E R R O R P R O C E S S I N G 19010 IF ERR=28% THEN Q$=SYS(CHR$(6%)+CHR$(-7%))\ RESUME 19100 !CTRL/C TRAPPED 19020 RESUME 2210 IF ERL= 2200% \RESUME 19120 IF ERL=20050% AND K0%<0% !HANDLE "NO TERMINAL INPUT" WHEN DISPLAYING !AND "FILE OPEN" ERROR WHEN REATTACHING 19090 PRINT "FATAL ERROR";ERR;", AT LINE";ERL;", TRAPPED AT";LINE \ON ERROR GOTO 0 !FATAL STOP 19100 CLOSE O%\ GOTO 32767 IF O1%<0% \Q$=SYS(CHR$(6%)+CHR$(-5%)+CHR$(O1%)+Z0$+Z1$+ CHR$(13%)+" The terminal is all yours now."+ CHR$(13%)+CHR$(10%)+CHR$(10%)) !EXIT UNLESS OUTPUT IS ON A KB: 19120 K0%=-1%\ CLOSE O% !PREPARE FOR RESTART 19130 Q%=PEEK(PEEK(PEEK(520%))) \IF (PEEK(518%) AND 255%) <> (PEEK(Q%+O%+O%) AND 255%) OR (PEEK(Q%+6%) AND 8192%) = 0% THEN SLEEP 15%\ GOTO 19150 !Q% -> CONSOLE KB: DDB !IF SOMEONE ELSE OWNS IT OR IT'S NOT A CONSOLE !WAIT A WHILE 19140 O1%=SWAP%(PEEK(Q%+2%)) AND 255% \INPUT "Continue detached"; Q$ \GOTO 32767 UNLESS CVT$$(LEFT(Q$,1%),-1%) = "Y" \GOSUB 25000\ Q$=SYS(CHR$(6%)+CHR$(7%))\ GOSUB 25100 !WE'RE ATTACHED, STOP OR DETACH AS DESIRED 19150 Q%=PEEK(H0%(7%)+H1%(9%)) \Q%=Q%+2% WHILE (SWAP%(PEEK(PEEK(Q%)+2%)) AND 255%) <> O1% !Q% -> MY (CURRENT) CONSOLE DDB 19160 IF (PEEK(PEEK(Q%)+2%) AND 255%) <> 0% THEN GOTO 19130 ELSE O0$="KB"+NUM1$(O1%)+":STATS.LST" \GOSUB 20050\ K0%=1%\ GOTO 1110 !CONSOLE IS AVAILABLE, OPEN IT AND START UP 20000 ! ! F U N C T I O N S A N D S U B R O U T I N E S 20010 Z0$=CHR$(13%)+CHR$(10%)+CHR$(12%) \Z1$,Z2$=""\ RETURN !TTY 20020 Z0$,Z2$=CHR$(29%)\ Z1$=CHR$(31%) \RETURN !VT05B 20030 Z0$,Z2$=CHR$(155%)+"H"\ Z1$=CHR$(155%)+"J" \RETURN !VT50, VT52, BEE 20040 Z0$,Z2$=CHR$(29%)\ Z1$=CHR$(153%) \RETURN !TANDBERG !NOTE "OTHER SCOPE" (T9%=4%) IS RESERVED !FOR WEIRD TERMINALS. 20050 GOSUB 25000\ OPEN O0$ FOR OUTPUT AS FILE O% \Q%=STATUS\ GOSUB 25100 !OPEN OUTPUT FILE WITH PRIVILEGE PROTECTION 20060 IF (Q% AND 255%) <> 2% THEN O1%=-1% ELSE O2%=PEEK(PEEK(PEEK(520%))+(O%*2%)) + 2% \O1%=(SWAP%(PEEK(O2%)) AND 255%) \O0$="KB"+NUM1$(O1%)+":STATS.LST" !FIND RUNNING KB: NUMBER (NOTE, CHANGED FOR RSTS V6B) 20070 RETURN !O1% KB: NUMBER, -1 IF NOT KB: TYPE !O2% -> KB: DDB JOB NBR AND KB: NBR !O0$ ACTUAL KB: NUMBER 20080 DEF FNP0(Q%) \Q=PEEK(Q%)\ Q=Q+65536.0 IF Q < 0.0 \FNP0=Q \FNEND !GET UNSIGNED TABLE ENTRY 20090 DEF FNP(Q%) \Q=PEEK(Q%+P%)\ Q=Q+65536.0 IF Q < 0.0 \FNP=Q+(65536.0*PEEK(Q%+P%+2%)) \FNEND !GET FLOATING TABLE ENTRY 20100 DEF FNX(Q%) \Q = FNP(Q%)\ T(Q%) = 0.0 IF I9%\ FNX = Q - T(Q%)\ T(Q%) = Q \FNEND !INCREMENTAL TABLE VALUE 21000 DEF FNP$(T%,Q,D) \IF Q = 0.0 OR D = 0.0 THEN PRINT #O%, TAB(T%); " .00% "; ELSE PRINT #O%, FNR1$(T%,Q*100.0/D,6%);"% "; 21010 FNP$="" \FNEND !PRINT PERCENTAGE 21020 DEF FNR$(T%,V,S%) ! TAB TO COLUMN T%, PRINT V RIGHT-JUSTIFIED ! IN AN S%-LENGTH FIELD, FORMAT ###,###,... 21030 Q$=NUM1$(FIX(V+.5))\ GOSUB 21080\ FNR$="" !CONVERT AND PRINT THE DATUM 21040 FNEND 21050 DEF FNR1$(T%,V,S%) ! TAB TO COLUMN T%, PRINT V RIGHT-JUSTIFIED ! IN AN S%-LENGTH FIELD, FORMAT ###,###.## 21060 FNR1$=""\ Q$=NUM1$(FIX(V*100.+.5)/100.+.001) \Q$=LEFT(Q$,LEN(Q$)-1%)\ GOSUB 21080 !CONVERT (FIX DECIMAL) AND PRINT THE DATUM 21070 FNEND 21080 Q$=LEFT(Q$,Q%)+","+RIGHT(Q$,Q%+1%) FOR Q%=INSTR(1%,Q$+".",".")-4% TO 1% STEP -3% \PRINT #O%, TAB(T%); SPACE$(S%-LEN(Q$)); Q$; !INTERNAL FUNCTION FOR FORMAT PRINTING !STUFF COMMAS EVERY THIRD PLACE AND PRINT 21090 RETURN 21100 DEF FNN$(Q%) \Q1%=1440%-PEEK(Q%+2%) \FNN$=DATE$(PEEK(Q%))+" " +RIGHT(NUM1$(100%+(Q1%/60%)),2%)+":" +RIGHT(NUM1$(100%+Q1%-((Q1%/60%)*60%)),2%)+":" +RIGHT(NUM1$(160%-(PEEK(Q%+4%) AND 255%)),2%) \FNEND !RETURN DD-MMM-YY HH:MM:SS 22000 DEF FND(C%,U%,I%) = FNP((C%*U9% + U%)*16% + I%*4%) !GET DISK BUFFER DATA: !C% WHICH (0-5) !I% WHAT (0-3) !U% WHERE (0-MAX UNITS) 22010 ! DISK DATA IS STORED AS FOLLOWS ! C% I% (ALREADY DESCRIBED) ! 0 SWAPS AND RTS READS ! 1 USER I/O ! 2 SAT ! 3 OVERLAY CODE ! 4 DIRECTORY I/O ! 5 DECTAPE BUFFER 22020 DEF FND$(L%) \PRINT #O%,TAB(26%);D$(L%);" ";FND1$(1%);FND1$(0%); FNP$(56%,D(L%,0%),D(L%,0%)+D(L%,2%)); FNP$(0%,D(L%,0%)+D(L%,2%),D(5%,0%)+D(5%,2%)); \FND$="" \FNEND ! PRINT DISK STATISTICS 22030 DEF FND1$(Q%) \PRINT #O%,FNR1$(0%,(D(L%,Q%)+D(L%,Q%+2%))/S0,9%);" "; IF S0>0 \FND1$="" \FNEND ! PRINT NUMBER OF ACCESSES/BLOCKS 22040 Q=((PEEK(512%)-PEEK(36%))*1440.+PEEK(38%)-PEEK(514%))*60.+ 60.-ASCII(CHR$(PEEK(516%))) \IF Q<0. OR Q>3600000. THEN Q$ = "???:??:?"\ RETURN !SUBROUTINE TO GET UPTIME AS HHH:MM:SS 22050 Q$ = ""\ Q% = 0%\ Q1% = Q/3600. \IF Q1% THEN Q = Q - 3600.*Q1%\ GOSUB 22080\ Q$ = Q$ + ":" !GET HOURS (IF ANY) !Q$ OUTPUT STRING !Q% FLAG (OUTPUT STARTED) !Q1% VALUE TO CONVERT !Q TIME (LEFT) TO CONVERT 22060 Q1% = Q/60% \IF Q1% OR Q% THEN Q=Q-60%*Q1%\ GOSUB 22080\ Q$ = Q$ + ":" !GET MINUTES 22070 Q1% = Q\ GOSUB 22080\ RETURN !AND GET SECONDS 22080 Q0$=NUM1$(Q1%+Q%*100%)\ Q$=Q$+MID(Q0$,Q%,LEN(Q0$)-Q%) \Q% = 1%\ RETURN ! CONVERT A VALUE FOR PRINTING 23000 DEF FNS%(K$,K%) \FNS%=0%\ Q%=INSTR(1%,O0$,"/"+K$) \IF Q% THEN FNS%=K% \O0$=LEFT(O0$,Q%-1%)+RIGHT(O0$,Q%+LEN(K$)+1%) 23010 FNEND !FNS%(K$,K%): IF /K$ IS FOUND IN O0$, RETURN K% 23020 DEF FNS0%(K$,K%) \FNS0%=K%\ GOTO 23040 UNLESS FNS%(K$+":",1%) \GOTO 23030 UNLESS INSTR(1%,"0123456789",MID(O0$,K%,1%)) FOR K%=Q% TO LEN(O0$) \K%=LEN(O0$)+1% !IF SWITCH IS FOUND, SCAN FOR FOLLOWING NUMBER 23030 FNS0%=VAL(MID(O0$,Q%,K%-Q%)) \O0$=LEFT(O0$,Q%-1%)+RIGHT(O0$,K%) !DONE SCANNING, RETURN THE VALUE AND FIX STRING 23040 FNEND !FNS0$(K$,K%): IF /K$:VALUE IS FOUND, RETURN VALUE ! ELSE RETURN K% 23050 DEF FNT \Q=H\ Q=50.0 IF H <> 60.0 \FNT=TIME(0)+(Q-(SWAP%(PEEK(516%)) AND 255%))/Q \FNEND !FNT TIME OF DAY (INCLUDING CLOCK TICKS) 23060 DEF FNV% = (T6% AND T7%) OR (NOT T6% AND (T8% AND 1%)) !TRUE IF PRINTING JOB STATS: !/VT50/BOTH AND "ODD" TYPED, OR !/JOB OR /BOTH AND NOT /VT50 REQUESTED 25000 Q$=SYS(CHR$(6%)+CHR$(-21%)+CHR$(-1%)) \RETURN !DROP PRIVILEGES TEMPORARILY !NOTE: RSTS/E V06B ONLY. 25100 Q$=SYS(CHR$(6%)+CHR$(-21%)+CHR$(0%)) \RETURN !REGAIN PRIVILEGES AFTER OPENING THE FILE !NOTE: RSTS/E V06B ONLY. 32767 END