.TITLE LCU .SBTTL Specification and resources .IDENT /100001/ .ENABLE MCL .NLIST BEX ; ; List Common Users ; ; Utility to find users of a common area ; ; Written by J.P.Simoons, december 1986 ; HCS Industrial Automation B.V. ; Apeldoorn (Holland) ; ; Syntax: ; LCU - list all tasks having 1 or more commons ; with all the common names. ; LCU xxxxxx - List all tasks which use common xxxxxx ; ; Remarks: ; Task uses vectored Exec, to be transportable. ; RSXMC.MAC is included for CALL macro for CALL $SWSTK ; ; Modified: 26-feb-88 Ident --> 100001 ;PS026 ; Prevent odd address trap on odd addresses from PCB pointers ; .INCLUDE /LB:[200,200]RSXMC.MAC/ .TITLE LCU .LIBRARY /LB:[1,1]EXEMC.MLB/ PCBDF$ ; Define partition control block offsets TCBDF$ ; Define task control block offsets .PAGE .SBTTL Initialyse vector table and get commandline .PCODE START: QIOW$S #IO.ATT,#1,#1 ; Attach terminal DIR$ #TRNVEC ; Initialyse exec vector table BCC 20$ ; O.K. 10$: JMP VECERR ; Report error and exit 20$: TST EXEVEC ; Vector table o.k.? BEQ 10$ ; No DIR$ #GCMD ; Get command line TST $DSW ; valid input? BMI 110$ ; No, list complete CMP $DSW,#5 ; At least "LRU x"? BLO 110$ ; No ; ; Find common name and convert into Rad 50 ; MOV $DSW,R0 ; Get #input chrs MOV #GCMD+G.MCRB,R1 ; Point to MCR buffer 30$: CMPB (R1)+,#40 ; A space? BEQ 40$ ; Yes, found terminator to common SOB R0,30$ BR 110$ ; Not found 40$: MOV R1,COMPNT ; Save pointer to ascii name DEC R0 ; Adjust counter for space CMP R0,#6 ; Complete name left? BHIS 60$ ; Yes MOV R1,R2 ; Copy pointer to name ADD R0,R2 ; Point after input SUB #6,R0 ; Calculate NEG R0 ; ... #spaces to add 50$: MOVB #' ,(R2)+ ; Add a space SOB R0,50$ 60$: MOV R1,R0 ; Copy input pointer MOV #1,R1 ; Dot is valid R50 chr CALL $CAT5B ; Convert common name into R50 BCS 130$ MOV R1,REFR50 ; Save MOV #1,R1 CALL $CAT5B BCS 130$ MOV R1,REFR50+2 ; ; Check if common known to system ; CLR REFPCB ; Common not found yet CALL $SWSTK,100$ ; Switch to system state MOV CBDHD,R0 ;; Common block directory header MOV (R0),R0 ;; Get address of first common PCB BEQ 90$ ;; None there 70$: BIC #1,R0 ;; Don't use odd addresses ;PS026 CMP P.NAM(R0),REFR50 ;; Check first half common name BNE 80$ ;; No match CMP P.NAM+2(R0),REFR50+2 ;; Check second half BNE 80$ ;; No match MOV R0,REFPCB ;; Save address of common PCB BR 90$ ;; Ready 80$: MOV P.CBDL(R0),R0 ;; Try next common PCB (if any) BNE 70$ 90$: RETURN ;; From system syate 100$: TST REFPCB ; Found common? BEQ 140$ ; No BR 120$ ; Go look for tasks 110$: JMP LITKCO ; List all tasks which have commons 120$: JMP LITK ; List tasks for a specified common 130$: DIR$ #R50LOG ; Print error message BR EXIT 140$: MOV COMPNT,R0 ; Address of start of ascii common MOV #NOCASC,R1 ; Destination MOV #6,R2 150$: MOVB (R0)+,(R1)+ SOB R2,150$ DIR$ #NOCLOG ; Print error message EXIT: EXIT$S ; Ready .PAGE .SBTTL List all tasks with their commons ; ; List all tasks with their commons ; LITKCO: ; ; Scan task list in primary pool. ; keep: task name, no of commons, common names but only if 1 or more commons ; 10$: CALL $SWSTK,60$ ; Switch to system state MOV TSKHD,R0 ;; Pointer to system task directory MOV #BUF,R1 CLR R2 ;; No tasks found yet MOV (R0),R0 ;; Point to first TCB BEQ 50$ ;; None there 20$: BIC #1,R0 ;; Don't use odd addresses ;PS026 CMP R1,#EOBUF-68. ;; Still space in buffer for taskname ;; ... # commons, 15 common names? BHI 50$ ;; No TST T.NAM(R0) ;; Ckeck name for end of list BEQ 50$ ;; Null task, end of list MOV T.PCBV(R0),R3 ;; Get pointer to common PCB vector BEQ 40$ ;; None there MOVB (R3)+,R4 ;; Get #commons BEQ 40$ ;; None there CMP R4,#15. ;; More than 15. commons? BHI 50$ ;; Exit, we might have lost track INC R3 ;; Skip high byte #commons MOV T.NAM(R0),(R1)+ ;; Save name MOV T.NAM+2(R0),(R1)+ ;; ... INC R2 ;; Count task MOV R4,(R1)+ ;; Save #commons 30$: MOV (R3)+,R5 ;; Get address of common PCB BIC #1,R5 ;; Don't use odd addresses ;PS026 MOV P.NAM(R5),(R1)+ ;; Save common name MOV P.NAM+2(R5),(R1)+ ;; ... SOB R4,30$ BR 40$ 40$: MOV T.TCBL(R0),R0 ;; Point to next task if any BNE 20$ ;; EQ = none left 50$: MOV R2,COUNT ;; Save #found tasks RETURN ;; From system state 60$: CALL PRIBUF ; Print tasks with commons ; ; Scan prototype task list in secondary pool ; keep: task name, no of commons, common names but only if 1 or more commons ; CALL $SWSTK,110$ ; Switch to system state MOV @APR6,-(SP) ;; Save KISAR6 mapping MOV PTCBL,R0 ;; Pointer to prototype task list MOV #BUF,R1 CLR R2 ;; No tasks found yet MOV (R0),R0 ;; Point to first TCB BEQ 100$ ;; None there ; ; Map TCB in secondary pool ; 70$: MOV R0,@APR6 ;; Map into sec. pool MOV #140000,R0 ;; Let R0 point to TCB CMP R1,#EOBUF-68. ;; Still space in buffer for taskname ;; ... # commons, 15 common names? BHI 100$ ;; No TST T.NAM(R0) ;; End of list? BEQ 100$ ;; Null task, end of list MOV T.PCBV(R0),R3 ;; Get pointer to common PCB vector BEQ 90$ ;; None there MOVB (R3)+,R4 ;; Get #commons BEQ 90$ ;; None there CMP R4,#15. ;; More than 15 commons? BHI 80$ ;; Ignore, we might have lost track INC R3 ;; Skip high byte #commons MOV T.NAM(R0),(R1)+ ;; Save name MOV T.NAM+2(R0),(R1)+ ;; ... INC R2 ;; Count task MOV R4,(R1)+ ;; Save #commons 80$: MOV (R3)+,R5 ;; Get address of common PCB BIC #1,R5 ;; Don't use odd addresses ;PS026 MOV P.NAM(R5),(R1)+ ;; Save common name MOV P.NAM+2(R5),(R1)+ ;; ... SOB R4,80$ 90$: MOV T.TCBL(R0),R0 ;; Point to next task if any BNE 70$ ;; EQ = none left 100$: MOV R2,COUNT ;; Save #found tasks MOV (SP)+,@APR6 ;; Restore KISAR6 mapping RETURN ;; From system state 110$: CALL PRIBUF ; Print tasks with commons ; JMP EXIT ; ; Subroutine to print tasks with commons ; PRIBUF: MOV COUNT,R2 ; Recouver #found tasks MOV R2,R5 ; Copy count of found tasks BEQ 30$ ; None, ready MOV #BUF,R4 ; Point to first entry 10$: MOV #TSKNAM,R0 ; Destination ascii MOV (R4)+,R1 ; Get task name first half CALL $C5TA ; Convert to ascii MOV (R4)+,R1 ; Get second half name CALL $C5TA ; Convert to ascii MOVB (R4),R1 ; Get no of commons ; ; Add common names to list ; MOV #COMS,R0 ; Ascii destination MOV R5,-(SP) ; Save task name loop counter MOV (R4)+,R5 ; Get common name loop counter 20$: MOVB #' ,(R0)+ ; Insert leading spaces MOVB #' ,(R0)+ ; Insert leading spaces MOV (R4)+,R1 ; Get common name first half CALL $C5TA ; Convert to ascii MOV (R4)+,R1 ; Get second half name CALL $C5TA ; Convert to ascii SOB R5,20$ ; Next common MOV (SP)+,R5 ; Restore task name loop counter ; ; Print task name with commons ; SUB #MES1,R0 ; Calculate size of message QIOW$S #IO.WVB,#1,#1,,,,<#MES1,R0,#40> SOB R5,10$ 30$: RETURN .PAGE .SBTTL List all tasks which use a particular common ; ; List all tasks which use a particular common ; LITK: MOV COMPNT,R0 MOV #REFASC,R1 MOV #6,R2 10$: MOVB (R0)+,(R1)+ SOB R2,10$ DIR$ #COMLOG ; ; Scan task list in primary pool and search for tasks using specified common ; CALL $SWSTK,70$ ; Switch to system state MOV TSKHD,R0 ;; Pointer to system task directory MOV #BUF,R1 CLR R2 ;; No tasks found yet MOV (R0),R0 ;; Point to first TCB BEQ 60$ ;; None there 20$: BIC #1,R0 ;; Don't use odd addresses ;PS026 CMP R1,#EOBUF-4 ;; Still space in buffer for taskname BHI 60$ ;; No TST T.NAM(R0) ;; Ckeck name for end of list BEQ 60$ ;; Null task, end of list MOV T.PCBV(R0),R3 ;; Get pointer to common PCB vector BEQ 50$ ;; None there MOVB (R3)+,R4 ;; Get #commons BEQ 50$ ;; None there CMP R4,#15. ;; More than 15. commons? BHI 60$ ;; Exit, we might have lost track INC R3 ;; Skip high byte #commons 30$: ;; CMP (R3)+,REFPCB ;; Right PCB? ;PS026 MOV (R3)+,R5 ;; Get PCB address from vector ;PS026 BIC #1,R5 ;; Be shure not an odd address ;PS026 CMP R5,REFPCB ;; Right PCB? ;PS026 BNE 40$ ;; ... MOV T.NAM(R0),(R1)+ ;; Save task name using common MOV T.NAM+2(R0),(R1)+ ;; ... INC R2 ;; Count task BR 50$ ;; Next task 40$: SOB R4,30$ ;; Try next common of this task 50$: MOV T.TCBL(R0),R0 ;; Point to next task if any BNE 20$ ;; EQ = none left 60$: MOV R2,COUNT ;; Save #found tasks RETURN ;; From system state 70$: CALL PRBUF2 ; Print tasks with commons ; ; Scan prototype task list in secondary pool ; keep: task name, no of commons, common names but only if 1 or more commons ; CALL $SWSTK,130$ ; Switch to system state MOV @APR6,-(SP) ;; Save KISAR6 mapping MOV PTCBL,R0 ;; Pointer to prototype task list MOV #BUF,R1 CLR R2 ;; No tasks found yet MOV (R0),R0 ;; Point to first TCB BEQ 120$ ;; None there ; ; Map TCB in secondary pool ; 80$: MOV R0,@APR6 ;; Map into sec. pool MOV #140000,R0 ;; Let R0 point to TCB CMP R1,#EOBUF-4. ;; Still space in buffer for taskname BHI 120$ ;; No TST T.NAM(R0) ;; End of list? BEQ 120$ ;; Null task, end of list MOV T.PCBV(R0),R3 ;; Get pointer to common PCB vector BEQ 110$ ;; None there MOVB (R3)+,R4 ;; Get #commons BEQ 110$ ;; None there CMP R4,#15. ;; More than 15 commons? BHI 120$ ;; Ignore, we might have lost track INC R3 ;; Skip high byte #commons 90$: ;; CMP (R3)+,REFPCB ;; Right PCB? ;PS026 MOV (R3)+,R5 ;; Get PCB address from vector ;PS026 BIC #1,R5 ;; Be shure not an odd address ;PS026 CMP R5,REFPCB ;; Right PCB? ;PS026 BNE 100$ ;; ... MOV T.NAM(R0),(R1)+ ;; Save name MOV T.NAM+2(R0),(R1)+ ;; ... INC R2 ;; Count task BR 110$ ;; Next task 100$: SOB R4,90$ ;; Try next common of this task 110$: MOV T.TCBL(R0),R0 ;; Point to next task if any BNE 80$ ;; EQ = none left 120$: MOV R2,COUNT ;; Save #found tasks MOV (SP)+,@APR6 ;; Restore KISAR6 mapping RETURN ;; From system state 130$: CALL PRBUF2 ; Print tasks with commons ; JMP EXIT ; ; Subroutine to print tasks ; PRBUF2: MOV COUNT,R5 ; Recover #found tasks BEQ 20$ ; None, ready MOV #BUF,R4 ; Point to first entry 10$: MOV #TKNAM,R0 ; Destination ascii MOV (R4)+,R1 ; Get task name first half CALL $C5TA ; Convert to ascii MOV (R4)+,R1 ; Get second half name CALL $C5TA ; Convert to ascii ; ; Print task name with commons ; DIR$ #PRITSK SOB R5,10$ 20$: RETURN .PAGE .SBTTL Error handling ; ; The vector table could not be initialysed ; VECERR: CALL DSWERR DIR$ #VECLOG DIR$ #DSWLOG JMP EXIT ; ; Convert an errorcode in $DSW into a printable number in DSWASC ; DSWERR: MOV #DSWASC,R0 ; Point to ascii field MOV #6,R1 ; 6 characters to initialyse 10$: MOVB #' ,(R0)+ ; Initialyse a byte SOB R1,10$ ; ... until all done MOV #DSWASC,R0 ; Point to ascii field MOV $DSW,R1 ; Get error code CLR R2 ; Specify zero suppression CALL $CBDSG ; Do conversion RETURN ; .PAGE .SBTTL Fixed data .PDATA TRNVEC: GIN$ GI.VEC,EXEVEC,EXEVCL VECLOG: QIOW$ IO.WVB,1,1,,,, DSWLOG: QIOW$ IO.WVB,1,1,,,, COMLOG: QIOW$ IO.WVB,1,1,,,, R50LOG: QIOW$ IO.WVB,1,1,,,, NOCLOG: QIOW$ IO.WVB,1,1,,,, PRITSK: QIOW$ IO.WVB,1,1,,,, VECMES: .ASCII /LCU -- initialisation error./ .BYTE CR,LF .ASCII / Vector table could not be initialised./ VECMSL =: . - VECMES R50MES: .ASCII /LCU -- Illegal characters in input string./ R50MSL =: . - R50MES .EVEN ; Allways end PSECTS even .PAGE .SBTTL R/W data .IDATA ; ; Executive vector table ; EXEVEC: .WORD 0 ; Initialyse check word CBDHD: .WORD $CBDHD ; Common block directory list header TSKHD: .WORD $TSKHD ; Task list header PTCBL: .WORD $PTCBL ; Prototype task control block header APR6: .WORD KISAR6 ; Data APR6 mapping register EXEVCL =: <<. - EXEVEC> / 2 > ; ; Command line ; GCMD: GMCR$ ; ; Messages with a variable part ; ; Directive error : xxxxx ; DSWMES: .ASCII /Directive error :/ DSWASC: .BLKB 6 DSWMSL =: . - DSWMES ; ; Common "xxxxxx" is in use by: ; COMMES: .ASCII /Common "/ REFASC: .BLKB 6 ; Ascii name of common to search for .ASCII /" is in use by:/ COMMSL =: . - COMMES ; ; LCU -- Common "xxxxxx" not in system ; NOCMES: .ASCII /LCU -- Common "/ NOCASC: .BLKB 6 .ASCII /" not in system/ NOCMSL =: . - NOCMES ; TKMES: .ASCII /"/ TKNAM: .BLKB 6 .ASCII /"/ TKMESL =: . - TKMES ; ; Task "xxxxxx" uses: yyyyyy yyyyyy yyyyyy yyyyyy ; MES1: .ASCII /Task "/ TSKNAM: .BLKB 6 .ASCII /" uses:/ COMS: .BLKB 8.*15. .EVEN ; ; Variables ; REFR50: .BLKW 2 ; Rad50 name of common to search for REFPCB: .BLKW 1 ; Address of PCB of common to search COUNT: .BLKW 1 ; Number of tasks found COMPNT: .BLKW 1 ; Pointer to ASCII common in MCR buf BUF: .BLKW 1000. EOBUF: ; .EVEN ; Allways end PSECTS even .END START