.TITLE ACCBYE .IDENT /V7.18/ ;******************************************************************* ; ; ACCBYE ; ; THIS MODULE IS CALLED FROM THE BYE COMMAND TO PERFORM THE ; ACCOUNTING SYSTEM PROCESSING AT LOGOFF. ; TO BE USED WITH ACCOUNTING SYSTEM VERSION 7. ; ; VERSION: V6 FEBRUARY 1980 ; VERSION: V7 JANUARY 1981 ; ; STEVE THOMPSON SCHOOL OF CHEMICAL ENGINEERING ; OLIN HALL ; CORNELL UNIVERSITY ; ITHACA NY 14853 ; ; REVISION HISTORY ; ---------------- ; ; SMT707 7-JUL-81 ADDITIONAL OF LOG... SIMULATED LOGON AT ; SYSTEM START. CODE IS REQUIRED HERE BECAUSE ; LOG... IS UNABLE TO SET UP THE ACCOUNT ; NUMBER. ; ; SMT718 20-JUL-81 ADDED PAGE COUNTER FROM LOG... THIS IS NOT ; RECORDED IN THE TRANSACTIONS FILE YET. ; ; SMT724 27-JUL-81 ADDED CODE TO CHARGE FOR AND RECORD PAGES ; PRINTED USING QMG.../LPP0 ; ; SMT734 30-JUL-81 EXETENDED BUFFERS FOR FORMATTING THE ACCOUNT ; BALANCE AND SESSION CHARGES COST TO PREVENT ; PROBLEMS WHEN USING THE "FMTUNI" MODULE. ; ; SMT753 7-OCT-81 CHANGED NAMES OF CONDITIONAL ASSEMBLY ; PARAMETERS; SEE THE FILES MODIFY.TXT AND ; CONDEF.MAC FOR DETAILS. ; ; SMT757 7-OCT-81 ADDED CODE FOR REPORTING OF MEMORY USAGE. ; NB. THERE IS NO CODE FOR CHARGING FOR THIS ; RESOURCE INCLUDED AT PRESENT. ; ; SMT769 12-OCT-81 CHANGED TO CENTRALISED BATCH STREAM NAME. ; ; SMT774 24-OCT-81 ADDED SUPPORT FOR CHARGING AND LOGGING OF ; MEMORY USAGE. ; ; SMT776 26-OCT-81 RESTORED ORIGINAL USE OF $USRSB ROUTINE. THE ; ROUTINE HEREIN WAS RENAMED TO $RQBYE. ; ; SMT779 31-OCT-81 FIXED A BUG THAT CAUSED ODD BEHAVIOUR IF THE ; TRANSACTIONS FILE COULD NOT BE OPENED. ; ; SMT794 24-NOV-81 DON'T PRODUCE PAGES PRINTED DISPLAY IF THERE ; WERE NO PAGES PRINTED. ; ; SMT804 16-MAR-82 CORRECT BALANCE FORMATTING IF "UNITS" OPTION ; IS SELECTED. ; ; SMT814 12-APR-82 ADDED RSX-11M V4.0 SUPPORT (LOWER CASE ; MESSAGES AND SILENT LOGOUT SUPPORT) ; ; SMT821 23-APR-82 CHANGED ENTRY POINT NAMES OF ACCOUNTING ; SUPPORT ROUTINES (SEE MODIFY.TXT) ; ; SMT842 13-APR-83 ADDED SUPPORT FOR BATCH SYSTEM VERSION 3. ; ; SMT851 22-JUL-83 ADDED RSX-11M V4.1 SUPPORT ; ; DLE001 4-apr-86 Added check for null device name string in ; the account files FDB. ; ;******************************************************************* .MCALL FINIT$ .MCALL GTIM$S,QIOW$ .MCALL EXIT$S .MCALL EXST$S .IF DF AA$V40 ! AA$V41 .IF DF A$$CLI .MCALL GCII$S .ENDC ; DF A$$CLI .ENDC ; DF AA$V40 ! AA$V41 ACTDF$ <:>,<=> ; DEFINE ADDITIONAL ACCOUNT FILE ENTRY OFFSETS GLOBALLY ACCDF$ <:>,<=> ; DEFINE ACCOUNTING PACKET OFFSETS GLOBALLY BITDF$ <:>,<=> ; DEFINE ACCOUNTING BIT MASKS GLOBALLY FILDF$ ; DEFINE A/C DATA FILE OFFSETS BATDV$ ; DEFINE BATCH STREAM DEVICE NAME EFN = 1 ; EVENT FLAG FOR A/C FILE I/O SPA = 40 CR = 15 LF = 12 BELL = 7 ; ; ERROR MESSAGES ; .NLIST BEX .IIF DF AA$V40 ! AA$V41, .ENABL LC .IIF NDF AA$V40 & AA$V41, .DSABL LC ERR1: .ASCIZ /BYE -- Logging task not in directory/ ERR2: .ASCIZ /BYE -- Logging task is inactive/ ERR3: .ASCIZ /BYE -- Memory allocation failure/ ERR4: .ASCIZ /BYE -- Can't provide accounting data/ ERR5: .ASCII /BYE -- Can't open records file - FCS / ERR5A: .BLKB 6. ERR6: .ASCII /BYE -- Can't write to records file - FCS / ERR6A: .BLKB 6 ERR7: .ASCIZ /BYE -- Account file open failure/ ERR8: .ASCIZ /BYE -- Can't find your account record/ ERR9: .ASCIZ /*WARNING* Account chained while logged on/ ; ; TEXT MESSAGES ; TSK: .ASCIZ / Tasks)/ MSG1: .ASCII /Connect time: / MSG1A: .ASCII /NNH NNM NNS (00000 TASKS)/ .IF DF AA$BV3 MSG1J: .ASCII /Elapsed time: / MSG1JA: .ASCII /NNH NNM NNS (00000 TASKS)/ .ENDC ; DF AA$BV3 MSG2: .ASCII /CPU Time: / MSG2A: .ASCII /NNH NNM NNS NNT/ .IF DF AA$QIO & AA$TCQ MSG3: .ASCII "I/O Requests: " MSG3A: .ASCII /000,000,000/ .ENDC ; DF AA$QIO & AA$TCQ MSG4: .ASCII /Session Charges: / MSG4A: .ASCII /$0000.000 Units/ .IF DF AA$BV3 MSG4J: .ASCII /Cost of job: / MSG4JA: .ASCII /$0000.000 Units/ .ENDC ; DF AA$BV3 MSG5: .ASCII /New Balance: / MSG5A: .ASCII /$0000.000 Units/ MSG6: .ASCIZ /*WARNING* Account Overdrawn/ MSG7: .BYTE CR,'>,LF,0 MSG8: .ASCII /Pages Printed: / MSG8A: .ASCII /00000/ .IF DF AA$MEM MSG9: .ASCII /Memory usage: / MSG9A: .ASCII /0000000.00/ MSG9B: .ASCIZ / Kw-Hrs/ .ENDC ; DF AA$MEM .EVEN LOGNAM: .RAD50 /LOG.../ ; LOGGING TASK NAME LOGPTR: .WORD 0 ; TCB ADDRESS OF LOGGING TASK PKTADR: .WORD 0 ; DSR PACKET ADDRESS ACCERR: .BYTE 0 ; ACCOUNT ERROR FLAG NEGFLG: .BYTE 0 ; ACCOUNT SIGN FLAG RECERR: .BYTE 0 ; TRANSACTIONS FILE OPEN ERROR FLAG WRNFLG: .BYTE 0 ; CHAIN WARNING FLAG PAGFLG: .BYTE 0 ; PAGES PRINTED MESSAGE FLAG .EVEN ACNO: .WORD 0 ; ACCOUNT NUMBER FOR CHARGING PURPOSES SESCHG: .WORD 0 ; TOTAL SESSION CHARGES .WORD 0 ; CONBLK: .WORD $CON1 ; CONNECT CHARGE CONSTANTS BLOCK .WORD $CON2 ; SPCBLK: .WORD 0 ; SPECIAL RATE CONSTANTS BLOCK .WORD 0 ; CPUBLK: .WORD $CPU1 ; CPU CHARGE CONSTANTS BLOCK .WORD $CPU2 ; .IF DF AA$QIO & AA$TCQ QIOBLK: .WORD $QIO1 ; I/O CHARGE CONSTANTS BLOCK .WORD $QIO2 ; .ENDC ; DF AA$QIO & AA$TCQ .IF DF AA$MEM MEMBLK: .WORD $MEM1 ; MEMORY USE CHARGE CONSTANTS BLOCK .WORD $MEM2 ; .ENDC ; DF AA$MEM .IF DF AA$V40 ! AA$V41 .IF DF A$$CLI CLIBUF: .BLKB 6 ; CLI INFORMATION BUFFER .ENDC ; DF A$$CLI .ENDC ; DF AA$V40 ! AA$V41 .BLKB 4 UIC: .BLKB 6 ; UIC FORMATTER WORKSPACE ;+ ; *** $GBLOG ; ; THIS ROUTINE PROVIDES LOG... SEARCH SUPPORT FOR BYE ; TO BE USED WITH ACCOUNTING SYSTEM VERSION 7. ; ;- $GBLOG:: MOV #LOGNAM,R3 ; GET NAME OF LOGGING TASK CALL $SRSTD ; SEARCH STD FOR IT BCC 20$ ; OK MOV #ERR1,R0 ; SET ADDRESS OF ERROR MESSAGE 10$: CALL OUT.PT ; WRITE IT OUT BR ERRORX ; AND EXIT 20$: BIT #TS.EXE,T.STAT(R0) ; GOT IT, BUT IS IT ACTIVE? BEQ 30$ ; IF EQ YES MOV #ERR2,R0 ; SET UP ERROR MESSAGE PARAMETERS BR 10$ ; SEND IT OUT AND EXIT 30$: MOV R0,LOGPTR ; SAVE LOG...'S TCB ADDRESS RETURN ; RETURN TO CALLER ;+ ; *** ERRORX ; ; THIS ROUTINE IS CALLED IF AN ERROR IS DETECTED THAT DOES NOT ALLOW ; US TO LOG OFF (!!). THE ACCOUNT FILE IS CLOSED AND WE MAKE SURE ; THAT THE TERMINAL IS NOT SLAVED. ; ;- ERRORX::CALL $AFCLS ; MAKE SURE ACCOUNT FILE IS NOT OPEN MOV $TKTCB,R0 ; GET OUR TCB ADDRESS MOV T.UCB(R0),R0 ; AND OUR TI: UCB ADDRESS BIC #U2.SLV,U.CW2(R0) ; MAKE SURE WE'RE NOT SLAVED EXST$S #EX$SEV ; EXIT WITH SEVERE ERROR ;+ ; *** $RQBYE ; ; THIS ROUTINE SENDS A LOGOFF REQUEST TO LOG... FOR BYE. ; ;- $RQBYE::CLR PKTADR ; SET NO DSR PACKET CALL $SWSTK,30$ ; SWITCH STACKS MOV #B.LBYE,R1 ;; GET LENGTH OF PACKET NEEDED CALL $ALOCB ;; TRY AND GET A BUFFER BCS 20$ ;; IF CS THEN COULDN'T GET ONE MOV R0,PKTADR ;; SAVE PACKET ADDRESS MOV $TKTCB,R5 ;; GET OUR TCB ADDRESS MOV R5,B.BTCB(R0) ;; PUT IT IN THE PACKET MOV T.UCB(R5),R5 ;; GET OUR TI: UCB ADDRESS 10$: MOV U.RED(R5),R5 ;; FOLLOW REDIRECT POINTER CMP R5,U.RED(R5) ;; END OF LIST? BNE 10$ ;; IF NE NO, LOOP MOV R5,B.UCB(R0) ;; PUT IT IN THE PACKET MOV #,B.MASK(R0) ;; AND BYE COMMAND MASK MOV R0,R1 ;; COPY PACKET ADDRESS TO R1 MOV LOGPTR,R0 ;; GET LOG...'S TCB ADDRESS CALL $EXRQF ;; QUEUE PACKET AND START LOG... CALLR $STPCT ;; STOP US UNTIL WE GET A REPLY 20$: RETURN ;; BACK TO USER LEVEL 30$: TST PKTADR ; DID WE DO IT OK? BNE 20$ ; NE IS GOOD SO RETURN MOV #ERR3,R0 ; SET UP MESSAGE PARAMETERS CALL OUT.PT ; TYPE OUT ERROR MESSAGE JMP ERRORX ; JUMP TO EXIT AND CLEAN UP ROUTINE ;+ ; *** $FINBY ; ; THIS ROUTINE TAKES THE USAGE FIGURES RETURNED BY LOG... AND ; CALCULATES AND LOGS THE CHARGES. IT IS CALLED BY THE MAIN ; BYE MODULE. REGISTER R5 IS USED THROUGHOUT THIS ROUTINE AS THE ; ADDRESS OF THE DSR PACKET USED FOR BYE/LOG... COMMUNICATION. ; ;- $FINBY:: FINIT$ ; .IF DF AA$BV3 TST $BATCH ; VERSION 3 BATCH JOB? BEQ 1$ ; IF EQ NO MOVB #240,OTPQIO+Q.IOPL+5 ; YES, FLAG MESSAGES FOR HISTORY FILE 1$: ; REF. LABEL .ENDC ; DF AA$BV3 .IF DF AA$V40 ! AA$V41 .IF DF A$$CLI GCII$S #CLIBUF,#6 ; GET INFO. ON OUR CLI BCS 5$ ; IF CS IT FAILED BIC #CP.NIO,CLIBUF+G.CICS ; ASSUME NOISY LOGOUT 5$: ; REF. LABEL .ENDC ; DF A$$CLI .ENDC ; DF AA$V40 ! AA$V41 MOV PKTADR,R5 ; GET PACKET ADDRESS MOV B.UCB(R5),R3 ; GET UCB ADDRESS BIT #1,R3 ; DID LOG... HAVE ANYTHING FOR US? BEQ 10$ ; IF EQ YES, PROCESS IT MOV #ERR4,R0 ; NO, GET MESSAGE ADDRESS CALL OUTPT4 ; AND PRINT IT JMP 50$ ; DEALLOCATE PACKET AND EXIT 10$: CALL $RFOPN ; OPEN THE ACCOUNTING DATA FILE ; *NOTE* $RFOPN ZEROES THE DATA BUFFER, HENCE ; HAVING THE OPEN HERE. BCC 20$ ; IF CC GOOD MOVB F.ERR(R0),R1 ; GET FCS ERROR CODE MOV #ERR5A,R0 ; SET BUFFER POINTER CALL DC.SGN ; FORMAT AS SIGNED DECIMAL CLRB (R0) ; MAKE IT ASCIZ MOV #ERR5,R0 ; SET MESSAGE ADDRESS CALL OUTPT4 ; AND PRINT IT INCB RECERR ; SET ERROR FLAG 20$: MOV #FF.BYE,$RFREC ; SET TRANSACTION TYPE MOV #F.LBYE,$RFLEN ; AND TRANSACTION RECORD LENGTH MOV #<$RFREC+F.UIC>,R3 ; GET ADDRESS OF UIC LOC. IN BUFFER MOV B.UIC(R5),(R3)+ ; SAVE THE LOGON-TIME UIC MOV B.BACN(R5),ACNO ; SAVE ACCOUNT NUMBER FOR LATER USE BNE 25$ ; IF NE, THIS WAS NOT A SIMULATED LOGON ; BY LOG... AT SYSTEM START MOV #UIC,R0 ; GET AREA FOR ASCII MEMBER CODE MOVB B.UIC(R5),R1 ; GET BINARY MEMBER CODE CALL $CBOMG ; CONVERT TO 6 OCTAL DIGITS MOV #UIC-3,R0 ; GET AREA FOR ASCII GROUP CODE MOVB B.UIC+1(R5),R1 ; GET BINARY GROUP CODE CALL $CBOMG ; CONVERT TO 6 OCTAL DIGITS 25$: MOV B.BACN(R5),(R3)+ ; A/C NUM. TO WHICH ORIGINALLY LOGGED ON MOV B.BCHW(R5),(R3)+ ; A/C NUM TO WHICH CHARGES ARE MADE BEQ 30$ ; IF EQ, ACCOUNT WAS NOT CHAINED MOV B.BCHW(R5),ACNO ; SAVE NUM. OF MASTER ACCOUNT 30$: BIC #100000,ACNO ; MAKE SURE THE MASTER FLAG IS CLEAR TST (R3)+ ; SKIP F.MSTR FIELD FOR NOW MOV $TKTCB,R0 ; GET OUR TCB ADDRESS MOV T.UCB(R0),R0 ; NOW TI: UCB ADDRESS MOV U.DCB(R0),R2 ; GET DEVICE CONTROL BLOCK ADDRESS MOV D.NAM(R2),(R3)+ ; SAVE NAME OF OUR TI: DEVICE (F.DEVN) SUB D.UCB(R2),R0 ; CALCULATE RELATIVE UCB ADDRESS MOV D.UCBL(R2),R1 ; GET UCB LENGTH CALL $DIV ; CALCULATE RELATIVE UNIT NUMBER ADD D.UNIT(R2),R0 ; CALCULATE ABSOLUTE UNIT NUMBER BIC #177400,R0 ; ZAP THE RUBBISH MOV R0,(R3)+ ; SAVE THE DEVICE NUMBER (F.DEVU) ; ; PROCESS CONNECT TIME RETURNED BY LOG... ; MOV B.CONN(R5),(R3)+ ; SAVE THE CONNECT TIME MOV B.CONN+2(R5),(R3)+ ; .IF DF AA$BAT CMP (R3)+,(R3)+ ; ASSUME BATCH AND SKIP CONNECT CHARGE CMP $RFREC+F.DEVN,BATDEV ; BATCH JOB? BEQ 40$ ; IF EQ YES, THERE IS NO CONNECT CHARGE CMP -(R3),-(R3) ; REPOSITION POINTER .ENDC ; DF AA$BAT MOV R5,-(SP) ; SAVE DATA PACKET ADDRESS ADD #B.CONN,R5 ; POINT R5 TO CONNECT TIME MOV #CONBLK,R4 ; GET ML.DV ARGUMENT BLOCK ADDRESS CALL ML.DV ; CALCULATE CONNECT CHARGE MOV R1,(R3)+ ; SAVE CONNECT CHARGE MOV R2,(R3)+ ; MOV (SP)+,R5 ; RESTORE DSR BLOCK ADDRESS ; ; DEAL WITH NON-STANDARD CONNECT TIME RATES ; MOV B.BSCN(R5),R1 ; IS CONNECT RATE NON-STANDARD? BEQ 40$ ; IF EQ NO MOV R5,-(SP) ; SAVE CONTROL BLOCK ADDRESS CMP -(R3),-(R3) ; ADJUST TO START OF CONNECT CHARGE MOV R3,R5 ; COPY TO R5 READY FOR ML.DV CALL NONSTA ; READJUST THE CONNECT CHARGE MOV R1,(R3)+ ; SAVE NEW CONNECT CHARGE MOV R2,(R3)+ ; MOV (SP)+,R5 ; RESTORE R5 40$: MOV -4(R3),SESCHG ; SAVE CONNECT CHARGE IN TOTALS BUFFER MOV -2(R3),SESCHG+2 ; MOV R3,-(SP) ; WE MUSN'T LOSE THIS NUMBER! ; ; FORMAT CONNECT TIME AND NUMBER OF TASKS MESSAGE ; MOV #MSG1A,R0 ; GET MESSAGE OUTPUT BUFFER .IF DF AA$BV3 TST $BATCH ; VERSION 3 BATCH JOB? BEQ 42$ ; IF EQ NO MOV #MSG1JA,R0 ; YES, DIFFERENT MESSAGE 42$: ; REF. LABEL .ENDC ; DF AA$BV3 MOV R5,R1 ; POINT R1 TO CONNECT TIME ADD #B.CONN,R1 ; CALL FM.CON ; FORMAT CONNECT TIME MOVB #SPA,(R0)+ ; INSERT A SPACE MOVB #'(,(R0)+ ; INSERT LEADING BRACKET MOV B.BTCB(R5),R1 ; GET NUMBER OF TASKS RUN CALL DE.CML ; CONVERT TO DECIMAL MOVSTR #TSK ; ADD TRAILING MESSAGE ; (THERE WILL BE A NULL BYTE AT THE END) ; ; PROCESS THE CENTRAL PROCESSOR TIME FOR THIS SESSION ; MOV #MSG2A,R0 ; GET CPU MESSAGE ADDRESS MOV R5,R1 ; POINT R1 TO CPU TIME ADD #B.SCPU,R1 ; CALL FM.CPU ; FORMAT CPU MESSAGE CLRB (R0) ; TERMINATE WITH NULL BYTE MOV (SP)+,R3 ; RESTORE DATA BUFFER POINTER MOV B.SCPU(R5),(R3)+ ; SAVE CPU TIME MOV B.SCPU+2(R5),(R3)+ ; MOV R5,-(SP) ; AND THE DSR BLOCK ADDRESS ADD #B.ECPU,R5 ; POINT R5 TO EFFECTIVE (PRIO. ADJ.) CPU TIME MOV (R5),R1 ; GET NON-STANDARD CPU RATE WORD BEQ 52$ ; IF EQ, STANDARD RATE APPLIES CALL NONSTA ; APPLY NON-STANDARD RATE MOV R2,-(R5) ; SAVE THE RESULT MOV R1,-(R5) ; 52$: MOV #CPUBLK,R4 ; GET CPU CHARGE ML.DV ARGUMENT BLOCK ADDRESS CALL ML.DV ; CALCULATE CPU CHARGE MOV (SP)+,R5 ; RESTORE DSR BLOCK ADDRESS MOV R1,(R3)+ ; SAVE THE CPU CHARGE IN DATA BUFFER MOV R2,(R3)+ ; ; ; PROCESS THE I/O REQUEST COUNT FOR THIS SESSION ; .IF DF AA$QIO & AA$TCQ MOV B.SQIO(R5),(R3)+ ; SAVE THE I/O COUNT MOV B.SQIO+2(R5),(R3)+ ; MOV R5,R1 ; POINT TO I/O TIME IN BUFFER ADD #B.SQIO,R1 ; MOV #MSG3A,R0 ; GET I/O MESSAGE ADDRESS CALL FM.QIO ; FORMAT I/O MESSAGE CLRB (R0) ; TERMINATE WITH NULL BYTE MOV R5,-(SP) ; SAVE DSR CORE BLOCK ADDRESS ADD #B.SQIO,R5 ; POINT R5 TO I/O COUNT MOV (R5),R1 ; GET NON-STANDARD I/O RATE WORD BEQ 54$ ; IF EQ, STANDARD RATE APPLIES CALL NONSTA ; APPLY NON-STANDARD RATE MOV R2,-(R5) ; SAVE THE RESULT MOV R1,-(R5) ; 54$: MOV #QIOBLK,R4 ; GET I/O CHARGE ARG. BLOCK ADDRESS CALL ML.DV ; CALCULATE I/O CHARGE MOV R1,(R3)+ ; SAVE I/O CHARGE IN DATA BUFFER MOV R2,(R3)+ ; MOV (SP)+,R5 ; RESTORE DSR CORE BLOCK ADDRESS .IFF ADD #8.,R3 ; SKIP UNUSED FIELDS .IFTF ; ; PROCESS THE PAGES PRINTED DURING THIS TERMINAL SESSION ; MOV #MSG8A,R0 ; GET OUTPUT BUFFER ADDRESS FOR # PAGES MOV B.BPAG(R5),R1 ; GET COUNT OF PAGES PRINTED BEQ 5401$ ; IF EQ NONE WERE PRINTED INCB PAGFLG ; SHOW THAT WE WANT TO PRINT THIS CALL DE.CML ; FORMAT AS ASCII DECIMAL CLRB (R0) ; END MESSAGE WITH NULL BYTE 5401$: MOV B.BPAG(R5),R0 ; GET NUMBER OF PAGES PRINTED CLR (R3)+ ; SAVE IN DATA BUFFER MOV R0,(R3)+ ; MOV #$PAG1,R1 ; GET CHARGE PER PAGE CALL $MUL ; CALCULATE PAPER COST MOV R0,(R3)+ ; SAVE IN DATA BUFFER MOV R1,(R3)+ ; ; ; PROCESS THE MEMORY USAGE DURING THIS TERMINAL SESSION. WE DIVIDE BY ; 576. TO CONVERT FROM 64W-SECS TO 100*KW-HRS. ; .IF DF AA$MEM MOV B.BCOR(R5),(R3)+ ; TRANSFER MEMORY USE TO RECORDING BUFFER MOV B.BCOR+2(R5),(R3)+ ; ADD #B.BCOR,R5 ; POINT R5 TO MEMORY USAGE MOV #MEMBLK,R4 ; GET ADDRESS OF CHARGE CONSTANTS BLOCK CALL ML.DV ; CALCULATE MEMORY USAGE CHARGE ; (OUTPUT R5=INPUT R5+4) MOV R1,(R3)+ ; SAVE THE RESULTS MOV R2,(R3)+ ; MOV R3,-(SP) ; SAVE R3 MOV #576.,R0 ; SET DIVISOR MOV -(R5),R2 ; GET LOW ORDER CORE USAGE MOV -(R5),R1 ; GET HIGH ORDER CORE USAGE CALL $DDIV ; CONVERT TO 100.*KW-HRS MOV R1,(R5) ; SAVE THE RESULT MOV R2,2(R5) ; MOV R5,R1 ; POINT R1 TO RESULT FIELD MOV #MSG9A,R0 ; GET BUFFER ADDRESS CALL F2.DEC ; FORMAT KW-HRS MEMORY USAGE MOVSTR #MSG9B ; INSERT "KW-HRS" TEXT (THERE WILL BE A ; NULL BYTE AT THE END) MOV (SP)+,R3 ; RESTORE R3 .IFF ; DF AA$MEM ADD #8.,R3 ; SKIP UNUSED FIELDS .IFTF ; DF AA$MEM ; ; ADD CPU, I/O, PAGE AND MEMORY CHARGES TO CONNECT CHARGE AND FORMAT RESULT ; MOV #SESCHG+2,R1 ; GET ADDRESS+2 OF SESSION CHARGES BUFFER .IFT ; DF AA$MEM ADD -(R3),(R1) ; ADD IN THE MEMORY CHARGE ADC -(R1) ; ADD -(R3),(R1)+ ; CMP -(R3),-(R3) ; POINT BACK TO PAGE CHARGE .IFF ; DF AA$MEM SUB #8.,R3 ; POINT BACK TO PAGE CHARGE .ENDC ; DF AA$MEM ADD -(R3),(R1) ; ADD IN THE PAGE CHARGE ADC -(R1) ; ADD -(R3),(R1)+ ; CMP -(R3),-(R3) ; POINT BACK TO I/O CHARGE .IFT ; DF AA$QIO & AA$TCQ ADD -(R3),(R1) ; ADD IN THE I/O CHARGE ADC -(R1) ; ADD -(R3),(R1)+ ; CMP -(R3),-(R3) ; POINT BACK TO CPU CHARGE .IFF ; DF AA$QIO & AA$TCQ SUB #8.,R3 ; POINT BACK TO CPU CHARGE .ENDC ; DF AA$QIO & AA$TCQ ADD -(R3),(R1) ; ADD IN CPU CHARGES ADC -(R1) ; ADD -(R3),(R1) ; MOV #MSG4A,R0 ; GET SESSION CHARGES MESSAGE ADDRESS .IF DF AA$BV3 TST $BATCH ; VERSION 3 BATCH JOB? BEQ 742$ ; IF EQ NO MOV #MSG4JA,R0 ; YES, DIFFERENT MESSAGE 742$: ; REF. LABEL .ENDC ; DF AA$BV3 CALL FM.CHG ; FORMAT THE CHARGE .IF DF AA$UNI CLRB (R0) ; MAKE IT ASCIZ .IFF CLRB -(R0) ; MAKE IT ASCIZ AND LOSE LAST DIGIT .ENDC ; DF AA$UNI ; ; DEALLOCATE THE RECEIVE PACKET ; 50$: MOV PKTADR,R5 ; GET DSR PACKET ADDRESS MOV B.UCB(R5),R3 ; GET UCB FIELD (MAY HAVE BIT 0 SET) CALL $SWSTK,60$ ; SWITCH STACKS MOV R5,R0 ;; GET PACKET ADDRESS MOV #B.LBYE,R1 ;; GET PACKET LENGTH CALLR $DEACB ;; DEALLOCATE THE PACKET ;; AND RETURN TO USER LEVEL 60$: BIT #1,R3 ; DID LOG... REPORT NO DATA? BEQ 61$ ; IF EQ NO, CONTINUE JMP 160$ ; YES, EXIT NOW 61$: ; REF. LABEL ; ; UPDATE THE USER'S BALANCE ; CALL $SWSTK,90$ ; SWITCH STACKS MOV $DEVHD,R2 ;; START AT BEGINNING OF DEVICE TABLE 70$: CMP D.NAM(R2),#"LB ;; LOOK FOR LB: BEQ 80$ ;; IF EQ WE FOUND IT MOV D.LNK(R2),R2 ;; TRY NEXT DEVICE BNE 70$ ;; AND SEE WHAT WE'VE GOT CLR 4(SP) ;; ERROR, SET USER R1 TO ZERO RETURN ;; AND RETURN TO USER STATE 80$: MOV D.UCB(R2),R0 ;; GET UCB ADDRESS MOV U.RED(R0),R0 ;; FIND PHYSICAL LB: MOV U.DCB(R0),R2 ;; FIND DCB OF PHSICAL DEVICE MOV D.NAM(R2),4(SP) ;; PUT ITS NAME IN USER STATE R1 SUB D.UCB(R2),R0 ;; CALCULATE UNIT NUMBER MOV D.UCBL(R2),R1 ;; CALL $DIV ;; ADD D.UNIT(R2),R0 ;; BIC #177400,R0 ;; MOV R0,6(SP) ;; PUT IT INTO USER STATE R2 RETURN ;; AND RETURN TO USER STATE 90$: TST R1 ; DID WE FIND LB:? BEQ 100$ ; IF EQ NO, SAY ACCOUNT FILE OPEN ERROR MOV $ACTFL+F.DSPT,R0 ; GET ADDRESS OF DATASET DESCRIPTOR MOV 2(R0),R0 ; GET ADDRESS OF DEVICE STRING beq 95$ ; If null then none given ; DLE001 MOV R1,(R0)+ ; INSERT LB:'S DEVICE NAME MOV R2,R1 ; SET UP TO CONVERT UNIT # TO ASCII MOV PC,R2 ; LEADING ZEROES CALL $CBTMG ; FORMAT UNIT # IN DEVICE STRING MOV $ACTFL+F.DSPT,R0 ; GET ADDRESS OF DATASET DESCRIPTOR ; DLE001 mov #5,(r0) ; Set length of previous info ; DLE001 ; ; DLE001 95$: ; DLE001 CALL $AFOPN ; OPEN ACCOUNT FILE BCC 110$ ; GOOD 100$: MOV #ERR7,R0 ; GET ERROR MESSAGE ADDRESS CALL OUTPT4 ; AND PRINT IT INCB ACCERR ; SET ACCOUNT ERROR JMP 150$ ; 110$: MOV #ACCPT1,$ASUBR ; SET ADDRESS OF A/C ACCEPTANCE ROUTINE TST ACNO ; SIMULATED LOGON BY LOG...? BNE 112$ ; IF NE NO MOV #ACCPT3,$ASUBR ; YES, USE ALTERNATE ACCEPTANCE ROUTINE 112$: CALL $ASCAN ; LOCATE THE ACCOUNT IN THE FILE BCC 120$ ; OK 115$: CALL $AFCLS ; CLOSE ACCOUNT FILE BEFORE TI: I/O IN CASE ; USER TYPES CTRL/S MOV #ERR8,R0 ; GET ADDRESS OF ACCOUNT NOT FOUND MESSAGE CALL OUTPT4 ; AND PRINT IT INCB ACCERR ; SET ACCOUNT ERROR JMP 150$ ; 120$: TST ACNO ; SIMULATED LOGON? BNE 122$ ; IF NE NO MOV A.ACNO(R0),R1 ; YES, SAVE ORIGINAL ACCOUNT NUMBER ; (LOG... WAS UNABLE TO SUPPLY IT) BIC #100000,R1 ; ZAP THE MASTER FLAG MOV R1,$RFREC+F.ACNO ; AND STORE IN RECORD BUFFER 122$: MOV A.CHWD(R0),ACNO ; HAS THE ACCOUNT BEEN CHAINED WHILE LOGGED ON? BEQ 125$ ; IF EQ NO, NORMAL SITUATION INCB WRNFLG ; SET FLAG TO PRINT WARNING MESSAGE MOV #ACCPT2,$ASUBR ; SET ACCEPTANCE ROUTINE ADDRESS CALL $ASCAN ; LOOK FOR THE NEW MASTER BCS 115$ ; IF WE CAN'T FIND IT 125$: MOV R0,-(SP) ; SAVE ACCOUNT ENTRY ADDRESS MOV A.ACNO(R0),R1 ; GET A/C NUMBER OF FINAL MASTER BIC #100000,R1 ; MAKE SURE THE MASTER FLAG IS CLEAR MOV R1,$RFREC+F.MSTR ; AND MAKE SURE WE LOG IT SUB SESCHG+2,A.CASH+2(R0) ; UPDATE THE USER'S BALANCE SBC A.CASH(R0) ; SUB SESCHG,A.CASH(R0) ; BGE 130$ ; IF GE BALANCE IS STILL POSITIVE INCB NEGFLG ; SHOW BALANCE AS NEGATIVE 130$: CALL $AFPUT ; REWRITE THE ACCOUNT FILE WITH THE ; NEW BALANCE CALL $AFCLS ; AND CLOSE THE ACCOUNT FILE MOV (SP)+,R1 ; RESTORE ACCOUNT ENTRY ADDRESS ADD #A.CASH,R1 ; POINT TO ACCOUNT BALANCE MOV #MSG5A,R0 ; GET BUFFER ADDRESS FOR BALANCE TEXT CALL FM.CHG ; AND FORMAT IT .IF DF AA$UNI CLRB (R0) ; MAKE IT ASCIZ .IFF CLRB -(R0) ; MAKE IT ASCIZ AND LOSE LAST DIGIT .ENDC ; DF AA$UNI TSTB RECERR ; WAS THERE A TRANSACTIONS FILE OPEN ERROR? BNE 142$ ; IF NE YES, SKIP RECORDING THIS SESSION CALL $RFPUT ; LOG THE TERMINAL SESSION IN THE FILE BCC 140$ ; DONE MOVB F.ERR(R0),R1 ; GET FCS ERROR CODE MOV #ERR6A,R0 ; SET BUFFER POINTER CALL DC.SGN ; FORMAT AS SIGNED DECIMAL CLRB (R0) ; MAKE IT ASCIZ MOV #ERR6,R0 ; SET ERROR MESSAGE ADDRESS CALL OUTPT4 ; AND PRINT IT 140$: CALL $RFCLS ; CLOSE THE ACCOUNTING DATA FILE 142$: ; REF. LABEL ; ; SIGNAL TIMES AND CHARGES TO USER ; 150$: TSTB WRNFLG ; SHOULD WE PRINT CHAIN WARNING MESSAGE? BEQ 155$ ; IF EQ NO MOV #ERR9,R0 ; GET MESSAGE ADDRESS (NOT REALLY AN ERROR) CALL OUTPT4 ; AND PRINT IT 155$: MOV #MSG1,R0 ; PRINT THE CONNECT TIME .IF DF AA$BV3 TST $BATCH ; VERSION 3 BATCH JOB? BEQ 1551$ ; IF EQ NO MOV #MSG1J,R0 ; YES, DIFFERENT MESSAGE 1551$: ; REF. LABEL .ENDC ; DF AA$BV3 CALL OUTPT4 ; MOV #MSG2,R0 ; PRINT THE CPU TIME CALL OUTPT4 ; .IF DF AA$QIO & AA$TCQ MOV #MSG3,R0 ; PRINT THE I/O REQUESTS CALL OUTPT4 ; .ENDC ; DF AA$QIO & AA$TCQ .IF DF AA$MEM MOV #MSG9,R0 ; PRINT THE MEMORY USAGE CALL OUTPT4 ; .ENDC ; DF AA$MEM TSTB PAGFLG ; SEND PAGES PRINTED MESSAGE? BEQ 156$ ; IF EQ NO MOV #MSG8,R0 ; PRINT THE # PRINTED PAGES CALL OUTPT4 ; 156$: TSTB ACCERR ; WAS THERE AN ACCOUNT ERROR? BNE 160$ ; IF NE YES, DON'T COMMENT ON SIGN OF BALANCE MOV #MSG4,R0 ; PRINT SESSION CHARGES .IF DF AA$BV3 TST $BATCH ; VERSION 3 BATCH JOB? BEQ 1561$ ; IF EQ NO MOV #MSG4J,R0 ; YES, DIFFERENT MESSAGE 1561$: ; REF. LABEL .ENDC ; DF AA$BV3 CALL OUTPT4 ; PRINT MESSAGE MOV #MSG5,R0 ; PRINT NEW ACCOUNT BALANCE CALL OUTPT4 ; TSTB NEGFLG ; IS NEW ACCOUNT BALANCE NEGATIVE? BEQ 160$ ; IF EQ NO MOV #MSG6,R0 ; PRINT A/C OVERDRAWN WARNING CALL OUTPT4 ; 160$: CALL $AFCLS ; MAKE SURE THE ACCOUNT FILE IS CLOSED .IF DF AA$BV3 TST $BATCH ; VERSION 3 BATCH JOB? BNE 170$ ; IF NE YES, DON'T SEND FINAL STUFF .ENDC ; DF,AA$BV3 MOV #MSG7,R0 ; FINISH WITH A COUPLE OF LINEFEEDS CALL OUTPT4 ; 170$: RETURN ; AND RETURN TO BYE COMMAND ;+ ; *** OUTPT4 ; ; OUTPUT ROUTINE. DOES NOTHING FOR V4.0 IF SILENT LOGOUT WAS ; REQUESTED. IF VERSION 3 OF THE BATCH SYSTEM IS SUPPORTED, ; AND THE MESSAGE STARTS WITH , IT IS REPLACED BY A TAB ; IF WE ARE LOGGING OFF A BATCH JOB. ; ; INPUTS: ; R0 ASCIZ MESSAGE ADDRESS ;- OUTPT4: ; .IF DF AA$BV3 TST $BATCH ; BATCH JOB? BEQ 5$ ; IF EQ NO CMPB #CR,(R0) ; MESSAGE STARTS WITH ? BNE 5$ ; IF NE NO MOVB #11,(R0) ; YES, CONVERT TO A TAB 5$: ; REF. LABEL .ENDC ; DF AA$BV3 .IF DF AA$V40 ! AA$V41 .IF DF A$$CLI BIT #CP.NIO,CLIBUF+G.CICS ; SILENT LOGOUT? BNE 10$ ; IF NE YES .ENDC ; DF A$$CLI .ENDC ; DF AA$V40 ! AA$V41 CALL OUT.PT ; PRINT MESSAGE 10$: RETURN ; AND RETURN ;+ ; *** NONSTA ; ; THIS ROUTINE IS CALLED TO ADJUST A DOUBLE WORD SYSTEM RESOURCE ; USAGE FIGURE TO ACCOUNT FOR A NON-STANDARD CHARGING RATE. ; ; INPUT: ; R1 NON-STANDARD RATE DESCRIPTOR WORD ; R5 ADDRESS OF DOUBLE WORD USAGE FIGURE ; ; OUTPUT: ; R1 HIGH ORDER RESULT ; R2 LOW ORDER RESULT ; R5 (INPUT R5)+4 ; R0,R3,R4 USED ; ;- NONSTA: MOV #SPCBLK+2,R4 ; GET ADDRESS+2 OF ML.DV ARGUMENTS BLOCK MOV R1,(R4) ; SET DIVISOR BIC #177400,(R4) ; WITHOUT THE HIGH ORDER BITS SWAB R1 ; POSITION MULTIPLIER IN LOW BYTE BIC #177400,R1 ; ZAP THE UNWANTED BITS MOV R1,-(R4) ; SET UP IN ARGUMENT BLOCK CALLR ML.DV ; PERFORM THE ADJUSTMENT ;+ ; *** ACCPT2 ; ; THIS ROUTINE IS CALLED BY $ASCAN IN THE CASE WHERE AN ACCOUNT ; HAS BEEN CHAINED WHILE IT WAS LOGGED ON. THE ACCOUNT NUMBER ; RETURNED BY LOG... IS NO LONGER THE CORRECT ONE TO CHARGE IN ; THIS CASE, BUT IT WILL SERVE TO LOCATE AN ACCOUNT WHOSE CHAIN ; WORD WILL NOW POINT TO THE CORRECT ACCOUNT TO CHARGE. ; ;- ACCPT2: ; FALL THROUGH TO ACCPT1 ;+ ; *** ACCPT1 - ACCOUNT ACCEPTANCE ROUTINE ; ; THIS ROUTINE IS CALLED BY $ASCAN FOR EACH ACCOUNT IN THE ACCOUNT ; FILE UP TO THE POINT WHERE WE RETURN CARRY CLEAR. IT IS USED ; TO LOCATE THE RIGHT ACCOUNT FOR LOGOFF PROCESSING. ; ; INPUT: ; R0 ADDRESS OF ACCOUNT ENTRY ; ; OUTPUT: ; R0 - UNCHANGED ; CARRY CLEAR - THIS IS THE ONE WE WANT ; CARRY SET - PLEASE KEEP LOOKING ;- ACCPT1: MOV A.ACNO(R0),R1 ; GET ACCOUNT NUMBER BIC #100000,R1 ; CLEAR MASTER FLAG (IF SET) CMP R1,ACNO ; ARE WE THE RIGHT ACCOUNT? BEQ 10$ ; IF EQ YES SEC ; ELSE SET THE CARRY BIT 10$: RETURN ; GO BACK TO $ASCAN ;+ ; *** ACCPT3 ; ; THIS ROUTINE IS CALLED BY $ASCAN IN THE CASE WHERE A SIMULATED LOGON ; IS BEING DEALT WITH. NORMALLY, THIS OCCURS WHEN LOG... IS STARTED AT ; SYSTEM BOOT. IT SIMULATES RECEIVING A LOGON MESSAGE FROM THE ; INITIATING TERMINAL. THIS DOES NOT PROVIDE THE ACCOUNT NUMBER, SO WE ; SEARCH THE A/C FILE BY UIC. ; ;- ACCPT3: CMP A.GRP(R0),UIC ; ASCII UIC MATCHES? BNE 10$ ; IF NE NO CMP A.GRP+2(R0),UIC+2 ; MAYBE BNE 10$ ; IF NE NO CMP A.GRP+4(R0),UIC+4 ; MAYBE BNE 10$ ; IF NE NO CLC ; OK, THIS ONE RETURN ; 10$: SEC ; NOT THIS ONE RETURN ; .END