Trailing-Edge
-
PDP-10 Archives
-
BB-H506D-SM_1983
-
cobol/source/metio.mac
There are 5 other files named metio.mac in the archive. Click here to see a list.
; UPD ID= 1991 on 7/30/79 at 5:10 PM by M:<MAYBERRY>
TITLE METIO FOR LIBOL - LSTATS METER I/O CODE
SUBTTL D. WRIGHT JAN, 1979
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1979, 1981 BY DIGITAL EQUIPMENT CORPORATION
; HAM 26-JUN-79
; SET VERSION NUMBER TO 2
SUBTTL DEFINITIONS
SEARCH LBLPRM ;DEFINE PARAMETERS.
SEARCH COMUNI
SEARCH FTDEFS
SEARCH UUOSYM
IFN TOPS20,<SEARCH MONSYM, MACSYM>
IFE TOPS20,<SEARCH UUOSYM, MACTEN>
IFN LSTATS,<SEARCH METUNV>
IFN LSTATS,<
EXTERN KILL.,RET.1,RET.2,LMETR. ;CBLIO ROUTINES
IFN TOPS20,<
EXTERN MRTM.E,MRTM.S ;TOPS20 ROUTINES IN CBLIO
>
EXTERN LIBVR.,LIBSW. ;ALSO DEFINED IN CBLIO
;LOWSEG LOCATIONS, DEFINED IN COMUNI, (LOADED IN LILOWS)
EXTERN MROPT.,MROPTT,MRNM6,MRNMA, MRTMB.,MBTIM.,MRHDBP,MRHDFL
EXTERN MRAFFT,MRFKFT,MRTDBP,MRAPN.,MRBLKO,MRBKO.,MRFPGT
EXTERN MRKILL,MRBNUM,MRPSTM,MRRERN,MRLDBL
IFE TOPS20, EXTERN MRCHNN,MRCHCF
IFN TOPS20, EXTERN MRJFN,MRLCJF
IFN DBMS6,< INTERN MRDBST,MRDBEN,MRDBDM
EXTERN MRDDBP
>
IFN FTLSDR,< ;FOR LSTATS.DIR STUFF
IFN TOPS20,<
EXTERN MRLDJF,MRLDNA
>
IFE TOPS20,<
EXTERN MRCHLS,MRLLDR,MRLLDV,MRCFNM,MRCFEX
>
EXTERN MRLBPC,MRLSZL,MRLFPR
>;END IFN FTLSDR
;ENTRY POINTS
ENTRY MRLSET ;SETUP TO WRITE LSTATS FILE
ENTRY MRDMP ;WRITE ONE LSTATS FILE BLOCK IF THERE IS DATA
ENTRY MRDMPT ;DUMP ALL LSTATS DATA AND FINISH WRITING METER FILE
>;END IFN LSTATS
ENTRY MROUT. ;LSTATS ROUTINE TO OUTPUT AN LSTATS BLOCK
HISEG
SALL
T0=0
T1=1
T2=2
T3=3
T4=4
T5=5
AC6=6
AC11=11
SUBTTL METERING STUFF
IFN LSTATS,<
;WORDS IN LSTATS.DIR
.LDBPC==0 ;BYTE PTR TO CURRENT FILENAME
.LDNFL==1 ;# FILES IN DIRECTORY,,# OF CURRENT FILE
.LDSZL==2 ; SIZE LIMIT OF EACH FILE (BLOCKS OR PAGES)
.LDTML==3 ;TIME LIMIT (AS DAYS,,1/3 SECS)
.LDFWR==4 ;TIME OF FIRST WRITE TO CURRENT FILE
.LDAFN==5 ;ASCIZ FILE SPECS
IFN FTLSDR,<
IFE TOPS20, MR.BFB==^D128+5 ;ONE BUFFER + A FEW EXTRA WORDS
IFN TOPS20, MR.BFB==^D128+1 ;ONE BUFFER AND BLANK WORD AT END
>;END IFN FTLSDR
IFE FTLSDR, MR.BFB==^D128 ;ONE BUFFER EXACTLY
IFE TOPS20,<
;TOPS10 LSTATS ROUTINE TO GET A FREE CHANNEL
; RETURNS .+1 IF NONE AVAILABLE, ELSE .+2 WITH NUMBER IN RH(T5)
GMCHAN: SKIPN T5,OPNCH.## ;ANY CHANNELS AVAIL?
POPJ PP, ;NO
MOVE AC6,OPNCBP## ;GET BYTE PTR
HRRI T5,1 ;START WITH 1
MOVEI T2,17 ; UPPER LIMIT
GMCHN2: ILDB AC11,AC6
SOJE AC11,GMCHN1 ; SEE GCHAN. ROUTINE
CAILE T2,(T5)
AOJA T5,GMCHN2
GMCHN0: SETZB T5,AC11 ;USE CHANNEL 0 IF NONE OTHER FREE
GMCHN1: DPB AC11,AC6 ;NOTE CHANNEL UNAVAILABLE
JRST RET.2 ;GIVE SKIP RETURN
>;END IFE TOPS20
>;END IFN LSTATS
IFN LSTATS,<
SUBTTL LSTATS SETUP - OPEN METER FILE
;ROUTINE MRLSET IS CALLED AT RESET TIME TO OPEN THE METER FILE
; PNAME.MTO. IT REMAINS OPEN DURING THE ENTIRE RUN. ON TOPS10
; THIS REQUIRES ONE OF THE PRECIOUS 16 CHANNELS.
MRLSET:
;GET FILENAME TO WRITE THE DATA TO.
;ON TOPS10 USE NNNMTR.TMP
;ON TOPS20 USE <LAST-SIX-DIGITS-OF-TIME-OF-DAY>.MTO;T
IFE TOPS20,<
PJOB T1,
SETZ T3,
MOVEI T4,3 ;WANT 3 DIGITS OF JOB NUMBER
MAKEJN: IDIVI T1,^D10
MOVEI T2,'0'(T2)
LSHC T2,-6
SOJG T4,MAKEJN
HRRI T3,'MTO' ;(T3) = NNNMTO
MOVEM T3,MRNM6 ;STORE SIXBIT FILENAME
>;END IFE TOPS20
IFN TOPS20,<
GTAD ;GET SOME FAIRLY UNIQUE DIGITS
HRRZ T1,T1 ;JUST SAVE RH
SETZ T3,
MOVEI T4,6 ;WANT 6 DIGITS
MAKEJN: IDIVI T1,^D10
MOVEI T2,'0'(T2)
LSHC T2,-6
SOJG T4,MAKEJN
MOVEM T3,MRNM6
>;END IFN TOPS20
; NOW SIXBIT NAME IS IN MRNM6
; MAKE AN ASCII NAME OUT OF IT
MOVE T2,[POINT 6,MRNM6]
MOVE T3,[POINT 7,MRNMA]
MRLST1: ILDB T4,T2
JUMPE T4,MRLST2
ADDI T4,40 ;CONVERT SIXBIT CHAR TO ASCII CHAR
IDPB T4,T3
TLNE T2,760000 ;SKIP IF DONE 6 CHARS
JRST MRLST1
MRLST2:
IFN TOPS20, MOVE 2,[POINT 7,[ASCIZ/.TMP;T/]] ;235123.TMP;T
IFE TOPS20, MOVE 2,[POINT 7,[ASCIZ/.TMP/]] ;WRITE TO NNNMTO.TMP
ILDB T4,T2
IDPB T4,T3
JUMPN T4,.-2
;NOW OUTPUT FILE NAME HAS BEEN OBTAINED. IT IS STORED
;IN SIXBIT IN MRNM6, IN ASCII IN MRNMA.
;
;NOW OPEN THE OUTPUT METER FILE
IFE TOPS20,<
PUSHJ PP,GMCHAN ;GET A FREE CHANNEL TO USE
JRST [OUTSTR [ASCIZ/?NO FREE CHANNELS TO WRITE METER FILE
/]
JRST KILL.] ;THIS SHOULD NEVER HAPPEN!!!
ANDI T5,17 ;T5:= CHANNEL NUMBER
DPB T5,[POINT 4,T5,12] ;SAVE IN AC FIELD OF T5
HLLZ T5,T5 ;FOR MAKING UUOS
MOVEM T5,MRCHNN ;SAVE CHANNEL NUMBER FOR CLOSE LATER
;DO OPEN UUO
MOVEI T1,.IODMP ;BINARY DUMP MODE
MOVSI T2,'DSK' ; TO DEVICE "DSK"
SETZ T3, ;NO BUFFER HEADERS
MOVE T0,[OPEN T1]
OR T0,T5 ;READY TO DO IT
XCT T0
JRST MROPNF ;OPEN FAILED!
SUBTTL LSTATS SETUP - ENTER METER FILE
;DO ENTER UUO
MRLKPF: MOVE T1,MRNM6 ;FILENAME
MOVSI T2,'TMP' ;.TMP
SETZB T3,T4
MOVE T0,[ENTER T1]
OR T0,T5
XCT T0
JRST MRENTF ;ENTER FAILED!
JRST MRENOK ;OK
MRENTF: OUTSTR [ASCIZ/? ENTER FAILED FOR METER FILE: /]
MRTYPF: OUTSTR MRNMA
OUTSTR [ASCIZ/
/]
SETZM MROPT. ;CLEAR BUCKET POINTER, SO WE DON'T
; TRY WRITING ANYMORE
JRST KILL. ;FATAL ERROR IF THIS HAPPENS
MROPNF: OUTSTR [ASCIZ/? OPEN FAILED FOR METER FILE: /]
JRST MRTYPF ;TYPE FILE NAME (EVEN THOUGH THIS
; ERROR IS INDEPENDENT OF THE FILE NAME)
>;END IFE TOPS20
IFN TOPS20,<
MOVX 1,GJ%SHT
HRROI 2,MRNMA
GTJFN
ERJMP MRJSER ;COULDN'T OPEN THE FILE FOR OUTPUT
MOVEM 1,MRJFN ;REMEMBER JFN
MOVX T2,OF%WR
OPENF
ERJMP MRJSER
JRST MRENOK
MRJSER: HRROI 1,[ASCIZ/?JSYS ERROR: /]
PSOUT
MOVEI 1,.PRIOU
HRLOI 2,.FHSLF
SETZ 3,
ERSTR
JFCL
JFCL
HRROI 1,[ASCIZ/ FOR METER FILE /]
PSOUT
MRTYPF: HRROI 1,MRNMA
PSOUT
HRROI 1,[ASCIZ/
/]
PSOUT
JRST KILL. ;FATAL ERROR--DIE OFF
;HERE FOR NON I/O JSYS ERRORS
MRJSSE: HRROI 1,[ASCIZ/?JSYS ERROR: /]
PSOUT
PUSHJ P,TYPFER ;TYPE LAST ERROR IN THIS FORK
JRST KILL. ;FATAL ERROR--DIE OFF
;ROUTINE TO TYPE LAST ERROR IN THIS FORK THEN CRLF
TYPFER: MOVEI T1,.PRIOU
HRLOI T2,.FHSLF
SETZ T3,
ERSTR
JFCL
JFCL
HRROI T1,[ASCIZ/
/]
PSOUT
POPJ PP,
>;END IFN TOPS20
SUBTTL LSTATS SETUP - SETUP CORE
;METER FILE HAS NOW BEEN SUCCESSFULLY OPENED FOR OUTPUT.
;CALL FUNCT. TO GET CORE AT PAGE BOUNDARY
; FOR THE BUCKETS, AND STORE ADDRESS IN MROPT.
MRENOK: MOVEI 16,1+[-5,,0
XWD 0,FUN.A0##
XWD 0,[ASCIZ/LBL/]
XWD 0,FUN.ST##
XWD 0,FUN.A1##
XWD 0,FUN.A2##]
F.PAG==15
MOVEI T1,F.PAG ;FUNCTION WE WANT
MOVEM T1,FUN.A0## ;STORE FUNCTION
SETZM FUN.ST## ;CLEAR STATUS
SETZM FUN.A1## ; AND ADDRESS RETURNED
MOVEI T1,.MBFSZ ;NUMBER OF WORDS TO ALLOCATE
IMULI T1,^D16
ADDI T1,.MBHSZ+.MBTSZ ;ACCOUNT FOR HEADER BLOCK & TRAILER BLOCK
ADDI T1,MBHISL ;CORE FOR FILE/PAGE TABLE
IFN DBMS6, ADDI T1,.MBDSZ ;AND DBMS BLOCK
ADDI T1,MR.BFB ;200 OR MORE WORDS FOR LSTATS.DIR BLOCK
MOVEM T1,FUN.A2## ;STORE AS ARG #2
PUSHJ PP,FUNCT.## ;CALL FUNCT. ROUTINE...
SKIPE FUN.ST## ; STATUS MUST BE 0...
JRST MRNCR ; ? NOPE - NO CORE AVAIL
HRRZ T1,FUN.A1## ;GOT IT -- GET ADDRESS OF START
MOVEM T1,MROPT. ;STORE IN MROPT.
;SETUP THE TABLE OF BUCKET ADDRESSES INDEXED BY CHANNEL NUMBER.
SETZ T2, ;T2=BUCKET BLOCK NUMBER
MRSBA: MOVEM T1,MROPTT(T2) ;STORE ADDRESS OF THIS BLOCK
ADDI T1,.MBFSZ ;NEXT BUCKET BLOCK ADDRESS
CAIGE T2,17 ;DONE ALL?
AOJA T2,MRSBA ;NO, LOOP
MOVEM T1,MRHDBP ; STORE POINTER TO HEADER BLOCK
ADDI T1,.MBHSZ
MOVEM T1,MRTDBP ; STORE POINTER TO TRAILER BLOCK
ADDI T1,.MBTSZ ;TRAILER SIZE
MOVEM T1,MRFPGT ;STORE POINTER TO FILE/PAGE # TABLE
..NXAD==MBHISL
IFN DBMS6,<
..NXAD==.MBDSZ
ADDI T1,MBHISL
MOVEM T1,MRDDBP ;STORE POINTER TO DBMS BLOCK
>
ADDI T1,..NXAD
MOVEM T1,MRLDBL ;STORE POINTER TO LSTATS.DIR BLOCK
SUBTTL LSTATS SETUP - SETUP HEADER BLOCK
;STORE HEADER BLOCK INFORMATION
DEFINE STOR1H(OFFSET),<
HRRZ T2,MRHDBP ;GET OFFSET
MOVEM T1,OFFSET(T2) ;STORE THE WORD
>
MOVEI T1,2 ;VERSION NUMBER OF LSTATS STUFF
STOR1H (MB.VNO) ; STORE IT
;HEADER BLOCK LENGTH IN WORDS
MOVEI T1,.MBHLN
STOR1H (MB.HLN)
;PER-FILE BLOCK LENGTH IN WORDS
MOVEI T1,.MBFLN ;ACTUAL SIZE OF THE BLOCK
STOR1H (MB.FLN)
;MONITOR TYPE (%CNMNT WORD ON TOPS10, BIT 21=1 ON TOPS20)
IFN TOPS20,<
MOVEI T2,4B23 ;MONITOR TYPE 4 = TOPS20
>
IFE TOPS20,<
MOVE T2,[%CNMNT]
GETTAB T2,
MOVEI T2,1B23 ;ASSUME TOPS10
>
;NOW FIND PROCESSOR TYPE. THIS ALGORITHM IS TAKEN
;DIRECTORY FROM THE HARDWARE REFERENCE MANUAL.
MOVNI T1,1 ;MAKE AC ALL 1'S
AOBJN T1,.+1 ;INCREMENT BOTH HALVES
JUMPN T1,MRKA10 ;KA10 IF AC= 1000000 (CARRY BETWEEN HALVES)
BLT T1,0
JUMPN T1,MRKL10 ;KL10 IF AC=1,,1
MRKI10: MOVEI T1,2 ;KI10 - SET PROCESSOR TYPE TO 2
JRST MRSTRP
MRKA10: MOVEI T1,1 ;KA10 - SET PROCESSOR TYPE TO 1
JRST MRSTRP
MRKL10: MOVEI T1,3 ;KL10 - SET PROCESSOR TYPE TO 3
MRSTRP: DPB T1,[POINT 3,T2,17] ;STORE IN 7B17
MOVE T1,T2 ;COPY PROCESSOR/OPERATING SYSTEM INFO TO T1
STOR1H (MB.MON) ;STORE IT IN HEADER WORD
;LIBOL VERSION NUMBER
MOVE T1,LIBVR.
STOR1H (MB.LBV)
;LIBOL SWITCH WORD
MOVE T1,LIBSW.
STOR1H (MB.LSW)
;PROGRAM NAME
IFE TOPS20,<
HRROI T1,-3
GETTAB T1,
MOVE T1,['METER']
>
IFN TOPS20,<
GETNM
SKIPN T1 ;IF NO NAME,
MOVE T1,['METER'] ;USE METER
>
STOR1H (MB.PNM) ;STORE IT
;CPU SERIAL NUMBER
IFN TOPS20,<
MOVEI T1,.APRID ;LH=0 (TABLE OFFSET), RH=.APRID TABLE
GETAB ; GET THE WORD
SETO T1, ;SET TO -1 IF CAN'T GET IT
STOR1H (MB.SER)
>
IFE TOPS20,<
MOVE T1,[%CNSER]
GETTAB T1,
SETO T1,
STOR1H (MB.SER)
>
;MONITOR VERSION NUMBER
IFE TOPS20,<
MOVE T1,[%CNVER]
GETTAB T1,
SETZ T1, ;SET TO ZEROES IF CAN'T GET
STOR1H (MB.MVR)
>
;DATE/TIME PROGRAM STARTED
IFN TOPS20,<
GTAD
STOR1H (MB.DTM)
>
IFE TOPS20,<
MOVE T1,[%CNDTM]
GETTAB T1,
SETO T1, ;COMPATIBLE WITH TOPS20
STOR1H (MB.DTM)
>
;SYSTEM NAME IN ASCIZ
HRRZ T5,MRHDBP ;GET POINTER TO HEADER BLOCK
ADDI T5,MB.SYN ;RH (T5) = PTR TO SYSTEM NAME
HRLI T5,(POINT 7,) ;GET ASCIZ BYTE PTR TO IT
IFN TOPS20,<
HRLZI T4,-32 ;MAX SIZE
MRVRS1: HRRI T1,.SYSVE ;SYSTEM VERSION TEXT
HRL T1,T4 ;WORD NUMBER
GETAB
SETZ T1, ;CLEAR IF CAN'T GET IT
MOVE T2,T1
MOVEI T3,5 ;5 CHARS/WORD
MRVRS2: SETZ T1,
LSHC T1,7
JUMPE T1,MRVRS3 ;END OF STRING
IDPB T1,T5 ;STORE BYTE
SOJG T3,MRVRS2 ;LOOP FOR CHARS IN THIS WORD
AOBJN T4,MRVRS1 ;LOOP FOR MORE WORDS
>;END IFN TOPS20
IFE TOPS20,<
HRLZI T4,-5 ;MAX SIZE
MRVRS1: HRRI T1,.GTCNF ;FROM CONFIG TABLE
HRL T1,T4 ;WORD NUMBER
GETTAB T1,
SETZ T1, ;CLEAR IF CAN'T GET IT
MOVE T2,T1
MOVEI T3,5 ;5 CHARS/WORD
MRVRS2: SETZ T1,
LSHC T1,7 ;GET NEXT CHAR
JUMPE T1,MRVRS3 ;END OF STRING
IDPB T1,T5 ;STORE BYTE
SOJG T3,MRVRS2 ;LOOP FOR CHARS IN THIS WORD
AOBJN T4,MRVRS1 ;LOOP FOR MORE WORDS
>;END IFE TOPS20
MRVRS3:
;BATCH JOB INDICATOR
IFE TOPS20,<
HRROI T1,.GTLIM ;.GTLIM WORD FOR MY JOB
GETTAB T1,
SETZ T1, ;ASSUME NOT A BATCH JOB
TXNN T1,JB.LBT ;BATCH JOB?
TDZA T1,T1 ;NO
SETO T1, ;YES
STOR1H (MB.BAT)
>
IFN TOPS20,<
SETO T1, ;GET INFORMATION FOR CURRENT JOB
HRROI T2,T4 ;ONE WORD TABLE, IN T4
MOVEI T3,.JIBAT ;FIRST (AND ONLY) ENTRY
GETJI ; GET INFO IN T4
ERJMP MRJSSE
MOVE T1,T4 ;GET THE WORD
STOR1H (MB.BAT)
>
;SYSTEM STATUS BITS
IFE TOPS20,<
MOVE T1,[%CNSTS]
GETTAB T1,
SETZ T1, ;ZERO IF CAN'T GET
STOR1H (MB.STS)
>
;SOFTWARE CONFIGURATION INDICATORS
IFE TOPS20,<
MOVE T1,[%CNST2]
GETTAB T1,
SETZ T1,
STOR1H (MB.ST2)
>
;AVERAGE OVERHEAD TIME
; DO IT OHTMS TIMES AND DIVIDE BY OHTMS
OHTMS==^D10 ;NUMBER OF TIMES TO DO IT TO GET THE
; AVERAGE
MOVEI T2,MRFKFT-D.CN ; FAKE FILE TABLE WORD
MOVEM T2,MRAFFT ;SAVE THE FAKE FILE TABLE ADDRESS
SETOM MRFKFT ;(CHANNEL 17 WILL BE RETURNED)
XLIST ;CALL MACROS OHTMS TIMES
REPEAT OHTMS,<
MRTMS. (T1) ;START
MOVEI T2,400+MB.OVH ;BUCKET OFFSET
MOVE T1,MRAFFT ;GET FAKE FILE TABLE ADDRESS
PUSHJ PP,LMETR. ;CALCULATE BUCKET ADDRESS
MRTME. (T1) ;STOP
>
LIST
MOVE T1,@MRTMB. ;GET TOTAL TIME
IDIVI T1,OHTMS ; DIVIDE BY # TIMES DONE
STOR1H (MB.OVH) ;STORE IN HEADER BLOCK
IFN TOPS20,<
SETZ T0, ;CLEAR FOR SHIFT
ASHC T0,^D12 ;SHIFT TIME LEAVING 12 0'S FOR
;JSYS 776 FORMAT
DMOVEM T0,MRBKO. ;SAVE FIXED OVERHEAD TIME
>;END IFN TOPS20
IFE TOPS20,<
MOVEM T1,MRBKO. ;SAVE FIXED OVERHEAD TIME
>
POPJ PP, ;ALL DONE, RETURN
MRNCR:
IFE TOPS20,<
OUTSTR [ASCIZ/? Not enough core available for METERing
/]
>
IFN TOPS20,<
HRROI T1,[ASCIZ/? Not enough core available for METERing
/]
PSOUT
>
JRST KILL. ;SORRY ABOUT THAT, CHIEF.
SUBTTL LSTATS - ROUTINE TO DUMP A FILE BLOCK
;ROUTINE MRDMP IS CALLED BEFORE EVERY OPEN TO WRITE THE
; DATA COLLECTED ON THE FILE PREVIOUSLY OPEN ON THIS CHANNEL.
; IF THERE WASN'T ANY FILE PREVIOUSLY OPEN ON THIS CHANNEL,
; THERE IS NO WORK TO BE DONE.
;
; CALLED WITH T1/ CHANNEL NUMBER (0 THRU 17)
MRDMP: MOVE T4,MROPTT(T1) ; T4 POINTS TO FIRST LOCATION
SKIPN MB.BAS+0(T4) ;SKIP IF ANY OLD INFO THERE
POPJ PP, ;NOTHING TO DO, RETURN
;WRITE OUT THIS CHUNK, AND THEN ZERO IT
PUSHJ PP,MRWONE ;CALL ROUTINE TO WRITE ONE
;NOW ZERO OUT THE BLOCK
SETZM (T4) ;CLEAR FIRST WORD
HRL T4,T4
MOVEI T3,.MBFSZ-1(T4)
ADDI T4,1
BLT T4,(T3)
POPJ PP, ;DONE, RETURN
;ROUTINE MRDMPT IS CALLED AT THE "STOP RUN" TO WRITE
; THE DATA COLLECTED ON ALL FILES WHICH WE HAVEN'T WRITTEN
; OUT YET. MOST OF THE I/O SHOULD BE DONE HERE.
MRDMPT: SKIPN MROPT. ;BUCKETS SETUP?
POPJ PP, ;NO, RETURN AND DO NOTHING
MOVEI T5,17 ;T5=CHANNEL NUMBER TO DO
MRDMT1: MOVE T4,MROPTT(T5) ;GET ADDRESS
SKIPE MB.BAS+0(T4) ;SKIP IF NO INFO TO WRITE
PUSHJ PP,MRWONE ;WRITE ONE
SOJGE T5,MRDMT1 ;LOOP FOR ALL CHANNELS
;IF WE HAVEN'T WRITTEN A HEADER YET, CHECK FOR ACCEPT/DISPLAY
; DATA IN THE TRAILER.. IF ANY WAS RECORDED, WRITE THE HEADER.
SKIPE MRHDFL ;HEADER WRITTEN?
JRST MRWTRL ; YES, WRITE TRAILER NOW
HRRZ T2,MRTDBP ;GET POINTER TO TRAILER
SKIPN MB.ACP(T2) ;ACCEPT DATA?
SKIPE MB.DSP(T2) ; OR DISPLAY DATA?
TRNA ;YES
JRST MRCLOS ;NO, DON'T WRITE HEADER OR TRAILER THEN
;SKIP INTO "WRITE TRAILER" ROUTINE
SUBTTL LSTATS - TRAILER BLOCK SETUP AND WRITE ROUTINE
; WRITE TRAILER BLOCK
DEFINE STOR1T(OFFSET),<
HRRZ T2,MRTDBP ;GET OFFSET
MOVEM T1,OFFSET(T2) ;STORE THE WORD
>
DEFINE STOR2T(OFFSET),<
HRRZ T3,MRTDBP ;GET OFFSET
DMOVEM T1,OFFSET(T3) ;STORE THE WORD
>
MRWTRL: MOVE T1,[MBBT.T,,.MBTSZ] ;TRAILER BLOCK TYPE,,LENGTH
MOVEM T1,@MRTDBP ;STORE IN THE BLOCK
;SIZE OF HISTOGRAM BLOCK
MOVEI T1,MBHISL ;LENGTH OF HISTOGRAM BLOCK
STOR1T (MB.HSL)
;DATE/TIME PROGRAM ENDED
IFN TOPS20,<
GTAD
STOR1T (MB.DTF)
>
IFE TOPS20,<
MOVE T1,[%CNDTM]
GETTAB T1,
SETO T1, ;COMPATIBLE WITH TOPS20
STOR1H (MB.DTF)
>
;KILL FLAG (-1 IF PROGRAM WAS ABORTED, 0 FOR NORMAL TERMINATION)
MOVE T1,MRKILL
STOR1T (MB.KIL)
;TOTAL RUNTIME OF PROGRAM (TICKS)
; ON TOPS20 THIS IS STORED AS A DOUBLE-WORD NUMBER OF TICKS
; ON TOPS10 IT IS JUST ONE WORD.
IFN TOPS20,<
JSYS 776 ;GET TICKS NOW IN T1,T2
ERJMP MRWTRX ;DO NOTHING IF NO CLOCK
DSUB T1,MRPSTM ;SUBTRACT STARTING TICKS
ASHC T1,-^D12 ;SHIFT ZEROES OUT
STOR2T (MB.TRT) ;STORE DOUBLE WORD QUANTITY
MRWTRX:>
IFE TOPS20,<
SETZ T1,
RUNTIME T1,
SUB T1,MRPSTM ;SUBTRACT STARTING TICKS
STOR1T (MB.TRT)
>
; NOW WRITE IT
HRRZ T1,MRTDBP ;START ADDRESS
HRLI T1,-.MBTSZ ;-SIZE
PUSHJ PP,MROUT. ;OUTPUT THE BLOCK
JRST MRCLOS ;OK--GO CLOSE FILE
SUBTTL LSTATS - DBMS SUPPORT ROUTINES
IFN DBMS6,<
;ROUTINES FOR DBMS V6 TO WRITE IN LSTATS FILE
;ALL ROUTINES MUST SAVE ALL ACS EXCEPT T0
;START TIMING, BUCKET NUMBER IN T0
MRDBST: MRTMS. (T0) ;START METER TIMING
POPJ PP,
;STOP TIMING, BUCKET NUMBER IN T0
MRDBEN: ADD T0,MRDDBP ;ADD DBMS BLOCK ADDRESS
MOVEM T0,MRTMB. ;SAVE TIMING BUCKET ADDRESS
MRTME. (T0) ;END METER TIMING
POPJ PP,
;DUMP AND CLEAR DBMS BLOCK
MRDBDM: PUSH PP,T1 ;SAVE ACS WE WILL USE
PUSH PP,T2
PUSH PP,T3
MOVE T1,[MBBT.D,,.MBDSZ]; BLOCK TYPE,, LENGTH
MOVEM T1,@MRDDBP ;STORE HEADER WORD
HRRZ T1,MRDDBP ;GET POINTER TO BLOCK
PUSHJ PP,MROUT. ;WRITE IT
;CLEAR THE BLOCK
HRR T1,MRDDBP ;MAKE T1 = BLT POINTER
MOVEI T2,.MBDSZ(T1) ;LAST LOCATION+1
HRL T1,T1
ADDI T1,1
SETZM @MRDDBP ;CLEAR FIRST LOC
BLT T1,-1(T2) ;FINISH CLEARING BLOCK
POP PP,T3 ;RESTORE SAVED ACS
POP PP,T2
POP PP,T1
POPJ PP,
>;END IFN DBMS6
SUBTTL LSTATS - ROUTINE TO OUTPUT ANY LSTATS BLOCK
;ROUTINE TO OUTPUT AN LSTATS BLOCK
;CALL: MOVE T1,[-LENGTH,,ADDRESS]
; PUSHJ PP,MROUT.
; USES T0,T1,T2,T3
; <RETURNS HERE>
MROUT.: SKIPN MRRERN ;SKIP IF RERUNNING AND WE CAN'T DO I/O
;TO MTO FILE
SKIPN MROPT. ;SKIP IF BUCKETS ARE SETUP
POPJ PP, ; CAN'T DO I/O - RETURN AND DO NOTHING
PUSH PP,T1 ;SAVE THE CALLING ARG
SKIPN MRHDFL ;HAVE WE WRITTEN THE HEADER YET?
PUSHJ PP,MRWRTH ;NO, WRITE IT NOW
HRRZ T1,(PP) ;GET ADDRESS FROM STACK
HLRZ T1,(T1) ;GET BLOCK TYPE
CAIN T1,MBBT.F ;A FILE BLOCK?
JRST MROUF ;YES
CAIN T1,MBBT.D ;A DBMS BLOCK?
JRST MROUD ;YES
CAIN T1,MBBT.S ;A SORT BLOCK?
JRST MROUS ;YES
MROUB:
IFN TOPS20,<
POP PP,T2 ;GET ADDRESS BACK
HLRE T3,T2 ;SIZE IN T3
HRLI T2,(POINT 36,)
MOVE T1,MRJFN ;JFN IN T1
SOUT ;WRITE IT
POPJ PP, ;RETURN
>
IFE TOPS20,<
POP PP,T1 ;GET ARG BACK
SOJA T1,MRWRT1 ;FORM IOWD AND OUTPUT BLOCK
>;END IFE TOPS20
MROUF: HRRZ T1,MRTDBP ;POINT TO TRAILER BLOCK
AOS T2,MB.NFB(T1) ; ANOTHER FILE BLOCK, HOW MANY SO FAR?
CAILE T2,^D100 ;IF .GT. 100, DON'T WRITE ANOTHER ONE.
JRST [POP PP,(PP) ;THROW AWAY SAVED VALUE
POPJ PP, ];AND RETURN
JRST MROUB ;GO OUTPUT IT
MROUS: HRRZ T1,MRTDBP ;POINT TO TRAILER BLOCK
AOS T2,MB.NSB(T1) ; ANOTHER SORT BLOCK, HOW MANY SO FAR?
CAILE T2,^D100 ;IF .GT. 100, DON'T WRITE ANOTHER ONE.
POPJ PP,
JRST MROUB ;GO OUTPUT IT
MROUD: HRRZ T1,MRTDBP ;COUNT TOTAL DBMS BLOCKS
AOS MB.NDB(T1)
JRST MROUB ;AND GO OUTPUT IT
SUBTTL LSTATS - FINISH WRITING METER DATA
;ALL DONE, CLOSE THE METER OUTPUT FILE
MRCLOS: SKIPE MRRERN ;IF RERUN WAS USED, DON'T CLOSE
JRST MRRERC ;BECAUSE FILE IS NOT OPEN!!
IFE TOPS20,<
;DO CLOSE UUO
MOVSI T0,(CLOSE 0,)
OR T0,MRCHNN ;OR IN CHANNEL NUMBER
XCT T0
>;END IFE TOPS20
IFN TOPS20,<
MOVE T1,MRJFN ;GET JFN OF METER FILE
TXO T1,CO%NRJ ;DON'T RELEASE JFN
CLOSF
ERJMP MRJSER
>;END IFN TOPS20
SKIPN MRHDFL ;DID WE WRITE ANYTHING?
JRST MRNOWR ;NO
REPEAT 0,<
; MOST USERS WILL NOT WANT THIS PRINTED OUT.
; IN ANY CASE, IT SHOULDN'T BE PRINTED OUT UNLESS THE DIRECTORY
;FILE LSTATS.DIR IS NOT BEING USED.
OUTSTR [ASCIZ/[LIBOL: METER file (/]
OUTSTR MRNMA
SKIPN MRAPN. ;DID WE APPEND?
JRST [OUTSTR [ASCIZ/) written]
/]
POPJ PP,] ;DONE
OUTSTR [ASCIZ/) appended]
/]
>;END REPEAT 0
IFN FTLSDR,<
IFE TOPS20, JRST GOLSPN ;APPEND TO THE APPROPRIATE FILE
IFN TOPS20, JRST GOLSDR ;APPEND TO THE APPROPRIATE FILE
>;END IFN FTLSDR
IFE FTLSDR,< ;NO LSTATS.DIR
IFE TOPS20, JRST DOAP10 ;GO APPEND TO JOBNAME.MTO
IFN TOPS20, JRST DOAP20 ;. .
>;END IFE FTLSDR
MRNOWR:; OUTSTR [ASCIZ .[LIBOL: No METER data was recorded, because no I/O was done]
;.]
POPJ PP, ;ALL DONE, RETURN
MRRERC: ;OUTSTR [ASCIZ .[LIBOL: No METER data was recorded, because
;program was RERUN]
;.]
POPJ PP, ;RETURN
SUBTTL LSTATS - ROUTINE TO WRITE ONE FILE BLOCK
;MRWONE WRITES OUT ONE CHUNK OF BUCKETS, USING THE
; START ADDRESS IN T4.
MRWONE: MOVE T1,[MBBT.F,,.MBFSZ]; BLOCK TYPE,, LENGTH
MOVEM T1,(T4) ;STORE HEADER WORD
HRRZ T1,T4 ;GET ADDRESS
HRLI T1,-.MBFSZ ;-SIZE IN LH
JRST MROUT. ;WRITE THE BLOCK AND RETURN
SUBTTL LSTATS - ROUTINE TO WRITE THE HEADER
; ROUTINE TO WRITE THE HEADER
;CALL: PUSHJ PP,MRWRTH
; RETURN HERE
;USES T0,T1,T2, T3
MRWRTH: SETOM MRHDFL ;REMEMBER WE WROTE THE HEADER
MOVE T1,[MBBT.H,,.MBHSZ] ;HEADER BLOCK TYPE,,LENGTH
MOVEM T1,@MRHDBP ;STORE IN THE BLOCK
SKIPE MRRERN ;IS THIS A 'RERUN' OF THE PROGRAM?
POPJ PP, ;YES, DON'T DO I/O TO MTO FILE
IFN TOPS20,<
MOVE T1,MRJFN
HRLI T2,(POINT 36,)
HRR T2,MRHDBP ;START ADDRESS
MOVNI T3,.MBHSZ ; 128 WORDS
SOUT ;WRITE IT
POPJ PP, ;RETURN
>
IFE TOPS20,<
HRR T1,MRHDBP ;GET POINTER
SUBI T1,1 ;ADDRESS-1
HRLI T1,-.MBHSZ ;-NO. WORDS
MRWRT1: SETZ T2,
MOVE T0,[OUT T1]
OR T0,MRCHNN ;LOAD UUO WITH CHANNEL NUMBER
XCT T0
POPJ PP, ;WORKED OK
OUTSTR [ASCIZ/? OUT UUO FAILED FOR METER FILE /]
JRST MRTYPF ;TYPE FILE NAME AND DIE OFF
>;END IFE TOPS20
;; ** END OF MRWRTH ROUTINE **
SUBTTL LSTATS - TOPS10 DIRECTORY FILE ROUTINE
;ALWAYS RETURNS .+1. IF SOME FATAL ERROR HAPPENS, TYPES
; A WARNING AND RETURN .+1 ALSO.
IFE TOPS20,<
IFN FTLSDR,<
GOLSPN:
;NOW LOOKUP THE ONE WE WROTE TO FOR READ NOW
;IF ANY ERRORS HAPPEN NOW, THE .TMP FILE WILL GET DELETED
; BY SIMPLY DOING A RENAME TO 0.
MOVE T1,MRNM6
MOVSI T2,'TMP'
SETZB T3,T4
MOVE T5,[LOOKUP T1]
OR T5,MRCHNN
XCT T5 ;LOOKUP
JRST LLKPF3 ;CAN'T!!
;TRY TO FIND LSTATS.DIR
PUSHJ PP,GMCHAN ;GET A FREE CHANNEL TO USE
JRST NFC1 ;CAN'T
ANDI T5,17
DPB T5,[POINT 4,T5,12] ;SAVE IN AC FIELD OF T5
HLLZM T5,MRCHLS ;SAVE CHANNEL
;AND WHILE WE'RE AT IT.. GET CHANNEL FOR "COMMON" FILE TOO
PUSHJ PP,GMCHAN
JRST NFC1 ;CAN'T
ANDI T5,17
DPB T5,[POINT 4,T5,12]
HLLZM T5,MRCHCF ;CHANNEL NUMBER IN AC FIELD
IFE LSPPN,<
MOVSI T1,'COB' ;FIND PPN FOR 'COB'
DEVPPN T1,
MOVE T1,[XWD 5,2] ;DEFAULT
>
IFN LSPPN, MOVE T1,[LSPPN] ;PPN WAS SPECIFIED
MOVEM T1,MRLLDR ;SAVE PPN WHERE LSTATS.DIR IS
;SEARCH THRU SYSTEM SEARCH LIST, AND TRY A LOOKUP ON EACH DEVICE
SETO T4, ;START AT THE BEGINNING
NXTGBS: MOVE T1,[3,,T2] ;SET UP FOR GOBSTR
SETZB T2,T3 ;CLEAR JOB NUMBER, PPN ARGS
GOBSTR T1,
JRST GOBSTE ;?FAILED!
JUMPE T4,NXTGBS ;IGNORE "FENCE"
CAMN T4,[-1] ;NOT FOUND?
JRST NOLSTS ;YES
MOVEM T4,MRLLDV ;SAVE DEVICE NAME
;OPEN THE DEVICE
MOVEI T1,.IODMP ;DUMP MODE
MOVE T2,T4 ;THAT DEVICE
SETZ T3, ;NO BUFFERS
MOVE T4,[OPEN T1] ; PLAIN OPEN UUO
OR T4,MRCHLS ;"OR" IN CHANNEL
XCT T4 ;DO OPEN
JRST LOPNF1 ;OPEN FAILED
;LOOKUP UUO
MOVE T1,[SIXBIT/LSTATS/]
MOVSI T2,'DIR'
SETZ T3,
MOVE T4,MRLLDR ;PPN
MOVE T5,[LOOKUP T1]
OR T5,MRCHLS
XCT T5 ;DO LOOKUP
CAIA ;FAILED - GO CHECK
JRST RD1200 ;FOUND IT
HRRZ T2,T2 ;GET LOOKUP ERROR CODE
CAIE T2,1 ;NO DIRECTORY, OR "NOT FOUND"?
JUMPN T1,LLKPE1 ;NO--OTHER LOOKUP ERROR, COMPLAIN
MOVSI T1,(RELEAS) ;RELEAS THE CHANNEL
OR T1,MRCHLS
XCT T1
MOVE T4,MRLLDV ; GET LAST DEVICE NAME WE TRIED
JRST NXTGBS ;AND DO ANOTHER GOBSTR
;READ IN FIRST 200 WORDS .. AND COPY INFORMATION
RD1200: HRRZ T1,MRLDBL ;POINTER TO BLOCK
SUBI T1,1
HRLI T1,-200 ;FORM IOWD
SETZ T2,
MOVE T3,[IN T1]
OR T3,MRCHLS
XCT T3
CAIA ;OK
JRST LSINF ;PROBLEMS
SETZM MRLFPR ;FILE IS AT BEGINNING NOW
MOVE T4,MRLDBL ;T4 = PTR TO THE BLOCK
MOVE T1,.LDBPC(T4) ;BYTE PTR TO CURRENT FILENAME
MOVEM T1,MRLBPC
MOVE T1,.LDSZL(T4) ;SIZE LIMIT
MOVEM T1,MRLSZL ;SAVE
SKIPN .LDTML(T4) ;ANY TIME LIMIT?
JRST TMLMOK ;NO
;CHECK TIME LIMIT
SKIPN T3,.LDFWR(T4) ;GET TIME OF FIRST WRITE
JRST SETTFW ;NONE THERE--SET TO NOW
ADD T3,.LDTML(T4) ;ADD TIME LIMIT
MOVX T1,%CNDTM ;GET TODAY'S DATE/TIME
GETTAB T1,
SETO T1,
CAML T1,T3 ;IS IT TIME TO INCREMENT?
JRST NXTFLE ;YES!
;TIME LIMIT IS OK -- OPEN FILE FOR APPEND AND CHECK SIZE LIMIT
TMLMOK: MOVE T4,MRLBPC ;BYTE PTR TO CURRENT FILE
PUSHJ PP,LDPOST ;POSITION LD FILE
JRST LRLLC0 ;ERROR - RELEASE CHANNEL AND QUIT
ADD T4,MRLDBL ; NOW GET ACTUAL BYTE PTR TO THE FILE
SUB T4,MRLFPR
;READ FILENAME AND PUT SIXBIT IN MRCFNM,MRCFEX
MOVE T3,T4 ;COPY PTR INCASE ERROR
MOVE T1,[POINT 6,MRCFNM]
TMLMO1: ILDB T2,T3 ;GET ASCII CHARACTER
JUMPE T2,ENDFN1 ;NULL ENDS STRING
CAIN T2,"." ;. STARTS EXTENSION
JRST ENDFN2
SUBI T2,40 ;MAKE SIXBIT CHARACTER
IDPB T2,T1 ;STORE
JRST TMLMO1 ;LOOP
ENDFN2: MOVE T1,[POINT 6,MRCFEX]
TMLMO2: ILDB T2,T3 ;GET ASCII CHARACTER
JUMPE T2,ENDFN1 ;NULL ENDS STRING
SUBI T2,40 ;ELSE STORE CHARACTER
IDPB T2,T1
JRST TMLMO2
ENDFN1: MOVEI T1,.IODMP ;OPEN OLD DEVICE IN DUMP MODE
MOVE T2,MRLLDV
SETZ T3,
MOVE T4,[OPEN T1]
OR T4,MRCHCF ;COMMON FILE CHANNEL
XCT T4
JRST LOPNFC ;OPEN FAILED FOR COMMON FILE
;TO APPEND: DO LOOKUP. IF NO ERROR OR ERROR CODE 0,
; DO ENTER AND USETO.
MOVE T1,MRCFNM ;FILENAME
MOVE T2,MRCFEX ;EXTENSION
SETZ T3,
MOVE T4,MRLLDR ;DIRECTORY
MOVE T5,[LOOKUP T1]
OR T5,MRCHCF
XCT T5 ;DO LOOKUP
JRST LLKPEC ;LOOKUP FAILED FOR COMMON FILE
;CHECK SIZE LIMIT
HLRE T1,T4 ;GET SIZE
JUMPL T1,[MOVM T1,T1 ;SOME # OF WORDS-- ROUND UP TO BLOCKS
IDIVI T1,200
JUMPE T2,.+1
AOJA T2,.+1]
MOVEI AC11,1(T1) ;GET BLOCK # TO USETO TO
SKIPN MRLSZL ;SKIP IF A SIZE LIMIT TO WORRY ABOUT
JRST DOENT ;NONE
CAML T1,MRLSZL ;SIZE TOO BIG?
JRST SIZTBG ;YES: GO ON TO NEXT FILE
DOENT: MOVSI T1,(RELEAS) ;CLOSE & RELEAS LSTATS.DIR
OR T1,MRCHLS
XCT T1
MOVEI T0,^D10 ;# TIMES TO TRY ENTER
DOENTA: MOVE T1,MRCFNM ;NAME
MOVE T2,MRCFEX ;EXTENSION
;NOTE: T3 HAS PROTECTION CODE RETURNED FROM LOOKUP
AND T3,[777000,,0] ;JUST SAVE PROTECTION CODE
MOVE T4,MRLLDR ;DIRECTORY
MOVE T5,[ENTER T1]
OR T5,MRCHCF
XCT T5 ;DO ENTER
JRST LENTEC ;ENTER FAILED FOR COMMON FILE
;DO USETO TO APPEND TO THE FILE
CAIN AC11,1 ;IF BLOCK 1, DON'T BOTHER
JRST NXTRDD
MOVSI T5,(USETO)
OR T5,MRCHCF
HRR T5,AC11 ;BLOCK NUMBER
XCT T5
;READ/WRITE FROM OUR 200 WORD BUFFER UNTIL WE HIT EOF ON THE FIRST FILE
NXTRDD: MOVE T1,MRLDBL ;POINTER TO BLOCK
SUBI T1,1
HRLI T1,-200
SETZ T2,
MOVE T3,[IN T1]
OR T3,MRCHNN
XCT T3
CAIA
JRST LINER1 ;UNTIL ERROR
;OUT UUO
MOVE T1,MRLDBL
SUBI T1,1
HRLI T1,-200
SETZ T2,
MOVE T3,[OUT T1]
OR T3,MRCHCF ;TO COMMON FILE
XCT T3
JRST NXTRDD ;OK--LOOP
JRST LOUTF1 ;OUT FAILED!
;COME HERE WHEN "IN" FAILS - ASSUME EOF
LINER1: PUSHJ PP,DELOF ;DELETE OLD FILE
MOVSI T1,(RELEAS) ;CLOSE THE INPUT FILE
OR T1,MRCHNN
XCT T1
MOVSI T1,(RELEAS) ;CLOSE THE OUTPUT FILE
OR T1,MRCHCF
XCT T1
POPJ PP, ;DONE OK, RETURN
;HERE IF SIZE LIMIT WAS EXCEEDED
; OPEN LSTATS.DIR FOR UPDATING, CHANGE THE THINGS
; AND GO WRITE TO THE NEW FILE
SIZTBG: MOVSI T1,(RELEAS)
OR T1,MRCHCF ;RELEASE OLD COMMON FILE CHANNEL
XCT T1 ;THEN FALL INTO "NXTFLE"
;HERE FROM ABOVE, OR TIME LIMIT WAS EXCEEDED
; OPEN LSTATS.DIR FOR UPDATING, CHANGE THE THINGS
; AND GO WRITE TO THE NEW FILE
NXTFLE: PUSHJ PP,OPNUPD ;OPEN FILE FOR UPDATING
POPJ PP, ;IF ERRORS, JUST RETURN
PUSHJ PP,NEWINF ;PUT IN NEW INFO
POPJ PP, ;ERRORS
JRST TMLMOK ;GO WRITE TO THAT MTO FILE
;HERE IF DATE/TIME OF FIRST WRITE HAS NOT BEEN PUT IN LSTATS.DIR
;DO SO, AND GO WRITE TO THAT MTO FILE
SETTFW: PUSHJ PP,OPNUPD ;OPEN FILE FOR UPDATING
POPJ PP, ;IF ERRORS, JUST RETURN
MOVX T1,%CNDTM ;CURRENT DATE/TIME
GETTAB T1,
SETZ T1, ;IF CAN'T GET IT, MAKE SURE THE NEXT GUY TRIES
HRRZ T4,MRLDBL
MOVEM T1,.LDFWR(T4) ;STORE THE INFO
PUSHJ PP,NEWIOT ;WRITE OUT THE UPDATED DATA BLOCK
POPJ PP, ;PROBLEMS--GIVE IT UP
JRST TMLMOK ;CONTINUE
;ROUTINE TO OPEN LSTATS.DIR FOR UPDATING
;POPJ IF ERROR, SKIP RETURN IF OK.
OPNUPD: MOVEI T0,^D10 ;# TIMES WE WILL TRY
OPNUP0: MOVE T1,['LSTATS']
MOVSI T2,'DIR'
SETZ T3,
MOVE T4,MRLLDR ;PPN
MOVE T5,[ENTER T1]
OR T5,MRCHLS
;ENTER MAY FAIL BECAUSE OF SIMULTANEOUS UPDATE
XCT T5
JRST OPNEU2 ;HOPEFULLY JUST SIMULTANEOUS UPDATE
;HERE WHEN FILE HAS BEEN OPENED
OPNUP1: SETZM MRLFPR ;SET FILE PTR TO ZERO
MOVE T1,[USETI 1] ; AND REALLY DO IT
OR T1,MRCHLS
XCT T1
HRRZ T1,MRLDBL ;NOW READ 1ST 200 WORDS
SUBI T1,1
HRLI T1,-200 ;FORM IOWD
SETZ T2,
MOVE T3,[IN T1]
OR T3,MRCHLS
XCT T3 ;DO IN UUO
JRST RET.2 ;ALL OK
JRST LSINF ;ERROR- GO COMPLAIN AND POPJ
;HERE FOR PROBLEMS
;ENTER FAILED
OPNEU2: HRRZ T2,T2 ;ISOLATE ERROR CODE
CAIN T2,3 ; SIMULATEOUS UPDATE PROBLEM?
JRST OPNEU3 ;YES--WAIT A LITTLE
OUTSTR [ASCIZ/%LIBOL: Can't OPEN LSTATS.DIR for updating: (/]
PUSHJ PP,TYPOT2 ;TYPE ERROR CODE
OUTSTR [ASCIZ/)
/]
JRST LRLLC ;RELEASE LSTATS CHANNEL AND POPJ
OPNEU3: SOJLE T0,OPNEU4 ;WAITED TOO LONG?
MOVEI T1,1 ;SLEEP A SEC
SLEEP T1,
JRST OPNUP0 ;GO TRY AGAIN
OPNEU4: OUTSTR [ASCIZ/%LIBOL: Can't OPEN LSTATS.DIR for updating:
% Someone has it open for UPDATING
/]
JRST LRLLC ;RELEASE LSTATS CHANNEL AND POPJ
;ROUTINE TO PUT NEW INFO IN THE HEADER WHICH SAYS WE
;BUMPED TO THE NEXT FILESPEC.
; IF I/O ERRORS, OR FILE IS EXHAUSTED, POPJ, ELSE POPJ1
;WITH FILE POSITIONED AT 0, NEW INFO IN PLACE, AND 1ST
;DISK BLOCK UPDATED.
; IF POPJ RETURN TAKEN, THE CHANNEL HAS BEEN RELEASED, TOO.
NEWINF: MOVE T4,MRLDBL ;POINTER TO BLOCK
MOVE T1,.LDNFL(T4) ;# FILES,,# OF CURRENT
HLRZ T2,T1 ;# FILES
CAIG T2,(T1) ;IS FILE EXHAUSTED?
JRST FILEXH ; YES, SAY THAT
AOS .LDNFL(T4) ;BUMP # OF CURRENT FILE
MOVX T1,%CNDTM
GETTAB T1,
SETZ T1,
MOVEM T1,.LDFWR(T4) ;SAVE TIME OF FIRST WRITE
;BUMP CURRENT POINTER
MOVE T1,.LDBPC(T4) ;BYTE PTR TO CURRENT
HRRZ T3,T1
CAIL T3,200 ;POINTING TO FIRST BLOCK?
JRST NEWIN1 ;NO, REPOSITION FILE
ADD T1,MRLDBL ;MAKE ABSOLUTE PTR
ILDB T2,T1 ;GET A BYTE
JUMPN T2,.-1 ;LOOK FOR NULL
SUB T1,MRLDBL ;GET RELATIVE BP
MOVEM T1,.LDBPC(T4) ;THAT'S THE STARTING BP ALL RIGHT
MOVEM T1,MRLBPC
;WRITE OUT THE UPDATED BLOCK TO DSK
NEWIOT: MOVE T0,[USETO 1] ;PREPARE TO WRITE 1ST BLOCK
OR T0,MRCHLS
XCT T0
HRRZ T1,MRLDBL
SUBI T1,1
HRLI T1,-200
SETZ T2, ;END OF IO LIST
MOVE T3,[OUT T1]
OR T3,MRCHLS
XCT T3
JRST RET.2 ;EVERYTHING IS COOL .. SKIP RETURN
JRST OUERRL
;CURRENT FILE STARTS OR ENDS IN ANOTHER BLOCK. WE HAVE TO REPOSITION
; THE FILE TO GET THE START OF THE NEXT ONE, REPOSITION AGAIN TO 0,
; AND STORE THE STARTING BP.
NEWIN1: MOVE T4,MRLBPC ;GET BP TO CURRENT NOW
PUSHJ PP,LDPOST ;REPOSITION FILE
JRST LRLLC0 ;ERROR - DELETE OLD FILE, RELEASE, RETURN
MOVE T1,MRLBPC
SUB T1,MRLFPR ;INDEX INTO BLOCK
ADD T1,MRLDBL ; ADD START OF DATA BLOCK
ILDB T2,T1 ;LOOK FOR FIRST NULL
JUMPN T2,.-1
SUB T1,MRLDBL
ADD T1,MRLFPR ;GET RELATIVE BP ADDRESS
MOVEM T1,MRLBPC ;SAVE IT HERE
;NOW WE MUST REPOSITION THE FILE TO WORD 0 AGAIN
SETZ T4,
PUSHJ PP,LDPOST
JRST LRLLC0 ;DELETE OLD FILE, RELEASE STUFF
HRRZ T4,MRLDBL ;T4= START OF BLOCK
MOVE T1,MRLBPC ;STORE AWAY NEW "CURRENT BP"
MOVEM T1,.LDBPC(T4)
JRST NEWIOT ;GO WRITE UPDATED BLOCK TO DSK
;HERE IF WE ARE ALREADY POINTING TO THE LAST FILE IN THE DIRECTORY
FILEXH: OUTSTR [ASCIZ/%LIBOL: LSTATS.DIR is exhausted
/]
JRST LRLLC ;RELEAS LSTATS CHANNEL AND POPJ
;ROUTINE TO POSITION LD FILE
;CALLED WITH BYTE PTR TO THE FILE NAME IN T4 (OR 0)
;RETURNS: PROPER BLOCK IN THE 200 WORD BUFFER
; MRLFPR= NUMBER OF THE 1ST WORD IN THE BLOCK
; POPJ IF ERROR, SKIP RETURN IF OK
LDPOST: HRRZ T3,T4 ;GRAB START OF BYTE PTR
SKIPN T2,MRLFPR ;ZERO IS SPECIAL
JRST LDPST1 ;WE ARE NOW AT START OF FILE
;SET FILE POSITION TO BLOCK WE WANT, READ NEXT 205 WORDS IN
;(THIS ENSURES THAT THE BYTE PTR WILL END WITHIN THE BUFFER).
LDPST0: TRZ T3,177 ;MAKE EVEN START OF BLOCK
MOVEM T3,MRLFPR ;THIS WILL BE FILE POINTER
LSH T3,-7 ;MAKE BLOCK NUMBER
ADDI T3,1
MOVE T0,[USETI (T3)]
OR T0,MRCHLS ;LSTATS CHANNEL
XCT T0 ;POSITION TO THE BLOCK
HRRZ T1,MRLDBL ;POINT TO BLOCK
SUBI T1,1 ;IOWD
HRLI T1,-204 ;READ 204 WORDS IN
SETZ T2,
MOVE T3,[IN T1]
OR T3,MRCHLS
XCT T3
JFCL ;EOF CONDITION IS OK--ASSUME WE GOT THAT
JRST RET.2
;WE ARE POSITIONED AT THE START OF THE FILE
LDPST1: JUMPE T3,RET.2 ;IF WE ARE ALREADY HERE, DON'T BOTHER
JRST LDPST0 ;JUST GO READ IN WHAT WE WANT
;I/O ERRORS FOR LSTATS.DIR
;LOOKUP FAILED FOR THE OLD FILE WE HAD BEEN WRITING
LLKPF3: OUTSTR [ASCIZ/%LIBOL: LOOKUP failed (/]
HRRZ T2,T2
PUSHJ PP,TYPOT2 ;THIS IS WIERD, AND "CAN'T HAPPEN"
OUTSTR [ASCIZ/ for the .TMP file we'd been writing
/]
JRST CNTWLS ;TYPE FINAL MSG AND POPJ
;NO FREE CHANNELS
NFC1: OUTSTR [ASCIZ/%LIBOL: No free channels to write LSTATS data
/]
PUSHJ PP,DELOF ;DELETE OLD FILE
POPJ PP,
;GOBSTR UUO FAILED
GOBSTE: OUTSTR [ASCIZ/%LIBOL: GOBSTR UUO failed
/]
PUSHJ PP,DELOF ;DELETE OLD FILE
JRST CNTWLS
CNTWLS: OUTSTR [ASCIZ/% Can't write LSTATS data
/]
POPJ PP,
;COULDN'T FIND AN LSTATS.DIR
NOLSTS: OUTSTR [ASCIZ/%LIBOL: LSTATS.DIR not found
/]
PUSHJ PP,DELOF ;DELETE OLD FILE
JRST CNTWLS
;OPEN FAILED FOR A SYSTEM DEVICE
LOPNF1: OUTSTR [ASCIZ/%LIBOL: OPEN failed for device /]
PUSHJ PP,TYP6T2 ;TYPE SIXBIT FROM T2
OUTSTR [ASCIZ/
/]
PUSHJ PP,DELOF ;DELETE OLD FILE
JRST CNTWLS
;LOOKUP FAILED FOR LSTATS.DIR - ERROR CODE IN T2
LLKPE1: OUTSTR [ASCIZ/%LIBOL: LOOKUP ERROR (/]
PUSHJ PP,TYPOT2
OUTSTR [ASCIZ/) FOR LSTATS.DIR
/]
LRLLC0: PUSHJ PP,DELOF ;DELETE OLD FILE
LRLLC: MOVSI T1,(RELEAS) ;RELEASE LSTATS CHANNEL
OR T1,MRCHLS
XCT T1
JRST CNTWLS ;THEN GO FINISH MESSAGE
;IN UUO FAILED READING LSTATS.DIR
LSINF: OUTSTR [ASCIZ/%LIBOL: IN UUO failed reading LSTATS.DIR
/]
JRST LRLLC0 ;DELETE OLD FILE, RELEASE CHANNEL, FINISH MSG
;OUT UUO FAILED TRYING TO WRITE THE 1ST BLOCK
OUERRL: OUTSTR [ASCIZ/%LIBOL: OUT UUO failed updating LSTATS.DIR
/]
JRST LRLLC0 ;RELEASE CHANNEL, FINISH MSG
;THIS ROUTINE TYPES OCTAL FROM T2
TYPOT2: IDIVI T2,10 ;YE OLDE
PUSH PP,T3 ; RECURSIVE
SKIPE T2 ;NUMBER PRINT
PUSHJ PP,TYPOT2 ; ROUTINE
POP PP,T2
ADDI T2,"0"
OUTCHR T2
POPJ PP,
;THIS ROUTINE TYPES THE SIXBIT WORD IN T2
TYP6T2: JUMPE T2,RET.1 ;RETURN IF NO MORE CHARACTERS TO TYPE
SETZ T1,
LSHC T1,6 ;SHIFT BYTE INTO RIGHT 6 BITS
ADDI T1,40 ;MAKE ASCII CHARACTER
OUTCHR T1 ;TYPE IT
JRST TYP6T2 ;LOOP AS LONG AS THERE IS SOMETHING TO DO
;I/O ERRORS FOR THE COMMON FILE
;OPEN FAILED FOR COMMON FILE DEVICE
LOPNFC: OUTSTR [ASCIZ/%LIBOL: Can't OPEN device /]
PUSHJ PP,TYP6T2 ;TYPE DEVICE NAME FROM T2
OUTSTR [ASCIZ/
/]
JRST LRLLC0 ;DELETE OLD FILE,
;RELEASE LSTATS.DIR AND POPJ
;LOOKUP FAILED FOR COMMON FILE - THIS IS PROBABLY OK (JUST START A NEW FILE)
; UNLESS THE ERROR IS NOT FILE-NOT-FOUND
LLKPEC: HRRZ T2,T2 ;GET ERROR CODE
JUMPN T2,LLKPEA ;FILE NOT FOUND, NO, BAD ERROR
MOVSI T3,111000 ;LOAD PROTECTION
MOVEI AC11,1 ;USETO TO BLOCK 1
JRST DOENT ;GO DO ENTER
LLKPEA: PUSHJ PP,DELOF ;DELETE OLD FILE
OUTSTR [ASCIZ/%LIBOL: LOOKUP ERROR (/]
PUSHJ PP,TYPOT2
OUTSTR [ASCIZ/ on LSTATS file /]
;TYPE FILE NAME
LLKPE2: MOVE T2,MRCFNM
PUSHJ PP,TYP6T2
OUTCHR ["."]
MOVE T2,MRCFEX
PUSHJ PP,TYP6T2
OUTSTR [ASCIZ/
/]
PUSHJ PP,LRCF ;RELEASE COMMON FILE
JRST LRLLC ;RELEASE LSTATS.DIR AND POPJ
;RELEASE COMMON FILE
LRCF: MOVSI T1,(RELEAS)
OR T1,MRCHCF ;COMMON FILE CHANNEL
XCT T1
POPJ PP, ;SILENTLY, RETURN
;RELEASE OLD FILE WITHOUT DELETING IT
LROLD: MOVSI T1,(RELEAS)
OR T1,MRCHNN
XCT T1
POPJ PP,
;ENTER FAILED FOR COMMON FILE
LENTEC: HRRZ T2,T2 ;GET ERROR CODE RETURNED
CAIN T2,3 ;SIMULATEOUS UPDATE?
JRST LENTE3 ;YES
OUTSTR [ASCIZ/%LIBOL: ENTER failed (/]
PUSHJ PP,TYPOT2 ;TYPE ENTER ERROR CODE
OUTSTR [ASCIZ/) for LSTATS output file /]
PUSHJ PP,DELOF ;DELETE OLD FILE
JRST LLKPE2 ;TYPE FILE NAME AND RELEASE CHANNELS
LENTE3: SOJLE T0,LENTE4 ;TRIED TOO LONG--GIVE UP
MOVEI T1,1 ;NO, SLEEP A SEC
SLEEP T1,
JRST DOENTA ;THEN TRY AGAIN
LENTE4: OUTSTR [ASCIZ/%LIBOL: Can't append to LSTATS output file -
(Someone else has it open for updating)
/]
PUSHJ PP,LRCF ;RELEASE COMMON FILE CHANNEL
JRST LRLLC0 ;DELETE OLD FILE,
;RELEASE LSTATS.DIR AND POPJ
;OUT FAILED TO THE COMMON FILE
LOUTF1: OUTSTR [ASCIZ/%LIBOL: OUT uuo failed for LSTATS common file
/]
PUSHJ PP,LROLD ;RELEASE OLD FILE (NOT DELETED)
PUSHJ PP,LRCF ;RELEASE COMMON FILE
JRST CNTWLS ;TYPE FINAL MSG AND POPJ
>;END IFN FTLSDR
>;END IFE TOPS20
SUBTTL LSTATS - TOPS20 DIRECTORY FILE ROUTINES
;IF ALL OK, RETURNS .+1. IF SOME FATAL ERROR HAPPENS, TYPES A
; WARNING TO THE USER AND RETURNS .+1 ALSO.
IFN TOPS20,<
IFDEF LSDIR,<
GOLSDR:
;TRY TO FIND LSTATS.DIR
MOVE T2,[POINT 7,[LSDIR]] ;LSTATS DIRECTORY
MOVE T1,[POINT 7,MRLDNA] ;POINTER TO ASCII STRING TO MAKE
ILDB T3,T2 ;GET A CHAR
JUMPE T3,.+3 ; IF NULL, STOP
IDPB T3,T1 ;STORE IT
JRST .-3 ;AND LOOP
MOVE T2,[POINT 7,[ASCIZ/LSTATS.DIR/]] ;THE FILENAME
ILDB T3,T2 ;GET A CHAR
IDPB T3,T1 ;STORE
JUMPN T3,.-2 ;LOOP, UNTIL WE'VE STORED LAST NULL
MOVX T1,GJ%SHT!GJ%OLD ;MUST BE AN OLD FILE
MOVE T2,[POINT 7,MRLDNA] ;POINTER TO FILENAME STRING WE JUST MADE
GTJFN
ERJMP LGTJNE ;GTJFN FAILED - GO SEE WHY
MOVEM T1,MRLDJF ;REMEMBER IT'S JFN
;FOUND IT! - OPEN FOR READING
MOVX T2,OF%RD ;JUST OPEN FOR READING
OPENF
ERJMP LOPNFF ;OPENF FAILED
;LSTATS.DIR IS OPEN FOR READING
;READ IN FIRST 200 WORDS .. AND COPY INFORMATION
MOVE T1,MRLDJF
HRRZ T2,MRLDBL ;POINTER TO BLOCK
HRLI T2,(POINT 36,)
MOVNI T3,200 ;-# WORDS
SIN ;COMMIT A SIN
ERJMP LSINF ;UH OH WE'RE IN TROUBLE NOW!
SETZM MRLFPR ;REMEMBER FILE POINTER IS 0
MOVE T4,MRLDBL ;T4 = INDEX TO THE BLOCK
MOVE T1,.LDBPC(T4) ;BYTE PTR TO CURRENT FILENAME
MOVEM T1,MRLBPC ;SAVE FOR LATER
MOVE T1,.LDSZL(T4) ;SIZE LIMIT
MOVEM T1,MRLSZL ;SAVE
SKIPN .LDTML(T4) ; SKIP IF ANY TIME LIMIT TO WORRY ABOUT
JRST TMLMOK ;NO
SKIPN T3,.LDFWR(T4) ;GET TIME OF FIRST WRITE
JRST SETTFW ;NONE THERE--SET TO NOW
ADD T3,.LDTML(T4) ;ADD TIME LIMIT
GTAD ; AND TODAY'S DATE/TIME
CAML T1,T3 ;IS IT TIME TO INCREMENT?
JRST NXTFLE ;YES!
;TIME LIMIT IS OK -- OPEN FILE FOR APPEND AND CHECK SIZE LIMIT
TMLMOK: MOVE T4,MRLBPC ;BYTE PTR TO CURRENT FILE
PUSHJ PP,LDPOST ;POSITION LD FILE
JRST RLDFJ ;ERROR - RELEASE JFN AND QUIT
ADD T4,MRLDBL ; NOW GET ACTUAL BYTE PTR TO THE FILE
SUB T4,MRLFPR
;BUILD FILENAME IN MRLDNA
MOVE T2,[POINT 7,[LSDIR]] ;DIRECTORY, OR LOGICAL DEVICE
MOVE T1,[POINT 7,MRLDNA]
ILDB T3,T2
JUMPE T3,.+3
IDPB T3,T1
JRST .-3
MOVE T2,T4 ;COPY BP
ILDB T3,T2 ;NOW STORE THE FILENAME
IDPB T3,T1
JUMPN T3,.-2
MOVE T2,[POINT 7,MRLDNA] ;POINT TO FILESPEC
MOVX T1,GJ%SHT
GTJFN
ERJMP FJFNF ;GTJFN FAILED -- COMPLAIN!!
MOVEM T1,MRLCJF ;SAVE JFN OF THIS COMMON FILE
SKIPN MRLSZL ;SKIP IF A SIZE LIMIT TO WORRY ABOUT
JRST SIZIOK ;NO - SIZE OK
SIZEF ; SEE IF SIZE LIMIT EXCEEDED
ERJMP SZEFF ;FAILED -- GO SEE WHY
CAML T3,MRLSZL ; SIZE TOO BIG?
JRST SIZTBG ;YES: GO ON TO NEXT FILE
;IT IS OK TO WRITE INTO THIS FILE! OPEN FOR APPEND, AND COPY THE INFO
; INTO IT.
SIZIOK: MOVE T1,MRLDJF ;CLOSE AND RELEASE LSTATS.DIR
CLOSF
ERJMP CLSFE ; * FAILED * ... ???
MOVE T1,MRLCJF ;JFN OF THIS FILE
MOVX T2,OF%APP
OPENF
ERJMP COPNFF ;CAN'T OPEN FOR APPEND!
MOVE T1,MRJFN ;OPEN THE ONE WE WROTE TO FOR READ NOW
MOVX T2,OF%RD
OPENF
ERJMP OOPNFF ;CAN'T!!
;READ/WRITE FROM OUR 200 WORD BUFFER UNTIL WE HIT EOF ON THE FIRST FILE
NXTRDD: MOVE T1,MRJFN ;READ FROM HERE
HRRZ T2,MRLDBL ;POINTER TO BLOCK
HRLI T2,(POINT 36,)
MOVNI T3,200 ;-# WORDS
SIN ;COMMIT A SIN
ERJMP NXTRD1 ;UNTIL ERROR
MOVE T1,MRLCJF ;WRITE TO HERE
HRRZ T2,MRLDBL
HRLI T2,(POINT 36,)
MOVNI T3,200
SOUT
ERJMP NXTRD2
JRST NXTRDD ;LOOP...
;COME HERE WHEN SIN FAILS - ASSUME EOF
NXTRD1: MOVE T1,MRJFN ;CLOSE THE INPUT FILE
TXO T1,CO%NRJ ;DON'T RELEASE JFN
CLOSF
ERJMP .+1 ;IGNORE ERRORS
MOVE T1,MRLCJF ;CLOSE THE OUTPUT FILE
CLOSF
ERJMP .+1 ;IGNORE ERRORS
PUSHJ PP,DELOF ;DELETE OLD FILE
POPJ PP,
;HERE IF SOUT FAILS FOR THE COMMON FILE
NXTRD2: HRROI T1,[ASCIZ/%LIBOL: Can't append to LSTATS file because:
/]
PSOUT
PUSHJ PP,TYPFER ;PRINT LAST ERROR IN THIS FORK
JRST NXTRD1 ;CLOSE FILES AND RETURN
; HERE IF SIZE LIMIT WAS EXCEEDED
; OPEN LSTATS.DIR FOR UPDATING, CHANGE THE THINGS
; AND GO WRITE TO THE NEW FILE
SIZTBG: MOVE T1,MRLCJF ;RELEASE OLD JFN
RLJFN
ERJMP .+1 ;IGNORE ERROR HERE
; HERE IF TIME LIMIT WAS EXCEEDED
;OPEN LSTATS.DIR FOR UPDATING, CHANGE THE THINGS
; AND GO WRITE TO THE NEW FILE
NXTFLE: PUSHJ PP,OPNUPD ;OPEN FILE FOR UPDATING
POPJ PP, ;IF ERRORS, JUST RETURN
PUSHJ PP,NEWINF ;PUT IN NEW INFO
POPJ PP, ;?FILE IS EXHAUSTED!
JRST TMLMOK ;GO WRITE TO THAT MTO FILE
;HERE IF DATE/TIME OF FIRST WRITE HAS NOT BEEN PUT IN LSTATS.DIR
;DO SO, AND GO WRITE TO THAT MTO FILE
SETTFW: PUSHJ PP,OPNUPD ;OPEN FILE FOR UPDATING
POPJ PP, ;IF ERRORS, JUST RETURN
GTAD ;GET DATE/TIME NOW
HRRZ T4,MRLDBL
MOVEM T1,.LDFWR(T4) ;STORE THE INFO
PUSHJ PP,NEWIOT ; WRITE OUT THE UPDATED DATA BLOCK
POPJ PP, ;PROBLEMS-- GIVE IT UP
JRST TMLMOK ;CONTINUE
;ROUTINE TO OPEN LSTATS.DIR FOR UPDATING
;POPJ IF ERROR, SKIP RETURN IF OK.
OPNUPD: MOVE T1,MRLDJF ;CLOSE FILE
TXO T1,CO%NRJ ;DON'T RELEASE JFN!
CLOSF
ERJMP OPNEU1 ;CLOSF SHOULDN'T FAIL!
MOVEI T4,^D10 ;# TIMES WE WILL TRY
OPNUP0: MOVE T1,MRLDJF
MOVX T2,OF%RD!OF%WR ;READ/WRITE ACCESS
OPENF
ERJMP OPNEU2 ;OPENF MAY FAIL BECAUSE OF SIMULATANEOUS ACCESS
;HERE WHEN FILE HAS BEEN OPENED
OPNUP1: SETZM MRLFPR ;SET FILE PTR TO ZERO
MOVE T1,MRLDJF ;GET READY TO READ IT
HRRZ T2,MRLDBL
HRLI T2,(POINT 36,)
MOVNI T3,200 ;-# WORDS
SIN
ERJMP OPNUP2 ;FAILED
JRST RET.2 ;SIGNAL ALL OK
; HERE FOR PROBLEMS
OPNUP2: HRROI T1,[ASCIZ/%LIBOL: Can't update LSTATS.DIR - SIN failed:
/]
PSOUT
OPNERC: PUSHJ PP,TYPFER ;TYPE THE ERROR
OPNERD: MOVE T1,MRLDJF ;NOW RELEASE JFN
RLJFN
ERJMP .+1 ;OH WELL, WE TRIED
POPJ PP, ;RETURN
OPNEU1: HRROI T1,[ASCIZ/%LIBOL: CLOSF failed for LSTATS.DIR: /]
PSOUT
JRST OPNERC
;OPENF FAILED FOR READ/WRITE ACCESS
OPNEU2: CAIN T1,OPNX9 ;INVALID SIMULTANEOUS ACCESS?
JRST OPNEU3 ;YES--WAIT A LITTLE
HRROI T1,[ASCIZ/%LIBOL: Can't OPENF LSTATS.DIR for updating: /]
PSOUT
JRST OPNERC ;TYPE REASON, AND RELEASE JFN
OPNEU3: SOJLE T4,OPNEU4 ;WAITED TOO LONG?
MOVEI T1,^D1000 ;NO, SLEEP A SEC
DISMS
JRST OPNUP0 ;GO TRY AGAIN
OPNEU4: HRROI T1,[ASCIZ/%LIBOL: Can't OPENF LSTATS.DIR for updating: /]
PSOUT
HRROI T1,[ASCIZ/
% Someone has it open for UPDATING
/]
PSOUT
JRST OPNERD ;RELEASE JFN AND POPJ
;ROUTINE TO PUT NEW INFO IN THE HEADER WHICH SAYS WE
;BUMPED TO THE NEXT FILESPEC.
; IF I/O ERRORS, OR FILE IS EXHAUSTED, POPJ, ELSE POPJ1
;WITH FILE POSITIONED AT 0, NEW INFO IN PLACE, AND 1ST DSK BLOCK UPDATED.
; IF POPJ RETURN TAKEN, THE JFN HAS BEEN RELEASED, TOO.
NEWINF: MOVE T4,MRLDBL ;POINTER TO BLOCK
MOVE T1,.LDNFL(T4) ;# FILES,,# OF CURRENT
HLRZ T2,T1 ;# FILES
CAIG T2,(T1) ;IS FILE EXHAUSTED
JRST FILEXH ; YES, SAY THAT
AOS .LDNFL(T4) ;BUMP # OF CURRENT FILE
GTAD ;SAVE LATEST DATE/TIME IN HEADER
MOVEM T1,.LDFWR(T4) ;SAVE TIME OF FIRST WRITE
;BUMP CURRENT POINTER
MOVE T1,.LDBPC(T4) ;BYTE PTR TO CURRENT
HRRZ T3,T1
CAIL T3,200 ;POINTING TO FIRST BLOCK?
JRST NEWIN1 ;NO, REPOSITION FILE
ADD T1,MRLDBL ;MAKE ABSOLUTE PTR
ILDB T2,T1 ;GET A BYTE
JUMPN T2,.-1 ;LOOK FOR NULL
SUB T1,MRLDBL ;GET RELATIVE BP
HRRZ T3,T1
CAIL T3,200 ;SKIP IF STILL IN 1ST BLOCK
JRST NEWIN1 ;NO, HAVE TO REPOSITION FILE
MOVEM T1,.LDBPC(T4) ;THAT'S THE STARTING BP ALL RIGHT
MOVEM T1,MRLBPC ; SAVE AS BP TO CURRENT
;WRITE OUT THE UPDATED BLOCK TO DSK
NEWIOT: MOVE T1,MRLDJF ;TO SFPTR TO 0 TO MAKE SURE
SETZ T2,
SFPTR
ERJMP SFPTE2 ;ERROR...?
MOVE T1,MRLDJF ;NOW GET READY FOR SOUT
HRRZ T2,MRLDBL
HRLI T2,(POINT 36,)
MOVNI T3,200
SOUT ;WRITE THE 1ST BLOCK
ERJMP NEWIES ;ERROR...?
;EVERYTHING IS COOL .. SKIP RETURN
JRST RET.2
;CURRENT FILE STARTS OR ENDS IN ANOTHER BLOCK. WE HAVE TO
;REPOSITION THE FILE TO GET THE START OF THE NEXT ONE,
;REPOSITION AGAIN TO 0, AND STORE THE STARTING BP.
NEWIN1: MOVE T4,MRLBPC ;GET BP TO CURRENT NOW
PUSHJ PP,LDPOST ;REPOSITION FILE
POPJ PP, ;ERROR - POPJ
HLLZ T1,MRLBPC ; GET LH OF BYTE PTR (RH = 0)
ADD T1,MRLDBL ;GET ABSOLUTE BP TO START OF OLD CURRENT
ILDB T2,T1 ;LOOK FOR FIRST NULL
JUMPN T2,.-1
SUB T1,MRLDBL ;GET REL ADDRESS IN THIS BLOCK
ADD T1,MRLFPR ;T1= RELATIVE PTR TO CURRENT FILE
MOVEM T1,MRLBPC ;SAVE HERE FOR A SEC..
;NOW WE MUST REPOSITION THE FILE TO WORD 0 AGAIN
SETZ T4,
PUSHJ PP,LDPOST
POPJ PP, ;ERROR - POPJ
HRRZ T4,MRLDBL
MOVE T1,MRLBPC ;GET SAVED BP
MOVEM T1,.LDBPC(T4) ;STORE IT
JRST NEWIOT ;GO WRITE UPDATED BLOCK TO DSK
;ERROR - SFPTR FAILED TRYING TO GET TO 0
SFPTE2: HRROI T1,[ASCIZ/%LIBOL: SFPTR failed trying to update LSTATS.DIR:
/]
PSOUT
PUSHJ PP,TYPFER
JRST RLDFJ ;RELEASE JFN AND POPJ
;ERROR - SOUT FAILED TRYING TO UPDATE 1ST BLOCK
NEWIES: HRROI T1,[ASCIZ/%LIBOL: SOUT failed trying to update LSTATS.DIR:
/]
PSOUT
PUSHJ PP,TYPFER
JRST RLDFJ ;RELEASE JFN AND POPJ
;HERE IF WE ARE ALREADY POINTING TO THE LAST FILE IN THE DIRECTORY
FILEXH: HRROI T1,[ASCIZ/%LIBOL: LSTATS.DIR is exhausted
/]
PSOUT
MOVE T1,MRLDJF
RLJFN
ERJMP .+1
POPJ PP,
; ROUTINE TO POSITION LSTATS.DIR
;CALL: T4/ BYTE PTR TO IT
; PUSHJ PP,LDPOST
; RETURNS: PROPER BLOCK IN THE 200 WORD BUFFER
; MRLFPR = NUMBER OF THE FIRST WORD IN THE BLOCK
; RETURNS POPJ IF ERROR, SKIP RETURN IF OK
LDPOST: HRRZ T3,T4 ;GRAB START OF BLOCK
SKIPN T2,MRLFPR ;ZERO IS SPECIAL
JRST LDPST1 ;WE ARE NOW AT START OF FILE
;SET FILE POSITION TO WORD WE WANT, READ NEXT 200 WORDS IN.
LDPST0: MOVEM T3,MRLFPR ;NEW FILE POINTER
MOVE T1,MRLDJF ; SET FILE PTR - GET JFN IN T1
MOVE T2,T3 ;T2= BYTE NUMBER
SFPTR
ERJMP SFPTRE ;SFPTR FAILED!
MOVE T1,MRLDJF ;GET READY TO READ IT
HRRZ T2,MRLDBL
HRLI T2,(POINT 36,)
MOVNI T3,200 ;-# WORDS
SIN
ERJMP .+1 ;EOF CONDITION IS OK -- ASSUME WE GOT THAT
JRST RET.2 ;GIVE SKIP RETURN
;WE ARE POSITIONED AT THE START OF THE FILE
LDPST1: JUMPE T3,LDPST0 ;GO READ 1ST 200 WORDS
;WE ARE AT START OF FILE, BUT WANT SOMETHING IN THE MIDDLE SOMEWHERE.
;IF IT IS WITHIN THE FIRST 200 WORDS, DON'T BOTHER REPOSITIONING THE FILE.
;HOWEVER, BE CAREFUL THAT THE WHOLE FILESPEC FITS IN THE FIRST 200 WORDS..
;ELSE WE MUST GO TO LDPST0.
MOVE T2,T4 ;GET POINTER NOW
ADD T2,MRLDBL ;MAKE ACTUAL BYTE PTR
ILDB T1,T2
JUMPN T1,.-1 ;LOOK FOR FIRST NULL
HRRZ T2,T2
SUB T2,MRLDBL
CAIGE T2,200 ;IF LESS THAN 200, WE'RE OK
JRST RET.2 ;IT ALL FITS IN THE BLOCK
JRST LDPST0 ;GO REPOSITION, ETC.
;SFPTR FAILED
SFPTRE: HRROI T1,[ASCIZ/%LIBOL: SFPTR failed for LSTATS.DIR: /]
PSOUT
JRST TYPFER ;TYPE MESSAGE
;I/O ERRORS FOR LSTATS.DIR
;HERE IF GTJFN FAILS FOR LSTATS.DIR
LGTJNE: CAIN T1,GJFX24 ;IF FILE-NOT-FOUND
JRST LGTJN1 ;GO SAY THAT
HRROI T1,[ASCIZ/%LIBOL: GTJFN failed for LSTATS.DIR: /]
PSOUT
JRST TYPFER ;TELL USER
LGTJN1: HRROI T1,[ASCIZ/%LIBOL: LSTATS.DIR not found
/]
PSOUT
POPJ PP, ;RETURN
;HERE IF OPENF FAILED FOR LSTATS.DIR (BUT THE GTJFN HAD WORKED!)
LOPNFF: HRROI T1,[ASCIZ/%LIBOL: Can't OPEN LSTATS.DIR for read: /]
PSOUT
PUSHJ PP,TYPFER ;TYPE REASON
RLDFJ: MOVE T1,MRLDJF ;RELEASE JFN
RLJFN
ERJMP .+1
POPJ PP, ;RETURN
;HERE IF SIN FAILED TRYING TO READ FIRST 200 WORDS OF LSTATS.DIR
LSINF: HRROI T1,[ASCIZ/%LIBOL: Can't read LSTATS.DIR: /]
PSOUT
PUSHJ PP,TYPFER ; EVERYTHING THAT COULD HAPPEN IS WRONG
JRST RLDFJ ;RELEASE JFN AND POPJ
;HERE IF CLOSF FAILED AFTER WE DID ALL WE HAD TO DO IN LSTATS.DIR
CLSFE: HRROI T1,[ASCIZ/%LIBOL: CLOSF failed for LSTATS.DIR: /]
PSOUT
PUSHJ PP,TYPFER ;TYPE WHY
JRST NXTRD1 ;CLOSE INPUT, OUTPUT FILES, AND RETURN
;I/O ERRORS FOR THE COMMON FILE
;HERE IF GTJFN FAILS FOR THE COMMON FILE THE DIRECTORY POINTS US TO
FJFNF: HRROI T1,[ASCIZ/%LIBOL: GTJFN failed for LSTATS file: /]
PSOUT
CMMERR: PUSHJ PP,TYPFER ;TYPE WHAT IS WRONG
HRROI T1,[ASCIZ/% Filespec is: /]
PSOUT
MOVE T1,[POINT 7,MRLDNA] ;STRING WAS HERE
PSOUT
JRST RLDFJ ;RELEASE JFN OF LSTATS.DIR AND POPJ
;THIS ROUTINE IS SIMILAR TO CMMERR, BUT ALSO RELEASES JFN OF COMMON FILE
CMMER1: PUSHJ PP,TYPFER ;TYPE WHAT IS WRONG
HRROI T1,[ASCIZ/% Filespec is: /]
PSOUT
MOVE T1,[POINT 7,MRLDNA]
PSOUT
MOVE T1,MRLCJF ;RELEASE COMMON FILE JFN
RLJFN
ERJMP .+1 ;HOPE WE DID
JRST RLDFJ ;RELEASE JFN OF LSTATS.DIR AND POPJ
;HERE IF SIZEF FAILS FOR COMMON FILE
SZEFF: HRROI T1,[ASCIZ/%LIBOL: SIZEF failed for LSTATS file: /]
PSOUT
JRST CMMERR ;GO TYPE REASON AND FILESPEC
;HERE IF OPENF FAILED - CAN'T OPEN IT FOR APPEND
COPNFF: HRROI T1,[ASCIZ/%LIBOL: Can't append to LSTATS file: /]
PSOUT
JRST CMMER1 ;GO TYPE REASON AND FILESPEC
;HERE IF OPENF FAILED FOR FILE WE HAD WRITTEN
OOPNFF: HRROI T1,[ASCIZ/%LIBOL: Can't append to LSTATS file - /]
PSOUT
HRROI T1,[ASCIZ/OPENF failed for old file:
/]
PSOUT
PUSHJ PP,TYPFER ;TYPE REASON
MOVE T1,MRLCJF ;RELEASE JFN OF COMMON FILE
RLJFN
ERJMP .+1 ;HOPE WE DID
JRST RLDFJ ;RELEASE JFN OF LSTATS.DIR AND POPJ
>;END IFDEF LSDIR
>;END IFN TOPS20
; ROUTINES TO APPEND TO <JOBNAME>.MTO ON DSK:
;(NO LSTATS.DIR IS USED)
SUBTTL TOPS10 JOBNAME.MTO APPEND CODE
IFE FTLSDR,<
IFE TOPS20,<
DOAP10: PUSHJ PP,GMCHAN ;GET A CHANNEL FOR THE .MTO FILE
JRST AP1NFC ;?CAN'T
ANDI T5,17
DPB T5,[POINT 4,T5,12] ;STORE IN AC FIELD
HLLZM T5,MRCHCF ;SAVE CHANNEL NUMBER
;OPEN 'DSK' ON THAT CHANNEL
MOVEI T1,17 ;DUMP MODE
MOVSI T2,'DSK'
SETZ T3,
MOVE T4,[OPEN T1]
OR T4,MRCHCF
XCT T4
JRST AP1ODF ;?OPEN OF DSK FAILED
;OPEN PREVIOUS FILE FOR READING
MOVE T1,MRNM6 ;NAME
MOVSI T2,'TMP' ;EXTENSION
SETZB T3,T4 ;ON DSK:
MOVE T5,[LOOKUP T1]
OR T5,MRCHNN
XCT T5
JRST AP1LKF ;?CAN'T FIND FILE WE'VE BEEN WRITING
;LOOK FOR JOBNAME.MTO
HRROI T1,3
GETTAB T1, ;GET MY PROGRAM NAME
MOVE T1,[SIXBIT/METER/] ;FAILED--GET 'METER'
MOVSI T2,'MTO'
SETZB T3,T4
MOVE T5,[LOOKUP T1] ;SEE IF ALREADY TEHRE
OR T5,MRCHCF
XCT T5
JRST AP1LF1 ;FAILED-- HOPEFULLY JUST NOT THERE
;IT IS THERE, OPEN FOR APPEND
HLRE T1,T4 ;GET SIZE
JUMPL T1,[MOVM T1,T1 ;SOME # OF WORDS-- ROUND UP TO BLOCKS
IDIVI T1,200
JUMPE T2,.+1
AOJA T2,.+1]
MOVEI AC11,1(T1) ;START WRITING TO NEXT BLOCK
MOVEI T0,^D5 ;# OF TIMES TO TRY
DOAPE: MOVSI T2,'MTO'
SETZB T3,T4
MOVE T5,[ENTER T1]
OR T5,MRCHCF
XCT T5
JRST AP1EN0 ;FAILED-- BAD ERROR
MOVSI T1,(USETO) ;PREPARE TO APPEND
OR T1,MRCHCF
HRR T1,AC11 ;GET BLOCK NUMBER TO START AT
XCT T1
JRST CENTOK ;COMMON ENTER OK
;HERE IF LOOKUP FAILED
AP1LF1: HRRZ T2,T2 ;GET ERROR CODE
JUMPN T2,AP1LFF ;OOPS.. SOMETHING BESIDES "FILE NOT FOUND"!
;JUST DO ENTER
MOVSI T2,'MTO'
SETZB T3,T4
MOVE T5,[ENTER T1]
OR T5,MRCHCF
XCT T5
JRST AP1CN1 ;NORMAL ENTER FAILED! (STRANGE!)
;HERE WHEN FILES ARE OPEN - COPY THE DATA
CENTOK: MOVE T1,MRLDBL ;PREPARE FOR "IN" UUO
SUBI T1,1 ; TO OUR 200-WORD BUFFER
HRLI T1,-200
SETZ T2,
MOVE T3,[IN T1]
OR T3,MRCHNN
XCT T3
CAIA ;OK
JRST AP1INE ;FAILED--ASSUME EOF
;OUT
MOVE T1,MRLDBL
SUBI T1,1
HRLI T1,-200
SETZ T2,
MOVE T3,[OUT T1]
OR T3,MRCHCF
XCT T3
JRST CENTOK ;WORKED--GO DO SOME MORE
JRST AP1OUF ;?OUT FAILED!
;HERE WHEN "IN" FAILS, ASSUMING EOF
AP1INE: PUSHJ PP,DELOF ;DELETE OLD FILE
JRST RLCMF ;AND RELEASE COMMON FILE CHANNEL
;ERRORS
AP1NFC: OUTSTR [ASCIZ/%LIBOL: No free channels to append LSTATS data
/]
POPJ PP, ;GIVE UP AND RETURN
;OPEN OF 'DSK' FAILED?
AP1ODF: OUTSTR [ASCIZ/%LIBOL: Can't OPEN DSK to append LSTATS data
/]
POPJ PP, ;GIVE UP AND RETURN
;LOOKUP FAILED FOR FILE WE'VE BEEN WRITING
AP1LKF: OUTSTR [ASCIZ/%LIBOL: LOOKUP faile for .TMP file we wrote!
/]
RLOF: MOVSI T1,(RELEAS)
OR T1,MRCHNN
XCT T1
POPJ PP,
;ENTER FAILED FOR UPDATE OF JOBNAME.MTO
AP1EN0: HRRZ T2,T2 ;GET ERROR CODE
CAIN T2,3 ;SIMULATANEOUS PROBLEM?
JRST AP1EN3 ;YES, WAIT A SEC
OUTSTR [ASCIZ/%LIBOL: ENTER failed for .MTO file on DSK:
/]
PUSHJ PP,DELOF ;DELETE OLD FILE
RLCMF: MOVSI T1,(RELEAS)
OR T1,MRCHCF
XCT T1
POPJ PP,
AP1EN3: SOJLE T0,AP1EN4 ;WAITED TOO LONG
MOVEI T2,1
SLEEP T2,
JRST DOAPE ;TRY ENTER AGAIN
AP1EN4: OUTSTR [ASCIZ/%LIBOL: ENTER failed for .MTO file on DSK:
% Someone else has it OPEN for update
/]
PUSHJ PP,DELOF ;DELETE OLD FILE
JRST RLCMF ;GO RELEASE COMMON CHANNEL
;LOOKUP FAILED OTHER THAN ERROR CODE 0 FOR DSK:JOBNAME.MTO
AP1LFF: OUTSTR [ASCIZ/%LIBOL: LOOKUP failed for .MTO file on DSK:
/]
PUSHJ PP,DELOF ;DELETE OLD FILE
JRST RLCMF ;GO RELEASE COMMON CHANNEL
;NORMAL ENTER FAILED FOR DSK:JOBNAME.MTO
AP1CN1: OUTSTR [ASCIZ/%LIBOL: ENTER failed for .MTO file on DSK:
/]
PUSHJ PP,DELOF ;DELETE OLD FILE
JRST RLCMF ;GO RELEASE COMMON CHANNEL
;"OUT" FAILED FOR .MTO FILE
AP1OUF: OUTSTR [ASCIZ/%LIBOL: OUT failed while appending to .MTO file
/]
PUSHJ PP,DELOF ;TRY TO DELETE OLD FILE
JRST RLCMF ;GO RELEASE COMMON CHANNEL
>;END IFE TOPS20
SUBTTL TOPS20 JOBNAME.MTO APPEND CODE
IFN TOPS20,<
DOAP20: MOVE T1,MRJFN
MOVX T2,OF%RD
OPENF
ERJMP AP20RF
;OPEN (FOR UPDATE) JOBNAME.MTO
GETNM
MOVE T2,[POINT 6,T1]
MOVE T3,[POINT 7,MRNMA] ;BUILD ASCII FILE NAME
DOAP21: ILDB T4,T2
JUMPE T4,DOAP22
ADDI T4,40
IDPB T4,T3
TLNE T2,760000
JRST DOAP21 ;LOOP FOR ALL CHARS
DOAP22: MOVE T2,[POINT 7,[ASCIZ/.MTO/]]
ILDB T4,T2
IDPB T4,T3
JUMPN T4,.-2
;GTJFN
MOVX T1,GJ%SHT
MOVE T2,[POINT 7,MRNMA]
GTJFN
ERJMP AP2GJF ;GTJFN FAILED
MOVEM T1,MRLCJF ;SAVE JFN
;OPENF
MOVEI T5,^D5 ;TIMES WE WILL TRY
DOAP25: MOVE T1,MRLCJF ;GET JFN
MOVX T2,OF%APP ;APPEND ACCESS
OPENF
ERJMP AP25ER ;FAILED (PROBABLY SIMULTANEOUS ACCESS)
;OK--BOTH FILES OPEN -- COPY THE DATA
DOAP26: MOVE T1,MRJFN ;OUR FAMILIAR READ/WRITE LOOP
HRRZ T2,MRLDBL
HRLI T2,(POINT 36,) ;BYTE PTR TO BLOCK
MOVNI T3,200
SIN ;READ DATA FROM .TMP FILE
ERJMP DOAP27 ;UNTIL ERROR
MOVE T1,MRLCJF ; APPEND IT TO COMMON FILE (.MTO)
HRRZ T2,MRLDBL
HRLI T2,(POINT 36,)
MOVNI T3,200
SOUT
ERJMP AP26ER ;SOUT FAILED - COMPLAIN!
JRST DOAP26 ;LOOP
;HERE WHEN SIN FAILS -- ASSUME EOF
DOAP27: MOVE T1,MRJFN ;CLOSE THE INPUT FILE
TXO T1,CO%NRJ ;BUT DON'T RELEAS JFN
CLOSF
ERJMP .+1 ;IGNORE ERRORS CLOSING
MOVE T1,MRLCJF ;CLOSE COMMON FILE
CLOSF ; AND RELEASE JFN
ERJMP .+1 ;IGNORE ERRORS CLOSING
JRST DELOF ;DELETE THE .TMP FILE
;AND RETURN (TO EXIT THE PROGRAM)
;HERE FOR PROBLEMS THAT OCCUR ABOVE
;OPENF FAILED FOR OLD FILE
AP20RF: HRROI T1,[ASCIZ/%LIBOL: OPENF failed for LSTATS .TMP file: /]
PSOUT
PUSHJ PP,TYPFER
MOVE T1,MRJFN
RLJFN ;TRY TO RELEAS JFN
ERJMP .+1 ;IGNORE ERRORS
POPJ PP, ;RETURN
;GTJFN FAILED FOR THE COMMON FILE
AP2GJF: HRROI T1,[ASCIZ/%LIBOL: GTJFN failed for output .MTO file: /]
PSOUT
PUSHJ PP,TYPFER ;WHAT IS IT EXACTLY
JRST DELOF ;DELETE THE OLD FILE AND RETURN
;OPENF FAILED FOR COMMON FILE
AP25ER: CAIE T1,OPNX9 ;SIMULTANEOUS UPDATE?
JRST AP25E1 ;NO -- SOME BAD ERROR
SOJLE T5,AP25E2 ;TRIED SEVERAL TIMES, GIVE UP
MOVEI T1,^D1000 ;SLEEP A SEC
DISMS
JRST DOAP25 ;AND TRY OPENF AGAIN
AP25E1: HRROI T1,[ASCIZ/%LIBOL: OPENF failed for output .MTO file: /]
PSOUT
PUSHJ PP,TYPFER ;WHAT IS IT??
AP25E3: PUSHJ PP,DELOF ;DELETE OLD FILE
MOVE T1,MRLCJF ;AND RELEAS THIS JFN
RLJFN
ERJMP .+1
POPJ PP, ;THEN RETURN
AP25E2: HRROI T1,[ASCIZ/%LIBOL: OPENF failed for output .MTO file
% Someone has it OPEN for updating
/]
PSOUT
JRST AP25E3 ;FINISH ERROR HANDLING
;SOUT FAILED
AP26ER: HRROI T1,[ASCIZ/%LIBOL: SOUT failed trying to append to .MTO file:
/]
PSOUT
PUSHJ PP,TYPFER ;TYPE WHY
JRST DOAP27 ;PRETEND WE ARE AT THE END OF THINGS
>;END IFN TOPS20
>;END IFE FTLSDR
;ROUTINE TO DELETE OLD .TMP FILE
IFE TOPS20,<
DELOF: MOVE T5,[RENAME T1]
OR T5,MRCHNN
SETZB T1,T2
SETZB T3,T4
XCT T5
JRST RENFAI ;RENAME FAILED!
DELOFR: MOVSI T1,(RELEAS)
OR T1,MRCHNN
XCT T1
POPJ PP,
RENFAI: OUTSTR [ASCIZ/%LIBOL: Can't DELETE DSK:/]
OUTSTR MRNMA ;TYPE FILENAME
OUTSTR [ASCIZ/
/]
JRST DELOFR ;GO RELEAS CHANNEL
>;END IFE TOPS20
IFN TOPS20,<
DELOF: MOVE T1,MRJFN ;DELETE THIS FILE
DELF
ERJMP .+2
JRST DELOF1 ;OK, RELEASE JFN AND RETURN
HRROI T1,[ASCIZ/% Can't delete LSTATS .TMP file: /]
PSOUT
PUSHJ PP,TYPFER
DELOF1: MOVE T1,MRJFN
RLJFN
ERJMP .+1 ;IGNORE ERRORS
POPJ PP, ;RETURN
>;END IFN TOPS20
>;END IFN LSTATS
IFE LSTATS,<MROUT.==:RET.1## ;FOR SORT>
END