.TITLE OPA - ONLINE POOL ANALYZER .SBTTL IDENT PAGE .IDENT /JN3.32/ ;WRITTEN BY J. NEELAND ;LAST MODIFIED 820402. ;MODIFIED 801021. BY DANIEL STEINBERG -- RECOVER FROM ODD ADDR. TRAPS BETTER ; BY USING THREADED ROUTINE LIST ;MODIFIED 801102. BY J. NEELAND TO HANDLE FUNNY INTRP. VECTORS (DECNET) ; BETTER, ALSO IMPROVE OCB HANDLING ;MODIFIED 820402. BY KITTY BETHE -- MODIFIED FOR MPLUS V 1, ADDED DATA ; STRUCTURES, MAPS TO TTCOM TO GET TERMINAL ; I/O PACKETS IF D-SPACE SUPPORT - N.B. ; WILL PROBABLY WORK OK FOR V2, BUT OPEN ; FILE COUNT AND WINDOW BLK PORTION IN ; PRIMARY POOL WILL NOT BE PICKED UP FOR ; TASKS WITH EXTERNAL HEADERS ; .LIST MEB ;NEED TO SEE ALL CODE FOR DEBUGGING .ENABL LC ;ALLOW LOWER-CASE I/O AND LISTING ; .MCALL QIOW$,DIR$,EXIT$S,GMCR$,PCBDF$,CLKDF$ .MCALL F11DF$,UCBDF$,DCBDF$,TCBDF$,PCBDF$,SCBDF$,KRBDF$ F11DF$ UCBDF$ DCBDF$ TCBDF$ SCBDF$ PCBDF$ CLKDF$ KRBDF$ ; M + ; UCB EXTENSION OFFSETS NEEDED (DEFINED BY [11,10]TTMAC.MAC) U.TIC =0 U.TOC =14 OPT.SZ =40. ; BYTE SIZE OF MAXPKT PACKETS, QIOS, SND/RCVS IN ; PRIMARY POOL ; MAXFRG=100. .IIF NDF,R$$MPL .ERROR ; THIS TASK WILL ONLY RUN UNDER MPLUS V.1 ; LOCAL MACROS .MACRO PRINT NAM MOV #'NAM'MSG,QIO+Q.IOPL MOV #'NAM'SIZ,QIO+Q.IOPL+2 DIR$ #QIO .ENDM PRINT .SBTTL OPA ENTRY - INIT THEN SWTSTK ; OPA:: ;ENTRY POINT DIR$ #GMCR ;EMPTY OUR MCR BUFFER IF ONE EXISTS MOV $EXSIZ,POOLWD ;CALC. TOTAL POOL SPACE SUB #$POOL,POOLWD MOV POOLWD,MAPSIZ ;SET SIZE OF OUR MAP ASR MAPSIZ ; IN # SEGMENTS OF 4 BYTES EA. ASR MAPSIZ MOV #MAP,R0 ;SET MAP TO ALL '?????' FOR UNKNOWN/USED MOV MAPSIZ,R2 MOV #'?,R1 5$: MOVB R1,(R0)+ SOB R2,5$ MOV #THRLST,THREAD ;INIT THREADED ROUTINE LIST ADDRESS CALL $SWSTK,END ;GET ONTO SYSTEM STACK TO LOOK AT POOL MOV SP,OKSP ;SAVE SP FOR RESTORE ON ODD OR MP TRAP MOV @#PS,OKPS ;SAVE VALID PSW TOO MOV @#4,OLDODD ;SAVE OLD ODD ADDR. TRAP VECTOR MOV @#250,OLDMPV ; SAME FOR MEM. PROT. VIOLATION MOV #ODDTRP,@#4 ;PUT IN OUR OWN TRAP VECTORS MOV #MPVTRP,@#250 CLR BADPC ;CLEAR FLAG/BAD PC LOCATION MOV #FRLIST,R5 ;GET POINTER TO BUFFER AREA CLR R4 ;ZERO COUNT OF FRAGMENTS MOV #MAXFRG,R3 ;GET MAXIMUM # ENTRIES MOV $CRAVL,R2 ;GET LISTHEAD OF FREE POOL 10$: MOV R2,R0 ;SAVE CURRENT ADDRESS INC R4 ;FOUND FREE SEGMENT; COUNT IT SUB #$POOL,R0 ;CALC. ADDR. RELATIVE TO START OF POOL MOV R2,(R5)+ ;SAVE REL. ADDRESS MOV 2(R2),R1 ;GET SEGMENT SIZE MOV R1,(R5)+ ;THEN SAVE IT CALL MRKMP1 ;MARK THE MAP .WORD '- ; WITH '-----' FOR FREE PIECES MOV (R2),R2 ;GET THE NEXT FREE SEGMENT ADDR. BEQ ENDFRE ;END IF POINTER TO NEXT IS ZERO SOB R3,10$ ;CONTINUE IF MORE ROOM IN LIST AREA ; ENDFRE: MOV R4,FRGMNT ;SAVE # FRAGMENTS .SBTTL NXTTHR - DISPATCH TO NEXT THREAD ;+ ;AT THIS POINT, SYSTEM SP AND PS SHOULD BE CORRECT AND THREAD POINTS ; TO THE FIRST ENTRY IN THE THREADED ROUTINE LIST ;- NXTTHR: MOV @THREAD,R0 ;GET NEXT LIST ENTRY BEQ XITSYS ;IF ZERO, END OF TABLE ADD #2,THREAD ;ADVANCE POINTER TO NEXT ENTRY JMP (R0) ;GO DO THIS PHASE OF DECODING ;+ ;GO BACK TO USER STATE ;- XITSYS: MOV OLDODD,@#4 ;RESTORE STANDARD TRAP VECTORS MOV OLDMPV,@#250 RETURN ;RETURN TO USER STATE (TO END:) ;+ ;ENTRY HERE ON ODD ADDRESS OR MEM. PROTECT TRAPS ;- MPVTRP: INC (SP) ;FLAG MEM. PROTECT VIOLATIONS W/ ODD PC ODDTRP: MOV (SP),BADPC ;SAVE MOST RECENT PC FOR ERROR MESSAGE MOV OKSP,SP ;RESTORE VALID SP (ELIMINATE JUNK ON STACK) MOV OKPS,@#PS ; SAME FOR PSW .IF DF,K$$DAS ; IF KERNAL DATA SPAE SUPPORT MOV KINAR5,KISAR5 ; RESTORE MAPPING OF KERNAL DATA APR 5 .ENDC ; K$$DAS BR NXTTHR ;THEN TRY NEXT THREADED CODE ENTRY .SBTTL STATCB - THREAD TO PICK UP TCBS ;+ ;NOW MARK TCB'S W/ THEIR NAMES ;- STATCB: MOV $TSKHD,R3 ;GET FIRST TCB 10$: MOV R3,R0 ;COPY ADDR. FOR DISTRUCTIVE USE CALL GTMOFF ;GET MAP OFFSET BCS 140$ ;IF OUTSIDE POOL, JUST IGNORE IT INC TCBCNT ; COUNT IT BIT #TS.EXE,T.STAT(R3) ; TASK ACTIVE ? BNE 15$ ; NO ; DERIVE SLOT FOR ACTIVE TASK ACCOUNTING AND SET IT UP MOV CURTCB,R2 ; GET LAST USED SLOT ADDR TST (R2)+ ; UPDATE IT TST TCBLST(R2) ; LIST FULL ? BMI 15$ ; YES, PUT INTO ****** SLOT MOV R0,TCBLST(R2) ; SAVE MAP ADDR OF TCB STRING MOV R2,CURTCB ; LEAVE NEW OFFSET IN SLOT PTR MOVB R2,(R0)+ ; SAVE ACCNTNG OFFSET IN MAP TCB STRING BR 17$ 15$: CLR R2 ; SLOT FOR ACCOUNTING IS ***** SLOT CLRB (R0)+ ; SAVE SLOT OFFSET IN TCB POSITION 17$: MOV #TCBSTG,R1 ; INSERT 'TCB - ' CALL MOVSTG MOV R0,NAMFLD ;SAVE ADDR OF TASKNAME FOR LATER COPIES MOV R0,NOFF(R2) ; AND FOR TASK ACCOUNTING CALL GTTSKN ; CONVERT FROM RAD50 AND COPY IN TASK NAME MOVB #'>,(R0)+ ;FINISH OFF W/ CLOSING BRACKET ; GET COMMON PCB VECTOR(S) MOV T.PCBV(R3),R0 ; GET ANY COMMON PCB VECTOR BEQ 90$ ; NONE MOVB @R0,R1 ; PICK UP ALLOCATION COUNT BMI 90$ ; (JUST IN CASE...) 20$: BIT #TS.EXE!TS.RDN,T.STAT(R3) ; TASK ACTIVE ? BEQ 70$ ; YES ; CHECK FOR PCBS FOR INSTALLED R/O SECTIONS NOT IN MEMORY MOV R2,-(SP) ; SAVE R2 MOV R0,-(SP) ; SAVE R0 MOV R0,R5 ; USE R5 FOR PCB VECTOR MOV R1,R2 ; USE R2 AS A COUNTER TST (R5)+ ; PASS 1ST WORD OF VECTOR 30$: MOV (R5)+,R0 ; LOOK AT A PCB TST P.STAT(R0) ; IN MEMORY ? BPL 40$ ; YES BIT #P2.RON,P.ST2(R0) ; RO SECTION ? BEQ 40$ ; NO MOV R0,R4 ; SAVE PCB ADDR FOR MRKCTP CALL GTMOFF BCS 40$ MOVB #'(,(R0)+ ; MARK PCB AS ($TASKNAME) MOVB #'$,(R0)+ CALL CPYNAM ; COPY THE TASKNAME (R1 CLOBBERED) MOVB #'),(R0)+ CALL MRKCTP ; MARK ANY COMMON CHECKPOINT PCB BR 50$ ; DONE (ONLY 1 TO A CUSTOMER) 40$: SOB R2,30$ ; DO EACH PCB VECTOR (UNLESS RO SECT FOUND) 50$: MOV (SP)+,R0 ; GET BACK VECTOR ADDR MOVB @R0,R1 ; AND VECTOR COUNT MOV (SP)+,R2 ; AND ACCOUNTING OFFSET BR 70$ ; MARK THE PCB VECTOR 70$: INC R1 ; ADD THREAD WORD ASL R1 ; MAKE A BYTE COUNT ADD R1,MOFF(R2) ; ADD VECTOR USAGE TO MISC ASR R1 ; MAKE A DBL WORD COUNT ASR R1 ADC R1 ; ROUND IT UP CALL GTMOFF ; GET MAP OFFSET BCS 90$ ; NOT IN POOL 80$: MOVB #'@,(R0)+ ; MARK EACH VECTOR WITH AN @ SOB R1,80$ ; DO ATTACHMENT DESCRIPTORS 90$: MOV T.ATT(R3),R4 ;LOOK FOR ATTACHMENT DESCRIPTOR LIST BEQ 120$ ;NONE IF ZERO 100$: MOV R4,R0 ;MAKE A COPY FOR DESTRUCTIVE USE SUB #6,R0 ;ADJUST TO BEGINNING OF BLOCK CALL GTMOFF ;GET THE OFFSET FROM BEGINNING OF POOL BCS 120$ ;IGNORE IF OUTSIDE OF POOL ;; INC ADBCNT INC AOFF(R2) ; COUNT IT MOVB #'*,(R0)+ ;MARK AREA WITH '*A*' MOVB #'A,(R0)+ MOVB #'*,(R0)+ 110$: MOV (R4),R4 ;LOOK FOR MORE ATTACHMENTS BNE 100$ ; AND CONTINUE WITH THEM ;CHECK FOR VARIOUS AST CONTROL BLOCKS 120$: MOV T.SAST(R3),R4 ;CHECK FOR ANY SPECIFIED AST CONTROL BLOCKS CALL MRKAST ; & GO MARK THEM OFF MOV T.ASTL(R3),R4 ;SAME FOR OTHER AST CONTROL BLOCKS CALL MRKAST MOV T.OCBH(R3),R4 ;LOOK FOR OFFSPRING CONTROL BLOCKS BEQ 140$ ;QUIT SEARCH IF NONE 130$: MOV R4,R0 ;NEED COPY OF ADDRESS FOR DESTRUCTIVE USE CALL GTMOFF ;CONVERT TO MAP ADDRESS BCS 140$ ;QUIT SEARCH IF OUTSIDE MAP AREA CALL MRKOCB ;GO MARK THEM AS: ^PARENTTASKNAME MOV (R4),R4 ;GET NEXT OCB ADDRESS BNE 130$ ; & PROCESS IT (IF THERE IS ONE) ; DO RECV BY REF QUEUE 140$: MOV T.RRFL(R3),R4 ; GET 1ST PACKET BEQ 160$ ; NONE 150$: MOV R4,R0 ; MAKE A COPY FOR GTMOFF CALL GTMOFF ; TURN INTO MAP BUFFER ADDR BCS 160$ ; FORGET IT IF NOT IN POOL INC ROFF(R2) ; COUNT IT IN OUR LISTS MOVB #'[,(R0)+ ; MARK AS [+TASKNAME+] MOVB #'+,(R0)+ CALL CPYNAM ; COPY THE TASKNAME MOVB #'+,(R0)+ MOVB #'],(R0)+ MOV @R4,R4 ; ANOTHER ONE ? BNE 150$ ; YES ; GET ANY RECEVE PACKETS IN PRIMARY POOL - N.B. THIS ARE SYSTEM TASKS ONLY ; AND THEY USE THE I/O PACKETS FROM MAXPKT LIST (F11ACP,TKTN,...LDR) 160$: MOV T.RCVL(R3),R4 ; GET 1ST PACKET BEQ 180$ ; NONE 170$: MOV R4,R0 ; MAKE A COPY FOR MAP ADDR CALL GTMOFF ; GET MAP ADDR BCS 180$ ; NOT IN PRIMARY POOL INC ROFF(R2) ; TASK ACCOUNTING AGAIN MOVB #'[,(R0)+ ; MARK AS [*TASKNAME*] MOVB #'*,(R0)+ CALL CPYNAM MOVB #'*,(R0)+ MOVB #'],(R0)+ MOV @R4,R4 ; GET NEXT PACKET BNE 170$ 180$: MOV T.PCB(R3),R0 ; GET PCB ADDR BEQ 190$ TST P.STAT(R0) ; TASK CHECKPTED ? BPL 190$ ; NO CALL GTMOFF ; YES, HAVE TO MARK IT HERE BCS 190$ MOVB #'(,(R0)+ MOVB #'-,(R0)+ ; MARK AS (-TASKNAME) CALL CPYNAM MOVB #'),(R0)+ 190$: MOV T.TCBL(R3),R3 ;GET NEXT TCB BEQ ENDTCB ; UNTIL END OF LIST TST T.TCBL(R3) ;HAVE WE GOTTEN TO THE NULL TASK? BEQ ENDTCB ; YES JMP 10$ ;IF NO, CONTINUE ; ENDTCB: JMP NXTTHR ;GO DO NEXT ROUTINE .SBTTL STACLQ - PICK UP CLOCK QUEUE PACKETS ;+ ;NOW DO CLOCK-QUEUE CONTROL BLOCKS (AN EASY ONE) ;- STACLQ: MOV $CLKHD,R4 ;GET FIRST CONTROL BLOCK BEQ ENDCLQ ;MAYBE THERE AREN'T ANY???? 10$: MOV R4,R0 ;WE NEED TO GET THIS INTO AN OFFSET CALL GTMOFF ;GET MAP OFFSET BCS 20$ ;IGNORE IF OUTSIDE POOL AREA ;; INC CLQCNT MOVB #'[,(R0)+ ;MARK JUST AS '[Cn]' MOVB #'C,(R0)+ ;WHERE n is REQUEST TYPE MOVB #'Q,(R0)+ MOVB C.RQT(R4),R1 ;GET THE REQUEST TYPE CALL CNVASC ;PUT OUT AS ASCII MOVB #'],(R0)+ ; DO ANY TASK ACCOUNTING FOR THIS PACKET MOV C.TCB(R4),R3 ; GET A POSSIBLE TCB ADDR CALL GTACNT ; GET THE ACCOUNTING SLOT INC COFF(R3) ; COUNT THE CLOCK QUEUE REQUEST 20$: ASSUME C.LNK,0 MOV (R4),R4 ;GET NEXT CONTROL BLOCK IF ANY BNE 10$ ; AND MARK THAT ONE ; ENDCLQ: JMP NXTTHR ;GO DO NEXT ROUTINE .SBTTL STALOG - PICK UP ASN CONTROL BLOCKS ;+ ;NOW MARK ASN CONTROL BLOCKS (ANOTHER EASY ONE) ;- STALOG: MOV $LOGHD,R3 ;GET 1ST ONE BEQ ENDLOG ; IF IT EXISTS, ELSE SKIP OUT 10$: MOV R3,R0 ;MAKE A COPY CALL GTMOFF ;GET OFFSET INTO MAP BCS 20$ ;IGNORE IF OUTSIDE POOL ;; INC ASNCNT ; COUNT IT MOVB #'*,(R0)+ ;MARK IN FORM '*n*' MOVB L.TYPE(R3),R1 ;GET THE ASN TYPE # CALL CNVASC ;PUT OUT IN ASCII MOVB #'*,(R0)+ ; WHERE n is ASN TYPE 20$: ASSUME L.LNK,0 MOV (R3),R3 ;GET NEXT ASN BLOCK IF IT EXISTS BNE 10$ ; ENDLOG: JMP NXTTHR ;GO DO NEXT ROUTINE .SBTTL STACBD - DO COMMON BLOCK DIRECTORY ; PCB'S FOR INSTALLED COMMONS NOT IN MEMORY ARE ONLY ON THIS CHAIN STACBD: MOV $CBDHD,R4 ; GET 1ST ONE BEQ 40$ 10$: BIT #PS.OUT,P.STAT(R4) ; COMMON OUT OF MEMORY ? BEQ 20$ ; NO MOV R4,R0 ; YES, SO MARK IT NOW CALL GTMOFF BCS 20$ MOVB #'(,(R0)+ ; MARK AS ($NAME) MOVB #'$,(R0)+ CALL GTPARN ; GET ANY COMMON TASK IMAGE PCB CALL MRKCTP 20$: CMP #^RTTC,P.NAM(R4) ; IS IT TTCOM BNE 30$ ; NO CMP #^ROM ,P.NAM+2(R4) ; MAYBE BNE 30$ ; NOT SO MOV P.REL(R4),TTCAPR ; YES, SAVE ITS PHYSICAL ADDR 30$: MOV P.CBDL(R4),R4 ; GET NEXT ON CBD CHAIN BNE 10$ 40$: JMP NXTTHR .SBTTL STAPAR - PICK UP PCBS (AND DO TASK HEADERS) ;+ ;NOW TRY TO DO PARTITION-CONTROL-BLOCKS ; EXTENSIVELY MODIFIED FOE M-PLUS (CODE BORROWED FROM RMDEMO) ;- STAPAR: MOV #$PARHD,R4 ;; HEAD OF PARTITION LIST ; OUTER LOOP - NEXT MAIN PARTITION STAOUT: ASSUME P.LNK,0 MOV (R4),R4 ;; GET NEXT PCB BNE 10$ ;; JMP NXTTHR ;; END OF LIST DO NEXT THREAD 10$: ;; REFERENCE LABEL MOV R4,SAVPAR ;; SAVE MAIN PARTITION ADDRESS MOV R4,R0 ; MAKE A COPY TO CALCULATE MAP OFFSET CALL GTMOFF ; GET ADDRESS IN OUR MAP BCS STAOUT ; TRY NEXT IF OUTSIDE POOL ;; INC PMACNT ; COUNT A MAIN PAR MOVB #'(,(R0)+ ; MARK IT WITH A ( MOVB #'_,(R0)+ ; CHARACTERISTIC (*) = MAIN CALL GTPARN ; LOAD P.NAM PLUS ) INTO R0 BUFFER ; INNER LOOP - DO EACH SUBPAR FOR THE MAIN PAR STAIN: 10$: MOV P.SUB(R4),R4 ;; SUB PARTITION PCB BNE 30$ ;; ANOTHER SUBPAR TO DO 20$: MOV SAVPAR,R4 ;; RESTORE MAIN PCB BR STAOUT ; GO FOR NEXT MAIN PAR 30$: MOV R4,R0 ; PUT ADDR IN R0 FOR GTMOFF CONVERSION CALL GTMOFF ; CONVERT TO BYTE OFFSET IN MAP BCS 10$ ; OUTSIDE OF POOL MOVB #'(,(R0)+ ; PCBS START WITH ( BIT #PS.COM,P.STAT(R4) ;; DYNAMIC COMMON BEQ 110$ ;; NO, TASK BIT #P2.DRV,P.ST2(R4) ;; LOADED (DRUNK?) DRIVER BEQ 40$ ;; NO ; DRIVER PCB ;; INC DRVCNT MOVB #40,(R0)+ ; NO SPECIAL CHAR MOV P.OWN(R4),R3 ;; DCB ADDRESS MOVB D.NAM(R3),(R0)+ ;; DEVICE NAME MOVB D.NAM+1(R3),(R0)+ ;; IN ASCII MOV #PDVSTG,R1 ; FINISH OFF WITH : ) CALL MOVSTG BR 10$ ;; GO FOR NEXT ; OTHER DYNAMIC COMMON 40$: ;; INC DYNCNT ; COUNT IT MOV P.NAM(R4),R1 BIS P.NAM+2(R4),R1 ;; UNNAMED COMMON BEQ 50$ ;; YES MOVB #'!,(R0)+ ;; DYNAMIC COMMON PCB MARKER CALL GTPARN ;; LOAD NAME IN PCB PLUS ) BR 100$ ; UNNAMED COMMON 50$: MOVB #'+,(R0)+ ;; COMMON PCB MARKER MOV P.OWN(R4),R3 ;; OWNING TASK BIT #P2.RON,P.ST2(R4) ;; RO SECTION OF MU TASK BNE 80$ ;; YES, P.OWN IS A TCB MOV P.ATT(R4),R3 ;; NO, GET ATTACHMENT LIST BEQ 60$ ;; NOBODY ATTACHED, LEAVE NAME BLANK MOV A.TCB(R3),R3 ;; GET TCB ADDRESS BNE 80$ 60$: MOV #6,R3 ;; LOAD WITH +++ 70$: MOVB #'+,(R0)+ SOB R3,70$ BR 90$ 80$: CALL GTTSKN ;; LOAD TASK NAME 90$: MOVB #'),(R0)+ ;; BRACKETING CHAR ; PICK UP ANY COMMON TASK IMAGE FILE PCB'S 100$: CALL MRKCTP BR 10$ ; TASK PCB 110$: ;; INC TSKCNT ; COUNT IT MOV P.TCB(R4),R3 ;; TCB ADDRESS MOVB #'>,(R0)+ ;; ASSUME ACTIVE BIT #TS.EXE,T.STAT(R3) ;; IS IT BEQ 120$ ;; YES MOVB #'[,-1(R0) ;; NO 120$: BIT #PS.FXD,P.STAT(R4) ;; PARTITION FIXED IN MEMORY BEQ 130$ ;; NO MOVB #'=,-1(R0) ; YES ,DO FIXED FLAG 130$: MOV R0,NAMFLD ; SAVE SLOT FOR CONVERTED NAME CALL GTTSKN MOVB #'),(R0) ;NOW LOOK FOR TASK HEADERS IN POOL BIT #PS.OUT!PS.CKP,P.STAT(R4) ; CHECKPOINTED ? BNE 10$ ; YES, HEADER NO LONGER MEMORY RESIDENT MOV P.HDR(R4),R0 ; NO, GET THE HEADER ADDRESS IN R0 BEQ 10$ ; IF ZERO, EXTERNAL HEADER - MPLUS V2 ; NOT YET HANDLED MOV H.HDLN(R0),R1 ;IT'S THERE, GET IT'S LENGTH CALL GTMOFF ;GET OFFSET INTO MAP BCS STAEND ;IF C SET, WASN'T IN POOL AREA ; PUT IN INTO ACTIVE TASK ACCOUNTING MOV P.TCB(R4),R3 ; GET TCB ADDR CALL GTACNT ; GET LOC IN MAPBUF FOR ACCOUNTING ENTRY ADD R1,HOFF(R3) ; SAVE HEADER SIZE ; MARK HEADER ON MAP MOV R0,R5 ;SAVE START OFFSET ADDRESS IN R5 CALL MRKMP2 ;MARK THE WHOLE HEADER AREA .WORD '# ; W/ '#######' MOVB #'>,-(R0) ;MARK END W/ USUAL ANGLE BRACKET MOV R5,R0 ;GET BACK BEGINNING OF HEADER MOV #HDRSTG,R1 ;INSERT '
MOVB #'>,@R0 ADD #44.,MOFF(R3) ; ADD TO MISCELLANY NOWB: TST (R2)+ ;SKIP TO NEXT LUN SOB R5,GTWB ;DECR. COUNT OF LUNS TO TEST STAEND: JMP STAIN ; GO DO NEXT SUB PAR .SBTTL STAVCB - DO VCBS AND FCBS ;+ ;NOW TRY TO PICK UP VOLUME-CONTROL-BLOCKS & FILE-CONTROL BLOCKS ;- STAVCB: MOV $DEVHD,R3 ;START WITH THE LIST OF DEVICES CLR -(SP) ; USR TOP OF STACK AS UNIT CNTR CHKDEV: MOVB D.UNIT+1(R3),R5 ;GET TOTAL # UNITS MOVB D.UNIT(R3),R4 ;GET THE BOTTOM UNIT NUMBER MOV R4,@SP ;PUT IT AT STACK TOP FOR DET UNIT # SUB R4,R5 ;SUBTRACT BOTTOM # INC R5 ;ADJUST FOR END COUNT MOV D.UCBL(R3),R4 ;SAVE LENGTH OF A UCB MOV D.UCB(R3),R2 ;GET A UCB TSTUCB: BIT #DV.MNT,U.CW1(R2) ;IS THIS DEVICE MOUNTABLE? BEQ NXTDEV ;IF NOT, GO TRY FOR ANOTHER DEVICE BIT #DV.F11,U.CW1(R2) ;IS IT FILES-11? BEQ NXTDEV ;IF NO, TRY ANOTHER DEVICE BITB #US.MNT,U.STS(R2) ;OKAY, IS IT ACTUALLY MOUNTED BNE NXTUNT ;IF NO, CHECK THE NEXT UNIT MOV U.VCB(R2),R0 ;AHA!, GOT ONE. GET ADDRESS OF VCB CALL GTMOFF ;GET OFFSET IN MAP BCS FNDFCB ;IGNORE IF OUTSIDE POOL ;; INC VCBCNT ; COUNT IT MOV #VCBSTG,R1 ;MARK WITH ',@R0 ; PUT TERMINATOR ON NXTFCB: MOV (R1),R1 ;GET ANOTHER FCB BNE CHKFCB ; & SEE IF IT'S IN POOL, IF ONE EXISTS ; GETWB: MOV U.VCB(R2),R1 ;GET THE VCB ADDRESS A 3RD TIME MOV V.IFWI(R1),R0 ;NOW GET THE INDEX-FILE WINDOW BLK ADDR. CALL GTMOFF ;INTO A MAP OFFSET BCS NXTUNT ; NOT IN POOL ;; INC WBCNT INC FOFF ; CHARGE TO INACTIVE TASK USAGE MOVB #'!,(R0)+ ; PRIMARY POOL PART OF WB IS ONLY MOVB #'W,(R0)+ ; 8 BYTES NXTUNT: ADD R4,R2 ;ADVANCE TO NEXT UCB INC @SP ; COUNT THE UNIT DEC R5 ; UNTIL NO MORE UNITS BNE TSTUCB NXTDEV: MOV (R3),R3 ;MOVE TO NEXT DEVICE IN CHAIN BNE CHKDEV ; AND GO CHECK IF IT'S A FILES-11 TYPE ; ENDVCB: TST (SP)+ ;CLEAN UP STACK JMP NXTTHR ;GO DO NEXT ROUTINE .SBTTL STADCB - DO DATA STRUCTURES FOR LOADED DRIVERS ;+ ;GET ALL I/O PACKETS ON DEVICE (SCB) QUEUES ; AND FIND ANY DEVICE DRIVER DATA STRUCTURES IN POOL ; ; REGISTER USAGE: ; R3 CURRENT UCB ; R4 CURRENT DCB ; R5 CURRENT I/O PACKET OR SCB ;- STADCB: MOV $DEVHD,R4 ;GET START OF DCB'S CLR -(SP) ; USE TOP STACK AS UCB LOOP CNTR MOV #UCXLST,NXTUCX ; SET UP UCBX LIST (IN CASE CLOBBERED) ; SET UP FOR THE NEW DCB TSTDCB: MOV D.UCB(R4),R3 ;GET 1ST UCB BIT #DV.PSE,U.CW1(R3) ;IS THIS A PSEUDO DEVICE? BEQ 2$ ;IF NOT, OK TO CONTINUE ON THIS ONE JMP NXTDCB ;IF YES, CAN'T DO MUCH WITH IT - GOTO NXT DVC. ; SET UP UNIT COUNT FOR THIS DCB 2$: MOVB D.UNIT+1(R4),R5 ;GET TOTAL # UNITS MOVB D.UNIT(R4),R1 ;GET THE BOTTOM UNIT NUMBER MOV R1,UNITNO ;SAVE IT SUB R1,R5 ;SUBTRACT BOTTOM # INC R5 ;ADJUST FOR END COUNT MOV R5,(SP) ; AND USE A COUNTER ON THE STACK BR NEWSCB TSTSCB: CMP U.SCB(R3),R5 ;HAVE WE GOT A NEW SCB ADDRESS? BEQ NXTUCB ;IF NOT, TRY ANOTHER UCB ;NOW CHECK FOR I/O PACKETS IN USE & QUEUED TO THIS CONTROLLER (SCB) NEWSCB: MOV U.SCB(R3),R5 ;GET THE SCB ADDRESS CLR CURPKT ;CLEAR ADDRESS FOR MAP OF CURRENT PACKET MOV R5,-(SP) ; SAVE SCB ADDR ON STACK MOV R3,-(SP) ; SAVE CURRENT UCB ADDR BIT #DV.TTY,U.CW1(R3) ; TERMINAL ? BEQ 5$ ; NO ; YES, S.PKT IS NOT THE CURRENT PACKET ; SO DO SPECIAL CASE PROCESSING CMP #"VT,D.NAM(R4) ; A VIRTUAL TERMINAL ? BNE 3$ ; NO MOV U.PKT(R3),R0 ; GET CURRENT I/O PACKET BEQ NXTPKT MOV R0,R3 ; SAVE PAKT ADDR MOV I.PRM+12(R3),R0 ; GET INTERMEDIATE BUFFER BEQ 1$ ; NONE CMP R0,#$POOL ; JUST IN CASE BLO 1$ MOV 2(R0),R1 ; GET SIZE ADD #4,R1 ; PLUS LINK + COUNT WORDS CALL MRKMAP ; MARK AS &&&&& .WORD '& 1$: MOV I.PRM+14(R3),R0 ; GET AST BLOCK ADDR BEQ 2$ CALL GTMOFF BCS 2$ MOV #OFASTG,R1 ; MARK AS [AO] CALL MOVSTG 2$: MOV R3,R0 ; RESTORE OFFSPRING PACKET ADDR BR IOPKT 3$: CMP #"TT,D.NAM(R4) ; TT DEVICE ? BEQ NXTPKT ; YES, IGNORE CURRENT PACKET IN SCB 5$: TSTB S.STS(R5) ;IS THIS CONTROLLER BUSY? BEQ NXTPKT ;IF NOT, PROCEED TO LOOK FOR I/O PACKETS ANYWAY MOV S.PKT(R5),R0 ;IS BUSY, GET CURRENT PACKET BEQ NXTPKT ; NO CURRENT PACKET CMP R0,#$POOL ; SOME USER DRIVERS DONT HAVE PACKETS HERE BLO NXTPKT IOPKT: MOV I.UCB(R0),-(SP) ; SAVE PACKET'S UCB ADDR CALL QIOACN ; COUNT THE QIO FOR TASK ACCTNG CALL GTMOFF ;CONVERT PACKET ADDRESS TO MAP ADDRESS BCS DOVEC ;TRY ANOTHER ONE IF OUTSIDE POOL MOV R0,CURPKT ;SAVE MAP ADDRESS TO COPY LATER MOV #IOP,R1 ;PUT 'QIO ' INTO MAP CALL MOVSTG MOVB D.NAM(R4),(R0)+ ;COPY OVER DEVICE NAME MOVB D.NAM+1(R4),(R0)+ MOV (SP)+,R3 ; GET PACKETS UCB IN R3 NXTUN: BIT #1,R3 ; VALID UCB ADDR ? BEQ 2$ ; YES MOV @SP,R3 ; NO, USE CURRENT UCB INSTEAD 2$: SUB D.UCB(R4),R3 ; MAKE AN OFFSET FROM FIRST MOV D.UCBL(R4),R1 ; SIZE OF A UCB IN R1 CLR R2 ; PREPARE FOR DIVIDE DIV R1,R2 ; MOV R2,R1 ; R1 NOW HAS THE RELATIVE UNIT # ADD UNITNO,R1 ; TURN R1 INTO ACTUAL UNIT # CALL DEVNUM ; LOAD ASCII UNIT # ONTO MAP NXTPKT: MOV @R5,R5 ; GET NEXT PACKET ADDR BEQ DOVEC ;IF NOT, GO FOR NEXT UCB MOV R5,R0 ;GET COPY FOR DESTRUCTIVE USE MOV CURPKT,R1 ;GET OLD PACKET ADDRESS BEQ IOPKT ;IF NONE, HAVE TO GET CONTENTS THE HARD WAY CALL QIOACN ; COUNT THE QIO FOR TASK ACCTNG CALL GTMOFF ;CONVERT NEW PACKET ADDRESS TO MAP ENTRY BCS DOVEC ;QUIT SCAN IF OUTSIDE POOL MOV #6,R3 ;SET UP TO COPY 6 BYTES FROM OLD MAP ADDRESS 10$: MOVB (R1)+,(R0)+ SOB R3,10$ MOV I.UCB(R5),R3 ; GET UCB ADDR OF PACKET BR NXTUN ;LOAD UNIT # & BACK FOR POSSIBLE NEW PACKET ; DOVEC: MOV (SP)+,R3 ; RESTORE UCB ADDR MOV (SP)+,R5 ; RESTORE OLD SCB ; ** MPLUS HAS NO ICBS IN POOL - POOL IS KERNAL DATA SPACE !!! NXTUCB: DEC @SP ; LOOP COUNT OF UCBS BEQ 70$ ; ALL DONE ADD D.UCBL(R4),R3 ;ADVANCE UCB POINTER TO NEXT UCB CMP #"TT,D.NAM(R4) ; A TT BEQ 20$ ; YES, PICK UP UCBX ADDRESSES 10$: JMP TSTSCB ; NO - GO PROCESS POSSIBLE NEW SCB ; COLLECT ADDRESSES OF UCB EXTENSIONS 20$: MOV U.TUX(R3),R1 ; UCB EXTENSION ? BEQ 10$ ; NO CMP R1,#120000 ; IN TTCOM ? BHIS 60$ ; YES CMP R1,#$POOL ; IN POOL ? BLO 10$ ; NO, IGNORE IT ; DEAL WITH UCBX IN PRIMARY POOL *** THIS CODE HAS NEVER BEEN EXECUTED ; ON OUR SYSTEM - OUR TTCOM IS BIG MOV R1,-(SP) ; SAVE UCBX ADDR MOV U.TOC(R1),R0 ; GET OUTPUT QIO ADDR BEQ 30$ CLR UNTFLD MOV R3,R2 ; SAVE UCB ADDR CALL QIOACN ; DO THE QIO TASK ACCOUNTING (R3 KILLED) MOV R2,R3 ; RESTORE UCB ADDR CALL MRKTIO ; MARK IT 30$: MOV @(SP),R0 ; GET INPUT QIO ADDR BEQ 40$ MOV R2,R3 ; SAVE UCB ADDR CALL QIOACN ; DO THE QIO TASK ACCOUNTING (R3 KILLED) MOV R2,R3 ; RESTORE UCB ADDR CALL MRKTII ; MARK IT 40$: MOV (SP)+,R0 ; GET UCBX ADDR CALL MRKUCX 50$: JMP TSTSCB ; SAVE INFO FOR UCBX IN TTCOM POOL 60$: .IF DF,K$$DAS ; UCBX PICKUP ONLY IMPLEMENTED FOR D SPACE MOV NXTUCX,R2 ; GET SAVE SLOT MOV R3,(R2)+ ; SAVE UCB ADDR MOV R1,(R2)+ ; UCBX ADDR CLR (R2)+ ; SLOT FOR OUTPUT QIO MOV R2,NXTUCX ; SAVE NEXT SLOT PTR .ENDC ;K$$DAS BR 50$ ; TRY FOR NEXT SCB ; LOOK FOR LOADED DEVICE DATA STRUCTURES IN POOL 70$: CMP R4,#$POOL ;IS THIS DCB INSIDE POOL AREA? BLO NXTDCB ;NO IF LOWER, SO DONE W/ THIS DEVICE ; VT: DEVICES HAVE ONLY UCB +SCB IN POOL CMP R5,#$POOL ; SCB IN POOL BHIS 90$ ; YES 80$: MOV R3,R5 ; TRY UCB CMP R5,#$POOL BLO 160$ ADD D.UCBL(R4),R5 ; UP TO END OF UCB IF UCB IN POOL SUB #10,R5 ; DON'T COUNT 1ST 4 WORDS (D.UCBL INCLUDES) BR 160$ ; GO LOAD %%% ; CHECK FOR DRIVER DISPATCH TABLE IN POOL 90$: MOV D.DSP(R4),R0 ; GET DRIVER DISPATCH TABLE CALL GTMOFF ; IN POOL ? BCS 100$ ; NO MOVB #'*,(R0)+ ; YES -- THIS DOESN'T HAPPEN ON OUR SYSTEM MOVB #'D,(R0)+ ; SO MARK AS *D* MOVB #'*,@R0 ;WE NOW HAVE ALL THE ASSOCIATED DATA STRUCTURES FOR THIS DEVICE. ; WE WILL ASSUME THAT THE DCB COMES FIRST 100$: MOV S.KRB(R5),R1 ; GET KRB ADDR CMP R3,R1 ; UCB COMES LAST ? BHI 80$ ; YES, USE IT TO FLAG THE END BIT #S2.CON,S.ST2(R5) ; CONTIGUOUS KRB ? BEQ 120$ ; NO MOV K.OFF(R1),R0 ; GET OFFSET TO UCB TABLE BEQ 120$ ; IF THIS IS NON0 SEEMS TO PT TO END OF KRB MOV R1,R5 ; GET START KRB ADD R0,R5 ; PLUS OFFSET TO END OR UCB TABLE BIT #KS.UCB,K.STS(R1) ; DOES IT HAVE A UCB TABLE ? BEQ 160$ ; NO, HAVE END PTR 110$: BIT #1,(R5)+ ; ADVANCE TO END OF UCB TABLE BEQ 110$ ; END ENTRY IS -1, THEREFORE ODD ! BR 160$ ; HAVE END+2 OF DRIVER DATA STRUCTURE IN R5 120$: CMP R1,R5 ; KRB AFTER SCB ? BLO 130$ ; NO MOV R1,R5 ; YES, USE IT TO DETERMINE END OF DATA STRUC ADD #K.URM,R5 ; PT TO END BIT #FE.EXT,$FMASK ;DO WE HAVE TO WORRY ABOUT UMR AREA? BEQ 150$ ; NO BITB #UC.NPR,U.CTL(R3) ;YES, BUT IS THIS AN NPR DEVICE? BEQ 150$ ; NO ADD #14.,R5 ;YES, SO ADD IN SPACE FOR UMR ALLOCATION BR 160$ 130$: BIT #S2.LOG,S.ST2(R5) ; ERROR LOGGING SUPPORTED BEQ 140$ ; NO CMP (R5)+,(R5)+ ; ADD IN 2 WORDS FOR THIS SUPPORT 140$: ADD #S.KRB,R5 ;ADVANCE TO END OF SCB AREA 150$: TST (R5)+ ; ADVANCE PAST END OF DATA STRUC FOR SUB ; COMMON CODE FOR DISPLAY OF DATA STRUCTURE AREA 160$: MOV R4,R0 ;GET COPY OF START ADDR IN R0 FOR GTMOFF CALL GTMOFF ;CONVERT TO OFFSET IN POOL MAP BCS NXTDCB ; SHOULDN'T HAPPEN SUB R4,R5 ;CONVERT R5 TO SIZE OF AREA (SUB DCB ADDR) MOV R5,R1 ;SET UP FOR MARKING OFF AREA MOV R0,-(SP) ;SAVE START OF AREA 170$: CALL MRKMP2 .WORD '% ;FILL AREA W/ '%%%%%%%' MOVB #'>,-(R0) ;END AREA W/ USUAL '>' MOV (SP)+,R0 ;RECOVER BEGINNING OF AREA CMP #"VT,D.NAM(R4) ; A VT ? BNE 180$ ;NO MOV #VTSTG,R1 ; YES MARK AS CALL MOVSTG MOVB D.UNIT(R4),R1 ; GET UNIT NUMBER FROM DCB CALL DEVNUM ; LOAD IT WITH nn:> MOVB #'%,-(R0) ; OVERWRITE THE > FROM DEVNUM BR NXTDCB ; ALL DONE ; NORMAL LOADED DRIVER DATABASES 180$: MOV #DCBSTG,R1 ;INSERT ',(R0) ;FINISH OFF WITH ENDING DELIMITER ; DO TASK ACCOUNTING CALL GTACNT ; PICK UP ACCOUNTING OFFSET IN R3 ADD #M$$CRB,MOFF(R3) ; ADD SIZE OF MCR BUFFER TO MISC 20$: MOV (R4),R4 ;GET NEXT MCR LINE ADDRESS BR 10$ ;AND GO TRY OUT THAT ONE ENDMCR: JMP NXTTHR ;GO DO NEXT ROUTINE .SBTTL STAOPK - PICK UP THE MAXPKT I/O PACKETS ;+ ;NOW GET ANY CURRENTLY UNUSED I/O PACKETS FROM I/O OPTIMIZATION ;- STAOPK: ;REF. LABEL .IF DF Q$$OPT MOV #$PKAVL,R2 ;GET POINTER TO PACKET TAIL MOV (R2)+,R0 ;GET ADDRESS OF 1ST PACKET BEQ ENDOPK ;DONE IF NONE AVAIL. MOVB (R2),R3 ;GET COUNT OF PACKETS AVAIL. OPKLUP: MOV R0,R2 ;SAVE COPY OF R0 CALL GTMOFF ;CONVERT TO OFFSET IN MAP BCS ENDOPK ;QUIT IF PACKET OUTSIDE POOL MOV #PKTOPT,R1 ;GET STRING ADDRESS TO INSERT IN MAP CALL MOVSTG ;INSERT '' MOV (R2),R0 ;GET NEXT PACKET ADDRESS SOB R3,OPKLUP ;ANY LEFT TO DO? .ENDC ;Q$$OPT ENDOPK: JMP NXTTHR ;GO DO NEXT ROUTINE .SBTTL STAMOU - PICK UP MOUNT CONTROL BLOCKS ;+ ;NOW LOOK FOR MOUNT CONTROL BLOCKS ;- STAMOU: MOV $MOULS,R3 ;GET LISTHEAD FOR MOUNT-CONTROL-BLOCKS 10$: BEQ ENDMOU ;QUIT IF NO MORE MOV R3,R0 ;GET COPY FOR DISTRUCTIVE USE CALL GTMOFF ;CONVERT TO MAP OFFSET BCS ENDMOU ;QUIT THIS IF NOT IN POOL MOVB #'!,(R0)+ ;LABEL WITH '!M' MOVB #'M,(R0) MOV (R3),R3 ;GET THE NEXT ONE IN THE LIST BR 10$ ; AND GO PROCESS IT ; ENDMOU: JMP NXTTHR ;GO DO NEXT ROUTINE .SBTTL STAPKT - PICKUP CHECKPOINT PCBS ;+ ;NOW FOR CHECKPOINT FILE PCB ;- STACKP: MOV $CFLPT,R4 ;GET LIST HEAD OF CHECKPT FILE PCBS BEQ ENDCKP ;QUIT IF NO MORE ENTRIES 2$: MOV R4,R3 ; COPY FOR P.SUB CHAIN SEARCH 10$: MOV R3,R0 ;NEED A COPY FOR DISTRUCTIVE USE CALL GTMOFF ;CONVERT TO MAP ADDRESS BCS ENDCKP ;QUIT IF BAD ADDRESS MOV #CKPSTG,R1 ;LABEL W/ '' CALL MOVSTG MOV P.SUB(R3),R3 ;GET NEXT FILE ALLOCATION PCB BNE 10$ ; GO PROCESS IT MOV @R4,R4 ;TRY NEXT CHECKPOINT FILE PCB BNE 2$ ; ENDCKP: JMP NXTTHR ;GO DO NEXT ROUTINE .SBTTL STAERR - GET ERRLOG BUFFERS ; STAERR: MOV $ERRHD,R4 ; GET 1ST ERRLOG BUFFER BEQ 20$ 10$: MOV R4,R0 ; MAKE A COPY OF PACKETS ADDR CALL GTMOFF ; TURN INTO MAP ADDR BCS 20$ MOV #ERRSTG,R1 ; START WITH ,R1 ; MINUS STRING JUST PUT IN BLE 15$ CALL MRKMP2 ; PUT MARKER IN MAP .WORD '= 15$: MOVB #'>,-(R0) ; TERMINATE WITH > MOV @R4,R4 ; TRY FOR NEXT BNE 10$ 20$: JMP NXTTHR ; GO FOR NEXT THREAD .SBTTL STAUMR - GET UMR ASSIGNMENT BLOCKS ; ; FORMAT OF UMR ASSIGNMENT BLOCK: ; ------------------------------ ; | PTR TO NEXT | ; ______________________________ ; | UMR ADDRESS | (NOTE POINTERS POINT HERE !!) ; ______________________________ ; 4 WORDS DRIVER CONTEXT ; ; 6 WORDS UMR ASSIGNMENT INFO ; STAUMR: MOV $UMRWT,R5 ; GET WAIT Q ADDR MOVB #'U,R2 ; 1ST Q IS *U* MOV $UMRHD,R4 ; GET 1ST BLOCK ADDR BEQ 20$ 10$: TST -(R4) ; ADJUST R4 TO BLOCK START MOV R4,R0 CALL GTMOFF BCS 15$ MOVB #'*,(R0)+ ; FLAG AS *U* MOVB R2,(R0)+ ; (OR *W*) MOVB #'*,(R0)+ 15$: MOV (R4),R4 ; GET NEXT UMR BLOCK ADDR BNE 10$ TST R5 BEQ 20$ MOV R5,R4 CLR R5 ; FLAG THAT THIS SCAN IS DONE MOVB #'W,R2 ; FLAG WAITING FOR UMR AS *W* BR 10$ 20$: JMP NXTTHR .SBTTL STAGFN - GET GROUP GLOBAL EVENT FLAG BLOCKS STAGFN: MOV $GGEF,R4 ; GET 1ST BLOCK BEQ 20$ ; NONE 10$: MOV R4,R0 ; COPY OF PACKET ADDR CALL GTMOFF ; INTO MAP BUFFER ADDR BCS 20$ MOVB #'*,(R0)+ ; MARK AS '*G*' MOVB #'G,(R0)+ MOVB #'*,(R0)+ MOV @R4,R4 ; GET NEXT GGEFB BNE 10$ 20$: JMP NXTTHR ; NEXT THREAD .SBTTL STAUCX - GET I/O PACKETS OUT OF UCB EXTENSIONS ; STAUCX: .IF DF,K$$DAS ; THIS ROUTINE NEEDS KERNAL DATA SPACE SUPPORT MOV NXTUCX,R4 ; GET SLOT PTR MOV #UCXLST,R5 CMP R4,R5 ; DID WE GET ANY BLOS 50$ ; NO MOV #TTCAPR,R3 MOV KDSAR5,-(SP) ; SAVE CONTENTS OF KERNAL DATA APR 5 MOV @R3,2(R3) BEQ 50$ ; DIDNT FIND TTCOM ADD #200,2(R3) ; SET UP FOR 2ND HALF OF TTCOM APR 10$: TST (R5)+ ; PASS UCB MOV (R5),R2 BIT #40000,R2 ; UCBX IN APR5 ? BNE 15$ ; NO MOV @R3,KDSAR5 ; LOAD 1ST HALF OF TTCOM BR 20$ 15$: SUB #20000,R2 ; ADJUST TO APR5 BIAS MOV 2(R3),KDSAR5 ; MAP TO 2ND HALF OF TTCOM 20$: ASSUME U.TIC,0 MOV (R2),(R5)+ ; GET INPUT I/O PACKET MOV U.TOC(R2),(R5)+ ; GET OUTPUT PACKET CMP R4,R5 ; DONE YET ? BNE 10$ ; NO MOV (SP)+,KDSAR5 ; RESTORE KERNAL DATA APR 5 ; TAKE CARE OF TASK ACCOUNTING MOV #UCXLST,R4 ; RESCAN THE LIST 25$: TST (R4)+ ; PASS THE UCB MOV (R4)+,R0 ; DO A PACKET BEQ 27$ ; NO INPUT PACKET, TRY FOR OUTPUT CALL QIOACN ; COUNT THE QIO FOR TASK ACCTNG 27$: MOV (R4)+,R0 ; AND AGAIN BEQ 30$ CALL QIOACN ; COUNT THE QIO FOR TASK ACCTNG 30$: CMP R4,R5 ; AT LIST END ? BLO 25$ ; NO .ENDC ;K$$DAS 50$: JMP NXTTHR .SBTTL END - USER MODE, PICK UP STATIC INFORMATION END: ; NOW FORMAT THE INFORMATION FROM THE UCB EXTENSION LIST MOV #UCXLST,R5 CMP -2(R5),R5 ; ANY UCB EXTENSIONS ? BLOS 40$ ; NO 22$: MOV (R5)+,R3 ; GET UCB ADDR CLR UNTFLD MOV (R5)+,R0 ; GET IST PACKET BEQ 25$ CALL MRKTII ; MARK AS 25$: MOV (R5)+,R0 ; TRY FOR NEXT PACKET BEQ 30$ CALL MRKTIO ; MARK AS 30$: CMP NXTUCX,R5 ; DONE YET ? BHI 22$ ; NO ; PUT IN THE ERROR LOG FILE POINTER 40$: MOV $ERRSV,R0 ; GET ADDR BEQ 50$ ; NONE CALL GTMOFF ; MAP ADDR BCS 50$ MOV #EFISTG,R1 CALL MOVSTG ; MARK AS [EF] ; CLEAN UP TASK ACCOUNTING 50$: MOV #2,R4 MOV CURTCB,R5 60$: CMP R4,R5 BHI FORMAT ; DONE MOVB #'<,@TCBLST(R4) ; REPLACE OFFSET WITH < TST (R4)+ BR 60$ ; FALL THRU TO FORMAT .SBTTL FORMAT - USER MODE OUTPUT OF RESULTS ;+ ;NOW WE HAVE ALL THE DATA - WE NEED TO DISPLAY IT ;- FORMAT: ;REF. LABEL MOV #IO.ATT,QIO+Q.IOFN ;1ST ATTACH TERMINAL DIR$ #QIO MOV #IO.WVB,QIO+Q.IOFN ;THEN RESTORE TO NORMAL QIO PRINT DON ; PRINT HEADER MESSAGE MOV #TEXTBF,QIO+Q.IOPL ; RELOAD TEXT BUFFER ADDR MOV BADPC,R2 ;CHECK FOR TRAP WHILE ON SYSTEM STACK BEQ NOERR MOV #ODDMSG,R1 ;OOPS, DEFAULT TO ODD ADDRESS MESSAGE ASR R2 ;CHECK FOR FLAG FOR MEM. PROT VIOLATION BCC 10$ ;FLAG CLEAR IF EVEN ADDRESS MOV #MPVMSG,R1 ;WAS MEM. PROT. VIOLATION, CHANGE MESSAGE 10$: ASL R2 ;CONVERT BACK TO VALID PC CLR R3 ;SET FLAG FOR OCTAL PRINTOUT CALL PRMSNM ; AND OUTPUT MESSAGE W/ NUMBER ;+ ; OUTPUT TASK ACCOUNTING ;- NOERR: PRINT HD1 ; PRINT THE 2 LINES OF HEADER INFO PRINT HD2 PRINT HD3 MOV CURTCB,R4 ; GET OFFSET TO LAST SLOT CLR TCBLST+2(R4) ; FLAG IT FF SLOT AS END CLR R5 ; INIT R5 TO ACTIVE TASK LIST MOV #NULNAM,NOFF ; SET UP FOR THINGS NOT ACTIVE DEC ACTCNT ; START ACTIVE TASK COUNT AT -1 5$: MOV #TEXTBF,QIO+Q.IOPL ; RESTORE OUTPUT BUFFER ADDR IN QIO DPB 10$: MOV #TEXTBF,R0 ; R0 IS TEXT BUFFER PTR INC ACTCNT ; COUNT AN ACTIVE TASK MOV NOFF(R5),R2 ; GET ADDR OF TASKNAME MOV #6,R4 ; USE R4 AS A COUNTER (TO INIT IT TO 0) 20$: MOVB (R2)+,(R0)+ ; COPY TASKNAME SOB R4,20$ MOVB #40,(R0)+ ; HDR FIELD IS 8 CHARS MOVB #40,(R0)+ MOV #1,R3 ; HEADER IS A BYTE SIZE SO MUL BY 1 MOV HOFF(R5),R1 ; GET SIZE OF HEADER ADD R1,HOFF ; MAINTAIN GRAND TOTAL CALL NUMRIT ; LOAD THE ASCII DECIMAL #, RIGHT JUSTIFIED MOV #8.,R3 ; ELEMENT SIZE MOV FOFF(R5),R1 ; GET # OF OPEN FILES ADD R1,FOFF ; MAINTAIN A RUNNING TOTAL CALL NUMRIT ; LOAD THE ASCII NUMBER RIGHT JUSTIFIED MOV #OPT.SZ,R3 MOV QOFF(R5),R1 ; GET # OF QIOS ADD R1,QOFF ; KEEP A TOTAL CALL NUMRIT MOV #OPT.SZ,R3 MOV ROFF(R5),R1 ; GET # OF RECV/RREF PACKETS ADD R1,ROFF ; KEEP A RUNNING TOTAL CALL NUMRIT MOV #16.,R3 MOV COFF(R5),R1 ; GET # OF CLOCK QUEUE ENTRIES ADD R1,COFF ; KEEP A RUNNING TOTAL CALL NUMRIT MOV #12.,R3 MOV AOFF(R5),R1 ; GET # OF ATTACHMENTS ADD R1,AOFF ; KEEP A TOTAL CALL NUMRIT MOVB #40,(R0)+ ; NEXT FIELD IS 8 CHARS WIDE MOVB #40,(R0)+ MOV #1,R3 ; R1 WILL BE TOTAL BYTES SO MUL BY 1 MOV MOFF(R5),R1 ; GET # OF OTHER BYTES IN USE ADD R1,MOFF ; KEEP A RUNNING TOTAL CALL NUMRIT MOVB #40,(R0)+ ; LAST FIELD IS 10 CHARS WIDE MOVB #40,(R0)+ MOVB #40,(R0)+ MOVB #40,(R0)+ MOV R4,R1 ; GET TOTAL ADD #T.LGTH+2,R1 ; ADD TCB LENGTH ADD #36.,R1 ; AND PCB LENGTH CALL NUMRT2 ; NO TOTALLING ENTRY CALL OUTIT ; PRINT IT TST R5 ; JUST DID 1ST ? BNE 90$ ; NO ASR HOFF ; YES, DIVIDE ALL TOTALS BY 2 ASR FOFF ASR QOFF ASR ROFF ASR COFF ASR AOFF ASR MOFF 90$: TST (R5)+ ; ADVANCE TO NEXT ENTRY TST TCBLST(R5) ; DONE ? BNE 10$ ; NO CMP R5,#2 ; JUST DID TOTALS ? BEQ 100$ ; YES, REALLY DONE PRINT TOT ; PRINT THE UNDERLINE CLR R5 ; POINT TO TOTALS SLOT MOV #TOTNAM,NOFF ; POINT NAME TO TOTALS CLR TCBLST+2 ; CREATE A DONE MARKER FF TOTALS ENTRY JMP 5$ ; RESTORE BUFFER ADDR AND REUSE LOOP CODE 100$: PRINT HD4 ; PRINT *** INSTALLED MESSAGE CLR R4 MOV #T.LGTH+2,R3 ; SIZE OF A TCB FOR A TASK MOV TCBCNT,R1 ; GET INSTALLED COUNT SUB ACTCNT,R1 ; LESS THE NUMBER OF ACTIVE TASKS INC R1 ;(TOTALS WERE COUNTED AS AN ACTIVE TASK) MOV #HD5NUM,R0 ; SLOT FOR CONVERTED # CALL NUMRIT ; LOAD IT PRINT HD5 ; PRINT IT MOV R4,R1 ; TOTAL BYTES USED MOV #HD6NUM,R0 ; SLOT TO LOAD IT WITH CALL NUMRT2 ; DO IT, NO TOTALLING PRINT HD6 ; OUTPUT THE MESSAGE MOV #TEXTBF,QIO+Q.IOPL ;RESTORE QIO BUFFER PTR ;+ ; DO FREE LIST STATISTICS ;- CMPB GMCR+G.MCRB+5,#'F ;INITIATED WITH 'OPA F' COMMAND? BNE ENFRAG ;IF NO, SKIP FRAGMENT LIST MOV FRGMNT,R2 MOV #FRGMSG,R1 ;SET FOR MESSAGE ABOUT FRAGMENTS MOV PC,R3 ;SET FOR DECIMAL CONVERSION CALL PRMSNM ;PRINT #FRAGMENTS MOV POOLWD,R2 ASR R2 ;CONVERT TO # WORDS MOV #POOLMS,R1 CALL PRMSNM ;PRINT POOL SIZE MOV #TEXTBF,R0 ;OUTPUT MESSAGE ABOUT NEXT PRINTOUT MOV #SEGMSG,R1 ;IT'S LIST OF FREE SEGMENT ADDRS. CALL MOVSTG CALL OUTIT MOV FRGMNT,R5 ;SET LOOP COUNT FOR PRINTING MOV #FRLIST,R4 ;GET ADDRESS OF SEGMENT LIST CLR R3 ;ACCUMULATE SEGMENT LENGTHS IN R3 PRSEG: MOV (R4),R1 ;GET ADDRESS OF SEGMENT MOV #1,R2 ;NO ZERO SUPPRESSION MOV #TEXTBF,R0 ;SET START OF OUTPUT BUFFER CALL $CBOMG ;CONVERT TO OCTAL MOVB #'-,(R0)+ ;INSERT A DASH MOV (R4)+,R1 ;GET START ADDR. AGAIN ADD (R4),R1 ;ADD LENGTH DEC R1 ;ADJUST TO LAST FREE BYTE ADDRESS MOV #1,R2 ;NO ZERO SUPPRESS FOR OCTAL PRINTOUT CALL $CBOMG ;1ST PRINT VALUE IN OCTAL MOVB #40,(R0)+ ;SEPARATE VALUES W/ A SPACE MOV (R4)+,R1 ;RECOVER LENGTH TO PRINT IN DECIMAL ASR R1 ;CONVERT LENGTH TO WORDS ADD R1,R3 ;ACCUMULATE SEGMENT LENGTHS CLR R2 ;SUPPRESS ZEROS THIS TIME CALL $CBDMG ;CONVERT TO DECIMAL FOR SEGMENT LENGTH MOVB #'.,(R0)+ ;SHOW IT TO BE A DECIMAL VALUE CALL OUTIT SOB R5,PRSEG ;KEEP GOING UNTIL ALL SEGMENTS DONE MOV R3,R2 ;PRINT TOTAL OF FREE SEGMENTS MOV #NFRMSG,R1 MOV PC,R3 ;PRINT IN DECIMAL CALL PRMSNM ENFRAG: ;REF. LABEL ;+ ;NOW PRINT MAP IN ROWS OF 64 CHARS. W/ ADDRESS OF EACH ROW ;- MOV #TEXTBF,R0 ;OUTPUT HEADER FOR MAP: MOV #MAPMSG,R1 CALL MOVSTG CALL OUTIT MOV #$POOL,R0 ;CALC. EVEN 100'S MAP ADDRESS TO START BIC #377,R0 MOV R0,POOLAD ;SAVE AS POOL ADDRESS MOV $EXSIZ,R5 ;CALC. MAP OUTPUT SIZE SUB R0,R5 ASR R5 ; IN # BYTES ASR R5 SUB #$POOL,R0 ASR R0 ;CONVERT TO MAP ADDRESS ASR R0 ADD #MAP,R0 MOV R0,MAPAD ;SAVE MAP ADDRESS PRTLUP: MOV POOLAD,R1 ;SET UP TO CONVERT POOL ADDRESS TO OCTAL ADD #400,POOLAD ;BUMP POOL ADDRESS TO NEXT LINE MOV #1,R2 ;SET FOR NO ZERO SUPPRESSION MOV #TEXTBF,R0 ;GET OUTPUT BUFFER ADDRESS CALL $CBOMG ;CONVERT TO OCTAL WORD MOVB #':,(R0)+ ;SEPARATE FROM MAP W/ ': ' MOVB #40,(R0)+ MOV MAPAD,R1 ;GET OUR CURRENT MAP ADDRESS MOV #64.,R4 ;SET R4 TO DEFAULT # BYTES/RECORD CMP R4,R5 ;IS THERE LESS REMAINING? BLE 10$ MOV R5,R4 ;YES, USE THE SMALLER # 10$: ADD R4,MAPAD ;ADVANCE MAP ADDRESS FOR NEXT RECORD SUB R4,R5 ;DECREASE #BYTES LEFT TO PRINT 11$: MOVB (R1)+,(R0)+ ;COPY MAP INTO BUFFER BNE 12$ MOVB #'<,-1(R0) ; FIX TCB UP ( REPLACE 0 WITH <) 12$: SOB R4,11$ ; UNTIL RECORD FILLED CALL OUTIT ;PRINT IT TST R5 ;ANYTHING LEFT TO PRINT? BNE PRTLUP ;IF SO, BACK FOR ANOTHER RECORD ; EXIT$S .SBTTL SUBROUTINES - FOR USER MODE OUTPUT ;+ ;SUBROUTINES ;- ;PRMSNM: PRINT MESSAGE W/ TRAILING NUMBER ; ENTRY W/ R1 = ADDR. OF ASCIZ STRING TO OUTPUT ; R2 = VALUE TO APPEND ; R3 = FLAG FOR TYPE OF CONVERSION: ZERO=OCTAL, NON-ZERO=DECIMAL PRMSNM: MOV #TEXTBF,R0 ;SET START OF OUTPUT BUFFER CALL MOVSTG ;COPY IN THE TEXT MOVB #'=,(R0)+ ;SEPARATE MESSAGE FROM VALUE MOV R2,R1 ;GET THE VALUE TO CONVERT CLR R2 ;SUPPRESS LEADING ZEROS MOV R3,-(SP) ;SAVE R3 FOR USER REUSE BEQ CNVOCT ; AND CONVERT TO OCTAL IF FLAG WAS ZERO CALL $CBDMG ;CONVERT TO DECIMAL MAGNITUDE MOVB #'.,(R0)+ ;APPEND DECIMAL POINT BR RESR3 ; CNVOCT: CALL $CBOMG ;CONVERT TO OCTAL RESR3: MOV (SP)+,R3 ;RESTORE R3 OUTIT: SUB #TEXTBF,R0 ;CALC. LENGTH OF MESSAGE MOV R0,QIO+Q.IOPL+2 ;SET IN DIRECTIVE PARAM. BLOCK DIR$ #QIO ;PRINT # RETURN ;NUMRIT ; INPUTS R1 = NUMBER TO CONVERT RIGHT JUSTIFIED ; R0 = BUFFER PTR ; R3 = SIZE OF ELEMENT ( TO KEEP TOTAL IN R4 ) ; OUTPUTS R0 = NEXT SLOT IN BUFFER ; R3 = NUMBER OF BYTES IN THIS ENTRY ; R4 = RUNNING TOTAL OF BYTES DONE ; R0,R1,R2 CLOBBERED .ENABL LSB NUMRIT: MUL R1,R3 ; GET TOTAL BYTE COUNT IN R3 BEQ 20$ ; DO ZERO ADD R3,R4 ; MAINTAIN RUNNING TOTAL NUMRT2: MOV SP,R2 ; DON'T SUPPRESS 0'S MOVB #40,(R0)+ ; FIELD SIZE IS 6 MOV R0,-(SP) ; SAVE CURRENT PTR CALL $CBDMG ; DO DECIMAL MAGNITUDE MOV (SP)+,R2 ; GET PTR TO NUMBER START MOV #5,R1 ; COUNT OF DIGITS 10$: CMPB #'0,@R2 BNE 30$ MOVB #40,(R2)+ ; REPLACE LEADING 0'S WITH SPACES SOB R1,10$ ; CONTINUE BR 30$ ; DONE 20$: MOV #5,R2 25$: MOVB #40,(R0)+ ; LOAD 5 SPACES SOB R2,25$ MOVB #'0,(R0)+ ; FF BY A 0 30$: RETURN .DSABL LSB .SBTTL SUBROUTINES - USED IN SYSTEM STATE ;MRKMAP ;ENTRY WITH: R0=ABSOLUTE ADDRESS OF POOL ; R1=SIZE OF SEGMENT IN BYTES ; @0(SP)=CHAR. TO PUT IN MAP ; ENTRY AT MRKMP1 W/ R0=REL. ADDRESS IN POOL ; ENTRY AT MRKMP1 W/ R0= BYTE ADDRESS IN MAP ; EXIT W/ NO-OP & CARRY SET IF MAP OFFSET NEGATIVE, ELSE CARRY CLEAR MRKMAP: ;MAIN ENTRY POINT SUB #$POOL,R0 ;ADJUST TO BEGINNING OF POOL MRKMP1: ASR R0 ;CONVERT TO SEGMENT NUMBER ASR R0 ADD #MAP,R0 ;GET START ADDRESS IN MAP ; MOST FREQUENTLY USED ENTRY POINT MRKMP2: CMP R0,#MAP ;IN MAP AREA? BHIS 10$ ; YES ADD #2,@SP ; NO, BYPASS THE CHARACTER TO BE COPIED SEC ; AND FLAG ERROR RETURN ; & RETURN ; 10$: ADD #3,R1 ;ROUND SIZE TO NEXT LARGER #SEGMENTS ASR R1 ASR R1 STOCH: MOVB @0(SP),(R0)+ ;STUFF CHAR. IN MAP SOB R1,STOCH ; UNTIL ALL SEGMENTS MARKED ADD #2,(SP) ;MOVE RETURN PAST MARK CHARACTER CLC ;SHOW SUCCESSFUL OPERATION RETURN ;NOW DONE ; GTMOFF: ;REF LABEL ; ENTERED W/ POOL ADDRESS IN R0 ; EXIT W/ MAP ADDRESS IN R0 ; RETURN W/ CARRY SET & NO-OP IF OUTSIDE POOL CMP R0,$EXSIZ ;ABOVE TOP OF POOL? BHIS 5$ ;IF YES, SKIP CONVERSION SUB #$POOL,R0 ;1ST GET ADDR. REL TO START OF POOL BHIS 10$ ;LEGAL IF POSITIVE OFFSET 5$: SEC ;NO, SHOW ERROR CODE RETURN ; & EXIT W/O DOING ANYTHING ELSE ; 10$: ASR R0 ;THEN GET BLOCK # ASR R0 ADD #MAP,R0 ;FINALLY CALC. ACTUAL MAP ADDR. RETURN GTACNT: ; GET TASK ACCOUNTING OFFSET IN R3 FROM TCB IN R3 ; CMP R3,$EXSIZ ;ABOVE TOP OF POOL? BHIS 10$ ;IF YES, SKIP CONVERSION SUB #$POOL,R3 ;1ST GET ADDR. REL TO START OF POOL BLO 10$ ;ILLEGAL IF NEGATIVE OFFSET ASR R3 ;THEN GET BLOCK # ASR R3 ADD #MAP,R3 ;FINALLY CALC. ACTUAL MAP ADDR. MOVB @R3,R3 ; AND GET OFFSET BIC #177400,R3 ; STRIP SXT CMPB #'?,R3 ; INSURANCE BNE 20$ 10$: CLR R3 ; USE OFFSET 0 20$: RETURN ; & EXIT W/O DOING ANYTHING ELSE CNVASC: ;REF LABEL ;ENTERED W/ HEX VALUE IN R1 ;EXIT W/ ASCII VALUE STORED @(R0)+ ADD #'0,R1 ;CONVERT TO ASCII CMP R1,#'9 ;USE HEX IF > 9. BLE 11$ ADD #<'@-'9>,R1 ;BUMP TO ASCII 'A' 11$: MOVB R1,(R0)+ ;INSERT INTO MAP RETURN ; MOVBYT: MOVB (R1)+,(R0)+ ;COPY A BYTE TO TARGET AREA MOVSTG: ;REF. LABEL ;ENTERED W/ OUTPUT ADDRESS IN R0 ; W/ INPUT ASCIZ STRING ADDRESS IN R1 TSTB (R1) ;AT END OF STRING? BNE MOVBYT RETURN ;NOT MUCH OF A ROUTINE, IS IT? ; ;CPYNAM ; COPIES 6 CHARACTERS POINTED TO BY NAMFLD TO R0 ; ;CPYDEV ; SAME AS CPYNAM FOR 5 CHARACTERS ; ;CPYUNT ; COPIES 4 CHARS FROM UNTFLD TO R0 AREA ; ; ALL CLOBBER R1 CPYUNT: MOV #4,-(SP) MOV UNTFLD,R1 BR CPYU CPYDEV: MOV #5,-(SP) BR CPYN CPYNAM: MOV #6,-(SP) ; USE STACK TOP AS COUNTER CPYN: MOV NAMFLD,R1 ; GET ADDRESS OF TASKNAME (LAST CONVERT) CPYU: 10$: MOVB (R1)+,(R0)+ ; COPY THE TASKNAME (OR DEVICE) DEC @SP BNE 10$ TST (SP)+ ; RESTORE STACK RETURN ; MRKTIO, MRKTII, MRKUCX ; MARK AN I/O PACKET FOR A TT: ; INPUTS R0 I/O PACKET ADDR ; R3 UCB ADDR ; UNTFLD 0 OR ADDR OF PREVIOUS STRING THIS UCB ; R0,R1,R2 CLOBBERED, R4 = DCB ON OUTPUT MRKUCX: MOV #UCXSTG,R1 BR MRKU MRKTIO: MOV #TTOSTG,R1 ;PUT '' FOR A DEVICE NAME ; INPUTS: ; R0 PTR TO SLOT IN MAP BUFFER ; R1 NUMBER TO CONVERT ; DEVNUM: MOV R2,-(SP) ; SAVE R2 MOV R1,-(SP) ; AND INPUT NUMBER CLR R2 ; SUPPRESS 0'S CALL $CBOMG ;CONVERT TO ASCII & INSERT IN MAP MOVB #':,(R0)+ CMP #10,(SP)+ ; 2 DIGIT NUMBER ? BLE 5$ ; YES MOVB #40,(R0)+ ; NO, PAD WITH A SPACE 5$: MOVB #'>,(R0)+ MOV (SP)+,R2 ; RESTORE R2 RETURN ;GTTSKN ; ENTERED W/ PCB ADDRESS IN R4 AT ENTRY GPTSKN ; OR W/ TCB ADDRESS IN R3 AT ENTRY GTTSKN ; OUTPUT IS TASK-NAME IN ASCII STORED AT ADDRESS IN R0 ; R0 IS UPDATED TO NEXT BYTE AFTER NAME ; R1 CLOBBERED GPTSKN: ;REF. LABEL MOV P.TCB(R4),R3 ;GET TCB ADDRESS TO GET TASK NAME GTTSKN: MOV T.NAM(R3),R1 ;GET TASK NAME FOR SUBPARTITION MOV R2,-(SP) ; SAVE R2 CALL $C5TA MOV T.NAM+2(R3),R1 CALL $C5TA ;CONVERT THIS 2ND HALF OF NAME MOV (SP)+,R2 ; RESTORE R2 RETURN ;DONE COPYING IN TASK NAME ; ;GTPARN ; ENTER WITH PCB ADDR IN R4 MAP BUF ADDR IN R0 ; OUTPUT IS PCB NAME PLUS ) STORED AT R0 ; R1,R2 CLOBBERED GTPARN: MOV P.NAM(R4),R1 ; GET RAD50 NAME CALL $C5TA ; AND CONVERT IT TO ASCII MOV P.NAM+2(R4),R1 CALL $C5TA MOVB #'),(R0)+ RETURN ;MRKCTP ; MARK ANY CHECKPOINT COMMON TASK IMAGE PCB AS [CT] ; INPUT R4 = A PCB ADDR FOR A COMMON OR LIBRARY PCB ; CLOBBERS R0 MRKCTP: MOV P.DPCB(R4),R0 ; TASK IMAGE PCB ? BEQ 15$ ; NO CALL GTMOFF ; YES, GET MAP BUFFER ADDR BCS 15$ ; NOT IN POOL MOVB #'[,(R0)+ ; MARK AS [CT] (FASTER THAN MOVSTG) MOVB #'C,(R0)+ MOVB #'T,(R0)+ MOVB #'],(R0)+ 15$: RETURN ; QIOACN ; DO TASK ACOUNTING FOR QIO PACKET IN R0 ; ; CLOBBERS R3 ( SET TO TCBLST ADDR) QIOACN: MOV I.TCB(R0),R3 ; GET TCB ADDR CALL GTACNT ; GET TASK ACCOUNTING OFFSET IN R2 INC QOFF(R3) ; COUNT THE QIO 7$: RETURN ; ;MRKAST: MARK AN AST CONTROL BLOCK - BASED ON KIND OF BLOCK ;ENTRY W/ R4 CONTAINING POSSIBLE START OF LIST OF CONTROL BLOCKS ; R2 = TASK ACCOUNTING ENTRY ; CLOBBERS R0,R1,R4 MRKAST: BEQ 20$ ;RETURN NOW IF NO LIST MOV R4,R0 ;GET COPY FOR DESTRUCTIVE USE CALL GTMOFF ;GET CORRESPONDING MAP ADDRESS BCS 19$ ;ADVANCE TO NEXT IN LIST IF OUTSIDE POOL TST A.CBL(R4) ;WHAT KIND OF BLOCK IS THIS? BNE 11$ ;IF DEQUEUED ELSEWHERE, ASSUME IT'S A BLOCK ; RESERVED BY THE TERMINAL DRIVER W/ THE SAME ; SIZE AS AN I/O PACKET MOV #TTEXT,R1 ;MARK IT AS ASSOCIATED W/ FDX TT: CALL MOVSTG ADD #OPT.SZ,MOFF(R2) ; COUNT IT BR 19$ ;THEN CONTINUE W/ NEXT AST BLOCK ; 11$: MOVB A.CBL(R4),R1 ;CHECK FOR SIZE/TYPE OF AST BLOCK BEQ 18$ ;IF ZERO, IS A SPECIFY-AST BLOCK - GO DO THAT BLT 12$ ;IF NOT, IS IT NEGATIVE (SPECIAL TYPE)? ADD R1,MOFF(R2) ; COUNT IT MOVB #'[,(R0)+ ;MARK AREA DEFINED BY SIZE AS: '[.....]' SUB #4,R1 ;ADJUST FOR THE LEADING '[' BLE 19$ ;DONE IF ONLY 4 BYTES LONG CALL MRKMP2 ; ELSE INSERT THE '.......' .WORD '. MOVB #'],-(R0) ;CLOSE AREA W/ TRAILING ']' BR 19$ ;OFF TO NEXT AST BLOCK ; ;HERE ON NEGATIVE AST BLOCK SIZES 12$: CMPB R1,#200 ;IS IT FOR BUFFERED I/O? BNE 13$ MOV #BIOSTG,R1 ;YES, MARK IT AS SUCH CALL MOVSTG ADD #OPT.SZ,MOFF(R2) ; COUNT IT BR 19$ ; & ADVANCE TO NEXT IN LIST ; 13$: CMPB R1,#300 ;IS IT ACTUALLY AN OFFSPRING CONTROL BLOCK??? BNE 19$ ;IF NOT, I'M LOST - GOTO NEXT ONE CALL MRKOCB ;YES, GO MARK IT W/ PARENT NAME BR 19$ ;ON TO THE NEXT ONE ; ;HERE ON SPECIFY-AST BLOCK 18$: MOVB #'[,(R0)+ ;MARK THESE W/ '[ASn]' MOVB #'A,(R0)+ MOVB #'S,(R0)+ MOVB A.CBL+1(R4),R1 ;GET THE AST TYPE CODE CALL CNVASC ;CONVERT TO ASCII & INSERT IN MAP MOVB #'],(R0)+ ;CLOSE AREA ADD #8.,MOFF(R2) ; COUNT IT ; ;HERE TO TRY FOR THE NEXT AST BLOCK IN LIST 19$: MOV (R4),R4 ;GET NEXT LIST ENTRY BNE MRKAST ; & PROCESS IF THERE IS ONE 20$: RETURN ;END OF AST BLOCK PROCESSING ; ;MRKOCB: MARK AN OFFSPRING CONTROL BLOCK ;ENTRY W/ OCB ADDRESS IN R4 ; ASSUMES R0 CONTAINS MAP ADDRESS ALREADY ; CLOBBERS R0,R1 MRKOCB: MOVB #'^,(R0)+ ;MARK AS ^TASKNAME MOV R3,-(SP) ; SAVE R3 MOV O.PTCB(R4),R3 ;GET PARENT TCB ADDRESS BEQ 10$ ;OOPS, PARENT GONE CALL GTTSKN ;INSERT PARENT NAME IN MAP BR 20$ ;PICK UP CODE AFTER ALTERNATE PATH ; 10$: MOV R2,-(SP) ; SAVE TASK ACCOUNTING SLOT MOV O.STAT(R4),R1 ;IT APPEARS THAT O.STAT BLOCK HAS PARENT NAME CALL $C5TA ; ALTHOUGH NOT DOCUMENTED ANYWHERE MOV O.STAT+2(R4),R1 ;BUT IT'S BETTER THAN NOTHING CALL $C5TA MOV (SP)+,R2 ; RESTORE TASK ACCNTG SLOT 20$: ADD #28.,MOFF(R2) ; CHARGE THE OCB TO THE OFFSPRING TASK MOV (SP)+,R3 ;RESTORE R3 RETURN ;THAT'S IT - NO ROOM TO MARK CLOSE OF AREA .SBTTL DATA AREA ;+ ;DATA AREA ;- ;LIST OF POOL ANALYSIS ROUTINES FOR DISPATCH THREAD: .WORD THREND ;POINTER TO CURRENT ENTRY THRLST: ; THIS MUST BE 1ST FOR TASK ACCOUNTING .WORD STATCB ;TCB'S / AD'S / AST'S / OCB'S .WORD STAPAR ;PCB'S / HDR'S / WB'S / SUB-PCB'S .WORD STACLQ ;CLOCK QUEUE CONTROL BLOCKS .WORD STALOG ;ASN CONTROL BLOCKS .WORD STACBD ;PCB'S FOR INSTALLED COMMONS OUT OF MEM .WORD STAVCB ;VCB'S / FCB'S .WORD STAMCR ;MCR CMD LINES .WORD STAMOU ;MCB'S .WORD STACKP ;CHECKPOINT PCB'S .WORD STAERR ;ERRLOG BUFFERS .WORD STAUMR ;UMR ALLOCATION BLOCKS .WORD STAGFN ;GROUP GLOBAL EFN BLOCKS .WORD STADCB ;DCB'S / ICB'S / UCB'S / SCB'S / I/O PKT'S .WORD STAOPK ;UNUSED I/O PKT'S .IF DF,K$$DAS .WORD STAUCX ; DO UCB EXTENSIONS IN TTCOM .ENDC ;?; .WORD STADMC ; DO I/O PACKETS IN XM DRIVER SPACE THREND: .WORD 0 ;END OF THREADED ROUTINE LIST ; CURPKT: .WORD 0 ;CURRENT I/O PACKET ADDRESS IN MAP SAVPAR: ;SAVED MAIN PARTITION PCB ADDRESS - PCB SCAN UNITNO: .WORD 0 ;SAVED UNIT NUMBER DURING UCB/SCB SCAN BADPC: .WORD 0 ;PC WHERE TRAP OCCURRED OKPS: .WORD 0 ;SAVED PSW BEFORE TRAP OCCURS OKSP: .WORD 0 ; SAME FOR SP AFTER SWITCHING TO SYSTEM STATE OLDODD: .WORD 0 ;ORIGINAL TRAP VECTOR CONTENTS OLDMPV: .WORD 0 POOLWD: .WORD 0 FRGMNT: .WORD 0 POOLAD: .BLKW 1 ;STARTING ADDRESS FOR PRINTOUT MAPAD: .BLKW 1 ;STARTING MAP ADDRESS FOR SAME MAPSIZ: .WORD 0 ;ACTUAL MAP SIZE IN SEGMENTS (4 BYTES EA.) NAMFLD: .WORD 0 ;ADDRESS OF NAME-FIELD (TEMP. USE) UNTFLD: .WORD 0 ;ADDRESS OF UNIT # FIELD (TEMP USE) FRLIST: .BLKW 2*MAXFRG QIO: QIOW$ IO.WVB,1,1,,,, GMCR: GMCR$ ;GET MCR LINE TO CLEAN POOL .NLIST BEX ;DON'T NEED TO SEE ALL THE ASCII STRINGS ODDMSG: .ASCIZ /ODD ADDRESS TRAP @ PC/ MPVMSG: .ASCIZ /MEM. PROT. VIOLATION @ PC/ FRGMSG: .ASCIZ /# FREE POOL FRAGMENTS/ POOLMS: .ASCIZ /TOTAL WORDS OF POOL/ NFRMSG: .ASCIZ /TOTAL FREE WORDS/ SEGMSG: .ASCIZ /FREE SEGMENT LIST:/ MAPMSG: .ASCII <14>/POOL MAP: . . . . . . . * . . . . . . . */ .ASCIZ / . . . . . . . * . . . . . . ./ IOP: .ASCIZ // HDRSTG: .ASCIZ /
/ CDPSTG: .ASCIZ /[CT]/ OFASTG: .ASCIZ /[AO]/ EFISTG: .ASCIZ /[EF]/ ERRSTG: .ASCIZ // ERR.SZ= .- PDVSTG: .ASCIZ /: )/ DONMSG: .BYTE 14 .ASCII / ANALYSIS OF ACTIVE TASK POOL USAGE:/ .BYTE 12,15,12,15 .ASCII / |---------- COUNTS ----------|/ DONSIZ= .-DONMSG HD1MSG: .ASCII / TASK HEADER OPEN RECV ATTCH/ HD1SIZ= .-HD1MSG HD2MSG: .ASCII / NAME SIZE FILES QIOS* PKTS CLQ MENTS/ .ASCII / OTHER TOTAL/ HD2SIZ= .-HD2MSG HD3MSG: .ASCII / (BYTES) (8) (40) (40) (16) (12)/ .ASCII / (BYTES) (BYTES)/<12><15> HD3SIZ= .-HD3MSG HD4MSG: .BYTE 12,15,12,15 .ASCII / * THIS ANALYSIS WILL NOT FIND / .ASCII /MOST QIOS TO DMC LINES/<12><15> .ASCII /****** (ANALYSIS FOR INACTIVE TASKS - OPEN FILES ARE/ .ASCII / INDEX FILES)/ .BYTE 12,15 HD4SIZ= .-HD4MSG HD5MSG: .ASCII /NUMBER OF INSTALLED INACTIVE TASKS: / HD5NUM: .ASCII / / HD5SIZ= .-HD5MSG HD6MSG: .ASCII / BYTES USED FOR THEIR TCBS: / HD6NUM: .ASCII / / HD6SIZ= .-HD6MSG NULNAM: .ASCII /******/ TOTNAM: .ASCII /TOTALS/ TOTMSG: .REPT 6 .ASCII /__________/ .ENDR .ASCII /__/ .BYTE 12,15 TOTSIZ= .-TOTMSG .EVEN ; OUTBUF: ;REF. LABEL TEXTBF: .BLKW 80. ; PARALELL LISTS FOR TASK ACCOUTING MAX.TC= 80. ; ACCOUNT FOR A MAXIMUM OF 80. ACTIVE TASKS GTOTAL: .WORD 0 ; GRAND TOTAL OF USAGE CURTCB: .WORD 0 ; MOST RECENT TCB SLOT USED ; N.B. 1ST SLOT USED FOR ALL INSTALLED INACTIVE TASKS TCBLST: .BLKW MAX.TC ; LIST OF TCB ADDRESSES (T.LGTH IN TCB PTS HERE) .WORD -1 ; EXTRA WORD FOR END FLAG NOFF: .BLKW MAX.TC ; SAVE ADDR IN MAPBUF OF TASKNAME HOFF: .BLKW MAX.TC ; SAVE HEADER SIZE HERE FOFF: .BLKW MAX.TC ; SAVE NUMBER OF OPEN FILES HERE QOFF: .BLKW MAX.TC ; SAVE NUMBER OF QIO PACKETS HERE ROFF: .BLKW MAX.TC ; SAVE NUMBER OF RREF AND RECV DATA HERE COFF: .BLKW MAX.TC ; SAVE NUMBER OF CLOCK QUEUE ENTRIES HERE AOFF: .BLKW MAX.TC ; SAVE NUMBER OF ADBS USED HERE MOFF: .BLKW MAX.TC ; SAVE ALL OTHER RANDOM SIZES HERE (WORD CNT) ; COUNTERS TCBCNT: .WORD 0 ; INSTALLED TASKS - TCBS ACTCNT: .WORD 0 ; ACTIVE TASK COUNT ADBCNT: .WORD 0 ; ATTACHMENT DESCRIPTORS RRFCNT: .WORD 0 ; RECEIVE BY REFERENCE PACKETS CLQCNT: .WORD 0 ; CLOCK QUEUE PACKETS ASNCNT: .WORD 0 ; LOGICAL ASSIGN CONTROL BLOCKS PMACNT: .WORD 0 ; PCB'S FOR MAIN PARTITIONS DRVCNT: .WORD 0 ; PCB'S FOR DRIVERS DYNCNT: .WORD 0 ; PCB'S FOR DYNAMIC REGIONS TSKCNT: .WORD 0 ; PCB'S FOR ACTIVE TASKS HDRCNT: .WORD 0 ; COUNT OF HEADERS FOR ACTIVE TASKS HDRSIZ: .WORD 0 ; TOTAL BYTES USED FOR TASK HEADERS WBCNT: .WORD 0 ; WINDOW BLOCK COUNT FCBCNT: .WORD 0 ; FILE CONTROL BLOCK COUNT VCBCNT: .WORD 0 ; VOLUME CONTROL BLOCK COUNT IOPCNT: .WORD 0 MCRCNT: .WORD 0 ; ENSURE NO SYSTEM CRASHES ON ACCIDENTAL BUFFER OVERFLOWS - ; SINCE WILL GET A MEMORY PROTECT VIOLATION .PSECT $$$DAT .REPT 8. ;LEADING PAD OF BLANKS .ASCII / / .ENDR MAP:: .BLKB 8.*1024. ;ENOUGH ROOM FOR 16.K WORDS OF POOL ; UCB EXTENSION LIST - THIS MUST BE ABOVE LOC 140000 TTCAPR: .WORD 0 ; SAVED APR 6 FOR TTCOM .WORD 0 NXTUCX: .WORD UCXLST UCXLST: ; SUPPORTS 100 TT: LINES .IF NDF,DEBUG$ .BLKW 310 ; ROOM FOR 100 3-WORD PACKETS .IFF .WORD 0 .ENDC .END OPA