.TITLE RSUREP .IDENT /V7.16/ ;********************************************************************** ; ; RSUREP ; ; THIS OVERLAY IS THE USAGE REPORT PREPARATION ROUTINE. ; THIS ROUTINE READS THE INPUT FILE CREATED BY THE ; ACCOUNTING PACKAGE AND PRODUCES A REPORT OF SYSTEM USE. ; ; FOR USE WITH ACCOUNTING SYSTEM VERSION 7 ONLY. ; ; VERSION: V7 MAY 1981 ; ; STEVE THOMPSON ; SCHOOL OF CHEMICAL ENGINEERING ; OLIN HALL ; CORNELL UNIVERSITY ; ITHACA ; NY 14853 ; ; REVISION HISTORY ; ---------------- ; ; SMT719 22-JUL-81 ADDED "M" AND "C" FLAGS IN BRIEF OUTPUT ; LISTING TO IDENTIFY MASTER AND CHAINED ; ACCOUNTS. ; ; SMT722 24-JUL-81 ADDED MORE INFORMATION TO OUTPUT. TOTAL ; CONNECT TIME/CHARGE, TOTAL CPU CHARGE AND ; TOTAL DISK CHARGES. ALSO ADDED SOME EXTRA ; CONDITIONALS TO ALLOW FOR NON-BATCH SUPPORT ; OF TERMINALS OTHER THAN "TT", AND ALSO ; TIDIED UP THE CODE A BIT HERE AND THERE. ; ; SMT727 28-JUL-81 CHANGED FULL FORMAT OUTPUT SO THAT USERS ; WHO HAVE BEEN INACTIVE (APART FROM DISK USE) ; DO NOT PRODUCE A FULL REPORT UNLESS THEY ; WERE MASTER ACCOUNTS. ; ; SMT728 28-JUL-81 ADDED PAGE COUNT/CHARGE LOGIC. ; ; SMT738 10-AUG-81 CORRECTED A BUG IN THE FILSUP ROUTINE THAT ; CAUSED BLOCK ALLOCATION CHANGES TO BE REPORTED ; AS ZERO, AND PROBABLY COULD HAVE MESSED UP ; REPORTING OTHER MACNT TRANSACTIONS IN CERTAIN ; CASES TOO. ; ; SMT749 23-SEP-81 CHANGED "PDP 11/70" TO "PDP-11" IN THE OUTPUT ; HEADINGS. ; ; SMT753 7-OCT-81 CHANGED NAMES OF CONDITIONAL ASSEMBLY ; PARAMETERS; SEE THE FILES MODIFY.TXT AND ; CONDEF.MAC FOR DETAILS. ; ; SMT765 10-OCT-81 REMOVED ATTRIBUTES READ AND GET REPORT ; PERIOD AS DATE/TIME OF FIRST AND LAST ; TRANSACTIONS RATHER THAN AS THE DATE AND ; TIME OF CREATION AND LAST REVISION TO ; ALLOW ANALYSIS OF OLD FILES. ; ; SMT777 27-OCT-81 MODIFIED TO INCORPORATE INTO THE NEW OVERLAID ; VERSION OF RSU WITH NEW FUNCTIONALITY. ; ; SMT782 6-NOV-81 ADDED THE /NA SWITCH ; ; SMT791 16-NOV-81 ADDED THE /LI SWITCH ; ; SMT801 1-MAR-82 HANDLE FCS ERROR CODE CORRECTLY WHEN DOING ; DISK I/O ; ; SMT804 16-MAR-82 FIX BALANCE FORMATTING IF "UNITS" OPTION IS ; SELECTED AT ACCGEN ; ; SMT806 16-MAR-82 ADD TOTAL I/O COUNT AND CHARGE TO SYSTEM- ; WIDE OUTPUT. ; ; SMT807 16-MAR-82 FIX TITLE UNDERLINING AT A CRT ; ; SMT812 5-APR-82 CHANGED COMMAND NAME FROM RPT TO RSU ; ; SMT814 12-APR-82 LOWER CASE MESSAGES FOR RSX-11M V4.0 ; ; SMT816 15-APR-82 ADDED THE /MA SWITCH; TYPE OUT THE COMMAND ; LINE IN THE REPORT HEADING ; ; SMT821 23-APR-82 CHANGED ENTRY POINT NAMES OF ACCOUNTING ; SUPPORT ROUTINES (SEE MODIFY.TXT) ; ; SMT832 30-AUG-82 ADDED THE /SA SWITCH. ; ; SMT833 30-AUG-82 GENERAL CLEANUP OF CODE. CHANGED THE ; NAMES OF THREE CONTROL BLOCK OFFSETS: ; R.CONN --> R.TCON ; R.TCOR --> R.TMEM ; R.CCOR --> R.CMEM ; REMOVED SOME WORDS IN THE CONTROL BLOCK: ; R.NALT R.NDA R.NDSK R.NMST ; REMOVED A WORD FROM R.NTRM AND R.NJOB ; REMOVED SOME UNNECESSARY CONDITIONALS ; ; SMT834 31-AUG-82 SHOW TERMINAL USAGE STATISTICS ONLY FOR ; UNITS FOR WHICH THERE WAS ACTIVITY. ; ; SMT835 31-AUG-82 ADDED THE /GR SWITCH. ; ; SMT836 6-SEP-82 CHANGED "CALLR" TO "JMP" SINCE RSXMC.MAC ; NO LONGER INVOLVED IN THE ASSEMBLY. ; DETERMINE TICKS/SECOND FROM EXECUTIVE ; RATHER THAN FROM ASSEMBLY PARAMETERS. ; ;*********************************************************************** .MCALL GTIM$S,DIR$,QIOW$ .MCALL OPNS$R .MCALL CLOSE$,EXST$S,PRINT$ .MCALL DELET$ ACTDF$ ; DEFINE ADDITIONAL ACCOUNT FILE OFFSETS FILDF$ ; DEFINE RECORDS FILE OFFSETS SPA = 40 ; SPACE COLON = ': ; COLON DPT = '. ; DECIMAL POINT CR = 15 ; CARRIAGE RETURN LF = 12 ; LINEFEED HT = 11 ; HORIZONTAL TAB FF = 14 ; FORM FEED RECLEN = 0 ; DATA BUFFER LENGTH .IIF GT F.LBYE-RECLEN,RECLEN=F.LBYE .IIF GT F.LDSK-RECLEN,RECLEN=F.LDSK .IIF GT F.LSET-RECLEN,RECLEN=F.LSET .IIF GT F.LUPD-RECLEN,RECLEN=F.LUPD .IIF GT F.LBLK-RECLEN,RECLEN=F.LBLK .IIF GT F.LMMA-RECLEN,RECLEN=F.LMMA .IIF GT F.LCHA-RECLEN,RECLEN=F.LCHA .IIF GT F.LMAS-RECLEN,RECLEN=F.LMAS .IIF GT F.LDMS-RECLEN,RECLEN=F.LDMS .PAGE .SBTTL CONTROL BLOCK DEFINITION .MACRO RSUDF$ L,B .ASECT .=0 R.LNK:'L' .BLKW 1 ; CONTROL BLOCK LINK WORD R.LIST:'L' .BLKW 2 ; LISTHEAD FOR ADDITIONAL INFORMATION R.GRP:'L' .BLKB 3 ; ASCII GROUP CODE R.MBR:'L' .BLKB 3 ; ASCII MEMBER CODE R.LNM:'L' .BLKB 14. ; LAST NAME R.FNM:'L' .BLKB 12. ; FIRST NAME R.CASH:'L' .BLKW 2 ; CURRENT ACCOUNT BALANCE R.BALL:'L' .BLKW 2 ; DISK BLOCK ALLOCATION R.ABLK:'L' .BLKW 2 ; AVERAGE DISK BLOCK USE R.MALL:'L' .BLKW 2 ; MONTHLY MONEY ALLOCATION R.ACNO:'L' .BLKW 1 ; ACCOUNT NUMBER R.CHWD:'L' .BLKW 1 ; ACCOUNT CHAIN WORD R.NTRM:'L' .BLKW 1 ; NUMBER OF TERMINAL SESSIONS R.NJOB:'L' .BLKW 1 ; NUMBER OF BATCH JOBS R.TCON:'L' .BLKW 2 ; TOTAL CONNECT TIME, TICKS R.CCON:'L' .BLKW 2 ; TOTAL CHARGE FOR CONNECT TIME R.TCPU:'L' .BLKW 2 ; TOTAL CPU TIME, TICKS R.CCPU:'L' .BLKW 2 ; TOTAL CHARGE FOR CPU TIME R.TQIO:'L' .BLKW 2 ; TOTAL NUMBER OF I/O REQUESTS R.CQIO:'L' .BLKW 2 ; TOTAL CHARGE FOR I/O R.TPAG:'L' .BLKW 2 ; NUMBER OF PAGES PRINTED R.CPAG:'L' .BLKW 2 ; PAGE PRINT CHARGE R.TMEM:'L' .BLKW 2 ; TOTAL MEMORY USAGE R.CMEM:'L' .BLKW 2 ; TOTAL CHARGE FOR MEMORY USAGE R.DCHG:'L' .BLKW 2 ; TOTAL CHARGE FOR DISK USE R.TCHG:'L' .BLKW 2 ; TOTAL CHARGES R.MCHG:'L' .BLKW 2 ; CHARGES ACCUMULATED BY VIRTUE OF MASTER STATUS R.CCHG:'L' .BLKW 2 ; CHARGES REDIRECTED BY VIRTUE OF CHAINED STATUS R.NENT:'L' .BLKW 1 ; TOTAL NUMBER OF ENTRIES R.FLAG:'L' .BLKW 1 ; FLAG WORD R.LGTH='B'. ; LENGTH OF DATA PACKET RR.GRP='B'1 ; GROUP PROCESSED BY /GR RR.USR='B'2 ; USER IN GROUP PROCESSED BY /GR .PSECT .MACRO RSUDF$,X,Y .ENDM .ENDM ; ; OTHER MACROS ; .MACRO PRINT MSG,MSGSZ MOV MSG,TIDPB+Q.IOPL .IF B MSGSZ MOV MSG'SZ,TIDPB+Q.IOPL+2 .IFF MOV MSGSZ,TIDPB+Q.IOPL+2 .ENDC ; B MSGSZ DIR$ #TIDPB .ENDM .MACRO FILE MSG,MSGSZ MOV MSG,FILADR .IF B MSGSZ MOV MSG'SZ,FILSIZ .IFF MOV MSGSZ,FILSIZ .ENDC ; B MSGSZ CALL FILOUT .ENDM .MACRO ENTER FUNC,LEN,SERVIC .WORD FUNC .WORD LEN .WORD SERVIC .ENDM ; ; DEFINE CONTROL BLOCK OFFSETS AND BITMASK DEFINITIONS ; RSUDF$ ORDER = R.TCHG ; OFFSET DEFINES THE 2-WORD TABLE ENTRY THAT ; GIVES THE TABULAR ORDER OF ENTRIES. ENTRIES ; ARE ARRANGED IN ORDER OF THE VALUE OF THIS ; FIELD, LARGEST FIRST. ; ; DEFINE COMMAND DISPATCHER TABLES ; CMDTAB: ENTER FF.BYE,F.LBYE,BYESUB ; BYE COMMAND ENTER FF.DSK,F.LDSK,DSKSUB ; DSK... ENTER FF.ALT,F.LBYE,ALTSUB ; ALT... ENTER FF.PAG,F.LBYE,PAGSUB ; PAGE COUNTS FROM ALT... ENTER FF.SET,F.LSET,SETSUB ; SET UP AN ACCOUNT ENTER FF.UPD,F.LUPD,UPDSUB ; UPDATE ACCOUNT BALANCE ENTER FF.BLK,F.LBLK,BLKSUB ; CHANGE BLOCK ALLOCATION ENTER FF.MMA,F.LMMA,MMASUB ; CHANGE MONTHLY ALLOCATION ENTER FF.CHA,F.LCHA,CHASUB ; CHAIN/UNCHAIN TRANSACTION ENTER FF.MAS,F.LMAS,MASSUB ; GIVE MASTER STATUS ENTER FF.DMS,F.LDMS,DMSSUB ; DELETE MASTER STATUS .WORD 0 ; END OF TABLE ; ; TABLES FOR COMPILING INDIVIDUAL TERMINAL USAGE FIGURES (SEE ALSO THE ; TASK BUILDER COMMAND FILE) ; EACH ENTRY IS 7 WORDS LONG: ; WORD 1 NUMBER OF SESSIONS OR JOBS ; WORDS 2 AND 3 TOTAL CONNECT TIME (TICKS) ; WORDS 4 AND 5 TOTAL CPU TIME (TICKS) ; WORDS 6 AND 7 TOTAL I/O REQUESTS ; .PSECT TTTAB0 TTTABL: ; TABLE FOR COMPILATION OF USAGE ; STATISTICS ON A PER-TERMINAL ; BASIS. .PSECT TTTAB1 TTSIZ: .WORD <<.-TTTABL>/14.> ; # ENTRIES IN THE ABOVE TABLE TTSIZW: .WORD </2> ; SIZE OF TABLE IN WORDS .PSECT VTTAB0 VTTABL: ; TABLE FOR COMPILATION OF USAGE ; STATISTICS ON A PER-BATCH-STREAM ; BASIS. .PSECT VTTAB1 VTSIZ: .WORD <<.-VTTABL>/14.> ; # ENTRIES IN THE ABOVE TABLE VTSIZW: .WORD </2> ; SIZE OF TABLE IN WORDS .PSECT .PAGE .SBTTL LOCAL STORAGE ; ; LOCAL STORAGE ; LISTHD: .WORD 0 ; LISHEAD FOR USER DATA PACKETS .WORD .-2 ; DOUBLE: .WORD 0,0 ; WORKSPACE FOR R.NTRM AND R.NJOB CONVERSION NUSER: .WORD 0 ; NUMBER OF USERS IN BUFFER GRPTOT: .WORD 0,0 ; TOTAL CHARGES FOR GROUP (/GR) ; ; THE FOLLOWING STORAGE RESERVATIONS ARE USED FOR ACCUMULATING TOTAL ; USER AND SYSTEM CHARGES. ; ; ** IMPORTANT ** BOTH TABLES MUST BE IN EXACTLY THE SAME ; ** IMPORTANT ** FORMAT. THEY MUST NOT BE MOVED FROM THIS ; ** IMPORTANT ** POINT. ; USRADR: ; ADDRESS OF START OF USER TABLE USRCPU: .WORD 0,0 ; TOTAL CPU TIME (USER) .WORD 0,0 ; TOTAL CPU CHARGE (USER) USRCON: .WORD 0,0 ; TOTAL CONNECT TIME (USER) .WORD 0,0 ; TOTAL CONNECT CHARGE (USER) USRDSK: .WORD 0,0 ; UNUSED .WORD 0,0 ; TOTAL DISK CHARGE (USER) USRPAG: .WORD 0,0 ; TOTAL NUMBER OF PAGES PRINTED (USER) .WORD 0,0 ; TOTAL PAGE CHARGE (USER) USRMEM: .WORD 0,0 ; TOTAL MEMORY USAGE (USER) .WORD 0,0 ; TOTAL MEMORY CHARGE (USER) USRQIO: .WORD 0,0 ; TOTTAL I/O COUNT (USER) .WORD 0,0 ; TOTAL I/O CHARGE (USER) USRTOT: .WORD 0,0 ; TOTAL USER CHARGES SYSADR: ; ADDRESS OF START OF SYSTEM TABLE SYSCPU: .WORD 0,0 ; TOTAL CPU TIME (SYSTEM) .WORD 0,0 ; TOTAL CPU CHARGE (SYSTEM) SYSCON: .WORD 0,0 ; TOTAL CONNECT TIME (SYSTEM) .WORD 0,0 ; TOTAL CONNECT TIME (SYSTEM) SYSDSK: .WORD 0,0 ; UNUSED .WORD 0,0 ; TOTAL DISK CHARGE (SYSTEM) SYSPAG: .WORD 0,0 ; TOTAL NUMBER OF PAGES PRINTED (SYSTEM) .WORD 0,0 ; TOTAL PAGE CHARGE (SYSTEM) SYSMEM: .WORD 0,0 ; TOTAL MEMORY USAGE (SYSTEM) .WORD 0,0 ; TOTAL MEMORY CHARGE (SYSTEM) SYSQIO: .WORD 0,0 ; TOTAL I/O COUNT (SYSTEM) .WORD 0,0 ; TOTAL I/O CHARGE (SYSTEM) SYSTOT: .WORD 0,0 ; TOTAL SYSTEM CHARGES GROUP: .BLKB 3 ; ASCII GROUP CODE FOR /FU SWITCH MEMBER: .BLKB 3 ; ASCII MEMBER CODE FOR /FU SWITCH FMTBUF: .BLKB 14. ; BUFFER USED BY NUMBER FORMATTERS RECBUF: .BLKB RECLEN ; COPY OF DATA BUFFER MADE BY INPUT ROUTINE ; (MUST START ON A WORD BOUNDARY) .EVEN .PAGE .SBTTL TEXT MESSAGES ; ; TEXT MESSAGES ; .NLIST BEX .ENABL LC INTRO: .ASCII /** PDP-11 System Usage Report / INTR1: .ASCII / - - 0 :0 :0 **/ INTR1S=.-INTRO INTR2: .ASCII /=================================/ .ASCII /==================/ INTR2S=.-INTR2 GRPMS1: .ASCII /** PDP-11 Usage Report for Group [/ GRGRP: .ASCII / / .ASCII /,*]/ GRP1SZ=.-GRPMS1 GRPMS2: .ASCII /========================================/ GRP2SZ=.-GRPMS2 FROM: .ASCII /This report covers the period from: / FRMTIM: .ASCII / - - 0 :0 :0 / FROMSZ=.-FROM TO: .ASCII /to: / TOTIM: .ASCII / - - 0 :0 :0 / TOSZ=.-TO HEADER: .ASCII /Username UIC Connect Time CPU Time / .ASCII / Av. blocks Charges/ HEADSZ=.-HEADER NUMUSR: .ASCII /Number of account file entries read = / NUMUS1: .BLKB 7. TOTREC: .ASCII "Total number of data records read/counted = " TOTRC1: .BLKB 20. TOTDYN: .ASCII "Total dynamic memory available/used (bytes) = " TOTDY1: .BLKB 20. CLINE1: .ASCII /Command line used:/ CLINE2=.-CLINE1 USRFLG: .ASCII /Total USER Charges:/ .ASCII /-------------------/ USRFLS=.-USRFLG SYSFLG: .ASCII /Total SYSTEM Charges:/ .ASCII /---------------------/ SYSFLS=.-SYSFLG ALLCPU: .ASCIZ /CPU time logged: / ALLCON: .ASCIZ /Connect time logged:/ ALLDSK: .ASCIZ /Disk charges: / ALLPAG: .ASCIZ /Pages Printed: / ALLMEM: .ASCIZ /Memory Usage (KW-Hrs):/ ALLQIO: .ASCIZ "I/O recorded: " ALLCHG: .ASCIZ /Total charges: / TRMTAB: .ASCII /Terminal usage statistics:/ .ASCII /--------------------------/ TRMTSZ=.-TRMTAB TTTEXT: .ASCIZ /TT/ ACCNO: .ASCIZ /Account number / MSTR: .ASCIZ / (Master)/ NOSET: .ASCIZ /** Account not set up/ CURBAL: .ASCII /Current account balance:/ .BYTE SPA,SPA,SPA,SPA,SPA,SPA,0 CURBLK: .ASCII /Current disk block allocation:/ .BYTE SPA,SPA,SPA,SPA,0 CHATXT: .ASCIZ /Account is chained to account number / AVRBLK: .ASCII /Average disk blocks this period:/ .BYTE SPA,SPA,SPA,SPA,0 ALLMON: .ASCII /Monthly money allocation:/ .BYTE SPA,SPA,SPA,SPA,SPA,SPA,0 TRMSES: .ASCII /Number of interactive terminal sessions:/ .BYTE SPA,SPA,SPA,SPA,0 BATJOB: .ASCII /Number of batch jobs run:/ .BYTE SPA,SPA,SPA,SPA,0 TOTCST: .ASCII /Total charges (see breakdown):/ .BYTE SPA,SPA,SPA,SPA,SPA,SPA,0 OTHER: .ASCII /Other transactions for this account:/ OTHERS=.-OTHER NONE: .ASCII /* none */ NONESZ=.-NONE FFSET: .ASCIZ / Account set up/ .IF DF AA$BLK FFSET1: .ASCIZ / Block allocation / FFSET2: .ASCIZ / Balance / .IFF FFSET2: .ASCIZ / Balance / .ENDC ; DF AA$BLK FFUPD: .ASCIZ / Balance updated by / FFBLK: .ASCIZ / Block allocation changed to / FFMMA: .ASCIZ / Monthly allocation changed to / FFCHA1: .ASCIZ / Account receives member #/ FFCHA2: .ASCIZ / Account chained to master #/ FFCHA3: .ASCIZ / Account unchained/ FFMAS: .ASCIZ / Account gained master status/ FFDMS: .ASCIZ / Master status deleted/ OPTXT: .ASCIZ / / BREAK: .ASCII /Breakdown of Charges/ .ASCII /====================/ .IF DF AA$UNI .ASCII /Amount Charge (units)/ .ASCII /------ --------------/ .IFF .ASCII /Amount Charge ($)/ .ASCII /------ ----------/ .ENDC ; DF AA$UNI BREAKS=.-BREAK CONTIM: .ASCIZ /Connect time:/ CPUTIM: .ASCIZ /Central Processor time:/ IOREQ: .ASCIZ "Input/Output Operations:" PAGES: .ASCIZ /Pages printed:/ MEMTIM: .ASCIZ /Memory Usage (KW-Hours):/ DSKCHG: .ASCII /Disk Charges:/ .BYTE SPA,SPA,SPA,SPA,SPA,SPA,0 KUMHER: .ASCII /Additional charges from member accounts:/ .BYTE SPA,SPA,SPA,SPA,SPA,SPA,0 GOAWAY: .ASCII /Charges made to master account (subtract):/ .BYTE SPA,SPA,SPA,SPA,0 GRAND: .ASCII /--------/ .ASCII /Grand total:/ .BYTE SPA,SPA,SPA,SPA,SPA,SPA,0 .EVEN WHO: .ASCII /Name-unknown / ; THIS FIELD MUST HAVE 14. CHARACTERS ; AND MUST START ON A WORD BOUNDARY DSKCH: .ASCII / - / ; THIS FIELD MUST HAVE 12. CHARACTERS NPAG1: .ASCIZ /RSU -- / NPAG2: .ASCIZ / Pages in report/ BYESTR: .ASCIZ /BYE / BYEDEV: .ASCIZ /DEV=/ BYEREC: .ASCIZ / REC=/ BYEVBN: .ASCIZ / VBN=/ BYECON: .ASCIZ / CONN=/ BYECPU: .ASCIZ /CPU=/ .PAGE .SBTTL ERROR MESSAGES ; ; ERROR MESSAGES ; .IIF NDF AA$V40, .DSABL LC ERR1: .ASCII /RSU -- *FATAL* dynamic memory overflow/ ERR1SZ=.-ERR1 ERR2: .ASCII /RSU -- Open error on input file/ ERR2SZ=.-ERR2 ERR3: .ASCII /RSU -- Read error on input file/ ERR3SZ=.-ERR3 ERR4: .ASCII /RSU -- *FATAL* Account file open failure/ ERR4SZ=.-ERR4 ERR5: .ASCII /RSU -- Unknown function code in record / ERR5A: .BLKB 10. ERR6: .ASCII /RSU -- Record length error in record / ERR6A: .ASCII /00000 - Expected=00000 Actual=00000/ ERR6B: .ASCIZ / - Expected=/ ERR6C: .ASCIZ / Actual=/ ERR7: .ASCII /RSU -- *WARNING* no data in specified time period/ ERR7SZ=.-ERR7 .EVEN .PAGE .SBTTL MAIN LINE CODE $REPEP:: ; OVERLAY TRANSFER ADDRESS CLR TTLSIZ ; SHOW NO PAGE TITLE AVAILABLE ; ; IF /FU IS PRESENT, CONVERT THE GROUP AND MEMBER CODES TO ASCII ; BIT #FUMSK,MASKW ; /FU SWITCH PRESENT? BEQ 3$ ; IF EQ NO MOVB FUGRP,R1 ; GET GROUP CODE BEQ 2$ ; IF EQ, IT WAS A WILD CARD MOV #GROUP,R0 ; GET ADDRESS OF ASCII GROUP BUFFER MOV SP,R2 ; INCLUDE LEADING ZEROES CALL $CBTMG ; CONVERT BYTE TO ASCII OCTAL 2$: MOVB FUMEM,R1 ; GET MEMBER CODE BEQ 3$ ; IF EQ IT WAS A WILD CARD MOV #MEMBER,R0 ; GET ADDRESS OF ASCII MEMBER BUFFER MOV SP,R2 ; INCLUDE LEADING ZEROES CALL $CBTMG ; CONVERT BYTE TO ASCII OCTAL 3$: ; REF. LABEL ; ; OPEN DATA FILE (SHARED READ) ; OPNS$R #$RFFDB ; OPEN THE DATA FILE BCC 4$ ; IF CC WE MADE IT PRINT #ERR2 ; OPEN FAILURE CALL $FCSEP ; GIVE ERROR DETAILS JMP EXSEV ; EXIT WITH SEVERE ERROR 4$: ; REF. LABEL ; ; PRINT INTRODUCTORY MESSAGE ; MOV #TIMBUF,R1 ; GET ADDRESS OF TIME BUFFER GTIM$S R1 ; FIND OUT WHAT TIME IT IS MOV #INTR1,R0 ; GET BUFFER ADDRESS FOR FORMATTED TIME CALL DATTIM ; FORMAT DATE AND TIME FILE #INTRO,#INTR1S ; TYPE OUT THE INTRODUCTION FILE #INTR2,#INTR2S ; ; ; ZERO THE TABLES FOR ACCUMULATION OF TERMINAL/JOB STATISTICS. ; MOV TTSIZW,R2 ; GET SIZE OF TERMINAL STATS. TABLE BEQ 20$ ; IF EQ, NONE ALLOCATED MOV #TTTABL,R0 ; OK, GET ITS ADDRESS 10$: CLR (R0)+ ; ZERO A WORD DEC R2 ; DONE YET? BGT 10$ ; IF GT NO, LOOP 20$: MOV VTSIZW,R2 ; GET SIZE OF BATCH STATS. TABLE BEQ 40$ ; IF EQ, NONE ALLOCATED MOV #VTTABL,R0 ; OK, GET ITS ADDRESS 30$: CLR (R0)+ ; ZERO A WORD DEC R2 ; DONE YET? BGT 30$ ; IF GT NO, LOOP 40$: ; REF. LABEL ; ; OPEN ACCOUNT FILE AND COPY INFORMATION TO DYNAMIC MEMORY REGION ; ; *** W A R N I N G *** ; ; THE CODE HERE DEPENDS ON THE ORDER OF THE OFFSETS IN ; RSUDF$ AND ACTDF$. ; CALL OPENAF ; OPEN THE ACCOUNT FILE ; (THIS ROUTINE DOES NOT RETURN CONTROL ; IF ANY ERRORS ARE DETECTED) 100$: CALL $AFGET ; READ DATA FROM THE ACCOUNT FILE BNE 110$ ; IF NE WE GOT SOME DATA JMP 130$ ; NO WORDS READ 110$: TST A.GRP(R0) ; ENTRY IN USE? BEQ 120$ ; IF EQ NO TST A.ACNO(R0) ; ENTRY ENABLED FOR ACCOUNTING? BEQ 120$ ; IF EQ NO INC NUSER ; SHOW ONE MORE USER IN BUFFER MOV R2,-(SP) ; SAVE R2 MOV R0,-(SP) ; SAVE R0 MOV #R.LGTH,R1 ; SET LENGTH OF MEMORY BLOCK NEEDED CALL CORE ; ALLOCATE A MEMORY BLOCK BCC 115$ ; IF CC WE DID IT CALL $AFCLS ; CLOSE THE ACCOUNT FILE PRINT #ERR1 ; PRINT ALLOCATION ERROR MESSAGE JMP EXSEV ; EXIT WITH SEVERE ERROR 115$: MOV R0,R1 ; COPY BLOCK ADDRESS TO R1 MOV #LISTHD,R0 ; GET USER INFO LISTHEAD ADDRESS CALL INSERT ; LINK IT INTO THE LIST MOV (SP),R0 ; GET ADDRESS OF USER DATA MOV R1,R2 ; SAVE R.LIST LISTHEAD ADDRESS ADD #R.LIST,R2 ; MOV R2,R.LIST+2(R1) ; SET UP 2ND LISTHEAD WORD MOV A.GRP(R0),R.GRP(R1) ; COPY ASCII UIC MOV A.GRP+2(R0),R.GRP+2(R1) ; MOV A.GRP+4(R0),R.GRP+4(R1) ; MOV #13.,R2 ; SIZE OF LNM AND FNM FIELDS ADD #A.LNM,R0 ; POINT R0 TO LAST NAME ADD #R.LNM,R1 ; POINT R1 TO LAST NAME CALL RCOPYW ; TRANSFER TO DYNAMIC MEMORY SUB #,R0 ; RESET TO ORIGINAL VALUES SUB #,R1 ; MOV A.CASH(R0),R.CASH(R1) ; COPY CURRENT BALANCE MOV A.CASH+2(R0),R.CASH+2(R1) ; MOV A.BALL(R0),R.BALL(R1) ; AND BLOCK ALLOCATION MOV A.BALL+2(R0),R.BALL+2(R1) ; MOV A.ABLK(R0),R.ABLK(R1) ; AND AVERAGE BLOCKS MOV A.ABLK+2(R0),R.ABLK+2(R1) ; MOV A.MALL(R0),R.MALL(R1) ; COPY MONTHLY ALLOCATION MOV A.MALL+2(R0),R.MALL+2(R1) ; MOV A.ACNO(R0),R.ACNO(R1) ; COPY ACCOUNT NUMBER MOV A.CHWD(R0),R.CHWD(R1) ; COPY CHAIN WORD CLR R.FLAG(R1) ; INITIALISE FLAG WORD MOV (SP)+,R0 ; RESTORE R0 MOV (SP)+,R2 ; RESTORE R2 120$: ADD #A.LEN,R0 ; POINT TO NEXT ACCOUNT ENTRY SUB #A.LEN,R2 ; ANY DATA LEFT IN BUFFER? BLOS 130$ ; IF LOS NO, DON'T LOOP JMP 110$ ; GIVE THE NEXT USER THE TREATMENT 130$: CMPB #IE.EOF,$AFIOS ; END OF FILE? BEQ 140$ ; IF EQ YES TSTB $AFIOS ; NO, ANY ERRORS? BMI 140$ ; IF MI YES CALL $AFNXB ; POINT TO NEXT BLOCK IN A/C FILE JMP 100$ ; GO DO IT 140$: CALL $AFCLS ; CLOSE THE ACCOUNT FILE MOV NUSER,R1 ; SET NUMBER OF USERS COPIED INTO BUFFER MOV #NUMUS1,R0 ; GET BUFFER ADDRESS FOR MESSAGE CALL DE.CML ; CONVERT TO DECIMAL SUB #NUMUSR,R0 ; CALCULATE STRING LENGTH FILE #NUMUSR,R0 ; AND TYPE IT OUT TST NUSER ; DID WE GET ANYTHING? BNE 150$ ; IF NE YES JMP EXSUC ; NO, JUST EXIT 150$: ; REF. LABEL ; ; NOW WE READ THE FIRST RECORD IN THE FILE AND USE THE DATE AND TIME ; RECORDED IN IT AS THE START OF THE ACCOUNTING PERIOD. ; CLR NRECT ; INITIALISE THE RECORD COUNTERS CLR NRECC ; CALL INPUT ; READ IN THE FIRST RECORD MOV $RFLEN,R3 ; ANYTHING READ? BEQ 168$ ; IF EQ, AN ERROR OCCURRED MOV #FRMTIM,R0 ; GET BUFFER ADDRESS FOR DATE/TIME MOV #RECBUF+F.TIME,R1 ; SET ADDRESS OF BINARY DATE/TIME BUFFER CALL DATTIM ; AND INSERT IT BR 170$ ; ANALYSE THIS RECORD ; ; LOOP OVER DATA FILE RECORDS, CALLING THE SERVICE ROUTINE AT ; EACH ONE ; 167$: CALL INPUT ; READ DATA FILE INFORMATION CMPB $RFFDB+F.ERR,#IS.SUC ; I/O OK? BEQ 170$ ; IF EQ YES 168$: CMPB $RFFDB+F.ERR,#IE.EOF ; END OF FILE REACHED? BEQ 230$ ; IF EQ YES PRINT #ERR3 ; READ ERROR ON INPUT FILE MOV #$RFFDB,R0 ; SET FDB ADDRESS CALL $FCSEP ; GIVE FCS ERROR DETAILS JMP EXSEV ; 170$: MOV $RFLEN,R3 ; ZERO LENGTH RECORD? BEQ 167$ ; IF EQ SKIP IT (FORMAT ERROR?) MOV #CMDTAB,R1 ; GET COMMAND TABLE ADDRESS 180$: MOV (R1)+,R2 ; GET NEXT FUNCTION CODE BEQ 200$ ; IF EQ, END OF TABLE, UNKNOWN FUNCTION CMP RECBUF,R2 ; THIS FUNCTION? BEQ 190$ ; IF EQ YES CMP (R1)+,(R1)+ ; NO, POINT TO NEXT TABLE ENTRY BR 180$ ; AND LOOP 190$: CMP (R1)+,R3 ; RECORD LENGTH CORRECT? BNE 210$ ; IF NE NO, ERROR MOV #RECBUF,R3 ; SET UP ADDRESS OF DATA BUFFER CALL @(R1) ; CALL THE SERVICE ROUTINE INC NRECC ; ONE MORE TRANSACTION IS COUNTED BIT #LIMSK,MASKW ; /LI SWITCH SPECIFIED? BEQ 167$ ; IF EQ NO, LOOP CALL LISWT ; YES, LIST TRANSACTION IN OUTPUT FILE BR 167$ ; AND LOOP 200$: MOV #ERR5A,R0 ; GET ADDRESS FOR RECORD NUMBER MOV NRECT,R1 ; GET RECORD NUMBER CALL DE.CML ; CONVERT TO ASCII DECIMAL SUB #ERR5,R0 ; CALCULATE MESSAGE LENGTH PRINT #ERR5,R0 ; AND PRINT IT BR 167$ ; GET A NEW RECORD 210$: MOV #ERR6A,R0 ; MOV -(R1),-(SP) ; SAVE EXPECTED RECORD LENGTH MOV NRECT,R1 ; GET RECORD NUMBER CALL DE.CML ; CONVERT TO ASCII DECIMAL MOVSTR #ERR6B ; INSERT "EXPECTED=" TEXT MOV (SP)+,R1 ; RESTORE EXPECTED LENGTH CALL DE.CML ; FORMAT AS ASCII DECIMAL MOVSTR #ERR6C ; INSERT "ACTUAL=" TEXT MOV R3,R1 ; GET ACTUAL RECORD LENGTH CALL DE.CML ; FORMAT AS ASCII DECIMAL SUB #ERR6,R0 ; CALCULATE MESSAGE LENGTH PRINT #ERR6,R0 ; AND PRINT IT BR 167$ ; GET A NEW RECORD 230$: DEC NRECT ; REMOVE EOF RECORD FROM COUNT CALL $RFCLS ; MAKE SURE DATA FILE IS CLOSED ; ; HAVING COME TO THE END OF THE DATA FILE, WE USE THE DATE AND TIME ; CONTAINED IN THE LAST RECORD AS THE END OF THE PERIOD RECORDED IN ; THE FILE. ; MOV #TOTIM,R0 ; GET BUFFER ADDRESS FOR TIME MOV #RECBUF+F.TIME,R1 ; SET ADDRESS OF BINARY DATE/TIME BUFFER CALL DATTIM ; INSERT DATE AND TIME TST NRECC ; ANY RELEVANT DATA READ? BEQ 234$ ; IF EQ NO FILE #FROM,#FROMSZ ; PRINT THE DATES FOR THIS PERIOD FILE #TO,#TOSZ ; 234$: ; REF. LABEL ; ; PRINT THE TOTAL RECORD COUNT ; MOV #TOTRC1,R0 ; GET ADDRESS FOR TOTAL RECORD # MOV NRECT,R1 ; GET TOTAL RECORD COUNTER CALL DE.CML ; FORMAT AS DECIMAL MOVB #'/,(R0)+ ; INSERT A SLASH MOV NRECC,R1 ; GET COUNTED RECORD COUNTER CALL DE.CML ; FORMAT AS ASCII DECIMAL SUB #TOTREC,R0 ; CALCULATE MESSAGE LENGTH FILE #TOTREC,R0 ; WRITE TO OUTPUT FILE ; ; PRINT THE DYNAMIC MEMORY USAGE STATISTICS ; MOV #TOTDY1,R0 ; GET ADDRESS FOR DYNAMIC MEMORY DATA MOV INISIZ,R1 ; GET INITIAL SIZE OF DYNAMIC MEMORY CALL DE.CML ; FORMAT AS ASCII DECIMAL MOVB #'/,(R0)+ ; INSERT A SLASH CALL FRESIZ ; SIZE CURRENT FREE DYNAMIC MEMORY NEG R1 ; COMPUTE AMOUNT USED ADD INISIZ,R1 ; CALL DE.CML ; FORMAT AS ASCII DECIMAL SUB #TOTDYN,R0 ; CALCULATE MESSAGE LENGTH FILE #TOTDYN,R0 ; AND WRITE IT OUT ; ; PRINT OUT THE COMMAND LINE THAT WAS USED TO START RSU ; TST CMDLEN ; ANY COMMAND LINE? BEQ 239$ ; IF EQ NO FILE #CLINE1,#CLINE2 ; YES, PRINT IT MOVB #HT,CMDBUF-1 ; START WITH A TAB INC CMDLEN ; FILE #CMDBUF-1,CMDLEN ; 239$: ; REF. LABEL ; ; CHECK FOR NON-ZERO FILE CONTENTS ; TST NRECC ; DID WE GET ANY DATA? BNE 240$ ; IF NE YES PRINT #ERR7 ; GIVE USER A WARNING MESSAGE JMP EXSUC ; NO, JUST EXIT 240$: ; REF. LABEL ; ; NOW LOOP OVER ALL THE CONTROL BLOCKS AND CALCULATE THE TOTAL CHARGES. ; ; TOTAL CHARGE = CONNECT CHARGE + CPU CHARGE + I/O CHARGE + DISK CHARGE ; ; + MEMORY CHARGE + MASTER ACCUMULATION - REDIRECTED CHARGE VIA CHAIN. ; ; MOV #LISTHD,R5 ; GET LISTHEAD ADDRESS 250$: MOV (R5),R5 ; GET ADDRESS OF NEXT CONTROL BLOCK BEQ 260$ ; IF EQ, END OF LIST MOV R.CCON(R5),R.TCHG(R5) ; START WITH CONNECT CHARGE MOV R.CCON+2(R5),R.TCHG+2(R5) ; ADD R.CCPU+2(R5),R.TCHG+2(R5) ; ADD CPU CHARGES ADC R.TCHG(R5) ; ADD R.CCPU(R5),R.TCHG(R5) ; ADD R.CQIO+2(R5),R.TCHG+2(R5) ; ADD I/O CHARGE ADC R.TCHG(R5) ; ADD R.CQIO(R5),R.TCHG(R5) ; ADD R.DCHG+2(R5),R.TCHG+2(R5) ; ADD DISK CHARGES ADC R.TCHG(R5) ; ADD R.DCHG(R5),R.TCHG(R5) ; ADD R.CPAG+2(R5),R.TCHG+2(R5) ; ADD PAGE CHARGE ADC R.TCHG(R5) ; ADD R.CPAG(R5),R.TCHG(R5) ; ADD R.CMEM+2(R5),R.TCHG+2(R5) ; ADD MEMORY CHARGE ADC R.TCHG(R5) ; ADD R.CMEM(R5),R.TCHG(R5) ; ADD R.MCHG+2(R5),R.TCHG+2(R5) ; ADD MASTER ACCUMULATION ADC R.TCHG(R5) ; ADD R.MCHG(R5),R.TCHG(R5) ; SUB R.CCHG+2(R5),R.TCHG+2(R5) ; SUBTRACT REDIRECTED CHARGE SBC R.TCHG(R5) ; SUB R.CCHG(R5),R.TCHG(R5) ; BR 250$ ; DO NEXT CONTROL BLOCK 260$: ; REF. LABEL ; ; HAVING ACCUMULATED THE TOTAL CHARGE, WE REORDER THE CONTROL BLOCKS ; SO THAT THEY APPEAR IN TOTAL CHARGE ORDER (HIGHEST FIRST). THIS IS ; DONE BY MANIPULATION OF THE CONTROL BLOCK LINKAGES. ; *NOTE* THE SECOND WORD OF THE LISTHEAD AT LISTHD+2 WILL NOT BE VALID ; AFTER THE FOLLOWING SEQUENCE. ; 270$: CLR R5 ; SET NO ORDER CHANGES MADE MOV #LISTHD,R0 ; GET LISTHEAD ADDRESS 280$: MOV (R0),R1 ; GET ADDRESS OF NEXT CONTROL BLOCK BEQ 300$ ; IF EQ, END OF LIST MOV (R1),R2 ; GET ADDRESS OF FOLLOWING PACKET BEQ 300$ ; IF EQ THERE WASN'T ONE TO COMPARE WITH MOV ORDER(R1),R3 ; GET TOTAL CHARGES FOR THIS ENTRY MOV ORDER+2(R1),R4 ; SUB ORDER+2(R2),R4 ; SUBTRACT TOTAL CHARGE FOR FOLLOWING ENTRY SBC R3 ; SUB ORDER(R2),R3 ; BGE 290$ ; IF GE THEY WERE IN CORRECT MONEY ORDER INC R5 ; SHOW ONE CHANGE MADE MOV R2,(R0) ; FOLLOWING PACKET SHOULD APPEAR FIRST MOV (R2),(R1) ; CURRENT PACKET POINTS TO AFTER WHAT THE ; FOLLOWING PACKET ORIGINALLY POINTED TO MOV R1,(R2) ; FOLLOWING PACKET POINTS TO CURRENT PACKET 290$: MOV R1,R0 ; SET UP TO CONTINUE ALONG LIST BR 280$ ; AND LOOP 300$: TST R5 ; ANY CHANGES MADE? BGT 270$ ; IF GT, KEEP GOING UNTIL THERE ARE NONE ; ; NOW WE PROCESS THE CONTROL BLOCK LIST ENTRY BY ENTRY AND TYPE OUT A ; BRIEF SUMMARY FOR EACH USER, SUITABLE FOR HANGING ON THE WALL OR ; THROWING AWAY. ; FILE #HEADER,#HEADSZ ; WRITE TITLE TO OUTPUT FILE MOV #HEADER,TTLADR ; SHOW TITLE AVAILABLE MOV #HEADSZ,TTLSIZ ; MOV #3,TTLLIN ; (HEADER HAS 3 LINES) TSTB TTYFLG ; OUTPUT DEVICE A TERMINAL? BEQ 308$ ; IF EQ NO DIR$ #TIATT ; ATTACH OUTPUT TERMINAL 308$: MOV #LISTHD,R5 ; GET CONTROL BLOCK LISTHEAD ADDRESS 310$: MOV (R5),R5 ; GET ADDRESS OF NEXT BLOCK BEQ 320$ ; IF EQ, END OF LIST BIT #FUMSK,MASKW ; /FU SWITCH SPECIFIED? BEQ 314$ ; IF EQ NO, GO STRAIGHT TO LIST TSTB FUGRP ; GROUP CODE A WILD CARD? BEQ 312$ ; IF EQ YES, SKIP GROUP CODE CHECK CMP GROUP,R.GRP(R5) ; GROUP CODE MATCHES? BNE 310$ ; IF NE NO CMPB GROUP+2,R.GRP+2(R5) ; MAYBE BNE 310$ ; IF NE NO 312$: TSTB FUMEM ; MEMBER CODE A WILD CARD? BEQ 314$ ; IF EQ YES, GO STRAIGHT TO LIST CMPB MEMBER,R.MBR(R5) ; MEMBER CODE MATCHES? BNE 310$ ; IF NE NO CMP MEMBER+1,R.MBR+1(R5) ;MAYBE BNE 310$ ; IF NE NO 314$: BIT #NAMSK,MASKW ; /NA SWITCH SPECIFIED? BEQ 318$ ; IF EQ NO MOV R5,R0 ; YES, SET ADDRESS OF NAME FIELD IN BLOCK ADD #R.LNM,R0 ; MOV #NAME,R1 ; SET ADDRESS OF SPECIFIED NAME MOV #14.,R2 ; SET LENGTH TO COMPARE 316$: CMPB (R0)+,(R1)+ ; NAMES MATCH? BNE 310$ ; IF NE NO DEC R2 ; YES, MORE TO MATCH? BGT 316$ ; IF GT YES, LOOP 318$: CALL LISTB ; PROCESS THE INFORMATION (BRIEF FORMAT) BR 310$ ; DO THE NEXT USER 320$: TSTB TTYFLG ; OUTPUT DEVICE A TERMINAL? BEQ 3201$ ; IF EQ NO DIR$ #TIDET ; DETACH OUTPUT TERMINAL 3201$: CLR TTLSIZ ; TITLE NO LONGER AVAILABLE ; ; IF THE /SA SWITCH WAS SPECIFIED, THE SYSTEM USAGE FIELDS ARE SET UP ; AND THE USER USAGE FIELDS ARE CORRECTLY DECREMENTED. ; BIT #SAMSK,MASKW ; /SA SWITCH SPECIFIED? BEQ 32011$ ; IF EQ NO CALL GETSYS ; DETERMINE SYSTEM USAGE 32011$: ; REF. LABEL ; ; A SUMMARY OF THE TOTALS IS PRINTED IF /FU WAS OMITTED OR /FU WAS PRESENT ; WITH BOTH GROUP AND MEMBER CODES AS WILD CARDS. IF /NA WAS PRESENT, THE ; SUMMARY IS ALSO SKIPPED. ; BIT #NAMSK,MASKW ; /NA SWITCH PRESENT? BNE 3202$ ; IF NE YES, SKIP SUMMARIES BIT #FUMSK,MASKW ; /FU SWITCH PRESENT? BEQ 3203$ ; IF EQ NO, PRINT SUMMARIES TSTB FUGRP ; GROUP CODE A WILD CARD? BNE 3202$ ; IF NE NO, SKIP SUMMARIES TSTB FUMEM ; MEMBER CODE A WILD CARD? BEQ 3203$ ; IF EQ, [*,*] WAS SPECIFIED 3202$: JMP 3291$ ; SKIP TOTALS SUMMARY 3203$: ; REF. LABEL ; ; PRINT TOTAL CPU TIME AND CHARGE ; TSTB TTYFLG ; OUTPUT DEVICE A TERMINAL? BEQ 3210$ ; IF EQ NO DIR$ #TIATT ; ATTACH TI: 3210$: BIT #SAMSK,MASKW ; /SA SWITCH SPECIFIED? BNE 3211$ ; IF NE YES MOV #USRADR,R5 ; NO, POINT TO USAGE TABLE CALL PRTTAB ; TABULATE TOTAL CHARGES BR 3212$ ; 3211$: FILE #USRFLG,#USRFLS ; PRINT "TOTAL USER CHARGES" HEADING MOV #USRADR,R5 ; POINT TO USER TABLE CALL PRTTAB ; PRINT TOTAL USER USAGE DATA FILE #SYSFLG,#SYSFLS ; PRINT "TOTAL SYSTEM CHARGES" HEADING MOV #SYSADR,R5 ; POINT TO SYSTEM TABLE CALL PRTTAB ; PRINT TOTAL SYSTEM USAGE DATA 3212$: ; REF. LABEL ; ; PRINT TERMINAL USAGE STATISTICS TABLE ; TST TTSIZW ; ANY TERMINAL USAGE DATA? BEQ 329$ ; IF EQ NO FILE #TRMTAB,#TRMTSZ ; PRINT HEADING FOR TABLE MOV TTSIZ,R3 ; GET NUMBER OF ENTRIES IN TABLE MOV #-1,R4 ; INITIALISE TERMINAL NUMBER COUNTER MOV #TTTABL+2,R5 ; INITIALISE TABLE ADDRESS 321$: INC R4 ; POINT TO NEXT TERMINAL TST -2(R5) ; ANY ACTIVITY FOR THIS UNIT? BEQ 322$ ; IF EQ NO MOV #OUTBUF,R0 ; GET OUTPUT BUFFER ADDRESS MOVSTR #TTTEXT ; INSERT "TT" MOV R4,R1 ; GET TERMINAL NUMBER CALL OC.TAL ; FORMAT AS OCTAL MOVB #':,(R0)+ ; INSERT A COLON MOVB #HT,(R0)+ ; AND A TAB MOV R5,R1 ; POINT TO TOTAL CONNECT TIME CALL FTIME ; AND FORMAT IT MOV -2(R5),R1 ; GET NUMBER OF TERMINAL SESSIONS MOVB #HT,(R0)+ ; INSERT TWO TABS MOVB #HT,(R0)+ ; CALL DE.CML ; FORMAT AS ASCII DECIMAL SUB #OUTBUF,R0 ; CALCULATE MESSAGE LENGTH FILE #OUTBUF,R0 ; AND PRINT IT 322$: ADD #14.,R5 ; POINT TO NEXT ENTRY DEC R3 ; ANY MORE ENTRIES? BGT 321$ ; IF GT YES, LOOP 329$: TSTB TTYFLG ; OUTPUT DEVICE A TERMINAL? BEQ 3291$ ; IF EQ NO DIR$ #TIDET ; DETACH OUTPUT TERMINAL 3291$: ; REF. LABEL ; ; NOW PROCESS THE CONTROL BLOCK LIST AND PRODUCE A GROUP-BY-GROUP REPORT ; IF THE /GR SWITCH WAS SPECIFIED. ; BIT #GRMSK,MASKW ; /GR SWITCH SPECIFIED? BEQ 3300$ ; IF EQ NO CALL GRPREP ; PRODUCE A GROUP-BY-GROUP REPORT 3300$: ; REF. LABEL ; ; NOW WE PROCESS THE CONTROL BLOCK LIST ENTRY BY ENTRY AND TYPE OUT A ; FULL SUMMARY FOR EACH USER IF REQUESTED. ; BIT #FUMSK,MASKW ; FULL REPORT REQUIRED? BNE 330$ ; IF NE YES JMP EXSUC ; ELSE JUMP TO EXIT ROUTINE 330$: MOV #LISTHD,R5 ; GET CONTROL BLOCK LISTHEAD ADDRESS 340$: MOV (R5),R5 ; GET ADDRESS OF NEXT BLOCK BEQ 350$ ; IF EQ, END OF LIST TST R.NENT(R5) ; ANY ENTRIES FOR THIS ACCOUNT? BEQ 340$ ; IF EQ NO, SKIP TO NEXT ONE TSTB FUGRP ; GROUP CODE A WILD CARD? BEQ 3401$ ; IF EQ YES, SKIP GROUP CODE CHECK CMP GROUP,R.GRP(R5) ; GROUP CODE MATCHES? BNE 340$ ; IF NE NO CMPB GROUP+2,R.GRP+2(R5) ; MAYBE BNE 340$ ; IF NE NO 3401$: TSTB FUMEM ; MEMBER CODE A WILD CARD? BEQ 3402$ ; IF EQ YES, GO STRAIGHT TO LIST CMPB MEMBER,R.MBR(R5) ; MEMBER CODE MATCHES? BNE 340$ ; IF NE NO CMP MEMBER+1,R.MBR+1(R5) ;MAYBE BNE 340$ ; IF NE NO 3402$: BIT #NAMSK,MASKW ; /NA SWITCH SPECIFIED? BEQ 3404$ ; IF EQ NO MOV R5,R0 ; YES, SET ADDRESS OF NAME FIELD IN BLOCK ADD #R.LNM,R0 ; MOV #NAME,R1 ; SET ADDRESS OF SPECIFIED NAME MOV #14.,R2 ; SET LENGTH TO COMPARE 3403$: CMPB (R0)+,(R1)+ ; NAMES MATCH? BNE 340$ ; IF NE NO DEC R2 ; YES, MORE TO MATCH? BGT 3403$ ; IF GT YES, LOOP 3404$: TSTB TTYFLG ; OUTPUT DEVICE A TERMINAL? BEQ 342$ ; IF EQ NO DIR$ #TIATT ; ATTACH TI: 342$: CALL LISTF ; PROCESS THE INFORMATION (FULL FORMAT) TSTB TTYFLG ; BEQ 340$ ; DIR$ #TIDET ; DETACH TI: BR 340$ ; DO THE NEXT USER 350$: BR EXSUC ; AND EXIT EXSEV: DELET$ #OUTFDB ; DELETE OUTPUT FILE MOV #EX$SEV,-(SP) ; PUSH SEVERE ERROR EXIT STATUS BR EXSTAT ; EXSUC: BIT #SPMSK,MASKW ; SPOOL OUTPUT FILE? BEQ 390$ ; IF EQ NO PRINT$ #OUTFDB ; YES, PRINT IT BR 392$ ; 390$: CLOSE$ #OUTFDB ; CLOSE OUTPUT FILE 392$: MOV #OUTBUF,R0 ; GET OUTPUT BUFFER ADDRESS MOVSTR #NPAG1 ; INSERT "RSU -- " TEXT MOV PAGNUM,R1 ; GET PAGE NUMBER CALL DE.CML ; FORMAT AS ASCII DECIMAL MOVSTR #NPAG2 ; INSERT "PAGES IN REPORT" TEXT SUB #OUTBUF,R0 ; CALCULATE MESSAGE LENGTH PRINT #OUTBUF,R0 ; AND REPORT IT ON TI: MOV #EX$SUC,-(SP) ; PUSH SUCCESS EXIT STATUS EXSTAT: CALL $RFCLS ; CLOSE DATA FILE (IF OPEN) CALL $AFCLS ; AND A/C FILE (IF OPEN) EXST$S (SP)+ ; EXIT WITH RIGHT STATUS .PAGE .SBTTL INPUT ROUTINE ;+ ; *** INPUT ; ; THIS ROUTINE READS A LINE FROM THE INPUT FILE AND APPLIES THE ; /DA, /BE AND /AF SWITCHES IF NECESSARY. RECORDS ARE READ ; UNTIL ONE IS FOUND THAT MATCHES THE SPECIFIES DATE AND/OR UIC ; COMBINATION, OR UNTIL THE END OF FILE IS REACHED. ; ;- INPUT: CALL $RFGET ; READ A LINE OF INPUT INC NRECT ; SHOW ONE MORE RECORD READ MOV #$RFREC,R3 ; SET UP RECORD POINTER TST $RFLEN ; DID WE GET ANYTHING? BEQ 40$ ; IF EQ AN ERROR OCCURRED SO RETURN BIT #,MASKW ; ANY DATE SWITCHES? BEQ 30$ ; IF EQ NO, RETURN WITH THIS LINE ; ; PROCESS /DA SWITCH ; BIT #DAMSK,MASKW ; /DA SWITCH SPECIFIED? BEQ 10$ ; IF EQ NO CMP DADAY,F.TIME+G.TIDA(R3) ; RIGHT DAY? BNE INPUT ; IF NE NO, GO FOR ANOTHER ONE CMP DAMON,F.TIME+G.TIMO(R3) ; RIGHT MONTH? BNE INPUT ; IF NE NO CMP DAYR,F.TIME+G.TIYR(R3) ; RIGHT YEAR? BNE INPUT ; IF NE NO BR 30$ ; DATE CHECKS OUT, RETURN ; ; PROCESS /BE SWITCH ; 10$: BIT #BEMSK,MASKW ; /BE SWITCH SPECIFIED? BEQ 20$ ; IF EQ NO CMP BEYR,F.TIME+G.TIYR(R3) ; TRANSACTION <= SPECIFIED YEAR? BLT INPUT ; IF NE NO CMP BEMON,F.TIME+G.TIMO(R3) ; TRANSACTION <= SPECIFIED MONTH? BLT INPUT ; IF NE NO CMP BEDAY,F.TIME+G.TIDA(R3) ; TRANSACTION <= SPECIFIED DAY? BLT INPUT ; IF NE NO ; ; PROCESS /AF SWITCH ; 20$: BIT #AFMSK,MASKW ; /AF SWITCH SPECIFIED? BEQ 30$ ; IF EQ NO CMP AFYR,F.TIME+G.TIYR(R3) ; TRANSACTION >= SPECIFIED YEAR? BGT INPUT ; IF GT NO CMP AFMON,F.TIME+G.TIMO(R3) ; TRANSACTION >= SPECIFIED MONTH? BGT INPUT ; IF GT NO CMP AFDAY,F.TIME+G.TIDA(R3) ; TRANSACTION >= SPECIFIED DAY? BGT INPUT ; IF GT NO 30$: MOV $RFLEN,R2 ; GET RECORD LENGTH IN BYTES BEQ 40$ ; IF EQ NOTHING WAS READ INC R2 ; JUST IN CASE IT IS ODD ASR R2 ; CONVERT TO WORDS MOV #RECBUF,R0 ; GET ADDRESS OF BUFFER COPY MOV R3,R1 ; SET ADDRESS OF INPUT BUFFER CALL CO.PYW ; TRANSFER TO LOCAL BUFFER 40$: RETURN ; RETURN TO CALLER .PAGE .SBTTL SERVICE ROUTINE - BYE COMMAND ;+ ; *** BYESUB ; ; THIS ROUTINE IS CALLED TO PROCESS ACCOUNTING DATA WRITTEN BY THE ; BYE COMMAND. ; ; INPUT: ; R3 DATA BUFFER ADDRESS ; ;- BYESUB: ADD F.CPU+2(R3),USRCPU+2 ; UPDATE TOTAL CPU TIME ADC USRCPU ; ADD F.CPU(R3),USRCPU ; ADD F.CPU+6(R3),USRCPU+6 ; UPDATE TOTAL CPU CHARGE ADC USRCPU+4 ; ADD F.CPU+4(R3),USRCPU+4 ; ADD F.PAGE+2(R3),USRPAG+2 ; UPDATE TOTAL PAGES PRINTED ADC USRPAG ; ADD F.PAGE+6(R3),USRPAG+6 ; UPDATE TOTAL PAGE CHARGE ADC USRPAG+4 ; ADD F.PAGE+4(R3),USRPAG+4 ; ADD F.CORE+2(R3),USRMEM+2 ; UPDATE TOTAL MEMORY USAGE ADC USRMEM ; ADD F.CORE(R3),USRMEM ; ADD F.CORE+6(R3),USRMEM+6 ; UPDATE TOTAL MEMORY CHARGE ADC USRMEM+4 ; ADD F.CORE+4(R3),USRMEM+4 ; ADD F.QIO+2(R3),USRQIO+2 ; UPDATE TOTAL I/O COUNT ADC USRQIO ; ADD F.QIO(R3),USRQIO ; ADD F.QIO+6(R3),USRQIO+6 ; UPDATE TOTAL I/O CHARGE ADC USRQIO+4 ; ADD F.QIO+4(R3),USRQIO ; MOV F.ACNO(R3),R4 ; GET ACCOUNT NUMBER CALL SEARCH ; LOCATE CONTROL BLOCK INC R.NENT(R5) ; SHOW ONE MORE ENTRY MOV F.DEVU(R3),R1 ; GET DEVICE NUMBER .IF DF AA$BAT CMP F.DEVN(R3),#"TT ; INTERACTIVE TERMINAL? BNE 10$ ; IF NE NO, MUST BE BATCH JOB .IFTF ADD F.CONN+2(R3),USRCON+2 ; UPDATE TOTAL CONNECT TIME ADC USRCON ; ADD F.CONN(R3),USRCON ; ADD F.CONN+6(R3),USRCON+6 ; UPDATE TOTAL CONNECT CHARGE ADC USRCON+4 ; ADD F.CONN+4(R3),USRCON+4 ; INC R.NTRM(R5) ; UPDATE NUMBER OF TERMINAL SESSIONS TST TTSIZ ; ANY TABLE SPACE? BEQ 30$ ; IF EQ NO, SKIP IT CMP TTSIZ,R1 ; TABLE LARGE ENOUGH? BLT 30$ ; IF LT NO, SKIP IT CALL INDEX ; CALCULATE TABLE INDEX ADD #TTTABL,R1 ; INDEX INTO TABLE .IFT BR 20$ ; UPDATE TABLE ENTRY 10$: INC R.NJOB(R5) ; UPDATE NUMBER OF BATCH JOBS TST VTSIZ ; ANY BATCH TABLE SPACE? BEQ 35$ ; IF EQ NO, SKIP IT CMP VTSIZ,R1 ; BATCH TABLE LARGE ENOUGH? BLT 35$ ; IF LT NO, SKIP IT CALL INDEX ; CALCULATE TABLE INDEX ADD #VTTABL,R1 ; INDEX INTO TABLE .IFTF 20$: INC (R1)+ ; INCREMENT NUMBER OF SESSIONS/JOBS ADD F.CONN+2(R3),2(R1) ; ADD IN CONNECT TIME ADC (R1) ; ADD F.CONN(R3),(R1)+ ; CMP (R1)+,(R1)+ ; MOVE UP THE TABLE A BIT ADD F.CPU+2(R3),(R1) ; ADD IN CPU TIME ADC -(R1) ; ADD F.CPU(R3),(R1)+ ; CMP (R1)+,(R1)+ ; MOVE UP THE TABLE A BIT ADD F.QIO+2(R3),(R1) ; ADD IN I/O REQUESTS ADC -(R1) ; ADD F.QIO(R3),(R1) ; 30$: ; REF. LABEL .IFT CMP F.DEVN(R3),#"TT ; INTERACTIVE TERMINAL SESSION? BNE 35$ ; IF NE NO, DON'T COUNT CONNECT .ENDC ; DF AA$BAT ADD F.CONN+2(R3),R.TCON+2(R5) ; ADD IN CONNECT TIME ADC R.TCON(R5) ; ADD F.CONN(R3),R.TCON(R5) ; ADD F.CONN+6(R3),R.CCON+2(R5) ; ADD IN CONNECT CHARGE ADC R.CCON(R5) ; ADD F.CONN+4(R3),R.CCON(R5) ; 35$: ADD F.CPU+2(R3),R.TCPU+2(R5) ; ADD IN CPU TIME ADC R.TCPU(R5) ; ADD F.CPU(R3),R.TCPU(R5) ; ADD F.CPU+6(R3),R.CCPU+2(R5) ; ADD IN CPU CHARGE ADC R.CCPU(R5) ; ADD F.CPU+4(R3),R.CCPU(R5) ; ADD F.QIO+2(R3),R.TQIO+2(R5) ; ADD IN I/O REQUEST COUNT ADC R.TQIO(R5) ; ADD F.QIO(R3),R.TQIO(R5) ; ADD F.QIO+6(R3),R.CQIO+2(R5) ; ADD IN I/O CHARGE ADC R.CQIO(R5) ; ADD F.QIO+4(R3),R.CQIO(R5) ; ADD F.PAGE+2(R3),R.TPAG+2(R5) ; ADD IN PAGES PRINTED ADC R.TPAG(R5) ; ADD F.PAGE+6(R3),R.CPAG+2(R5) ; ADD IN PAGE CHARGE ADC R.CPAG(R5) ; ADD F.PAGE+4(R3),R.CPAG(R5) ; ADD F.CORE+2(R3),R.TMEM+2(R5) ; ADD IN MEMORY USAGE ADC R.TMEM(R5) ; ADD F.CORE(R3),R.TMEM(R5) ; ADD F.CORE+6(R3),R.CMEM+2(R5) ; ADD IN MEMORY CHARGE ADC R.CMEM(R5) ; ADD F.CORE+4(R3),R.CMEM(R5) ; MOV F.CHWD(R3),R4 ; WAS THE ACCOUNT CHAINED? BEQ 40$ ; IF EQ NO, THAT'S IT ADD #R.CCHG,R5 ; POINT TO FIELD WHERE REDIRECTED ; CHARGES ARE ACCUMULATED CALL 50$ ; AND ADD THEM IN CALL SEARCH ; LOCATE THE MASTER ACCOUNT BIT #MAMSK,MASKW ; /MA SWITCH SPECIFIED? BEQ 39$ ; IF EQ NO CALL 45$ ; ADD IN IF /MA 39$: INC R.NENT(R5) ; SHOW ONE MORE ENTRY ADD #R.MCHG,R5 ; POINT TO FIELD WHERE CHARGES GAINED ; BY A MASTER ARE ACCUMULATED CALL 50$ ; AND ADD THEM IN 40$: RETURN ; THEN RETURN FOR NEXT RECORD ;+ ; ; THIS SUBROUTINE IS CALLED ONLY IF /MA IS USED. ALL TIME (AS ; WELL AS CHARGES) ARE ADDED TO THE ENTRY FOR THE MASTER ; ACCOUNT, SINCE CHAINED ACCOUNTS ARE NOT LISTED. ; ;- 45$: ; .IF DF AA$BAT CMP F.DEVN(R3),#"TT ; INTERACTIVE TERMINAL? BNE 46$ ; IF NE NO, DON'T ADD CONNECT TIME .ENDC ; DF AA$BAT ADD F.CONN+2(R3),R.TCON+2(R5) ; ADD IN CONNECT TIME ADC R.TCON(R5) ; ADD F.CONN(R3),R.TCON(R5) ; 46$: ADD F.CPU+2(R3),R.TCPU+2(R5) ; ADD IN CPU TIME ADC R.TCPU(R5) ; ADD F.CPU(R3),R.TCPU(R5) ; ADD F.QIO+2(R3),R.TQIO+2(R5) ; ADD IN I/O REQUESTS ADC R.TQIO(R5) ; ADD F.QIO(R3),R.TQIO(R5) ; ADD F.PAGE+2(R3),R.TPAG+2(R5) ; ADD IN PAGES PRINTED ADC R.TPAG(R5) ; ADD F.PAGE(R3),R.TPAG(R5) ; ADD F.CORE+2(R3),R.TMEM+2(R5) ; ADD IN MEMORY USAGE ADC R.TMEM(R5) ; ADD F.CORE(R3),R.TMEM(R5) ; RETURN ; THEN RETURN TO BYESUB ;+ ; ; THIS SUBROUTINE IS CALLED FOR CHAINED ACCOUNTS, AND ADDS THE ; RELEVANT CHARGES TO THE MASTER ENTRY. ; ;- 50$: ADD F.CONN+6(R3),2(R5) ; SHOW REDIRECTED CHARGE... ADC (R5) ; ...FOR CONNECT TIME ADD F.CONN+4(R3),(R5) ; ADD F.CPU+6(R3),2(R5) ; ...FOR CPU TIME... ADC (R5) ; ADD F.CPU+4(R3),(R5) ; ADD F.QIO+6(R3),2(R5) ; ...FOR I/O REQUESTS... ADC (R5) ; ADD F.QIO+4(R3),(R5) ; ADD F.PAGE+6(R3),2(R5) ; ...FOR PAGES PRINTED ADC (R5) ; ADD F.PAGE+4(R3),(R5) ; ADD F.CORE+6(R3),2(R5) ; ...FOR MEMORY USAGE ADC (R5) ; ADD F.CORE+4(R3),(R5) ; RETURN ; THEN RETURN TO BYESUB .PAGE .SBTTL SERVICE ROUTINE - DISK ACCOUNTING ;+ ; *** DSKSUB ; ; THIS ROUTINE IS CALLED TO PROCESS ACCOUNTING DATA WRITTEN ; BY THE DISK ACCOUNTING PROGRAM DSK... ; NOTE THAT THE R.NENT FIELD IS NOT INCREMENTED FOR THE ACCOUNT ; SO THAT THIS ACCOUNT MAY NOT ; APPEAR IN A FULL LISTING IF IT DID NOTHING ELSE. ; ;- DSKSUB: ADD F.DCHG+2(R3),USRDSK+6 ; UPDATE TOTAL DISK CHARGES ADC USRDSK+4 ; ADD F.DCHG(R3),USRDSK+4 ; MOV F.ACNO(R3),R4 ; GET ACCOUNT NUMBER CALL SEARCH ; LOCATE CONTROL BLOCK ADD F.DCHG+2(R3),R.DCHG+2(R5) ; UPDATE DISK CHARGES ADC R.DCHG(R5) ; ADD F.DCHG(R3),R.DCHG(R5) ; MOV F.CHWD(R3),R4 ; WAS THE ACCOUNT CHAINED? BEQ 10$ ; IF EQ NO ADD F.DCHG+2(R3),R.CCHG+2(R5) ; YES, SHOW THAT CHARGES WERE ; REDIRECTED ADC R.CCHG(R5) ; ADD F.DCHG(R3),R.CCHG(R5) ; CALL SEARCH ; LOCATE THE MASTER ACCOUNT INC R.NENT(R5) ; SHOW ONE MORE ENTRY FOR THIS A/C ADD F.DCHG+2(R3),R.MCHG+2(R5) ; SHOW CHARGES GAINED AS MASTER ADC R.MCHG(R5) ; ADD F.DCHG(R3),R.MCHG(R5) ; 10$: RETURN ; RETURN FOR NEXT DATA RECORD .PAGE .SBTTL SERVICE ROUTINE - AUXILIARY LOGGING ;+ ; *** ALTSUB ; ; THIS ROUTINE IS CALLED TO PROCESS AN ACCOUNTING DATA ENTRY ; THAT WAS WRITTEN BY THE AUXILIARY LOGGING TASK ALT... ; ; ;- ALTSUB: ADD F.CPU+2(R3),USRCPU+2 ; UPDATE TOTAL CPU TIME ADC USRCPU ; ADD F.CPU(R3),USRCPU ; ADD F.CPU+6(R3),USRCPU+6 ; UPDATE TOTAL CPU CHARGE ADC USRCPU+4 ; ADD F.CPU+4(R3),USRCPU+4 ; ADD F.CORE+2(R3),USRMEM+2 ; UPDATE TOTAL MEMORY USAGE ADC USRMEM ; ADD F.CORE(R3),USRMEM ; ADD F.CORE+6(R3),USRMEM+6 ; UPDATE TOTAL MEMORY CHARGE ADC USRMEM+4 ; ADD F.CORE+4(R3),USRMEM+4 ; ADD F.QIO+2(R3),USRQIO+2 ; UPDATE TOTAL I/O COUNT ADC USRQIO ; ADD F.QIO(R3),USRQIO ; ADD F.QIO+6(R3),USRQIO+6 ; UPDATE TOTAL I/O CHARGE ADC USRQIO+4 ; ADD F.QIO+4(R3),USRQIO+4 ; MOV F.ACNO(R3),R4 ; GET ACCOUNT NUMBER CALL SEARCH ; LOCATE CONTROL BLOCK INC R.NENT(R5) ; SHOW ONE MORE ENTRY ADD F.CPU+2(R3),R.TCPU+2(R5) ; ADD IN CPU TIME ADC R.TCPU(R5) ; ADD F.CPU(R3),R.TCPU(R5) ; ADD F.CPU+6(R3),R.CCPU+2(R5) ; ADD IN CPU CHARGE ADC R.CCPU(R5) ; ADD F.CPU+4(R3),R.CCPU(R5) ; ADD F.QIO+2(R3),R.TQIO+2(R5) ; ADD IN I/O REQUEST COUNT ADC R.TQIO(R5) ; ADD F.QIO(R3),R.TQIO(R5) ; ADD F.QIO+6(R3),R.CQIO+2(R5) ; ADD IN I/O CHARGE ADC R.CQIO(R5) ; ADD F.QIO+4(R3),R.CQIO(R5) ; ADD F.CORE+2(R3),R.TMEM+2(R5) ; ADD IN MEMORY USAGE ADC R.TMEM(R5) ; ADD F.CORE(R3),R.TMEM(R5) ; ADD F.CORE+6(R3),R.CMEM+2(R5) ; ADD IN MEMORY CHARGE ADC R.CMEM(R5) ; ADD F.CORE+4(R3),R.CMEM(R5) ; MOV F.CHWD(R3),R4 ; WAS THE ACCOUNT CHAINED? BEQ 10$ ; IF EQ NO ADD #R.CCHG,R5 ; POINT TO REDIRECTED CHARGE FIELD CALL 20$ ; ADD COST OF THIS TRANSACTION CALL SEARCH ; LOCATE MASTER CONTROL BLOCK ADD #R.MCHG,R5 ; POINT TO ACCUMULATED CHARGE FIELD CALL 20$ ; AND ADD THEM IN 10$: RETURN ; RETURN FOR NEXT DATA RECORD 20$: ADD F.CPU+6(R3),2(R5) ; ADD IN CPU CHARGE ADC (R5) ; ADD F.CPU+4(R3),(R5) ; ADD F.QIO+6(R3),2(R5) ; ADD IN I/O CHARGE ADC (R5) ; ADD F.QIO+4(R3),(R5) ; ADD F.CORE+6(R3),2(R5) ; ADD IN MEMORY CHARGE ADC (R5) ; ADD F.CORE+4(R3),(R5) ; RETURN ; RETURN TO SERVICE ROUTINE .PAGE .SBTTL SERVICE ROUTINE - PAGE PRINTS FROM ALT... ;+ ; *** PAGSUB ; ; THIS ROUTINE IS CALLED TO PROCESS A PAGE PRINT REQUEST THAT WAS ; WRITTEN BY ALT... WHEN THE USER WAS NOT LOGGED ON. ; ;- PAGSUB: ADD F.PAGE+2(R3),USRPAG+2 ; UPDATE TOTAL PAGES PRINTED ADC USRPAG ; ADD F.PAGE+6(R3),USRPAG+6 ; UPDATE TOTAL PAGE CHARGE ADC USRPAG+4 ; ADD F.PAGE+4(R3),USRPAG+4 ; MOV F.ACNO(R3),R4 ; GET ACCOUNT NUMBER CALL SEARCH ; LOCATE THE CONTROL BLOCK INC R.NENT(R5) ; SHOW ONE MORE ENTRY ADD F.PAGE+2(R3),R.TPAG+2(R5) ; ADD IN PAGES PRINTED ADC R.TPAG(R5) ; ADD F.PAGE+6(R3),R.CPAG+2(R5) ; ADD IN PAGE CHARGE ADC R.CPAG(R5) ; ADD F.PAGE+4(R3),R.CPAG(R5) ; MOV F.CHWD(R3),R4 ; WAS THE ACCOUNT CHAINED? BEQ 10$ ; IF EQ NO ADD F.PAGE+6(R3),R.CCHG+2(R5) ; SHOW REDIRECTED CHARGE ADC R.CCHG(R5) ; ADD F.PAGE+4(R3),R.CCHG(R5) ; CALL SEARCH ; LOCATE MASTER'S CONTROL BLOCK INC R.NENT(R5) ; ONE MORE ENTRY IN TOTAL ADD F.PAGE+6(R3),R.MCHG+2(R5) ; SHOW CHARGES GAINED ADC R.MCHG(R5) ; ADD F.PAGE+4(R3),R.MCHG(R5) ; 10$: RETURN ; RETURN TO CALLER .PAGE .SBTTL SERVICE ROUTINE - MACNT OPTIONS ;+ ; *** SETSUB SERVICE MACNT "S" COMMAND ; *** UPDSUB SERVICE MACNT "U" COMMAND ; *** BLKSUB SERVICE MACNT "B" COMMAND ; *** MMASUB SERVICE MACNT "A" COMMAND ; *** CHASUB SERVICE MACNT "C" COMMAND ; *** MASSUB SERVICE MACNT "M" COMMAND ; *** DMSSUB SERVICE MACNT "N" COMMAND ; ; THE DATA RECORD WRITTEN BY THESE OPTIONS IS LINKED INTO ; THE LISTS RESIDING IN EACH CONTROL BLOCK FOR THE RELEVANT ; ACCOUNTS. ; ; INPUT: ; R3 DATA RECORD ADDRESS ; ;- SETSUB: ; FALL THROUGH TO COMMON CODE UPDSUB: ; BLKSUB: ; MMASUB: ; CHASUB: ; MASSUB: ; DMSSUB: ; MOV F.ACNO(R3),R4 ; GET ACCOUNT NUMBER CALL SEARCH ; LOCATE ACCOUNT ENTRY INC R.NENT(R5) ; SHOW ONE MORE ENTRY CALL SUPPL ; ALLOCATE/LINK SUPPLEMENTARY BLOCK CALL FILSUP ; COPY DATA TO IT 10$: MOV F.CHWD(R3),R4 ; ACCOUNT CHAINED? BEQ 20$ ; IF EQ NO CALL SEARCH ; YES, LOCATE THE ENTRY CALL SUPPL ; REPEAT ABOVE OPERATION CALL FILSUP ; 20$: RETURN .PAGE .SBTTL ROUTINE TO PRODUCE GROUP-BY-GROUP SUMMARIES ;+ ; *** GRPREP ; ; THIS ROUTINE PRODUCES A GROUP-BY-GROUP SUMMARY FOR ALL ; THE ACCOUNTS. ; ;- GRPREP: TSTB TTYFLG ; OUTPUT DEVICE A TERMINAL? BEQ 5$ ; IF EQ NO DIR$ #TIATT ; YES, ATTACH 5$: CALL NXTGRP ; GET THE NEXT GROUP TO EXAMINE BCS 20$ ; IF CS NO MORE GROUPS 10$: CALL NXTUSR ; GET THE NEXT USER IN THIS GROUP BCS 15$ ; IF CS THERE AREN'T ANY MORE CALL LISTB ; SHOW DETAILS FOR THIS USER BR 10$ ; REPEAT FOR NEXT USER 15$: MOV #OUTBUF,R0 ; GET OUTPUT BUFFER ADDRESS MOVSTR #ALLCHG ; START WITH "TOTAL CHARGES" TEXT MOV #GRPTOT,R1 ; POINT TO TOTAL CHARGES CALL FMONEY ; AND FORMAT IT SUB #OUTBUF,R0 ; PRINT RESULT FILE #OUTBUF,R0 ; BR 5$ ; DO NEXT GROUP 20$: TSTB TTYFLG ; OUTPUT DEVICE A TERMINAL? BEQ 30$ ; IF EQ NO DIR$ #TIDET ; YES, DETACH 30$: RETURN ; RETURN TO CALLER .PAGE .SBTTL ROUTINE TO GET NEXT GROUP FOR /GR REPORT ;+ ; *** NXTGRP ; ; THIS ROUTINE SCANS THE CONTROL BLOCK LIST AND OBTAINS THE NEXT ; GROUP FOR REPORTING. THIS IS OBTAINED FROM THE R.GRP ; FIELD OF THE FIRST CONTROL BLOCK FOUND THAT HAS BIT RR.GRP ; CLEAR IN WORD R.FLAG. ; ; OUTPUT: ; CARRY SET -- ALL GROUPS HAVE BEEN PROCESSED ; CARRY CLEAR GRGRP HAS BEEN SET UP WITH THE GROUP ; CODE ;- NXTGRP: CLR TTLSIZ ; SHOW NO PAGE TITLE AVAILABLE MOV #LISTHD,R5 ; GET CONTROL BLOCK LIST ADDRESS 10$: MOV (R5),R5 ; GET ADDRESS OF NEXT ENTRY BEQ 20$ ; IF EQ, NONE LEFT BIT #RR.GRP,R.FLAG(R5) ; ALREADY PROCESSED? BNE 10$ ; IF NE YES, SKIP IT MOVB R.GRP(R5),GRGRP ; SAVE GROUP CODE MOVB R.GRP+1(R5),GRGRP+1 ; MOVB R.GRP+2(R5),GRGRP+2 ; FILE #GRPMS1,#GRP1SZ ; WRITE TITLE TO OUTPUT FILE FILE #GRPMS2,#GRP2SZ ; FILE #FROM,#FROMSZ ; WITH TIMES AND DATES FILE #TO,#TOSZ ; FILE #HEADER,#HEADSZ ; WRITE COLUMN HEADINGS MOV #HEADER,TTLADR ; SHOW HEADINGS AVAILABLE... MOV #HEADSZ,TTLSIZ ; ...AT TOP OF NEXT PAGE MOV #3,TTLLIN ; (HEADER HAS 3 LINES) CLR GRPTOT ; ZERO TOTAL GROUP CHARGES CLR GRPTOT+2 ; BIS #RR.GRP,R.FLAG(R5) ; SHOW THIS GROUP PROCESSED CLC ; SET SUCCESS BR 30$ ; 20$: SEC ; SHOW NO MORE GROUPS LEFT 30$: RETURN ; RETURN TO CALLER .PAGE .SBTTL ROUTINE TO FIND NEXT USER FOR /GR PROCESSING ;+ ; *** NXTUSR ; ; THIS ROUTINE SCANS THE CONTROL BLOCK LIST AND FINDS THE NEXT USER ; WHO HAS A GROUP CODE EQUAL TO "GRGRP" AND BIT RR.USR CLEAR IN ; THE FLAG WORD AT OFFSET R.FLAG. ; ; OUTPUT: ; R5 USER'S CONTROL BLOCK ADDRESS ; ;- NXTUSR: MOV #LISTHD,R5 ; GET CONTROL BLOCK LIST ADDRESS 10$: MOV (R5),R5 ; GET ADDRESS OF NEXT ENTRY BEQ 20$ ; IF EQ NONE LEFT CMPB GRGRP,R.GRP(R5) ; THIS A/C IN CURRENT GROUP? BNE 10$ ; IF NE NO CMPB GRGRP+1,R.GRP+1(R5) ; MAYBE BNE 10$ ; IF NE NO CMPB GRGRP+2,R.GRP+2(R5) ; MAYBE BNE 10$ ; IF NE NO BIT #RR.USR,R.FLAG(R5) ; THIS ENTRY BEEN DONE YET? BNE 10$ ; IF NE YES, SKIP IT BIS #,R.FLAG(R5) ; SHOW THIS ENTRY PROCESSED CLC ; SHOW ENTRY FOUND BR 30$ ; 20$: SEC ; SHOW NO ENTRIES LEFT 30$: RETURN ; RETURN TO CALLER .PAGE .SBTTL ROUTINE TO DETERMINE SYSTEM USAGE ;+ ; *** GETSYS ; ; THIS ROUTINE IS CALLED IF THE /SA SWITCH WAS USED. IF THE ACCOUNT ; NUMBER MATCHES ONE OF THE VALUES GIVEN WITH /SA, THE ACCOUNT IS ; CONSIDERED TO BE A SYSTEM ACCOUNT. IN THIS CASE, THE TOTAL ; CHARGES ARE ADDED TO THE SYSTEM USAGE FIELDS AND SUBTRACTED ; FROM THE USER USAGE FIELDS. ACCOUNT HAS TO BE TAKEN OF THE ; PRESENCE OR ABSENCE OF THE /MA SWITCH. ; ; SUPPLEMENTARY ROUTINES ARE: ; ; SAMATC - CHECK FOR MATCH WITH /SA ACCOUNT NUMBER ; UPDUSR - SUBTRACT CURRENT FROM USER TOTALS ; UPDSYS - ADD CURRENT TO SYSTEM TOTALS ;- GETSYS: MOV #LISTHD,R5 ; GET CONTROL BLOCK LISTHEAD ADDRESS 10$: MOV (R5),R5 ; GET ADDRESS OF NEXT BLOCK BEQ 40$ ; IF EQ, END OF LIST CLR R3 ; ASSUME MEMBER CHARGE FIELDS NOT NEEDED MOV R.CHWD(R5),R1 ; ACCOUNT CHAINED? BEQ 20$ ; IF EQ NO BIT #MAMSK,MASKW ; YES, /MA ALSO GIVEN? BEQ 11$ ; IF EQ NO INC R3 ; SHOW MEMBER CHARGES ONLY NEEDED 11$: CALL SAMATC ; NUMBER IN /SA LIST? BCC 30$ ; IF CC YES MOV R.ACNO(R5),R1 ; NO, TRY REAL A/C NUMBER CALL SAMATC ; NUMBER IN /SA LIST? BCS 10$ ; IF CS NO BR 30$ ; CHECK FOR MATCH WITH /SA 20$: MOV R.ACNO(R5),R1 ; GET ACCOUNT NUMBER BIC #100000,R1 ; CLEAR MASTER FLAG IF SET CALL SAMATC ; CHECK FOR /SA MATCH BCS 10$ ; IF CS NO, TRY NEXT USER 30$: CALL UPDSYS ; MATCH OK: ADD TO SYSTEM TIME CALL UPDUSR ; MATCH OK: SUBTRACT FROM USER TIME BR 10$ ; LOOP 40$: RETURN ; RETURN TO CALLER ;+ ; *** SAMATC ; ; THIS ROUTINE CHECKS TO SEE IF A SPECIFIED ACCOUNT NUMBER ; IS IN THE LIST GIVEN WITH THE /SA SWITCH. ; ; INPUTS: ; R1 ACCOUNT NUMBER TO CHECK WTH /SA ; ; OUTPUTS: ; CC YES; A/C NUMBER IS IN THE LIST ; CS NO; A/C NUMBER NOT IN LIST ; ;- SAMATC: MOV #SANUM1,R0 ; SET ADDRESS OF FIRST /SA VALUE MOV #6,R2 ; GET NUMBER OF /SA VALUES 10$: CMP (R0)+,R1 ; ACCOUNT NUMBER MATCHES? BEQ 20$ ; IF EQ YES DEC R2 ; NO, ANY MORE TO CHECK? BGT 10$ ; IF GT YES, LOOP SEC ; NO MATCH BR 30$ ; 20$: CLC ; MATCH 30$: RETURN ; ;+ ; *** UPDUSR ; ; IF THE /SA SWITCH IS SPECIFIED, THIS ROUTINE SUBTRACTS THE ; USAGES AND CHARGES FOR AN ACCOUNT FROM THE USER TOTALS. ; ; INPUT: ; R3 CONTROL FLAG: ; R3.EQ.0 --> INCLUDE BOTH USAGES AND CHARGES ; R3.NE.0 --> INCLUDE ONLY CHARGES ; R5 CONTROL BLOCK ADDRESS ;- UPDUSR: TST R3 ; INCLUDE ONLY CHARGES? BNE 10$ ; IF NE YES SUB R.TCPU+2(R5),USRCPU+2 ; DECREMENT TOTAL USER CPU TIME SBC USRCPU ; SUB R.TCPU(R5),USRCPU ; SUB R.TCON+2(R5),USRCON+2 ; DECREMENT TOTAL USER CONNECT TIME SBC USRCON ; SUB R.TCON(R5),USRCON ; SUB R.TPAG+2(R5),USRPAG+2 ; DECREMENT TOTAL USER PAGES PRINTED SBC USRPAG ; SUB R.TMEM+2(R5),USRMEM+2 ; DECREMENT TOTAL USER MEMORY USAGE SBC USRMEM ; SUB R.TMEM(R5),USRMEM ; SUB R.TQIO+2(R5),USRQIO+2 ; DECREMENT TOTAL USER I/O COUNT SBC USRQIO ; SUB R.TQIO(R5),USRQIO ; 10$: SUB R.CCPU+2(R5),USRCPU+6 ; DECREMENT TOTAL USER CPU CHARGE SBC USRCPU+4 ; SUB R.CCPU(R5),USRCPU+4 ; SUB R.CCON+2(R5),USRCON+6 ; DECREMENT TOTAL USER CONNECT CHARGE SBC USRCON+4 ; SUB R.CCON(R5),USRCON+4 ; SUB R.DCHG+2(R5),USRDSK+6 ; DECREMENT TOTAL USER DISK CHARGE SBC USRDSK+4 ; SUB R.DCHG(R5),USRDSK+4 ; SUB R.CPAG+2(R5),USRPAG+6 ; DECREMENT TOTAL USER PAGE CHARGE SBC USRPAG+4 ; SUB R.CPAG(R5),USRPAG+4 ; SUB R.CMEM+2(R5),USRMEM+6 ; DECREMENT TOTAL USER MEMORY CHARGE SBC USRMEM+4 ; SUB R.CMEM(R5),USRMEM+4 ; SUB R.CQIO+2(R5),USRQIO+6 ; DECREMENT TOTAL USER I/O CHARGE SBC USRQIO+4 ; SUB R.CQIO(R5),USRQIO+4 ; RETURN ; RETURN TO CALLER ;+ ; *** UPDSYS ; ; THIS ROUTINE IS CALLED IF THE /SA SWITCH WAS SPECIFIED. THE ; USAGES AND CHARGES FOR A GIVEN ACCOUNT (WHICH HAS BEEN ; CONSIDERED AS A SYSTEM ACCOUNT) ARE ADDED TO THE SYSTEM ; USAGE TOTALS. ; ; INPUTS: ; R3 CONTROL FLAG: ; R3.EQ.0 --> INCLUDE BOTH USAGES AND CHARGES ; R3.NE.0 --> INCLUDE ONLY CHARGES ; R5 CONTROL BLOCK ADDRESS ; ;- UPDSYS: TST R3 ; INCLUDE ONLY CHARGES? BNE 10$ ; IF NE YES ADD R.TCPU+2(R5),SYSCPU+2 ; UPDATE TOTAL SYSTEM CPU TIME ADC SYSCPU ; ADD R.TCPU(R5),SYSCPU ; ADD R.TCON+2(R5),SYSCON+2 ; UPDATE TOTAL SYSTEM CONNECT TIME ADC SYSCON ; ADD R.TCON(R5),SYSCON ; ADD R.TPAG+2(R5),SYSPAG+2 ; UPDATE TOTAL SYSTEM PAGES PRINTED ADC SYSPAG ; ADD R.TMEM+2(R5),SYSMEM+2 ; UPDATE TOTAL SYSTEM MEMORY USAGE ADC SYSMEM ; ADD R.TMEM(R5),SYSMEM ; ADD R.TQIO+2(R5),SYSQIO+2 ; UPDATE TOTAL SYSTEM I/O COUNT ADC SYSQIO ; ADD R.TQIO(R5),SYSQIO ; 10$: ADD R.CCPU+2(R5),SYSCPU+6 ; UPDATE TOTAL SYSTEM CPU CHARGE ADC SYSCPU+4 ; ADD R.CCPU(R5),SYSCPU+4 ; ADD R.CCON+2(R5),SYSCON+6 ; UPDATE TOTAL SYSTEM CONNECT CHARGE ADC SYSCON+4 ; ADD R.CCON(R5),SYSCON+4 ; ADD R.DCHG+2(R5),SYSDSK+6 ; UPDATE TOTAL SYSTEM DISK CHARGE ADC SYSDSK+4 ; ADD R.DCHG(R5),SYSDSK+4 ; ADD R.CPAG+2(R5),SYSPAG+6 ; UPDATE TOTAL SYSTEM PAGE CHARGE ADC SYSPAG+4 ; ADD R.CPAG(R5),SYSPAG+4 ; ADD R.CMEM+2(R5),SYSMEM+6 ; UPDATE TOTAL SYSTEM MEMORY CHARGE ADC SYSMEM+4 ; ADD R.CMEM(R5),SYSMEM+4 ; ADD R.CQIO+2(R5),SYSQIO+6 ; UPDATE TOTAL SYSTEM I/O CHARGE ADC SYSQIO+4 ; ADD R.CQIO(R5),SYSQIO+4 ; RETURN ; RETURN TO CALLER .PAGE .SBTTL ROUTINE TO PRINT USER CHARGE SUMMARY ;+ ; *** PRTTAB ; ; THIS ROUTINE PRINTS A SUMMARY OF THE TOTAL USAGE AND CHARGE FOR ; ALL RESOURCES. IT IS USED FOR BOTH USER AND SYSTEM TABLES. ; ; INPUTS: ; R5 ADDRESS OF RESOURCE SUMMARY TABLE ; ;- PRTTAB: MOV R5,R4 ; POINT R4 TO TOTAL CHARGE FIELD+2 ADD #,R4 ; MOV #OUTBUF,R0 ; GET OUTPUT BUFFER ADDRESS MOVSTR #ALLCPU ; INSERT "CPU USED" MESSAGE MOV R5,R1 ; POINT TO TOTAL CPU TIME ADD #,R1 ; CALL FTIME ; AND FORMAT IT MOVB #SPA,(R0) ; INSERT THREE SPACES MOVB (R0)+,(R0) ; MOVB (R0)+,(R0)+ ; MOV R5,R1 ; POINT TO TOTAL CPU CHARGE+2 ADD #,R1 ; ADD (R1),(R4) ; ADD UP TOTAL CHARGES ADC -(R4) ; ADD -(R1),(R4)+ ; CALL FM.CHG ; FORMAT TOTAL CPU CHARGE .IF DF AA$UNI SUB #OUTBUF,R0 ; CALCULATE MESSAGE LENGTH .IFF SUB #OUTBUF+2,R0 ; CALCULATE MESSAGE LENGTH .ENDC ; DF AA$UNI FILE #OUTBUF,R0 ; AND PRINT IT ; ; PRINT TOTAL CONNECT TIME AND CHARGE ; MOV #OUTBUF,R0 ; GET OUTPUT BUFFER ADDRESS MOVSTR #ALLCON ; INSERT "CONNECT TIME" TEXT MOV R5,R1 ; POINT TO TOTAL CONNECT TIME ADD #,R1 ; CALL FTIME ; AND FORMAT IT MOVB #SPA,(R0) ; INSERT THREE SPACES MOVB (R0)+,(R0) ; MOVB (R0)+,(R0)+ ; MOV R5,R1 ; POINT TO TOTAL CONNECT CHARGE+2 ADD #,R1 ; ADD (R1),(R4) ; ADD UP TOTAL CHARGES ADC -(R4) ; ADD -(R1),(R4)+ ; CALL FM.CHG ; FORMAT TOTAL CONNECT CHARGE .IF DF AA$UNI SUB #OUTBUF,R0 ; CALCULATE MESSAGE LENGTH .IFF SUB #OUTBUF+2,R0 ; CALCULATE MESSAGE LENGTH .ENDC ; DF AA$UNI FILE #OUTBUF,R0 ; AND PRINT IT ; ; PRINT TOTAL DISK CHARGE ; MOV #OUTBUF,R0 ; GET OUTPUT BUFFER ADDRESS MOVSTR #ALLDSK ; INSERT "DISK CHARGES" MOV R5,R1 ; POINT TO TOTAL DISK CHARGES+2 ADD #,R1 ; ADD (R1),(R4) ; ADD UP TOTAL CHARGES ADC -(R4) ; ADD -(R1),(R4)+ ; CALL FM.CHG ; FORMAT TOTAL DISK CHARGES .IF DF AA$UNI SUB #OUTBUF,R0 ; CALCULATE MESSAGE LENGTH .IFF SUB #OUTBUF+2,R0 ; CALCULATE MESSAGE LENGTH .ENDC ; DF AA$UNI FILE #OUTBUF,R0 ; AND PRINT IT ; ; PRINT TOTAL PAGES PRINTED AND TOTAL PAGE CHARGE ; MOV #OUTBUF,R0 ; GET OUTPUT BUFFER ADDRESS MOVSTR #ALLPAG ; INSERT "PAGES" TEXT MOV R5,R1 ; POINT TO TOTAL PAGES PRINTED ADD #,R1 ; CALL FNUMBR ; FORMAT TOTAL MOVB #SPA,(R0) ; INSERT THREE SPACES MOVB (R0)+,(R0) ; MOVB (R0)+,(R0)+ ; MOV R5,R1 ; POINT TO TOTAL PAGE CHARGE+2 ADD #,R1 ; ADD (R1),(R4) ; ADD UP TOTAL CHARGES ADC -(R4) ; ADD -(R1),(R4)+ ; CALL FM.CHG ; FORMAT TOTAL PAGE CHARGES .IF DF AA$UNI SUB #OUTBUF,R0 ; CALCULATE MESSAGE LENGTH .IFF SUB #OUTBUF+2,R0 ; CALCULATE MESSAGE LENGTH .ENDC ; DF AA$UNI FILE #OUTBUF,R0 ; ; ; PRINT TOTAL MEMORY USAGE AND MEMORY USAGE CHARGE ; MOV #OUTBUF,R0 ; GET OUTPUT BUFFER ADDRESS MOVSTR #ALLMEM ; INSERT "MEMORY USAGE" TEXT MOV R5,R1 ; POINT TO TOTAL MEMORY USAGE ADD #,R1 ; CALL NORMEM ; CONVERT TO KW-HRS CALL FNUMBR ; FORMAT TOTAL MEMORY USAGE MOVB #SPA,(R0) ; INSERT THREE SPACES MOVB (R0)+,(R0) ; MOVB (R0)+,(R0)+ ; MOV R5,R1 ; POINT TO TOTAL MEMORY CHARGE+2 ADD #,R1 ; ADD (R1),(R4) ; ADD UP TOTAL CHARGES ADC -(R4) ; ADD -(R1),(R4)+ ; CALL FM.CHG ; FORMAT TOTAL MEMORY CHARGES .IF DF AA$UNI SUB #OUTBUF,R0 ; CALCULATE MESSAGE LENGTH .IFF SUB #OUTBUF+2,R0 ; CALCULATE MESSAGE LENGTH .ENDC ; DF AA$UNI FILE #OUTBUF,R0 ; AND PRINT IT ; ; PRINT TOTAL I/O COUNT AND CHARGE ; MOV #OUTBUF,R0 ; GET OUTPUT BUFFER ADDRESS MOVSTR #ALLQIO ; INSERT "I/O RECORDED" TEXT MOV R5,R1 ; POINT TO TOTAL I/O COUNT ADD #,R1 ; CALL FNUMBR ; FORMAT TOTAL I/O COUNT MOVB #SPA,(R0) ; INSERT THREE SPACES MOVB (R0)+,(R0) ; MOVB (R0)+,(R0)+ ; MOV R5,R1 ; POINT TO TOTAL I/O CHARGE+2 ADD #,R1 ; ADD (R1),(R4) ; ADD UP TOTAL CHARGES ADC -(R4) ; ADD -(R1),(R4)+ ; CALL FM.CHG ; FORMAT TOTAL I/O CHARGES .IF DF AA$UNI SUB #OUTBUF,R0 ; CALCULATE MESSAGE LENGTH .IFF SUB #OUTBUF+2,R0 ; CALCULATE MESSAGE LENGTH .ENDC ; DF AA$UNI FILE #OUTBUF,R0 ; AND PRINT IT ; ; PRINT TOTAL CHARGES ; MOV #OUTBUF,R0 ; GET OUTPUT BUFFER ADDRESS MOVSTR #ALLCHG ; INSERT "TOTAL" STRING MOV R4,R1 ; POINT R1 TO TOTAL CHARGES TST -(R1) ; CALL FM.CHG ; FORMAT TOTAL CHARGE .IF DF AA$UNI SUB #OUTBUF,R0 ; CALCULATE MESSAGE LENGTH .IFF SUB #OUTBUF+2,R0 ; CALCULATE MESSAGE LENGTH .ENDC ; DF AA$UNI FILE #OUTBUF,R0 ; AND PRINT IT RETURN ; RETURN TO CALLER .PAGE .SBTTL BRIEF FORMAT LISTING ROUTINE ;+ ; *** LISTB ; ; THIS ROUTINE IS CALLED TO PRODUCE A BRIEF (ONE LINE) LISTING ; OF THE ACCUMULATED STATISTICS FOR THE CURRENT CONTROL BLOCK. ; IF THE /GR SWITCH IS SPECIFIED, THIS ROUTINE IS ALSO CALLED ; TO PRODUCE A ONE-LINE LISTING FOR INCLUSION IN THE GROUP ; USAGE REPORT. ; ; INPUTS: ; R5 CONTROL BLOCK ADDRESS ; ; OUTPUTS: ; R5 MUST BE PRESERVED. ; OTHER REGISTERS CAN BE ALTERED AT WILL) ; ;- LISTB: TST R.CHWD(R5) ; ACCOUNT CHAINED? BEQ 5$ ; IF EQ NO, DON'T CHECK FOR /MA BIT #MAMSK,MASKW ; YES, /MA SPECIFIED? BNE 40$ ; IF NE YES, DON'T SHOW CHAINED ACCOUNTS 5$: MOV R5,-(SP) ; SAVE R5 MOV #OUTBUF,R0 ; GET OUTPUT BUFFER ADDRESS MOV R5,R1 ; POINT R0 TO LAST NAME ADD #R.LNM,R1 ; MOV #7,R2 ; SET LENGTH OF NAME (WORDS) CALL CO.PYW ; TRANSFER TO OUTPUT (N.B. THIS ; ONLY WORKS BECAUSE BOTH THE ; OUTPUT BUFFER AND THE LAST NAME ; FIELD ARE WORD-ALIGNED) CALL FMTUIC ; FILL IN UIC MOV R5,R1 ; POINT R1 TO CONNECT TIME ADD #R.TCON,R1 ; CALL FTIME ; FORMAT CONNECT TIME MOV R5,R1 ; POINT R1 TO CPU TIME ADD #R.TCPU,R1 ; CALL FTIME ; FORMAT CPU TIME .IF DF AA$BLK TST R.CHWD(R5) ; ACCOUNT CHAINED? BEQ 20$ ; IF EQ NO, PRINT BLOCK USE MOV #DSKCH,R1 ; GET ADDRESS OF " - " FIELD MOV #12.,R2 ; AND ITS LENGTH 17$: MOVB (R1)+,(R0)+ ; MOVE IT IN DEC R2 ; DONE YET? BGT 17$ ; IF GT NO, LOOP BR 30$ ; 20$: MOV R5,R1 ; POINT R1 TO AVERAGE BLOCKS ADD #R.ABLK,R1 ; CALL FNUMBR ; FORMAT AVERAGE BLOCKS 30$: ; REF. LABEL .ENDC ; DF AA$BLK MOV R5,R1 ; POINT R1 TO TOTAL CHARGES+2 ADD #R.TCHG+2,R1 ; ADD (R1),GRPTOT+2 ; UPDATE GROUP CHARGES (USED BY /GR ONLY; ADC GRPTOT ; NOT MEANINGFUL DURING BRIEF LISTING CALL). ADD -(R1),GRPTOT ; CALL FMONEY ; FORMAT TOTAL CHARGES BIT #100000,R.ACNO(R5) ; MASTER ACCOUNT? BEQ 35$ ; IF EQ NO MOVB #SPA,(R0)+ ; YES, INSERT " M" MOVB #SPA,(R0)+ ; MOVB #'M,(R0)+ ; 35$: TST R.CHWD(R5) ; CHAINED ACCOUNT? BEQ 36$ ; IF EQ NO MOVB #SPA,(R0)+ ; YES, INSERT " C" MOVB #SPA,(R0)+ ; MOVB #'C,(R0)+ ; 36$: ; SUB #OUTBUF,R0 ; CALCULATE FINAL LENGTH OF LINE FILE #OUTBUF,R0 ; PRINT IT MOV (SP)+,R5 ; RESTORE R5 40$: RETURN ; AND RETURN FOR THE NEXT USER .PAGE .SBTTL FULL FORMAT LISTING ROUTINE ;+ ; *** LISTF ; ; THIS ROUTINE IS CALLED TO PRODUCE A FULL (TWO PAGE) LISTING ; OF THE ACCUMULATED STATISTICS FOR THE CURRENT CONTROL BLOCK. ; ; INPUTS: ; R5 CONTROL BLOCK ADDRESS ; ; OUTPUTS: ; R5 MUST BE PRESERVED ; OTHER REGISTERS USED. ; ;- LISTF: TST R.CHWD(R5) ; ACCOUNT CHAINED? BEQ 5$ ; IF EQ NO, DON'T CHECK FOR /MA BIT #MAMSK,MASKW ; /MA SPECIFIED? BEQ 5$ ; IF EQ NO JMP 147$ ; YES, DON'T SHOW CHAINED ACCOUNTS 5$: MOV R5,-(SP) ; SAVE R5 FILE #INTRO,#INTR1S ; GIVE THE REPORT A TITLE FILE #INTR2,#INTR2S ; MOV #OUTBUF,R0 ; GET OUTPUT BUFFER ADDRESS MOVB #HT,(R0)+ ; START WITH A TAB CALL FMTUIC ; INSERT UIC MOVB #SPA,(R0)+ ; INSERT A SPACE MOV R5,R1 ; POINT R1 TO FIRST NAME ADD #R.FNM,R1 ; MOV #12.,R2 ; SET ITS MAXIMUM LENGTH CALL MOVNAM ; INSERT FIRST NAME MOV R5,R1 ; POINT R1 TO LAST NAME ADD #A.LNM,R1 ; MOV #14.,R2 ; SET MAXIMUM LENGTH CALL MOVNAM ; INSERT LAST NAME MOV R.ACNO(R5),R2 ; GET ACCOUNT NUMBER BEQ 10$ ; IF EQ, A/C NOT SET UP BIC #100000,R2 ; CLEAR MASTER FLAG (IF SET) MOVSTR #ACCNO ; INSERT A/C NUM TEXT MOV R2,R1 ; ACCOUNT NUMBER GOES IN R1 CALL OC.TAL ; FORMAT A/C NUM AS OCTAL BIT #100000,R.ACNO(R5) ; MASTER STATUS? BEQ 20$ ; IF EQ NO MOVSTR #MSTR ; YES, SAY SO BR 20$ ; PRINT IT 10$: MOVSTR #NOSET ; SAY A/C NOT SET UP 20$: SUB #OUTBUF,R0 ; CALCULATE MESSAGE LENGTH FILE #OUTBUF,R0 ; AND PRINT IT TST R.ACNO(R5) ; WAS THE ACCOUNT SET UP? BNE 30$ ; IF NE YES, CONTINUE RETURN ; ELSE JUST RETURN 30$: FILE #FROM,#FROMSZ ; SAY WHAT TIME IS COVERED BY THE REPORT FILE #TO,#TOSZ ; TST R.CHWD(R5) ; ACCOUNT CHAINED? BNE 40$ ; IF NE YES MOV #OUTBUF,R0 ; GET OUTPUT BUFFER ADDRESS AGAIN MOVSTR #CURBAL ; INSERT CURRENT BALANCE TEXT MOV R5,R1 ; POINT R1 TO CURRENT BALANCE ADD #R.CASH,R1 ; CALL FMONEY ; AND FORMAT IT SUB #OUTBUF,R0 ; PRINT RESULT FILE #OUTBUF,R0 ; .IF DF AA$BLK MOV #OUTBUF,R0 ; REPEAT FOR CURRENT BLOCK ALLOCATION MOVSTR #CURBLK ; MOV R5,R1 ; ADD #R.BALL,R1 ; CALL FNUMBR ; SUB #OUTBUF,R0 ; FILE #OUTBUF,R0 ; MOV #OUTBUF,R0 ; REPEAT FOR AVERAGE BLOCK USE MOVSTR #AVRBLK ; MOV R5,R1 ; ADD #R.ABLK,R1 ; CALL FNUMBR ; SUB #OUTBUF,R0 ; FILE #OUTBUF,R0 ; .ENDC ; DF AA$BLK BR 50$ ; CONTINUE IN COMMON CODE 40$: MOV #OUTBUF,R0 ; GET OUTPUT BUFFER ADDRESS MOVSTR #CHATXT ; INSERT "ACCOUNT IS CHAINED" TEXT MOV R.CHWD(R5),R1 ; GET NUMBER OF MASTER ACCOUNT CALL OC.TAL ; FORMAT AS OCTAL SUB #OUTBUF,R0 ; PRINT MESSAGE FILE #OUTBUF,R0 ; 50$: ; REF. LABEL .IF DF AA$MMA MOV #OUTBUF,R0 ; GET OUTPUT BUFFER ADDRESS MOVSTR #ALLMON ; INSERT MONTHLY ALLOCATION TEXT MOV R5,R1 ; POINT R1 TO ALLOCATION ADD #R.MALL,R1 ; CALL FMONEY ; FORMAT THE ALLOCATION SUB #OUTBUF,R0 ; FILE #OUTBUF,R0 ; AND PRINT THE MESSAGE .ENDC ; DF AA$MMA MOV #OUTBUF,R0 ; MOVSTR #TRMSES ; INSERT TERMINAL SESSIONS TEXT MOV #DOUBLE+2,R1 ; POINT TO D.P. FIELD + 2 MOV R.NTRM(R5),(R1) ; INSERT NUMBER OF TERMINAL SESSIONS CLR -(R1) ; CALL FNUMBR ; FORMAT AS DECIMAL SUB #OUTBUF,R0 ; FILE #OUTBUF,R0 ; MOV #OUTBUF,R0 ; MOVSTR #BATJOB ; INSERT BATCH JOBS TEXT MOV #DOUBLE+2,R1 ; POINT TO D.P. FIELD + 2 MOV R.NJOB(R5),(R1) ; GET NUMBER OF BATCH JOBS CLR -(R1) ; CALL FNUMBR ; FORMAT AS DECIMAL SUB #OUTBUF,R0 ; PRINT MESSAGE FILE #OUTBUF,R0 ; MOV #OUTBUF,R0 ; MOVSTR #TOTCST ; INSERT TOTAL CHARGES TEXT MOV R5,R1 ; POINT R1 TO TOTAL CHARGES ADD #R.TCHG,R1 ; CALL FMONEY ; FORMAT THEM SUB #OUTBUF,R0 ; PRINT THE MESSAGE FILE #OUTBUF,R0 ; FILE #OTHER,#OTHERS ; PRINT "OTHER TRANSACTIONS MESSAGE" TST R.LIST(R5) ; WERE THERE ANY? BEQ 60$ ; IF EQ NO CALL LISTOT ; LIST OTHER TRANSACTIONS BR 70$ ; AND CONTINUE 60$: FILE #NONE,#NONESZ ; PRINT "NONE" IF NOTHING ELSE 70$: ; FILE #BREAK,#BREAKS ; START A NEW PAGE MOV #OUTBUF,R0 ; MOVSTR #CONTIM ; INSERT "CONNECT TIME" TEXT MOV R5,R1 ; POINT R1 TO CONNECT TIME ADD #R.TCON,R1 ; CALL FTIME ; AND FORMAT IT MOV R5,R1 ; POINT R1 TO CONNECT CHARGE ADD #R.CCON,R1 ; CALL FMONEY ; AND FORMAT IT SUB #OUTBUF,R0 ; PRINT FILE #OUTBUF,R0 ; MOV #OUTBUF,R0 ; MOVSTR #CPUTIM ; INSERT "CPU TIME" MOV R5,R1 ; POINT R1 TO CPU TIME ADD #R.TCPU,R1 ; CALL FTIME ; FORMAT IT MOV R5,R1 ; POINT R1 TO CPU CHARGE ADD #R.CCPU,R1 ; CALL FMONEY ; FORMAT IT SUB #OUTBUF,R0 ; AND PRINT FILE #OUTBUF,R0 ; MOV #OUTBUF,R0 ; MOVSTR #IOREQ ; INSERT "I/O REQUESTS" MOV R5,R1 ; POINT R1 TO I/O REQUEST COUNT ADD #R.TQIO,R1 ; CALL FNUMBR ; AND FORMAT IT MOV R5,R1 ; POINT R1 TO I/O CHARGE ADD #R.CQIO,R1 ; CALL FMONEY ; FORMAT IT SUB #OUTBUF,R0 ; CALCULATE MESSAGE LENGTH FILE #OUTBUF,R0 ; AND PRINT IT MOV #OUTBUF,R0 ; GET OUTPUT BUFFER ADDRESS MOVSTR #PAGES ; INSERT "PAGES PRINTED" TEXT MOV R5,R1 ; POINT R1 TO # PAGES ADD #R.TPAG,R1 ; CALL FNUMBR ; FORMAT AS ASCII DECIMAL MOV R5,R1 ; POINT R1 TO PAGE CHARGE ADD #R.CPAG,R1 ; CALL FMONEY ; FORMAT IT SUB #OUTBUF,R0 ; CALCULATE MESSAGE LENGTH FILE #OUTBUF,R0 ; AND PRINT IT MOV #OUTBUF,R0 ; MOVSTR #DSKCHG ; INSERT "DISK CHARGES" MOV R5,R1 ; POINT R1 TO TOTAL DISK CHARGES ADD #R.DCHG,R1 ; CALL FMONEY ; FORMAT THE AMOUNT SUB #OUTBUF,R0 ; PRINT THE RESULT FILE #OUTBUF,R0 ; MOV #OUTBUF,R0 ; MOVSTR #MEMTIM ; INSERT "MEMORY USAGE" MOV R5,R1 ; POINT R1 TO TOTAL MEMORY USAGE ADD #R.TMEM,R1 ; CALL NORMEM ; CONVERT TO KW-HRS CALL FNUMBR ; FORMAT AS XXX.XX MOV R5,R1 ; POINT R1 TO TOTAL MEMORY CHARGES ADD #R.CMEM,R1 ; CALL FMONEY ; FORMAT THE AMOUNT SUB #OUTBUF,R0 ; PRINT THE RESULT FILE #OUTBUF,R0 ; MOV #OUTBUF,R0 ; MOVSTR #KUMHER ; INSERT "GAINED BY VIRTUE OF MASTER STATUS" MOV R5,R1 ; POINT R1 TO THE AMOUNT ADD #R.MCHG,R1 ; CALL FMONEY ; AND FORMAT IT SUB #OUTBUF,R0 ; CALCULATE MESSAGE LENGTH FILE #OUTBUF,R0 ; AND PRINT IT MOV #OUTBUF,R0 ; MOVSTR #GOAWAY ; INSERT "REDIRECTED CHARGES" MESSAGE{ MOV R5,R1 ; POINT R1 TO THE AMOUNT ADD #R.CCHG,R1 ; CALL FMONEY ; AND FORMAT IT SUB #OUTBUF,R0 ; PRINT THE RESULT FILE #OUTBUF,R0 ; MOV #OUTBUF,R0 ; MOVSTR #GRAND ; GET SET FOR GRAND TOTAL OF CHARGES MOV R5,R1 ; POINT TO GRAND TOTAL ADD #R.TCHG,R1 ; CALL FMONEY ; AND FORMAT IT SUB #OUTBUF,R0 ; PRINT FILE #OUTBUF,R0 ; MOV (SP)+,R5 ; RESTORE R5 147$: RETURN ; .PAGE .SBTTL OTHER TRANSACTIONS LISTING ROUTINE ;+ ; *** LISTOT ; ; THIS ROUTINE IS CALLED DURING FULL LIST PROCESSING TO PRINT ; OUT A SUMMARY OF THOSE TRANSCATIONS FOR AN ACCOUNT THAT ; ORINGINATED WITH THE MACNT PROGRAM. ; ; INPUT: ; R5 CONTROL BLOCK ADDRESS (LISTHEAD FOR OTHER ; TRANSACTIONS IS AT OFFSET R.LIST) ; ;- LISTOT: MOV R5,-(SP) ; SAVE CONTROL BLOCK ADDRESS ADD #R.LIST,R5 ; POINT TO OT LISTHEAD 10$: MOV (R5),R5 ; GET ADDRESS OF NEXT PACKET BNE 11$ ; IF NE, GOT ONE JMP 110$ ; END OF LIST 11$: TST (R5)+ ; POINT PAST LINK WORD MOV #OUTBUF,R0 ; GET OUTPUT BUFFER ADDRESS MOVB #HT,(R0)+ ; AND START WITH A TAB MOV R5,R1 ; POINT R1 TO TIME PARAMETERS ADD #2,R1 ; CMP 4(R1),#10. ; TWO DIGITS IN DAY? BGE 12$ ; IF GE YES MOVB #'0,(R0)+ ; ELSE INSERT ONE 12$: CALL $DAT ; FILL IN THE DATE AS DD-MMM-YY MOVB #SPA,(R0)+ ; INSERT A SPACE MOV #3,R2 ; SET TIME FORMAT TO HH:MM:SS CALL $TIM ; FORMAT THE TIME CMP #FF.SET,(R5) ; SET FUNCTION? BNE 40$ ; IF NE NO MOVSTR #FFSET ; INSERT SET OPTION MESSAGE SUB #OUTBUF,R0 ; CALCULATE MESSAGE LENGTH FILE #OUTBUF,R0 ; AND PRINT IT MOV #OUTBUF,R0 ; SET UP BUFFER ADDRESS .IF DF AA$BLK MOVSTR #FFSET1 ; COPY IN "BLOCK ALLOCATION" TEXT MOV R5,R1 ; POINT R1 TO BLOCK ALLOCATION ADD #F.INFO,R1 ; CALL FM.QIO ; FORMAT BLOCK ALLOCATION .ENDC ; DF AA$BLK MOVSTR #FFSET2 ; INSERT BALANCE TEXT MOV R5,R1 ; POINT R1 TO BALANCE ADD #,R1 ; CALL FM.CHG ; FORMAT THE BALANCE .IF DF AA$UNI SUB #OUTBUF,R0 ; CALCULATE MESSAGE LENGTH .IFF SUB #,R0 ; CALCULATE MESSAGE LENGTH (2 DIGITS AFTER .) .ENDC ; DF AA$UNI FILE #OUTBUF,R0 ; AND PRINT IT MOV R5,R1 ; POINT R1 TO DESCRIPTIVE TEXT ADD #,R1 ; BR 90$ ; INSERT DESCRIPTIVE TEXT AND PRINT 40$: CMP #FF.UPD,(R5) ; BALANCE UPDATE TRANSACTION? BNE 50$ ; IF NE NO MOVSTR #FFUPD ; INSERT "BALANCE UPDATED" MOV R5,R1 ; POINT R1 TO AMOUNT OF UPDATE ADD #F.INFO,R1 ; CALL FM.CHG ; AND FORMAT IT .IF DF AA$UNI SUB #OUTBUF,R0 ; CALCULATE MESSAGE LENGTH .IFF SUB #,R0 ; CALCULATE MESSAGE LENGTH (2 DIGITS AFTER .) .ENDC ; DF AA$UNI FILE #OUTBUF,R0 ; AND PRINT IT MOV R5,R1 ; POINT R1 TO DESCRIPTIVE TEXT ADD #,R1 ; BR 90$ ; INSERT DESCRIPTIVE TEXT AND PRINT 50$: CMP #FF.BLK,(R5) ; BLOCK ALLOCATION CHANGE TRANSACTION? BNE 60$ ; IF NE NO MOVSTR #FFBLK ; INSERT "BLOCK ALLOCATION CHANGE" MOV R5,R1 ; POINT R1 TO NEW ALLOCATION ADD #F.INFO,R1 ; CALL FM.QIO ; FORMAT IT BR 100$ ; 60$: CMP #FF.MMA,(R5) ; CHANGE OF MONTHLY ALLOCATION? BNE 70$ ; IF NE NO MOVSTR #FFMMA ; INSERT "MONTHLY ALLOCATION CHANGED" MOV R5,R1 ; POINT R1 TO CHANGED AMOUNT ADD #F.INFO,R1 ; CALL FM.CHG ; FORMAT IT .IF NDF AA$UNI SUB #2,R0 ; PRINT ONLY 2 DIGITS AFTER DECIMAL POINT .ENDC ; NDF AA$UNI BR 100$ ; 70$: CMP #FF.CHA,(R5) ; CHAIN/UNCHAIN OPERATION? BNE 80$ ; TST F.CHWD(R5) ; UNCHAINING OPERATION? BNE 72$ ; IF NE NO MOVSTR #FFCHA3 ; YES, SAY "ACCOUNT UNCHAINED" BR 100$ ; 72$: MOV (SP),R3 ; GET ORIGINAL CONTROL BLOCK ADDRESS MOV R.ACNO(R3),R1 ; GET ORIGINAL ACCOUNT NUMBER BIC #100000,R1 ; CLEAR MASTER FLAG (IF SET) CMP F.ACNO(R5),R1 ; ARE WE BEING CHAINED TO A MASTER? BEQ 74$ ; IF EQ YES MOVSTR #FFCHA1,SAVER1 ; SAY MASTER IS RECEIVING MEMBER MOV F.ACNO(R5),R1 ; GET NEW MEMBER A/C NUMBER CALL OC.TAL ; FORMAT NEW MEMBER A/C NUMBER MOVB #SPA,(R0)+ ; INSERT A SPACE MOV F.UIC(R5),R3 ; GET UIC OF THIS A/C CALL FM.UIC ; AND FORMAT IT BR 100$ ; 74$: MOVSTR #FFCHA2 ; SAY WE ARE BEING CHAINED MOV F.CHWD(R5),R1 ; GET NUMBER OF MASTER ACCOUNT CALL OC.TAL ; FORMAT IT BR 100$ ; 80$: CMP #FF.MAS,(R5) ; ACCOUNT GIVEN MASTER STATUS? BNE 85$ ; IF NE NO MOVSTR #FFMAS ; INSERT "ACCOUNT GAINED MASTER STATUS" BR 100$ ; 85$: CMP #FF.DMS,(R5) ; DELETING MASTER STATUS? BNE 105$ ; IF NE NO, END OF LIST MOVSTR #FFDMS ; INSERT "MASTER STATUS DELETED" TEXT BR 100$ ; 90$: CMPB (R1),#CR ; ANY DESCRIPTIVE TEXT? BEQ 105$ ; IF EQ NO MOV #OUTBUF,R0 ; SET BUFFER ADDRESS MOVSTR #OPTXT,SAVER1 ; START WITH FORMATTING TEXT MOV #F.LTXT,R2 ; SET MAXIMUM SIZE OF TEXT 95$: CMPB (R1),#CR ; END OF TEXT YET? BEQ 100$ ; IF EQ YES TSTB (R1) ; NULL BYTE? (FOR HISTORICAL REASONS) BEQ 100$ ; IF EQ YES MOVB (R1)+,(R0)+ ; NO, MOVE A CHARACTER OF THE TEXT DEC R2 ; DONE YET? BGT 95$ ; IF GT NO, LOOP ; FALL THROUGH TO 100$ 100$: SUB #OUTBUF,R0 ; CALCULATE LENGTH OF MESSAGE FILE #OUTBUF,R0 ; AND PRINT IT 105$: TST -(R5) ; POINT R5 BACK TO LINK WORD JMP 10$ ; AND DO THE NEXT TRANSACTION 110$: MOV (SP)+,R5 ; RESTORE R5 RETURN ; AND RETURN TO CALLER .PAGE .SBTTL NAME MOVING ROUTINE ;+ ; *** MOVNAM ; ; THIS ROUTINE MOVES NAME TEXT UNTIL EITHER THE END OR A SPACE IS ; FOUND. THE NAME IS TERMINATED WITH A SPACE IN THE OUTPUT BUFFER. ; ; INPUTS: ; R0 OUTPUT BUFFER ; R1 ADDRESS OF NAME ; R2 MAXIMUM LENGTH OF NAME ; ;- MOVNAM: MOVB (R1),(R0)+ ; MOVE A CHARACTER CMPB (R1)+,#SPA ; WAS IT A SPACE? BEQ 10$ ; IF EQ YES, END OF NAME DEC R2 ; MAXIMUM CHARACTERS TRANSFERRED? BGT MOVNAM ; IF GT NO, LOOP MOVB #SPA,(R0)+ ; MAXIMUM CHARS., INSERT A SPACE 10$: RETURN ; AND RETURN TO CALLER .PAGE .SBTTL TABLE INDEXING ROUTINE ;+ ; *** INDEX ; ; THIS ROUTINE IS CALLED TO CALCULATE THE OFFSETS FROM THE START ; OF THE DEVICE USAGE TABLES. SINCE EACH ENTRY IS 14(10) BYTES ; LONG, AND THE FIRST DEVICE IS UNIT ZERO, THE OFFSET IS JUST ; 14 TIMES THE UNIT NUMBER. ; ; INPUTS: ; R1 UNIT NUMBER ; ; OUTPUTS: ; R1 TABLE OFFSET ; ;- INDEX: ASL R1 ; MULTIPLY BY TWO MOV R1,-(SP) ; SAVE IT ASL R1 ; MULTIPLY BY FOUR MOV R1,-(SP) ; SAVE IT ASL R1 ; MULTIPLY BY EIGHT ADD (SP)+,R1 ; 4 + 8 = 12 ADD (SP)+,R1 ; 12 + 2 = 14 RETURN ; RETURN WITH ANSWER .PAGE .SBTTL SUPPLEMENTARY BLOCK ALLOCATION/LINK ROUTINE ;+ ; *** SUPPL ; ; DURING THE PROCESSING OF A MACNT OPTION RECORD, THIS ROUTINE ; IS CALLED TO ALLOCATION A BLOCK OF DYNAMIC MEMORY TO CONTAIN ; THE INFORMATION. IF SUCCESSFUL, THE BLOCK IS LINKED INTO THE ; LIST OF SIMILAR BLOCKS ORIGINATING IN EACH ACCUNT ENTRY. ; ; INPUTS: ; R3 DATA BUFFER ADDRESS ; R5 ACCOUNT ENTRY BLOCK ADDRESS ; ; OUTPUTS: ; R1 BLOCK ADDRESS ; ;- SUPPL: MOV $RFLEN,R1 ; GET THE SIZE OF BLOCK WE NEED ADD #2,R1 ; MAKE SPACE FOR LINK WORD CALL CORE ; ALLOCATE A CORE BLOCK BCC 10$ ; IF CC WE MADE IT PRINT #ERR1 ; ALLOCATION ERROR JMP EXSEV ; EXIT WITH SEVERE ERROR 10$: MOV R0,R1 ; COPY PACKET ADDRESS TO R1 MOV R5,R0 ; POINT R0 TO THE LISTHEAD ADDRESS ADD #R.LIST,R0 ; JMP INSERT ; LINK IN PACKET AND RETURN .PAGE .SBTTL SUPPLEMENTARY BLOCK FILL ROUTINE ;+ ; *** FILSUP ; ; THIS ROUTINE IS CALLED TO TRANSFER THE CONTENTS OF THE DATA ; BUFFER TO THE SUPPLEMENTARY CORE BLOCK JUST ALLOCATED. ; ; INPUTS: ; R1 ADDRESS OF CORE BLOCK ; R3 DATA BUFFER ADDRESS ; ;- FILSUP: MOV R3,R0 ; SOURCE ADDRESS MUST BE IN R0 FOR COPY MOV $RFLEN,R2 ; GET LENGTH OF DATA ASR R2 ; CONVERT TO WORDS TST (R1)+ ; SKIP LINK WORD IN BLOCK JMP RCOPYW ; AND TRANSFER THE DATA .PAGE .SBTTL CONTROL BLOCK SEARCH ROUTINE ;+ ; *** SEARCH ; ; THIS ROUTINE IS CALLED FOR EACH DATA FILE RECORD. IT LOCATES ; THE ACCOUNT ENTRY FOR THE CURRENT DATA RECORD. ; IF THE ACCOUNT ENTRY CANNOT BE FOUND, WE TRY AND ALLOCATE ONE ; USING DATA IN THE CURRENT RECORD. ; ; INPUT: ; R4 ACCOUNT NUMBER TO SEARCH FOR ; ; OUTPUT: ; R5 ADDRESS OF CONTROL BLOCK ; ;- SEARCH: BIC #100000,R4 ; CLEAR MASTER FLAG (IF SET) MOV #LISTHD,R5 ; GET CONTROL BLOCK LISTHEAD ADDRESS 10$: MOV (R5),R5 ; GET ADDRESS OF NEXT ENTRY BEQ 20$ ; IF EQ, END OF LIST MOV R.ACNO(R5),R2 ; GET ACCOUNT NUMBER FOR THIS ENTRY BIC #100000,R2 ; AND CLEAR THE MASTER FLAG (IF SET) CMP R2,R4 ; THIS ENTRY? BNE 10$ ; IF NE NO, LOOP RETURN ; RETURN TO CALLER 20$: MOV #R.LGTH,R1 ; GET LENGTH OF BLOCK NEEDED CALL CORE ; ALLOCATE A BLOCK BCC 30$ ; IF CC WE MADE IT PRINT #ERR1 ; GIVE MEMORY OVERFLOW MESSAGE JMP EXSEV ; AND EXIT WITH SEVERE ERROR 30$: MOV R0,R1 ; COPY ENTRY ADDRESS TO R1 MOV #LISTHD,R0 ; GET ADDRESS OF BLOCK LISTHEAD CALL INSERT ; AND INSERT THE NEW ENTRY MOV R1,R5 ; SET UP BLOCK POINTER MOV R1,R2 ; POINT R2 TO LISTHEAD WITHIN IT ADD #R.LIST,R2 ; CLR R.LIST(R1) ; AND INITIALISE IT MOV R2,R.LIST+2(R1) ; MOV R4,R.ACNO(R5) ; SET UP ACCOUNT NUMBER MOV R5,R1 ; POINT R1 TO LAST NAME FIELD ADD #R.LNM,R1 ; MOV #WHO,R0 ; POINT R0 TO "NAME UNKNOWN" TEXT MOV #7,R2 ; SET TEXT SIZE (WORDS) CALL RCOPYW ; TRANSFER INTO CONTROL BLOCK MOVB #SPA,R.FNM(R5) ; MAKE THE FIRST NAME FIELD JUST A SPACE CMP F.CHWD(R3),R4 ; IS THIS THE CHAINED ACCOUNT? BEQ 40$ ; IF EQ YES MOV F.CHWD(R3),R.CHWD(R5) ; SET UP THE RIGHT LINKAGE 40$: MOV R5,R2 ; POINT R2 TO PLACE FOR UIC ADD #R.GRP,R2 ; MOV F.UIC(R3),R3 ; GET BINARY UIC MOV #3,R4 ; SET UIC FORMAT TO GGGMMM CALL .PPASC ; CONVERT UIC TO ASCII MOV #RECBUF,R3 ; RESTORE R3 TO ENTRY VALUE RETURN ; AND RETURN TO CALLER .PAGE .SBTTL ROUTINE TO OPEN ACCOUNT FILE ;+ ; *** OPENAF ; ; THIS ROUTINE OPENS THE RSX11 SYSTEM ACCOUNT FILE. IF THERE ; ARE ERRORS, AN ERROR MESSAGE IS PRINTED AND A JUMP IS MADE ; TO EXSEV TO GENERATE A SEVERE ERROR. ; ;- OPENAF: CALL $AFOPN ; CALL A/C FILE OPEN ROUTINE BCC 10$ ; GOOD PRINT #ERR4 ; ERROR, PRINT MESSAGE JMP EXSEV ; AND GENERATE A SEVERE ERROR EXIT 10$: RETURN ; RETURN TO CALLER .PAGE .SBTTL DATE/TIME FORMATTER ROUTINE ;+ ; *** DATTIM ; ; THIS ROUTINE IS CALLED TO FORMAT THE DATE AND TIME AS OBTAINED ; FROM A DATA RECORD. FORMAT IS DD-MMM-YY HH:MM:SS. ; ; INPUTS: ; R0 ADDRESS OF OUTPUT BUFFER ; R1 ADDRESS OF BUFFER CONTAINING DATE TIME IN ; STANDARD GTIM$ FORMAT. ; ;- DATTIM: CMP G.TIDA(R1),#10. ; DAY LESS THAN 10.? BGE 10$ ; IF GE NO MOVB #'0,(R0)+ ; YES, INSERT A ZERO CHARACTER 10$: CALL $DAT ; FILL IN THE DATE MOVB #SPA,(R0)+ ; INSERT A SPACE MOV #3,R2 ; SET TIME FORMAT TO HH:MM:SS JMP $TIM ; FILL IN THE TIME AND RETURN TO CALLER .PAGE .SBTTL MEMORY USAGE RENORMALISATION ROUTINE ;+ ; *** NORMEM ; ; AS ALL MEMORY USAGE FIGURES APPEAR INTERNALLY AS 64W-SECONDS, ; AND WE WISH TO DISPLAY THE RESULTS IN KW-HOURS, WE DIVIDE THE ; MEMORY USAGE FIGURES BY 57600. (=3600*1024/64) TO CONVERT THEM ; TO THE RIGHT UNITS. THIS DIVISION HAS TO BE DONE BY DIVIDING ; BY TWO FIRST AND THEN BY 28800 (<32768) OTHERWISE $DDIV DOES ; NOT PRODUCE THE CORRECT RESULT. ; ; INPUT: ; R1 ADDRESS OF 2-WORD MEMORY USAGE FIELD ; ; OUTPUT: ; R0,R1 UNCHANGED ; ;- NORMEM: MOV R0,-(SP) ; SAVE R0 MOV R1,-(SP) ; SAVE R1 MOV 2(R1),R2 ; GET LOW ORDER FIGURE MOV (R1),R1 ; GET HIGH ORDER FIGURE ASR R1 ; DIVIDE BY TWO ROR R2 ; MOV #28800.,R0 ; AND THEN BY 28800. CALL $DDIV ; MOV (SP),R0 ; RESTORE 2-WORD FIELD ADDRESS (AS R0) MOV R1,(R0)+ ; INSERT RENORMALISED RESULT (HIGH) MOV R2,(R0)+ ; (LOW) MOV (SP)+,R1 ; RESTORE R1 MOV (SP)+,R0 ; RESTORE R0 RETURN ; .PAGE .SBTTL TIME FORMATTER ROUTINE ;+ ; *** FTIME ; ; THIS ROUTINE TAKES A TIME IN TICKS (2 WORDS) AND FORMATS IT AS ; HOURS, MINUTES AND SECONDS IN A FIELD 14 CHARACTERS WIDE. SPACES ; ARE INSERTED WHERE NECESSARY. ; THIS ROUTINE SHOULD BE REWRITTEN TO USE THE FM.CPU ROUTINE. ; ; INPUT: ; R0 BUFFER ADDRESS ; R1 ADDRESS OF 2-WORD BLOCK CONTAINING TIME. ; ; OUTPUT: ; R0 UPDATED ; R1,R2 USED ; R3,R4,R5 PRESERVED ; ;+ FTIME: JSR R5,$SAVRG ; SAVE R3,R4 AND R5 MOV R0,-(SP) ; SAVE BUFFER POINTER MOV 2(R1),R2 ; GET LOW ORDER TIME MOV (R1),R1 ; GET HIGH ORDER TIME MOV TIMBUF+G.TICP,R0 ; GET TICKS PER SECOND CALL $DDIV ; CONVERT TO SECONDS MOV #60.,R0 ; SECONDS PER MINUTE CALL $DDIV ; CONVERT TO MINUTES ; TWO CALLS OF $DDIV ARE REQUIRED HERE ; IN ORDER TO GET THE SECONDS AS ; REMAINDER, RATHER THAN TICKS. MOV R0,-(SP) ; PUSH REMAINING SECONDS ON STACK MOV #60.,R0 ; MINUTES PER HOUR CALL $DDIV ; CONVERT TO HOURS MOV R0,-(SP) ; PUSH REMAINING MINUTES ON STACK MOV #FMTBUF,R0 ; GET TEMPORARY BUFFER ADDRESS MOV R2,R1 ; PUT HOURS IN R1 BEQ 10$ ; IF EQ THERE AREN'T ANY CALL 40$ ; FORMAT HOURS MOVB #'h,(R0)+ ; INSERT UNIT TEXT MOVB #SPA,(R0)+ ; AND A SPACE 10$: MOV (SP)+,R1 ; GET NUMBER OF MINUTES BEQ 20$ ; IF EQ THERE ARE NON CMP R1,#10. ; WILL WE GET TWO DIGITS? BGE 15$ ; IF GE YES MOVB #SPA,(R0)+ ; NO, INSERT A SPACE 15$: CALL 40$ ; FORMAT AS DECIMAL MOVB #'m,(R0)+ ; INSERT UNIT TEXT MOVB #SPA,(R0)+ ; AND A SPACE 20$: MOV (SP)+,R1 ; GET SECONDS CMP R1,#10. ; WILL WE GET TWO DIGITS? BGE 25$ ; IF GE YES MOVB #SPA,(R0)+ ; NO, INSERT A SPACE 25$: CALL 40$ ; FORMAT AS DECIMAL MOVB #'s,(R0)+ ; INSERT UNIT TEXT SUB #FMTBUF,R0 ; CALCULATE LENGTH OF STRING MOV R0,R2 ; SAVE THE RESULT NEG R0 ; CALCULATE AMOUNT OF BLANK FILL REQUIRED ADD #14.,R0 ; MOV R0,R1 ; COPY IT TO R1 MOV (SP)+,R0 ; GET THE ORIGINAL BUFFER ADDRESS BLE 35$ ; IF LE WE WANT NO BLANK FILL 30$: MOVB #SPA,(R0)+ ; INSERT A BLANK DEC R1 ; ANY MORE REQUIRED? BGT 30$ ; IF GT YES, LOOP 35$: MOV #FMTBUF,R1 ; GET ADDRESS OF TEMPORARY BUFFER 36$: MOVB (R1)+,(R0)+ ; MOVE A BYTE DEC R2 ; DONE YET? BGT 36$ ; IF GT NO, LOOP RETURN ; AND RETURN TO CALLER ;+ ; SUBROUTINE TO FORMAT NUMBER AS ASCII DECIMAL ;- 40$: CLR R2 ; SET NO LEADING ZEROES JMP $CBDMG ; CONVERT TO ASCII DECIMAL .PAGE .SBTTL D.P. INTEGER FORMATTER ROUTINE ;+ ; *** FNUMBR ; ; THIS ROUTINE TAKES A BINARY NUMBER (2 WORDS) AND FORMATS IT AS ; N,NNN,NNN IN A FIELD 12 CHARACTERS WIDE. SPACES ARE INSERTED ; WHERE NECESSARY. ; THIS ROUTINE SHOULD BE REWRITTEN TO USE THE FM.QIO ROUTINE. ; ; INPUT: ; R0 BUFFER ADDRESS ; R1 ADDRESS OF 2-WORD BLOCK CONTAINING NUMBER. ; ; OUTPUT: ; R0 UPDATED ; R1,R2 USED ; R3,R4,R5 PRESERVED ; ;- FNUMBR: ; ENTRY POINT JSR R5,$SAVRG ; SAVE R3,R4 AND R5 MOV R0,R5 ; COPY BUFFER POINTER MOV #FMTBUF,R0 ; SET ADDRESS FOR INTERNAL FORMAT CLR R2 ; SET NO LEADING ZEROES CALL $CDDMG ; FORMAT AS DECIMAL WITHOUT COMMAS SUB #FMTBUF,R0 ; CALCULATE NUMBER OF DIGITS MOV R0,R2 ; COPY IT DEC R0 ; REMOVE A DIGIT BEQ 10$ ; IF EQ ONLY ONE DIGIT (CAN SKIP DIVISION) MOV #3,R1 ; SET DIVISOR CALL $DIV ; DIVIDE INTO GROUPS 10$: MOV R0,-(SP) ; SAVE NUMBER OF COMMAS REQUIRED MOV R2,R3 ; CALCULATE LENGTH OF FINAL STRING ADD R0,R3 ; ASL R0 ; MULTIPLY BY THREE ADD (SP),R0 ; NEG R3 ; CALCULATE BLANK FILL REQUIREMENT ADD #12.,R3 ; BLE 14$ ; IF LE NONE REQUIRED 12$: MOVB #SPA,(R5)+ ; INSERT A BLANK DEC R3 ; DONE YET? BGT 12$ ; IF GT NO, LOOP 14$: NEG R0 ; CALC. PLACES LEFT OF LEADING COMMA ADD R2,R0 ; MOV #FMTBUF,R4 ; GET ADDRESS OF INTERNAL FORMATTED VERSION 15$: MOVB (R4)+,(R5)+ ; MOVE A LEADING DIGIT DEC R0 ; DONE YET? BNE 15$ ; IF NE NO, LOOP MOV (SP)+,R0 ; RESTORE NUMBER OF GROUPS OF 3 BEQ 30$ ; IF EQ THAT'S IT. 20$: MOVB #',,(R5)+ ; PUT IN A COMMA MOVB (R4)+,(R5)+ ; THEN THREE DIGITS MOVB (R4)+,(R5)+ ; MOVB (R4)+,(R5)+ ; DEC R0 ; ANY MORE GROUPS TO MOVE? BNE 20$ ; IF NE YES, LOOP 30$: MOV R5,R0 ; RESTORE UPDATED BUFFER POINTER RETURN ; AND RETURN TO CALLER .PAGE .SBTTL MONEY FORMATTER ROUTINE ;+ ; *** FMONEY ; ; THIS ROUTINE CONVERTS A 2-WORD SUM OF MONEY IN INTERNAL ; FORMAT TO ASCII FOR DISPLAY. TWO PLACES ARE PRESERVED ; AFTER THE DECIMAL POINT. SPACES ARE INSERTED TO MAKE THE ; FIELD RIGHT-JUSTIFIED AND 10 CHARACTERS WIDE. ; THIS ROUTINE SHOULD BE REWRITTEN TO USE THE FM.CHG ROUTINE. ; ; INPUT: ; R0 BUFFER ADDRESS ; R1 ADDRESS OF BALANCE TO CONVERT ; ; OUTPUT: ; R0 UPDATED WITH [-]0.00 ; R1,R2 USED ; ;- FMONEY: JSR R5,$SAVRG ; SAVE R3-R5 MOV R0,R5 ; COPY USER'S BUFFER POINTER MOV #FMTBUF,R0 ; SET UP OUT OWN MOV 2(R1),-(SP) ; PUSH LOW ORDER MONEY ON STACK MOV (R1),-(SP) ; FOLLOWED BY HIGH ORDER BGE 10$ ; IF GE IT'S POSITIVE MOVB #'-,(R0)+ ; AMOUNT IS NEGATIVE, PUT MINUS SIGN IN BUFFER NEG (SP) ; FIND THE MAGNITUDE OF THE AMOUNT NEG 2(SP) ; (NEGATE IT) SBC (SP) ; 10$: MOV SP,R1 ; LET R1 POINT TO THE NUMBER CLR R2 ; SET NO LEADING ZEROES TST (SP) ; HIGH ORDER BALANCE NON-ZERO? BNE 20$ ; IF NE YES, DON'T WANT LEADING ZEROES CMP #10000.,2(SP) ; AMOUNT LESS THAN ONE DOLLAR? BLOS 20$ ; IF LOS NO, DON'T WANT LEADING ZEROES INC R2 ; < 1 DOLLAR, SET TO INCLUDE LEADING ZEROES MOVB #'0,(R0)+ ; START STRING WITH A ZERO 20$: CALL $CDDMG ; FORMAT THE AMOUNT CMP (SP)+,(SP)+ ; CLEAN THE STACK MOVB -(R0),1(R0) ; MOVE OVER THE LAST FOUR DIGITS MOVB -(R0),1(R0) ; MOVB -(R0),1(R0) ; MOVB -(R0),1(R0) ; MOVB #'.,(R0)+ ; INSERT A DECIMAL POINT ADD #2,R0 ; INCLUDE TWO DIGITS SUB #FMTBUF,R0 ; CALCULATE LENGTH OF STRING MOV R0,R2 ; COPY IT MOV R5,R0 ; RESTORE USER'S BUFFER ADDRESS MOV R2,R3 ; CALCULATE BLANK FILL REQUIREMENT NEG R3 ; ADD #10.,R3 ; BLE 40$ ; IF LE NONE REQUIRED 30$: MOVB #SPA,(R0)+ ; INSERT A BLANK DEC R3 ; ANY MORE NEEDED? BGT 30$ ; IF GT YES, LOOP 40$: MOV #FMTBUF,R1 ; GET ADDRESS OF INTERNAL VERSION 50$: JMP CO.PY ; TRANSFER CHARACTERS AND RETURN .PAGE .SBTTL ASCII TO BINARY UIC CONVERSION ROUTINE ;+ ; *** CVTUIC ; ; THIS ROUTINE TAKES AN ASCII UIC IN THE FORM GGGMMM AND CONVERTS ; IT TO BINARY. THE RESULT IS STORED IN THE RECORD BUFFER. ; ; INPUTS: ; R0 ADDRESS OF LOCATION TO STORE BINARY UIC ; R5 ADDRESS OF ASCII UIC STRING ; ; OUTPUTS: ; R0 (INPUT R0)+2 ; R1 USED ; R5 (INPUT R5)+6 ; ;- CVTUIC: CALL 10$ ; CONVERT GROUP CODE TO BINARY MOVB R1,(R0)+ ; INSERT IN BUFFER CALL 10$ ; CONVERT MEMBER CODE TO BINARY MOVB R1,(R0)+ ; INSERT IN BUFFER SWAB -2(R0) ; POSITION GRP/MEM IN RIGHT PLACES RETURN ; AND RETURN TO CALLER 10$: MOVB (R5)+,R1 ; GET FIRST CHARACTER SUB #'0,R1 ; SUBTRACT CHARACTER BIAS ASL R1 ; MULTIPLY BY EIGHT ASL R1 ; ASL R1 ; MOVB (R5)+,R2 ; GET SECOND CHARACTER SUB #'0,R2 ; SUBTRACT CHARACTER BIAS ADD R2,R1 ; ADD TO RUNNING TOTAL ASL R1 ; MULTIPLY BY EIGHT ASL R1 ; ASL R1 ; MOVB (R5)+,R2 ; GET THIRD AND LAST CHARACTER SUB #'0,R2 ; SUBTRACT CHARACTER BIAS ADD R2,R1 ; ADD TO FORM COMPLETE RESULT RETURN ; RETURN TO CALLER .PAGE .SBTTL STRING COPY ROUTINE ;+ ; *** RCOPYW ; ; THIS ROUTINE TRANSFERS WORDS OF DATA FROM ONE PLACE TO ANOTHER. ; ; INPUTS: ; R0 SOURCE ADDRESS (EVEN) ; R1 DESTINATION ADDRESS (EVEN) ; R2 WORD COUNT ; ;- RCOPYW: MOV (R0)+,(R1)+ ; MOVE A WORD DEC R2 ; DONE YET? BGT RCOPYW ; IF GT NO, LOOP RETURN ; .PAGE .SBTTL UIC FORMATTER ROUTINE ;+ ; *** FMTUIC ; ; THIS ROUTINE STICKS THE UIC IN THE FORM [GGG,MMM] INTO ; THE OUTPUT BUFFER. ; ; INPUT: ; R0 BUFFER POINTER ; R5 CONTROL BLOCK ADDRESS ; ; OUTPUT: ; R0 UPDATED ; ALL OTHER REGISTERS PRESERVED ; ;- FMTUIC: MOVB #'[,(R0)+ ; INSERT LEADING SEPARATOR ADD #R.GRP,R5 ; POINT TO ASCII UIC MOVB (R5)+,(R0)+ ; INSERT GROUP CODE MOVB (R5)+,(R0)+ ; MOVB (R5)+,(R0)+ ; MOVB #',,(R0)+ ; INSERT A COMMA MOVB (R5)+,(R0)+ ; INSERT MEMBER CODE MOVB (R5)+,(R0)+ ; MOVB (R5)+,(R0)+ ; MOVB #'],(R0)+ ; INSERT FINAL SEPARATOR SUB #,R5 ; ADJUST R5 BACK TO ENTRY VALUE RETURN ; AND RETURN .PAGE .SBTTL QUEUE INSERTION ROUTINE ;+ ; *** INSERT ; ; THIS ROUTINE IS CALLED TO LINK A PACKET THAT HAS BEEN OBTAINED ; FROM DYNAMIC MEMORY INTO A FIFO LIST. ; ; INPUT: ; R0 ADDRESS OF LISTHEAD ; R1 ADDRESS OF PACKET TO BE INSERTED ; ; OUTPUT: ; THE ENTRY IS INSERTED ; ALL REGISTERS ARE PRESERVED ; ;- INSERT: MOV R2,-(SP) ; SAVE R2 MOV 2(R0),R2 ; GET ADDRESS OF LAST ENTRY IN LIST MOV R1,2(R0) ; SET ADDRESS OF NEW LAST ENTRY CLR (R1) ; AND CLEAR ITS LINK TO THE NEXT ENTRY MOV R1,(R2) ; LINK THE NEW ENTRY TO THE PREVIOUS ENTRY MOV (SP)+,R2 ; RESTORE R2 RETURN ; AND RETURN TO THE CALLER .PAGE .SBTTL /LI SWITCH PROCESSING ROUTINE ;+ ; *** LISWT ; ; THIS ROUTINE IS CALLED FOR EACH ACCEPTED TRANSACTION IF THE /LI ; SWITCH WAS SPECIFIED. IT LISTS DETAILS OF THE TRANSACTION IN THE ; OUTPUT FILE. ; CURRENTLY, THIS ROUTINE HANDLES ONLY REQUESTS WRITTEN BY ...BYE ; ;- LISWT: MOV #RECBUF,R5 ; SET RECORD BUFFER ADDRESS CMP #FF.BYE,F.CODE(R5) ; LOGOFF TRANSACTION? BNE 100$ ; IF EQ NO, SKIP IT MOV #OUTBUF,R0 ; GET OUTPUT BUFFER ADDRESS MOVSTR #BYESTR ; INSERT "BYE " TEXT MOV R5,R1 ; POINT TO DATE AND TIME ADD #F.TIME,R1 ; CALL DATTIM ; FORMAT DATE AND TIME MOVB #SPA,(R0)+ ; INSERT A SPACE MOV F.UIC(R5),R3 ; GET UIC CALL FM.UIC ; AND FORMAT MOVSTR #BYEDEV ; INSERT " DEV=" MOVB F.DEVN(R5),(R0)+ ; INSERT DEVICE NAME MOVB F.DEVN+1(R5),(R0)+ ; MOV F.DEVU(R5),R1 ; CALL OC.TAL ; MOVB #':,(R0)+ ; MOVSTR #BYEREC ; INSERT " REC=" MOV NRECT,R1 ; GET RECORD NUMBER CALL DE.CML ; FORMAT AS DECIMAL ASCII MOVSTR #BYEVBN ; INSERT " VBN=" MOV #$RFFDB+F.VBN,R1 ; POINT TO VIRTUAL BLOCK NUMBER CALL FM.QIO ; FORMAT MOVSTR #BYECON ; INSERT " CONN=" MOV R5,R1 ; POINT TO CONNECT TIME ADD #F.CONN,R1 ; CALL FM.CON ; FORMAT MOVSTR #BYECPU ; INSERT " CPU=" MOV R5,R1 ; POINT TO CPU TIME ADD #F.CPU,R1 ; CALL FM.CPU ; FORMAT CPU TIME SUB #OUTBUF,R0 ; CALCULATE MESSAGE LENGTH FILE #OUTBUF,R0 ; AND WRITE TO OUTPUT FILE 100$: RETURN ; AND RETURN TO CALLER .END