.TITLE ACCLOG .IDENT /04.23X/ ; THIS PROGRAM IS TO PROVIDE A LISTING OF THE KMS FUSION MODIFIED ; ACCOUNT FILE [0,0]RSX11.SYS. IT WILL ONLY WORK PROPERLY WITH ; THE MODIFIED VERSION OF ACTFL.MAC. THE ACTFL.MAC MODIFICATIONS ; DEFINE NEW OFFSETS FOR TOTAL TERMINAL CONNECT TIME AND PRIVLEGE ; MASK WORD. ; ; ; JAMES G. DOWNWARD 7/3/77 ; KMS FUSION, INC ; 3941 RESEARCH PARK DR ; ANN ARBOR, MICH 48104 ; 313-769-8500 ; ; ; MODIFIED: ; JGD01 -- 1/11/78 CHANGED ALL REFERENCES TO U.CW3 TO U.PRV1 ; CHANGE MADE TO ALLOW THE ACCOUNTING PACKAGE TO ; BE USED ON TERMINALS USING MULTIPLEXERS. THE ; MULTIPLEXERS USE U.CW3, SO I CAN'T. U.PRV1 AND ; U.PRV2 ARE DEFINED IN ACTFIL.MAC. ; AS IT TURNS OUT ACCLOG.MAC DOES NOT REFERENCE ; U.CW3 AT THIS TIME. ; ; JGD02 -- 5/29/79 UPDATED ACCLOG TO INCLUDE ACCOUNT NUMBER DISPLAY, ; SESSION IDENTIFIER, AND CPU TIME ; ; JGD03 -- 8/24/79 ATTACH/DETACH TERMINAL SO ^O WILL WORK. ; ; .MCALL QIO$,DIR$,WTSE$S,OPEN$R,CLOSE$,READ$,QIOW$ .MCALL EXIT$S,GTIM$S,MRKT$,GMCR$ ; ; CONSTANTS ; LUN1 = 1 ; TI: LUN LUN2 = 2 ; ACCOUNT FILE LUN EFN1 = 1 ; EVENT FLAG FOR ALL I/O EFN2 = 2 ; EVENT FLAG FOR MARK TIME ; ; LOCAL DATA -- MESSAGES AND ERROR MESSAGES ; .NLIST BEX TITLE: .ASCII <15><12>/ / TITLE1: .ASCIZ /KMS FUSION ACCOUNT FILE SUMMARY/ DATE: .ASCII <15><12>/ / DATE1: .ASCIZ /DD-MMM-YY HH:MM/ HEADR0: .ASCIZ <15><12>/ TIME/ HEADR: .ASCII <15>/ACCOUNT LAST NAME FIRST NAME / HEADR1: .ASCII / ID ACT# LOGINS CNCT CPU PRVMSK DISK FILES U.BLKS A.BLKS TASK/ HEADR2: .ASCIZ <15><12><11><11><11><11>/ HH:MM HH:MM:SS/ ACNT: UIC: .ASCII /[ , ] / TFLAG: .ASCII / / LNAME: .ASCII / / FNAME: .ASCII / / ID: .ASCII / / ACTNUM: .ASCII / / NLGIN: .ASCII / / CTIME: .ASCII / / CPUTIM: .ASCII /HH:MM:SS / PRVMSK: .ASCII / / STAR: .ASCII / / DISK: .ASCII / / FILES: .ASCII / / BLOCKS: .ASCII / / ALBLKS: .ASCII / / TASK: .ASCIZ / / TOTLOG: .ASCIZ /TOTAL NUMBER OF LOGONS = / TOTTIM: .ASCIZ /TOTAL TERMINAL CONNECT TIME = / TOTCPU: .ASCII /TOTAL CPU TIME = / CPUTOT: .ASCIZ / HH:MM / ; HHH:MM:SS UTLMSG: .ASCII /TOTAL SYSTEM UTILIZATION = / PERCNT: .ASCIZ / / MONTH: .ASCII /JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC/ ; ; ER1: .ASCIZ <15><12>/ACCLOG -- ACCOUNT FILE OPEN FAILURE/ ER2: .ASCIZ <15><12>/ACCLOG -- ACCOUNT FILE READ ERROR/ .LIST BEX .EVEN ; ; FILE DPB'S ; ODPB: QIO$ IO.WVB,LUN1,EFN1,,,, ; TI: OUTPUT DPB ATTDPB: QIOW$ IO.ATT,LUN1,EFN1 ; ATTACH TI: DETDPB: QIOW$ IO.DET,LUN1,EFN1 ; DETACH TI: FDPB: QIO$ IO.RVB,LUN2,EFN1,,IOSB,,<$ACTBF,$BFLEN,,,1> ; DBP FOR [0,0]RSX11.SYS IOSB: .BLKW 2 ; I/O STATUS BLOCK BUF: .BLKW 66. ; BUFFER FOR ALL TI: I/O MKT: MRKT$ EFN2,100.,1 ; WAIT 100 TICKS ; ; VARIABLES ; COUNT: .WORD 0 FILOPN: .WORD 0 ; FILE OPEN FLAG ENTRY: .WORD 0 ; CURRENT ENTRY POINT TO ACCOUNT OPNERR: .WORD 0 ; ERROR FLAG FOR OPEN ACCOUNT TIMBUF: .BLKW 8. ; BUFFER FOR GET TIME TEMP: .WORD 0 ; TEMPORARY STORAGE HOUR: .WORD 0 ; HOURS OF CONNECT TIME MIN: .WORD 0 ; MINUITS OF CONNECT TIME TLOG: .WORD 0 ; TOTAL NUMBER OF LOGINS TTIM: .WORD 0 ; TOTAL TERMINAL CONNECT TIME(LOW ORDER PART) TTIM2: .WORD 0 ; HIGH ORDER PART OF TOTAL CONNECT TIME CPHOUR: .WORD 0 ; HOURS OF CPU TIME CPMIN: .WORD 0 ; MIN OF CPU TIME CPSEC: .WORD 0 ; SECONDS OF CPU TIME CPTIM: .WORD 0 ; TOTAL CPU TIME LOW ORDER PART(IN SEC) CPTIM2: .WORD 0 ; TOTAL CPU TIME HIGH ORDER PART(IN SEC) ; ; .SBTTL MAIN LINE CODE ; + ; ; $ACCEP - ACCOUNT FILE REPORT GENERATOR ; ; - $ACCEP: DIR$ #ATTDPB ; ATTACH THE TERMINAL ; JGD03 MOV #TITLE,R0 ; PRINT THE REPORT TITLE CALL WRIT ; AT THE TOP OF THE PAGE GTIM$S #TIMBUF ; PUT THE CURRENT TIME AND DATE INTO TIMBUF MOV #DATE1,R0 ; PUT ADDRESS OF DATE MESSAGE INTO R0 CALL DATTIM ; AND CALL DATTIME TO FILL IT IN MOV #DATE,R0 ; ALSO PRINT THE DATE RIGHT CALL WRIT ; UNDER THE TITLE MOV #HEADR0,R0 ; PRINT OUT 'TIME' ABOVE 'CNCT CPU' CALL WRIT ; WRITE IT OUT MOV #HEADR,R0 ; PRINT THE HEADER TWO CALL WRIT ; LINES DOWN CALL OPEN ; OPEN ACCOUNT FILE FOR READ ONLY BCS 50$ ; OPEN ERROR PRINT MESSAGE, CLOSE FILE, AND EXIT CALL DISPLY ; GO DISPLAY FILE INFORMATION BCC 40$ ; CLOSE FILE AND EXIT IF NO ERROR MOV #ER2,R0 ; GET READY TO PRINT A ACCOUNT FILE READ CALL WRIT ; ERROR MESSAGE, NOW PRINT IT 40$: CLOSE$ #$ACTFL ; CLOSE FILE MOV #TOTLOG,R0 ; GET THE ADRESS OF THE MESSAGE ADD #25.,R0 ; OFFSET IT PAST THE = SIGN MOV TLOG,R1 ; GET READY TO CONVERT TO DECIMAL # LOGINS CALL $CBDMG ; DO IT MOV #TOTLOG,R0 ; GET READY TO PRINT OUT THE TOTAL NUMBER OF LOGINS CALL WRIT ; PRINT IT OUT MOV #60.,R0 ; R0 WILL BE DIVISOR FOR DOUBLE PRECISION DIVIDE MOV TTIM2,R1 ; GET SET BY PUTTING HIGH PART OF TIME INTO HIGH PART MOV TTIM,R2 ; AND LOW PART OF TIME INTO LOW PART ; OF THE 32 BIT WORD FORMED BY R1 AND R2 CALL $DDIV ; DIVIDE (R1,R2) BY R0. ANSWER(LOW PART) IN R2 ; THE REMAINDER IS IN R0. MOV R2,HOUR ; THE TOTAL CONNECT TIME IN HOURS MOV R0,MIN ; THE TOTAL CONNECT TIME IN MINUTES MOV #TOTTIM,R0 ; GET ADRESS OF MESSAGE ADD #30.,R0 ; OFFSET PAST =SIGN CLR R2 ; SUPRESS PRINTING OF LEADING ZEROS MOV HOUR,R1 ; CONVERT HOUR FIRST CALL $CBDMG ; TO DECIMAL ASCII STRING MOVB #72,(R0)+ ; PUT IN A ":" TO SEPERATE HOURS AND MINUTES MOV MIN,R1 ; NOW GET READY TO CONVERT TO MINUTES CALL TWODEC ; DO IT MOV #TOTTIM,R0 ; GET READY TO PRINT OUT THE TOTAL TERMINAL CONNECT TIME CALL WRIT ; PRINT IT OUT MOV #60.,R0 ; DIVISOR ; JGD02 MOV CPTIM2,R1 ; HIGH TIME IN SEC ; JGD02 MOV CPTIM,R2 ; LOW TIME IN SEC ; JGD02 CALL $DDIV ; DIVIDE IT OUT ; JGD02 MOV R0,CPSEC ; AND STORE VALUE ; JGD02 MOV #60.,R0 ; GET READY AGAIN ; JGD02 CALL $DDIV ; AND DIVIDE ; JGD02 MOV R0,CPMIN ; STORE MINUTES ; JGD02 MOV R2,CPHOUR ; AND HOURS ; JGD02 CLR R2 ; SUPRESS LEADING ZEROS ; JGD02 MOV #CPUTOT,R0 ; ADDRESS OF WHERE TO SHOVE IT ; JGD02 MOV CPHOUR,R1 ; GET READY TO CONVERT ; JGD02 CALL $CBDMG ; DO IT ; JGD02 MOVB #':,(R0)+ ; SHOVE IN A ":" ; JGD02 MOV CPMIN,R1 ; GET MINUTES ; JGD02 CALL TWODEC ; CONVERT TWO DECIMAL DIGITS ; JGD02 MOVB #':,(R0)+ ; INSERT ANOTHER ":" ; JGD02 MOVB CPSEC,R1 ; GET SECONDS ; JGD02 CALL TWODEC ; CONVERT ; JGD02 MOV #TOTCPU,R0 ; OUTPUT STRING ; JGD02 CALL WRIT ; WRITE IT OUT. ; JGD02 CALL PERPNT ; COMPUTE THE SYSTEM % UTILIZATION ; JGD02 MOV #UTLMSG,R0 ; AND WRITE IT OUT ; JGD02 CALL WRIT ; THE SAME WAY WE ALWAYS DO ; JGD02 DIR$ #DETDPB ; DETACH TI: ; JGD03 EXIT$S ; AND EXIT 50$: CLOSE$ #$ACTFL ; CLOSE FILE MOV #ER1,R0 ; PRINT ACCOUNT FILE OPEN ERROR CALL WRIT ; MESSAGE ON TI: EXIT$S ; AND EXIT .SBTTL SUBROUTINES ;+ ; *** - WRIT - WRITE OUT BUFFER ; ;+ ; *** - OPEN - OPEN FILE ; ;- OPEN: OPEN$R #$ACTFL,,,#FD.RWM ; OPEN FILE BCS 10$ ; ERROR INC FILOPN ; SET FILE IS OPEN 10$: RETURN ; ;+ ; *** - QIO - ISSUE QIO ; ; INPUT: ; R0 - MESSAGE ADDRESS ; ;- WRIT: MOV R0,R1 ; COPY BUFFER ADDRESS 10$: TSTB (R1)+ ; END OF MESSAGE? BNE 10$ ; NO, LOOP TILL END SUB R0,R1 ; COMPUTE LENGTH MOV #ODPB,R4 ; GET OUTPUT DPB ADDRESS MOV R0,Q.IOPL(R4) ; SET BUFFER ADDRESS MOV R1,Q.IOPL+2(R4) ; SET BUFFER LENGTH CALLR QIO ; WRITE IT OUT ;+ ; *** - QIO - ISSUE QIO ; ; INPUT: ; R4 - DPB ADDRESS ;- QIO: DIR$ R4 ; ISSUE QIO BCS 10$ ; ERROR MOVB Q.IOEF(R4),R5 ; GET EVENT FLAG TO WAIT ON WTSE$S R5 ; AND WAIT 10$: RETURN ; ;+ ; ***DISPLY - READ ACCOUNT INFORMATION INTO THE BUFFER AND ; WRITE IT ONTO THE TERMINAL ; EACH BUFFER(ACTBF) IS 512 BYTES LONG AND CONTAINS 4 ; USER ACCOUNT BLOCKS ; ;- DISPLY: MOV #FDPB,R4 ; GET FILE DPB ADDRESS MOV R4,TEMP ; SAVE R4 FOR LATER MOV #1,Q.IOPL+10(R4) ; SET TO START AT VBN 1 CLR Q.IOPL+6(R4) ; 5$: CALL QIO ; READ IN THE BLOCK MOV IOSB+2,COUNT ; GET COUNT OF WORDS READ BEQ 50$ ; IF ZERO WORDS READ, TEST FOR END OF FILE MOV #$ACTBF,R0 ; GET BUFFER ADDRESS 10$: MOV R0,ENTRY ; SAVE ENTRY ADRESS FOR LATER, WE'LL NEED IT CALL PRINT ; WE ARE AT THE START OF A 128 BYTE ACCOUNT BLOCK ; GO AND PRINT THE INFORMATION MOV ENTRY,R0 ; RESTORE ENTRY, SO WE CAN STEP THROUGH THE ACCOUNT ; BUFFER. ADD #A.LEN,R0 ; POINT TO NEXT ENTRY SUB #A.LEN,COUNT ; COMPUTE WORDS LEFT IN BUFFER BHI 10$ ; IF STILL MORE TO PROCESS IN THIS BUFFER ; LOOP BACK AND PRINT SOME MORE 50$: CMPB #IE.EOF,IOSB ; OTHERWISE CHECK FOR END OF FILE BEQ 60$ ; YES, EOF FOUND AND WE ARE DONE FOR NOW TSTB IOSB ; BE SURE WE DON'T HAVE ANY READ ERRORS BMI 55$ ; A READ ERROR FOUND, SET CARRY BEFORE EXITING MOV TEMP,R4 ; RESTORE R4 ADD #$BFLEN/512.,Q.IOPL+10(R4) ; NO ERRORS, SO POINT TO NEXT VBN ADC Q.IOPL+6(R4) ; BR 5$ ; READ IN A NEW BUFFER 55$: SEC ; SET CARRY AS AN ERROR FLAG 60$: RETURN ; ;+ ; ; ***PRINT -- PRINT OUT THE INFORMATION AT TI: ; ; ;- PRINT: ADD #A.GRP,R0 ; POINT TO GROUP CODE(IN ASCII) MOVB (R0)+,UIC+1 ; FILL UP THE UIC MOVB (R0)+,UIC+2 ; MOVB (R0)+,UIC+3 MOVB (R0)+,UIC+5 ; NOW MOVE IN THE MEMBER CODE MOVB (R0)+,UIC+6 ; MOVB (R0),UIC+7 ; MOV ENTRY,R0 ; RESTORE ENTRY POINTER ADD #A.LNM,R0 ; POINT TO LAST NAME MOV #14.,R3 ; SET UP # BYTES TO TRASNFER MOV #LNAME,R1 ; INSERT ASCII CHARACTERS INTO LNAME CALL LOOP ; GO FILL UP LNAME MOV ENTRY,R0 ; RESTORE ENTRY ADRESS ADD #A.FNM,R0 ; POINT TO FIRST NAME ENTRY MOV #FNAME,R1 ; PUT ADDRESS OF FNAME INTO R1 MOV #12.,R3 ; TRANSFER 12 BYTES CALL LOOP ; GO FILL UP FNAME MOV ENTRY,R0 ; RESTORE POINTER ; JGD02 ADD #A.SID,R0 ; POINT TO SESSION IDENTIFIER ; JGD02 MOV (R0),R1 ; CONTAINS RAD50 VALUE OF SESSION ID ; JGD02 MOV #ID,R0 ; ADDRESS OF OUTPUT STRING ; JGD02 CALL $C5TA ; CONVERT RAD50 WORD TO 3 ASCII CHARACTERS ; JGD02 MOV ENTRY,R0 ; RESTORE POINTER ADD #A.NLOG,R0 ; POINT TO # OF LOGINS ENTRY ADD (R0),TLOG ; COMPUTE THE TOTAL NUMBER OF LOGONS SO FAR MOV (R0),R1 ; SET UP TO CONVERT TO DECIMAL MOVB #40,NLGIN ; CLEAR OUT ANY OLD ASCII DATA MOVB #40,NLGIN+1 ; BY INSERTING SPACES MOVB #40,NLGIN+2 ; WHERE OLD DATA WAS. MOV #NLGIN,R0 ; KEEP SETTING UP-- THIS IS FOR A SYSLIB ; ROUTINE(USING R0,R1,R2) CLR R2 ; DON'T FILL LEADING ZEROS CALL $CBDMG ; CONVERT TO DECIMAL ASCII NUMBER MOV ENTRY,R0 ; RESTORE POINTER ; JGD02 ADD #A.ACN,R0 ; POINT TO ACCOUNT NUMBER ; JGD02 MOV (R0),R1 ; GET NUMBER TO CONVERT TO DECIMAL ; JGD02 MOVB #40,ACTNUM ; CLEAR OUT ANY REMNENTS ; JGD02 MOVB #40,ACTNUM+1 ; LEFT OVER FROM LAST TIME ; JGD02 MOVB #40,ACTNUM+2 ; ACNT.TSK INSURES THAT THE NUMBER ; JGD02 MOVB #40,ACTNUM+3 ; WILL BE <= 4 DIGITS LONG ; JGD02 MOV #ACTNUM,R0 ; HERE IS THE OUTPUT STRING ADDRESS ; JGD02 CLR R2 ; SUPPRESS LEADING ZEROS ; JGD02 CALL $CBDMG ; CONVERT TO DECIMAL ASCII NUMBER ; JGD02 MOV ENTRY,R0 ; RESTORE POINTER ADD #A.CTIM,R0 ; POINT TO TOTAL CONNECT TIME IN MINUTES MOV (R0),HOUR ; SAVE CONNECT TIME ADD (R0),TTIM ; COMPUTE A RUNNING TOTAL OF LOGON TIME ADC TTIM2 ; ADD CARRY TO TTIM2(IN CASE RESULT >2^15 2$: CLR R0 ; CLEAR R0 FOR DIVISION MOV HOUR,R1 ; GET SET TO DIVIDE BY PUTTING THE TIME ; INTO THE HIGH PART OF THE 32 BIT WORD ; FORMED BY R0 AND R1. DIV #60.,R0 ; DIVIDE BY 60. MINUTES. ANSWER IS IN R0 ; THE REMAINDER IS IN R1 MOV R0,HOUR ; THE CONNECT TIME IN HOURS MOV R1,MIN ; THE ADDITIONAL CONNECT TIME IN MINUTES MOV HOUR,R1 ; CONVERT HOUR FIRST CLR R2 ; SUPRESS PRINTING LEADING ZEROS MOVB #40,CTIME-1 ; CLEAR OUT THE CHARACTER AHEAD, JUST IN CASE MOVB #40,CTIME+4 ; CLEAR OUT AREA WHERE CHARACTERS MAY BE LEFT MOVB #40,CTIME+5 ; AND AGAIN MOV #CTIME,R0 ; ADDRESS OF CTIME TO R0 CMP R1,#100. ; ARE THERE LESS THAN 100 HOURS BLE 3$ ; YES, BRANCH AROUND DEC R0 ; >= 100, SO BACK UP A SPACE 3$: CALL $CBDMG ; CONVERT HOUR TO DECIMAL ASCII STRING CMPB #60,CTIME ; IS THE FIRST CHARACTER A ZERO BNE 4$ ; NO, SKIP OVER CMP HOUR,#100. ; IF >=100 HOURS DON'T PUT IN ZERO BGE 4$ ; IF GREATER, SKIP OVER MOVB #60,(R0)+ ; YES, SO ADD ANOTHER ZERO TO ALLIGN THE LIST BR 5$ ; SKIP, THE NEXT OR WE WOULD ADD TOO MANY ZEROS 4$: CMP HOUR,#10. ; HAVE LESS THAN 10 HOURS ACCUMULATED BGE 5$ ; NO , SKIP OVER DEC R0 ; YES, BACK UP TO CHARACTER IN BUFFER CLR R1 ; CLEAR R1 OF OLD JUNK MOVB (R0),R1 ; SAVE (R0) FOR A BIT MOVB #60,(R0)+ ; YES MOVE IN A FILLER "0" MOVB R1,(R0)+ ; PUT BAC IN THE OLD CHARACTER 5$: MOVB #72,(R0)+ ; PUT A ":" IN TO SEPERATE HOURS FROM MINUTES MOV MIN,R1 ; NOW GET READY TO CONVERT MINUTES CALL TWODEC ; DO IT MOV ENTRY,R0 ; RESTORE POINTER ; JGD02 ADD #A.CPU,R0 ; POINT TO CPU TIME IN SEC ; JGD02 MOV (R0)+,R2 ; GET LOW ORDER VALUE ; JGD02 MOV (R0),R1 ; AND HIGH ORDER VALUE ; JGD02 ADD R2,CPTIM ; COMPUTE RUNNING TOTAL OF CPU TIME ; JGD02 ADC CPTIM2 ; ADD CARRY IF NEEDBE ; JGD02 ADD R1,CPTIM2 ; AND ADD IN HIGH PART ; JGD02 MOV #60.,R0 ; GET READY TO DIVIDE BY 60(GET MIN) ; JGD02 CALL $DDIV ; DO DOUBLE PRECISION DEVIDE ; JGD02 MOV R0,CPSEC ; STORE SECONDS(REMAINDER) ; JGD02 MOV #60.,R0 ; DIVIDE AGAIN BY 60 TO GET HOURS ; JGD02 CALL $DDIV ; DO DIVIDE ; JGD02 MOV R0,CPMIN ; STORE MIN(REMAINDER) ; JGD02 MOV R2,CPHOUR ; HOURS BETTER BE IN LOW ORDER PART ; JGD02 MOV #CPUTIM,R0 ; ADDRESS OF OUTPUT STRING ; JGD02 MOVB #40,CPUTIM-1 ; CLEAR OUT AREA JUST AHEAD IN CASE >99 HOURS ; JGD02 CMP CPHOUR,#100. ; ARE THERE LESS THAN 100 HOURS ; JGD02 BLE 51$ ; YES, BRANCH AROUND ; JGD02 DEC R0 ; >= 100 HOURS SO BACK UP A SPACE ; JGD02 51$: CLR R2 ; SUPRESS LEADING ZEROS ; JGD02 MOV CPHOUR,R1 ; NUMBER TO CONVERT ; JGD02 CALL $CBDMG ; CONVERT HOUR TO DECIMAL ASCII STRING ; JGD02 CMPB #60,CPUTIM ; IS THE FIRST CHARACTER A 0? ; JGD02 BNE 52$ ; NO, SKIP OVER ; JGD02 CMP CPHOUR,#100. ; IF >=100 HOURS DON'T PUT IN ZERO ; JGD02 BGE 52$ ; IF GREATER , SKIP OVER ; JGD02 MOVB #60,(R0)+ ; YES, SO ADD ANOTHER ZERO TO ALLIGN LIST ; JGD02 BR 53$ ; SKIP THE NEXT OR WE WOULD ADD TOO MANY ZEROS ; JGD02 52$: CMP CPHOUR,#10. ; HAVE LESS THAN 10 HOURS ACCUMULATED ; JGD02 BGE 53$ ; NO, SKIP OVER ; JGD02 DEC R0 ; BACK UP TO OLD CHARACTER IN BUFFER ; JGD02 CLR R1 ; CLEAR R1 OF OLD JUNK ; JGD02 MOVB (R0),R1 ; SAVE (R0) FOR A BIT ; JGD02 MOVB #60,(R0)+ ; YES MOVE IN A FILLER "0" ; JGD02 MOVB R1,(R0)+ ; PUT BACK IN THE OLD CHARACTER ; JGD02 53$: MOVB #':,(R0)+ ; INSERT A ':' ; JGD02 MOV CPMIN,R1 ; CONVERT MINUTES ; JGD02 CALL TWODEC ; CONVERT ; JGD02 MOVB #':,(R0)+ ; INSERT ANOTHER ":" ; JGD02 MOV CPSEC,R1 ; CONVERT SECONDS NEXT ; JGD02 CALL TWODEC ; DO IT ; JGD02 MOV ENTRY,R0 ; RESTORE ENTRY ADD #A.PRIV,R0 ; POINT TO PRIVLEGE MASK MOV (R0),R1 ; GET READY TO CONVERT TO OCTAL ASCII MOV #PRVMSK,R0 ; GET READY TO FILL IN PRVMSK INC R2 ; R2>0 SO 0'S WILL PRINT CALL $CBOMG ; CONVERT TO OCTAL MAGNITUDE ASCII MOV ENTRY,R0 ; RESTORE ENTRY POINTER ADD #A.TNAM,R0 ; POINT TO 6 LETTER ASCII TASK NAME MOV #TASK,R1 ; GET SET TO SHOVE CHARACTERS INTO TASK: MOV #6.,R3 ; ONLY 6 CHARACTER TASK NAME CALL LOOP ; GO PACK CHARACTERS MOV ENTRY,R0 ; RESTORE ENTRY POINT ADD #A.SYDV,R0 ; POINT TO SYSTEM DEVICE ENTRY MOVB (R0)+,DISK ; MOVE IN SYSTEM DEVICE NAME MOVB (R0)+,DISK+1 ; MOVB (R0)+,DISK+2 ; MOVB (R0),DISK+3 ; MOV ENTRY,R0 ; RESTORE ENTRY POINT ADD #A.TERM,R0 ; POINT TO LOGIN TERMINAL ENTRY MOVB #40,TFLAG ; CLEAR OUT OLD STUFF MOVB #40,TFLAG+1 ; BY PUTTING IN SPACES MOVB #40,TFLAG+2 ; AND STILL ANOTHER SPACE MOVB #40,TFLAG+3 ;AND AGAIN TSTB (R0) ; BE SURE TT IS PRESENT, OTHERWISE FILLING TFLAG WITH BEQ 10$ ; ZERO WOULD SCREW UP THE PRINT OUT MOVB (R0)+,TFLAG ; MOVE IN TERMINAL ENTRY MOVB (R0)+,TFLAG+1 ; THE SECOND T MOV (R0),R1 ; POINT TO TERMINAL NUMBER BIC #177400,R1 ; CLEAR ALL BITS IN HI BYTE MOV #TFLAG,R0 ; POINT TO START OF BUFFER ADD #2,R0 ; POINT TO POINT FOR NUMBER ENTRY CLR R2 ; SUPRESS LEADIING ZEROS 10$: CALL $CBOMG ; CONVERT THE NUMBER TO OCTAL MOV ENTRY,R0 ; RESTORE ENTRY POINTER ADD #A.FILS,R0 ; POINT TO NUMBER OF USER FILES ENTRY MOV (R0),R1 ; NUMBER TO CONVERT TO DECIMAL ASCII MUST BE IN R1 MOVB #40,FILES ; CLEAR OUT ANY OLD ASCII DATA MOVB #40,FILES+1 ; BY INSERTING SPACES MOVB #40,FILES+2 ; MOVB #40,FILES+3 ; STOP CLEARING HERE , >9999 FILES IMPOSSIBLE MOV #FILES,R0 ; SET UP TO USE SYSLIB ROUTINE CLR R2 ; DON'T FILL LEADING ZEROS CALL $CBDMG ; CONVERT TO DECIMAL ASCII NUMBER MOV ENTRY,R0 ; RESET POINTER ADD #A.UBLK,R0 ; POINT TO THE NUMBER OF USED BLOCKS MOV (R0),R1 ; NUMBER TO CONVERT TO DECIMAL ASCII MUST BE IN R1 MOVB #40,BLOCKS ; CLEAR OUT ANY OLD ASCII DATA MOVB #40,BLOCKS+1 ; MOVB #40,BLOCKS+2 ; MOVB #40,BLOCKS+3 ; MOVB #40,BLOCKS+4 ; CAN HAVE UP TO 2^16 -1 BLOCKS CLR R2 ; DON'T FILL IN LEADING ZEROS MOV #BLOCKS,R0 ; SET UP TO USE SYSLIB ROUTINE CALL $CBDMG ; CONVERT TO DECIMAL ASCII NUMBER MOV ENTRY,R0 ; POINT TO INITIAL ENTRY ADD #A.ABLK,R0 ; POINT TO THE NUMBER OF ALLOWED BLOCKS ENTRY MOVB #40,ALBLKS ; CLEAR OUT ANY OLD ASCII DATA MOVB #40,ALBLKS+1 ; MOVB #40,ALBLKS+2 ; MOVB #40,ALBLKS+3 ; STOP HERE MORE THAN 9999 BLOCKS IMPOSSIBLE MOVB #40,ALBLKS+4 ; BUT TO BE SURE BLANK THE LAST ONE CLR R2 ; SUPRESS LEADING ZEROS MOV (R0),R1 ; PUT VALUE OF ALLOWED BLOCKS IN R1(FOR $CBDMG) MOV #ALBLKS,R0 ; PUT ADDRESS OF WHERE TO STUF NUMBER IN R0 CALL $CBDMG ; CONVERT BINARY NUMBER IN R1 TO ASCII STRING IN ALBLKS MOVB #40,STAR ; PUT SPACE IN STAR AREA IN CASE AN OLD STAR LEFT OVER MOVB #40,STAR+1 ; AND AGAIN MOV ENTRY,R0 ; POINT TO START OF ACOUNT BLOCK ADD #A.ABLK,R0 ; POINT TO ALLOWED NUMBER OF BLOCKS MOV (R0),R2 ; R2 NOW HAS THE NUMBER OF ALLOWED BLOCKS MOV ENTRY,R0 ; POINT TO START AGAIN ADD #A.UBLK,R0 ; POINT TO USED NUMBER OF BLOCKS MOV (R0),R1 ; R1 HAS THE NUMBER OF USED BLOCKS CMP R1,R2 ; ARE THE ALLOWED NUMBER OF BLOCKS GREATER THAN THE USED BLE 15$ ; YES, SKIP OVER MOVB #52,STAR ; NO, PUT IN FIRST STAR MOVB #52,STAR+1 ; PUT IN SECOND STAR ;MORE STUFF GOES IN HERE 15$: MOV #ACNT,R0 ; GET READY TO PRINT INFO CALL WRIT ; PRINT IT RETURN ; ;+ ; ***LOOP -- COMMON LOOP TO FILL IN CHARACTERS ; ; R0 - ADDRESS OF BUFFER CONTAINING CHARACTER ; R1 - ADDRESS OF BUFFER TO FILL ; R3 - NUMBER OF CHARACTERS TO TRANSFER ;- LOOP: MOVB (R0)+,(R1)+ ; MOVE CHARACTER INTO NAME DEC R3 ; DECREMENT COUNT BGT LOOP ; KEEP LOOPING IF MORE CHARACTERS LEFT RETURN ; OTHERWISE , RETURN ;+ ; *** - DATTIM - CONVERT DATE AND TIME TO ASCII ; ; INPUT: ; R0 - BUFFER ADDRESS ; TIMBUF - DATA RETURNED BY GTIM$ ; OUTPUT: ; R0 - UPDATED (16. CHARACTERS) ; R1, R2, R3 - USED ;- DATTIM: MOVB TIMBUF+4,R1 ; GET DAY CALL TWODEC ; CONVERT TO TWO DECIMAL DIGITS MOVB #'-,(R0)+ ; MOVB TIMBUF+2,R1 ; GET MONTH CALL GETMON ; CONVERT TO ASCII MOVB #'-,(R0)+ ; MOVB TIMBUF,R1 ; GET YEAR CALL TWODEC ; CONVERT TO TWO DECIMAL DIGITS MOVB #40,(R0)+ ; MOVB TIMBUF+6,R1 ; GET HOUR CALL TWODEC ; CONVERT TO TWO DECIMAL DIGITS MOVB #':,(R0)+ ; MOVB TIMBUF+10,R1 ; GET MINUTE CALL TWODEC ; CONVERT TO TWO DECIMAL DIGITS MOVB #40,(R0)+ ; RETURN ; ;+ ; *** - TWODEC - CONVERT BINARY NUMBER TO TWO DECIMAL DIGITS ; ; INPUT: ; R0 - BUFFER ADDRESS ; R1 - BINARY NUMBER TO BE CONVERTED ; OUTPUT: ; R0 - UPDATED ; R1, R2, AND R3 USED ;- TWODEC: CMP R1,#10. ; >= 10.? BGE 10$ ; YES MOVB #'0,(R0)+ ; NO, PUT IN LEADING ZERO 10$: CLR R2 ; SET TO SUPPRESS LEADING ZEROES CALL $CBDMG ; CONVERT TO DECIMAL RETURN ; ;+ ; PERPNT -- FORMAT PERCENTAGES INTO SUITABLE VALUES FOR PRINTING ; ; IN EACH CASE THE DISPLAY IS RIGHT JUSTIFIED SO THAT THE "."'S WILL ; LINE UP ; THIS ROUTINE WILL FORMAT THE TIME POINTED TO BY R0 ; INTO THE FOLLOWING FORMAT: ; ; XX.X% ; PERPNT: ; REF LABLE ; FIRST CONVERT TO MINIUTS MOV CPTIM,R2 ; LOW ORDER VALUE(SEC) MOV CPTIM2,R1 ; HIGH ORDER PART(SEC) MOV #60.,R0 ; DIVISOR CALL $DDIV ; DIVIDE IT MOV R2,R3 ; GET LOW ORDER NUMBER MOV R1,R2 ; GET HIGH ORDER NUMBER MOV #1000.,R0 ; GET SCALE FACTOR CALL $DMUL ; AND MULTIPLY MOV R1,R2 ; GET THE INFO WHERE IT BELONGS MOV R0,R1 ; BMI 190$ ; IF < 0 , THEN AN OVERFLOW OCCURED MOV TTIM,R0 ; GET LOW ORDER TOTAL TIME MOV TTIM2,-(SP) ; PUT HIGH ORDER TIME ON STACK 176$: TST (SP) ; IS THERE ANY HIGH ORDER TIME LEFT? BNE 177$ ; YES. CONTINUE SCALING TST R0 ; IS THE LOW ORDER UNSIGNED YET? BPL 180$ ; YES. DO IT! 177$: ASR R1 ; DIVIDE HIGH ORDER BY 2 ROR R2 ; AND CONTINUE WITH LOW ORDER ASR (SP) ; SHIFT HIGH ORDER TOTAL ALSO ROR R0 ; AND LOW ORDER BR 176$ ; DO THE TEST. 180$: TST (SP)+ ; CLEAN THE STACK AND CONTINUE CALL $DDIV ; DO D.P. DIVIDE MOV R2,R1 ; GET RESULT (PERCENT * 10.) CLR R2 ; SUPPRESS ZEROES TST CPTIM2 ; IF CPU TIME IS IDENTICALLY 0 BNE 181$ ; IF NE IT ISN'T TST CPTIM ; IN EITHER HIGH OR LOW ORDER PART BNE 181$ ; IF NE IT ISN'T CLR R1 ; THEN WE MUST FORCE % UTILIZ. TO ZERO 181$: ; REF LABLE MOV #PERCNT,R0 ; GET BUFFER ADDRESS CMP R1,#100. ; IS IT <10%, IF SO MUST SLIDE RIGHT 1 PLACE BGE 184$ ; IF GT, NO INC R0 ; IF LT, YES , BUMP POINTER 1 PLACE RIGHT CMP R1,#10. ; IS IT <1%, IF SO MUST SLIDE RIGHT 1 PLACE BGE 184$ ; IF GT NO, PROCEED WITHOUT SHIFTING INC R0 ; SLIDE POINTER RIGHT 184$: CALL $CBDMG ; CONVERT TO ASCII MOVB -(R0),1(R0) ; MOVE LAST BYTE OVER TO MAKE ROOM MOVB #'.,(R0)+ ; PUT IN A DECIMAL POINT INC R0 ; STEP PAST LAST NUMBER MOVB #'%,(R0)+ ; MAKE IT A PERCENT 190$: RETURN ; AND RETURN ;+ ; *** - GETMON - CONVERT MONTH TO ASCII ; ; INPUT: ; R0 - BUFFER ADDRESS ; R1 - MONTH (1-12) ; OUTPUT: ; R0 - UPDATED ; R1, R2 USED ;- GETMON: DEC R1 ; CONVERT TO INDEX MOV R1,R2 ; COPY IT ADD R2,R1 ; MULTIPLY BY ADD R2,R1 ; THREE ADD #MONTH,R1 ; GET ADDRESS OF MONTH IN ASCII MOVB (R1)+,(R0)+ ; MOVE MONTH MOVB (R1)+,(R0)+ ; INTO BUFFER MOVB (R1)+,(R0)+ ; RETURN ; .END $ACCEP