.TITLE WHO - SYSTAT PROGRAM ; .IDENT /JKN2.2/ ;WRITTEN BY J. NEELAND ;LAST MODIFIED 780817. ; .MCALL EXIT$S,QIOW$,UCBDF$,TCBDF$,DIR$,GMCR$ ;INVOKE DEFINITION MACROS: UCBDF$ TCBDF$ ; .LIST MEB ;LET'S SEE THE CODE GENERATED ;(MAKES DEBUGGING EASIER) ; ;DEFINITIONS: MAXTSK=8. ;MAX. # OF TASKS/TERMINAL TO LIST ; WHO:: ;REF LABEL DIR$ #GMCR ;GET THE COMMAND LINE (IF ANY) BCS NRM ;THERE CAN'T BE A /HE REQUEST IF NO MCR LINE CMP $DSW,#7 ;ARE THERE AT LEAST 7 CHARS? BLT NRM ;NO, SO NO REQUEST FOR HELP MOV #GMCR+G.MCRB+3,R0 ;YES, LET'S CHECK IT OUT. START AFTER 'WHO' MOV $DSW,R1 ;GET THE # CHARS SENT SUB #3,R1 ;ADJUST COUNT FOR 'WHO' STRING SKIPPED FNDSP: DEC R1 ;KEEP CHECKING THAT THERE ARE STILL CHARS BLT NRM ;NO CMPB (R0)+,#40 ;YES, DO WE HAVE A SPACE YET? BNE FNDSP ;NO, KEEP TRYING FNDNSP: DEC R1 ;YES, ANYTHING LEFT? BLT NRM ;NO CMPB (R0)+,#40 ;YES, NOW SKIP THE SPACES BEQ FNDNSP CMP R1,#2 ;AT LEAST 2 CHARS LEFT? BLT NRM ;NO, GIVE UP TSTB -(R0) ;YES, LOOK AT THE CHAR. WE JUST PASSED CMPB (R0)+,#'/ ;WAS IT A SLASH? BNE NRM ;NO CMPB (R0)+,#'H ;YES, IS NEXT A 'H'? BNE NRM ;NO CMPB (R0)+,#'E ;YES, IS IT NOW A '/HE'? BNE NRM ;NO, GIVE UP ON THIS GUY MOV #HLPTXT,TTWRT+Q.IOPL ;YEA!!!, SET IN ADDR. & SIZE OF HELP MSG. MOV #HLPSIZ,TTWRT+Q.IOPL+2 DIR$ #TTWRT ;PRINT THE HELP STUFF MOV #DEVNAM,TTWRT+Q.IOPL ;RESTORE THE NORMAL BUFFER ADDR. ; NRM: MOV #"CO,DEVNAM ;START OUT W/ CO:OR 'DETACHED' TASKS MOV #"0:,DEVNAM+2 MOV #PARBUF,R3 ;SET A POINTER TO A BUFFER AREA MOV #DEVNAM,R0 ; & A POINTER TO THE DEVICE STRING CALL $FDUCB ; & FIND THE 'CO' UCB BCS TRYTT ;WELL, IF THERE REALLY ISN'T ONE, GO ON MOV R1,UCB ;SAVE THE UCB ADDRESS FOR LATER COMPARISON MOV #DEVNAM+4,R0 ;COPY IN THE 'DETACHED' STUFF MOV #DETMSG,R1 MOV #DETSIZ,R2 MOVDET: MOVB (R1)+,(R0)+ SOB R2,MOVDET CALL LOOKTK ;THEN GO LOOKING FOR TASKS BELONGING TO 'CO' TRYTT: MOV #"TT,DEVNAM ;CONTINUE W/ THE TT'S CALL TRYDEV MOV #"VT,DEVNAM ;THEN THE VT'S CALL TRYDEV DONE: EXIT$S ;THAT'S IT FOR NOW TRYDEV: CLR UNITNO ;CLEAR UNIT # (START W/ TT0:) NEXTNO: MOV #DEVNAM+2,R0 ;SET STRING ADDRESS MOV UNITNO,R1 ;PROVIDE CURRENT VALUE OF UNIT # MOV #<2*4000>!<1*1000>!10,R2 ;SET FOR 2 BYTES FIELD WIDTH, RADIX 8. ; AND NO LEADING ZERO SUPPRESSION CALL $CBTA ;CONVERT TO ASCII MOVB #':,(R0) ;APPEND ':' TO DEVICE NAME/NUMBER MOV #DEVNAM,R0 ;SET POINTER FOR COMPLETE NAME MOV #PARBUF,R3 ;PROVIDE A BUFFER AREA CALL $FDUCB ;FIND A UCB, IF IT EXISTS BCC GOTONE ;CARRY CLEAR IF WE HAVE SUCH A DEVICE RETURN ;RETURN IF NO SUCH DEVICE ; GOTONE: BIT #U2.LOG,U.CW2(R1) ;LOGGED IN? BNE INCNO ;IF NOT ZERO, NO, SO TRY NEXT UNIT ;GOT A LIVE ONE, NEXT GET LOGIN UIC AND PUT INTO OUTPUT BUFFER ; 1ST RESTORE PART OF TEXT POSSIBLY MESSED UP MOV #DEVNAM+5,R0 MOVB #40,(R0)+ ;2 SPACES MOVB #40,(R0)+ MOVB #'[,(R0)+ ;THEN THE LEFT BRACKET MOV R1,R5 ;SAVE UCB ADDRESS FOR FURTHER USE MOV R1,UCB ;SAVE MORE PERMANENTLY TOO MOV U.LUIC(R5),R1 ;GET THE LOGIN UIC SWAB R1 MOV #1,R2 ;DON'T SUPPRESS LEADING ZEROS CALL $CBTMG ;DO THE CONVERSION MOVB #',,(R0)+ ;SEPARATE W/ A COMMA MOV U.LUIC(R5),R1 ;REPEAT FOR THE MEMBER # MOV #1,R2 CALL $CBTMG MOVB #'],(R0)+ ;CLOSE BRACKET AROUND UIC ;LOOK FOR TASKS W/ THIS TI: LOOKTK: MOV #MAXTSK,NUMACT ;SET MAX NUMBER OF TASKS TO LOOK FOR CALL $SWSTK,ENDLST ;SWITCH TO SYSTEM STATE TO SCAN LIST MOV #TSKNAM,R0 ;GET ADDRESS OF ASCII BUFFER MOV $TSKHD,R5 ;GET BEGINNING OF TASK-LIST 10$: TST T.TCBL(R5) ;AT END OF LIST (NULL TASK)? BEQ 30$ CMP UCB,T.UCB(R5) ;NO, SO DOES THIS TASK BELONG TO THIS TI:? BNE 20$ MOVB #',,(R0)+ ;YES, FIRST INSERT ',' ;NOW CHECK FOR SOME SPECIAL TASK STATES BIT #TS.OUT,T.STAT(R5) ;CHECKPOINTED? BEQ 12$ ;BRANCH IF NOT MOVB #'/,(R0)+ ; YES, INDICATE WITH A '/' BR 18$ ; AND CONTINUE 12$: BIT #T2.TIO,T.ST2(R5) ;DOING TERMINAL I/O? BEQ 13$ ;BRANCH IF NOT MOVB #'?,(R0)+ ; YES, INDICATE WITH A '?' BR 18$ ; AND CONTINUE 13$: TSTB T.IOC(R5) ;I/O OUTSTANDING? BEQ 14$ ;BRANCH IF NOT MOVB #'*,(R0)+ ; YES, INDICATE WITH A '*' BR 18$ ; AND CONTINUE 14$: BIT #1,T.ST2(R5) ;IS TASK WAITING FOR AN EVENT FLAG? BEQ 15$ ;BRANCH IF NOT MOVB #'#,(R0)+ ;YES, INDICATE WITH A '#' BR 18$ ; AND CONTINUE ; 15$: BIT #T2.STP,T.ST2(R5) ;IS THIS TASK ACTUALLY RUNNING? BEQ 16$ ;SKIP IF IT IS DEC R0 ;BACK UP POINTER TO OVERWRITE THE ',' BR 20$ ; & GO LOOK FOR ANOTHER TASK 16$: MOVB #40,(R0)+ ;NOTHING WE THINK IS WORTH MENTIONING ; SO JUST SPACE-FILL 18$: MOV T.NAM(R5),R1 ;GET 1ST HALF OF NAME CALL $C5TA ; & CONVERT TO ASCII MOV T.NAM+2(R5),R1 ;REPEAT FOR 2ND HALF CALL $C5TA DEC NUMACT ;DECR. COUNT OF REMAINING TO LOOK FOR BEQ 30$ ;IF ZERO, DON'T LOOK ANY MORE 20$: MOV T.ACTL(R5),R5 ;MOVE POINTER TO NEXT ACTIVE TASK BR 10$ ; & GO LOOK AGAIN ; 30$: MOV R0,TTWRT+Q.IOPL+2 ;SAVE THE END-OF-LINE POINTER RETURN ;RETURN FROM SYSTEM STATE ENDLST: SUB #DEVNAM,TTWRT+Q.IOPL+2 ;CALC. LNGTH OF MSG. ;NOW WE CAN ACTUALLY OUTPUT THE MESSAGE ABOUT THIS LOGGED-IN TERMINAL DIR$ #TTWRT INCNO: INC UNITNO ;BUMP COUNT TO NEXT UNIT NUMBER JMP NEXTNO ; & GO TRY ANOTHER UNIT AFTER PRINTING MSG. ; ;DATA AREA ; GMCR: GMCR$ ;DEFINE EXEC CALL & MCR LINE BUFFER .ENABL LC TTWRT: QIOW$ IO.WVB,1,1,,,, UCB: .BLKW 1 ;UCB ADDRS. FOR LOGGED-IN TERMINAL NUMACT: .BLKW 1 ;MAXTSK-NUMBER OF JOBS W/ T.UCB=UCB PARBUF: .BLKW 2 ;BUFFER AREA FOR $FDLOG UNITNO: .WORD 0 ;CURRENT UNIT # DETMSG: .ASCII / [DETACHED]/ DETSIZ=.-DETMSG .EVEN ;NEED WORD ALIGNMENT HERE DEVNAM: .ASCII /TT00: [/ UICGRP: .ASCII /000,/ UICMEM: .ASCII /000]/ MSGCNT=.-DEVNAM TSKNAM: .BLKB 80.-MSGCNT ;HAVE A 80-CHAR OUTPUT BUFFER .NLIST BEX ;DON'T PRINT ALL THE TEXT CODE HLPTXT: .ASCII %Lists active tasks associated with CO: ([DETACHED]),% .ASCII <15><12>% logged-in terminal #s, including any virtual% .ASCII % terminals (VTnn:),% .ASCII <15><12>% their login UIC, and tasks with that % .ASCII %terminal as TI:% .ASCII <15><12>%Task states are indicated with % .ASCII %symbols in the following order:%<15><12><11> .ASCII %/ = Checkpointed%<15><12><11> .ASCII %? = Terminal input wait%<15><12><11> .ASCII %* = I/O outstanding%<15><12><11> .ASCII %# = Wait for event flag%<15><12><11> .ASCII %sp= no special state flagged%<12> HLPSIZ=.-HLPTXT .LIST BEX .EVEN .END WHO