.TITLE OPA - ONLINE POOL ANALYZER .SBTTL IDENT PAGE .IDENT /KB2.1/ ;WRITTEN BY J. NEELAND ;LAST MODIFIED 19-AUG-87 ; ;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 ;QUICK FIX 830401 BY KITTY BETHE -- M PLUS V 2, MCR BUFFER AND ERRLOG ; BUFFER CODE REMOVED ;MODIFIED 26-MAY-83 K.BETHE -- V 2, UCB EXTENSIONS IN SECPOL ; PROTO TCB'S IN SECPOL, REGISTER DUMP ; ON FAILURE IN SYSTEM STATE, IMPROVED ; PRINTOUT, LARGER TCB AND WINDOW BLKS ;MODIFIED 12-OCT-83 K.BETHE -- LENGTHEN FREE LIST, CHECK THAT ; BUFFERS USED IN SYS STATE < 160000 ; ; 18-AUG-87 U.SCHMELING -- fix problems with non I/D space ; systems (mapping external headers ; through KINAR5 isn't the best choice) ; correct restoring of APR in partition routine ; (non I/D systems) ; ; 19-AUG-87 U.SCHMELING -- Include some DECNET info: ; ; PROCESS DESCRIPTOR TABLES ; DECNET HOMEBLOCK ; SYSTEM LINES ; ; U.Schmeling -- add CLI Parser Blocks ; ; 10-Nov-89 U.Schmeling CSA-Da.-Weiterstadt ; add some more DecNet structures, move Usermode-Routines ; to end of task (via psect $$$usr) ; .LIST MEB ;NEED TO SEE ALL CODE FOR DEBUGGING .NLIST CND .ENABL LC ;ALLOW LOWER-CASE I/O AND LISTING ; .library /lb:[1,1]netlib.mlb/ .library /netmac.mlb/ ; .MCALL QIOW$,DIR$,EXIT$S,GMCR$,PCBDF$,CLKDF$ .MCALL F11DF$,UCBDF$,DCBDF$,TCBDF$,PCBDF$,SCBDF$,KRBDF$ .MCALL PDVDF$,DHBDF$,XPDDB$,EPMDF$,LLTDF$,llwdf$,ECDDB$,SLTDF$ F11DF$ UCBDF$ ,,TTDEF DCBDF$ TCBDF$ SCBDF$ PCBDF$ CLKDF$ KRBDF$ ; M + ; ; The following macros deal with DecNet ; and are usually contained in lb:[1,1]netlib.mlb ; DHBDF$ ,,A ; DECNET HOMEBLOCK PDVDF$ ; DECNET PROCESS DESCRIPTOR VECTORS SLTDF$ ; SYSTEM LINE TABLES XPDDB$ ; XPT Data Base (Routing nodes only) ECDDB$ ; ECL Data Base EPMDF$ ; DLC for EPM LLTDF$ ; Logical link tables llwdf$ ; 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=200. .IIF NDF,R$$MPL .ERROR ; THIS TASK WILL ONLY RUN UNDER MPLUS V.2 ; CBLSHR = 1 ; THIS SYSTEM HAS CABLESHARES X29 PACKAGE ; LOCAL MACROS .MACRO PRINT NAM,RESTORE MOV #'NAM'MSG,QIO+Q.IOPL MOV #'NAM'SIZ,QIO+Q.IOPL+2 DIR$ #QIO .IF NB,RESTORE MOV #TEXTBF,QIO+Q.IOPL .ENDC .ENDM PRINT .SBTTL OPA ENTRY - INIT THEN SWTSTK ; OPA:: ;ENTRY POINT DIR$ #GMCR ;EMPTY OUR MCR BUFFER IF ONE EXISTS ; CMP #APR7OK,#160000 ;BUFFER SPACE FITS ? ; BLOS 5$ ;YES ; EXIT$S ;NO 5$: MOV $EXSIZ,POOLWD ;CALC. TOTAL POOL SPACE SUB #$POOL,POOLWD 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: .IF DF,K$$DAS ; KERNAL DATA SPACE ONLY MOV KINAR5,KDSAR5 ; RESTORE MAPPING OF KERNAL DATA APR 5 ; (TO SAME AS I-SPACE APR 5) .ENDC 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 MOV R0,BADR0 ; SAVE R0 OF FAILURE MOV #BADR1,R0 MOV R1,(R0)+ ; AND ALL OTHER REGS MOV R2,(R0)+ MOV R3,(R0)+ MOV R4,(R0)+ MOV R5,(R0)+ 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 BCC 12$ ; ITS OK, TCB IS IN PRIMARY POOL JMP 190$ ;IF OUTSIDE POOL, JUST IGNORE IT 12$: 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 18$ 15$: CLR R2 ; SLOT FOR ACCOUNTING IS ***** SLOT CLRB (R0)+ ; SAVE SLOT OFFSET IN TCB POSITION 17$: CMP TCBDOT,T.NAM(R3); IS FIRST PART OF NAME "..." ? BEQ 18$ ; YES, DONT COUNT THE TCB (ITS IN SECPOL) INC TCBCNT ; COUNT IT 18$: 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 GTTCB ; CONVERT FROM RAD50 AND COPY IN TASK NAME MOVB #'>,(R0)+ ;FINISH OFF W/ CLOSING BRACKET ; GET COMMON PCB VECTOR(S) .IF DF,R$$PRO ; Professional has Vectors in secpol br 90$ ; skip for now .endc MOV T.PCBV(R3),R0 ; GET ANY COMMON PCB VECTOR BEQ 90$ ; NONE BIC #1,R0 ;if set -> odd adress trap *** USC002 ; BIT #1,R0 ; IS IT ODD?(P/OS) ; BNE 90$ ; YES -- SKIP 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 (maybe) BIT #1,R0 ; IS IT ODD?(P/OS) BNE 40$ ; YES -- SKIP 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 BIT #P2.SEC,P.ST2(R4) ;; TCB IN SECPOL BNE 80$ 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 GTKSEC ;; LOAD TASK NAME (WHEN TCB MAY BE IN SECPOL) 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 ; PUT TASK NAME INTO MAP 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 ; PUT IN INTO ACTIVE TASK ACCOUNTING MOV P.TCB(R4),R3 ; GET TCB ADDR CALL GTACNT ; GET LOC IN MAPBUF FOR ACCOUNTING ENTRY MOV P.HDR(R4),R0 ; GET THE HEADER ADDRESS IN R0 BNE 170$ ; GOT A HEADER IN POOL ; EXTERNAL HEADER .IF DF,K$$DAS MOV P.REL(R4),KDSAR5 ; LOAD TASKS MEMORY ADDR (= HEADER) MOV #120000,R2 .IFF MOV KINAR4,-(SP) ;USE KERNAL APR4 (KINAR5 is mapped to us!!!) MOV P.REL(R4),KINAR4 MOV #100000,R2 .ENDC MOV H.NLUN(R2),R5 ;GET NUMBER OF LUNS FOR THIS TASK IN R5 MOV R5,-(SP) ;SAVE COUNT BEQ 160$ ;IF NO LUNS ADD #H.LUN,R2 ;MOVE POINTER TO 1ST LUN MOV #UCXLST,R1 ;USE TT IOPACKET LIST TO COPY LUN TABLE CMP R5,#UCX.SZ ;ROOM FOR ALL ? BLE 150$ ; YES MOV #UCX.SZ,R5 ; NO, USE LIST SIZE 150$: MOV (R2)+,(R1)+ ; COPY LUN TABLE MOV (R2)+,(R1)+ SOB R5,150$ MOV #UCXLST,R2 ; GET LOC 160$: MOV (SP)+,R5 ; AND COUNT ***USC was pushed before apr!! .IF DF,K$$DAS MOV KINAR5,KDSAR5 ; RESTORE APR 5 .IFF MOV (SP)+,KINAR4 .ENDC TST R5 BNE GTWB ; GO PROCESS WINDOW BLKS BR STAEND ; UNLESS NO LUNS ; HEADER IN POOL ; NOT YET HANDLED 170$: 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 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)+ ; 12 BYTES MOVB #'],(R0)+ 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 MOV R3,FSTUCB BIT #DV.PSE,U.CW1(R3) ;IS THIS A PSEUDO DEVICE? BEQ 2$ ;IF NOT, OK TO CONTINUE ON THIS ONE cmp #"NS,d.nam(r4) ;do DecNet ECL device beq 2$ cmp #"NX,d.nam(r4) ;do DecNet DLX device beq 2$ cmp #"NW,d.nam(r4) ;do DecNet PSI device beq 2$ 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.RPKT(R3),R0 ; GET CURRENT READ I/O PACKET BNE 15$ 20$: MOV U.WPKT(R3),R0 ; GET CURRENT WRITE I/O PACKET BEQ NXTPKT ; ** (N.B. WON'T PICK UP BOTH YET) 15$: 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 .IF DF,CBLSHR CMP #"KB,D.NAM(R4) ; A KB BNE 10$ ; NO TST STARKB ; GOT 1ST KB ALREADY BNE 20$ ; YES MOV NXTUCX,STARKB ; NO, SAVE START OF KB INFO BR 20$ ; GO PICK UP UCBX ADDRESSES .ENDC ;CBLSHR 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 ; SAVE INFO FOR UCBX IN SEC POOL 60$: MOV NXTUCX,R2 ; GET SAVE SLOT CMP R2,#157774 ; MAKE SURE WE DONT OVERFLOW INTO APR7 BHIS 50$ ; WE HAVE, STOP THE SCAN MOV R3,(R2)+ ; SAVE UCB ADDR MOV R1,(R2)+ ; UCBX ADDR MOVB U.TSTA(R3),R1 ; GET STATUS W SIGN EXTEND BEQ 50$ ; NO I/O ACTIVE ASSUME S1.IBY,200 ASSUME S1.OBY,100 MOVB R1,(R2)+ ; SAVE INPUT BUSY FLAG (NEG IF TRUE) ASLB R1 ; PUT INPUT BUSY IN C-BIT, OUTPUT IN BIT 7 MOVB R1,(R2)+ ; SAVE OUTPUT BUSY FLAG (NEG IF TRUE) BMI 40$ ; OUTPUT IS BUSY SO SAVE FOR UCBX SCAN BCC 50$ ; NEITHER INPUT NOR OUTPUT BUSY, DONT SAVE 40$: MOV R2,NXTUCX ; SAVE NEXT SLOT PTR 50$: JMP TSTSCB ; 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 beq 130$ ; special case for DecNet devices 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 CMP #"TT,D.NAM(R4) ; USC001 ONLY LAT TERMINAL'S IN POOL BEQ TTSPEC ; DO SPECIAL HANDLING 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) ; AND DELIMITER MOV (SP)+,R0 ; MOV #TTUCB,R1 ; ADD IN ,(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 .ENDC .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 ; .IF DF,V1 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 .ENDC .if df,V1 ; DON'T NEED THAT USSUALLY .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 17$ 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$ 17$: 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 .ENDC ;U$$UMR .IF DF,G$$GEF ; Group global event flag support .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 .ENDC ;G$$GEF .SBTTL STAPDV - GET SOME NETWORK STRUCTURE INFO STAPDV: ; ; Examine Process Descriptor Vector ; is pointed to by $PDVTA from NETCM ; its length is $PDVNM (NETCM) ; -------------------------------------- ; | Ptr to 1st Processdescriptor block | ; -------------------------------------- ; : : ; | | ; -------------------------------------- ; | Ptr to nth PDB | ; -------------------------------------- ; MOV $PDVTA,R0 ; FETCH PDV TABLE ENTRY (NETCM) MOV R0,R4 ; BEQ 20$ ; NONE MOV $PDVNM,R2 ; GET LENGTH COUNT DEC R2 ASL R2 ; MAKE WORD COUNT MOV R2,R1 ; FOR MRKMAP SIZE ADD R0,R2 ; GET LAST ENTRY ADR CALL GTMOFF ; R0 -- MAP ADR CALL MRKMP2 ; MARK AS #### .WORD '# 10$: CMP R2,R4 ; TEST IF LAST ENTRY BLT 20$ ; LT -- DONE MOV (R4)+,R0 ; GET ENTRY to process descriptor MOV R0,R3 ; save address MOVB Z.LLN(R0),R1 ; GET NUMBER OF CHANNELS ALLOCATED BIC #177400,R1 ; CALL GTMOFF ; R0 -- MAP ADR MOV R1,-(SP) ; SAVE R1 MOV R2,-(SP) ; AND R2 movb #'$,(r0)+ ; MARK PDV AS $XXX MOV Z.NAM(R3),R1 ; GET PROCESS NAME CALL $C5TA ; CONVERT TO MAP CMP #^RXPT,Z.NAM(r3) ; if XPT -- some more work for us bne 12$ call doxpt ; examine XPDDB and friends br 300$ ; skip 12$: CMP #^RECL,Z.NAM(r3) ; if ECL -- some more work for us bne 14$ call doecl ; examine ECLDDB br 300$ 14$: CMP #^RLAT,Z.NAM(r3) ; if LAT -- some more work for us bne 16$ mov #LATSTG,r1 call doltb br 300$ 16$: cmp #^RRTH,z.nam(r3); RTH bne 200$ mov #RTHSTG,r1 call doltb br 300$ 200$: cmp #^RNCT,z.nam(r3); NCT bne 300$ mov #NCTSTG,r1 call doltb 300$: MOV (SP)+,R2 ; RESTORE R2 MOV (SP)+,R1 ; RESTORE R1 BEQ 10$ ; NO CHANNELS ALLOCATED -- DONE THIS GUY SUB #1,R1 ; BLE 10$ ; ONLY ONE -- IS STILL DONE BY ROUNDING ; ASL R1 ; 2 BYTE EACH CHANNEL CALL MRKMP2 ; MARK AS * .WORD '* BR 10$ 20$: ; decnet Homeblock MOV $DECPT,R0 ; POINTER TO DECNET HOMEBLOCK mov r0,r2 ; save home-block ptr CALL GTMOFF ; R0 -- MAP ADR MOV #DNHOM,R1 ; mark as ,(r0)+ ; ; ; System line tables ; MOV $SLTMA,R0 ; FETCH SLT TABLE ENTRY MOV R0,R4 BEQ 40$ ; NONE MOV $SLTNM,R2 ; GET LENGTH COUNT ASL R2 ; MAKE WORD COUNT MOV R2,R1 ; FOR MRKMAP SIZE ADD R0,R2 ; GET LAST ENTRY ADR CALL GTMOFF ; R0 -- MAP ADR BCS 30$ CALL MRKMP2 ; MARK AS +++++++++++ .WORD '+ 30$: CMP R2,R4 ; TEST IF LAST ENTRY BLT 60$ ; LT -- DONE MOV (R4)+,R0 ; GET ENTRY MOV r0,r5 ; save for later use MOVB L.NSTA(R0),R3 ; GET NUMBER OF STATIONS MOV #L.LEN,R1 ; GET LENGTH OF SLT MUL #S.LEN,R3 ; MULTIPLY BY TRIBUTARY EXTENSION LENGTH ADD R3,R1 ; ADD TO SLT LENGTH CALL GTMOFF ; BCS 34$ ; MOV R0,-(SP) CALL MRKMP2 .WORD '+ MOVB #'>,-(R0) MOV (SP)+,R0 MOV #SLTSTR,R1 CALL MOVSTG ; ; KRB block ; mov l.krba+2(r5),r0 ; get KRB addr (there is an additional word beq 400$ ; to insert in SLTDF$ for level 2 router) sub #10,r0 ; KRB has entries at negativ offset call gtmoff ; map offset mov #KRBSTG,r1 ; mark as CALL MOVSTG ; ; ; now dlc table (if in primary pool) ; 400$: tst l.dlm(r5) ; line table bias bne 34$ ; <>0 --> not in pool mov l.dls(r5),r0 ; get table address movb l.dlc(r5),r1 ; get index of owner bic #177400,r1 ; just in case mov $pdvta,r3 ; get pdv table address add r1,r3 ; this is our process mov (r3),r3 ; get ptr to pdv cmp #^REPM,z.nam(r3); do line specific stuff bne 34$ call doepm ; do epm specific block 34$: BR 30$ 60$: ; ; Do the free CCB's chain available from ; $CCBLH entry of NETCM ; 40$: mov #$CCBLH,r0 ; get the pointer mov r0,r4 ; save it 70$: mov (r4),r0 ; get next CCB beq 100$ ; done if 0 mov r0,r4 ; save ptr CALL GTMOFF ; setup to local map mov #CCBSTG,r1 ; CALL MOVSTG br 70$ 100$: JMP NXTTHR ; NEXT THREAD ; ; we've found a EPM-DLC ; ; r0 is address of line table ; doepm: mov r2,-(sp) mov r0,r3 call gtmoff ; offset destination buffer mov #EPMSTG,r1 ; mark as call movstg mov #c$len,r1 ; get length of primary line table mov c$len(r3),r2 ; enter port table chain (contigoues beq 20$ ; to the line table) 10$: add #p$len,r1 ; add this port mov (r2),r2 ; chain to next bne 10$ ; more to do 20$: sub #16.,r1 ; sub length of ,-(r0) mov (sp)+,r2 ; return ; ; examine XPT Database ; ; Input: ; r0 - Pointer to output map ; r3 - Pointer to PDV ; r1,r2 available ; doxpt: mov r0,-(sp) ; save map ptr mov r3,-(sp) ; save for ECL mov #XPTSTG,r1 ; mark as call doltb mov z.dat(r3),r3 ; mov N$PLD(r3),r2 ; get count of vector table mov N$PLD+2(r3),r3 ; start of vector mov r3,r0 ; put para's mov r2,r1 ; in desired regs call GTMOFF ; get buffer address CALL MRKMP2 ; mark as vvvvv .WORD 'v ; 10$: mov (r3)+,r0 ; get Physical link block address beq 20$ ; empty slot call GTMOFF ; get buffer address mov #PLBSTG,r1 ; mark as call movstg ; write to output buffer 20$: sob r2,10$ ; do all slots mov (sp)+,r3 ; point to Pool-PDV mov (sp)+,r0 ; restore PDV ptr return ; ; examine ECL Database ; ; Input: ; r0 - Pointer to output map ; r3 - Pointer to PDV ; r1,r2 available ; doecl: mov r0,-(sp) ; save map ptr mov r3,-(sp) mov #ECLSTG,r1 ; mark as call doltb ; ; ; llt's are in secpol ; mov z.dat(r3),r2 ; mov N$LVC(r2),r1 ; get count of vector table mov N$LVC+2(r2),r0 ; start of vector mov r0,-(sp) mov r1,-(sp) call GTMOFF ; get buffer address CALL MRKMP2 ; mark as vvvvv .WORD 'v ; ; ; get some LL - Block info (iopacket) ; ; r1 - count of vectors ; mov (sp)+,r1 mov (sp)+,r0 mov r3,-(sp) mov r0,r3 520$: mov (r3)+,r0 ; get first vector mov r3,r5 beq 500$ ; none - skip bit #1,r0 ; in extended pool ? beq 540$ ; no, in DSR ; ; map to extended pool ; .IF DF,K$$DAS mov $xbias,KDSAR5 ; Map to base address of pool using KDSAR5 .IFF MOV KINAR4,-(SP) ; don't use KINAR5!! MOV $xbias,KINAR4 .ENDC mov r0,r2 ; save r0 bic #177701,r0 ; Return virtual address .IF DF,K$$DAS bis #120000,r0 ; ... mapped through KDSAR5 .IFF bis #100000,r0 ; ... mapped through KINAR4 .ENDC ASH #-6,R2 ; Convert address to block bias bic #176000,r2 ; Clear extraneous bits .IF DF,K$$DAS add r2,KDSAR5 ; ... update to proper block .IFF add r2,KINAR4 ; ... update to proper block .ENDC ; ; now we are mapped to extended pool with ; r0 containing the pointer to a llc table ; mov l.wind(r0),r0 ; pick up window pointer .IF DF,K$$DAS mov KINAR5,KDSAR5 ; restore data apr 5 .IFF MOV (SP)+,KINAR4 ; restore executive apr .ENDC ; ; r0 now points to a window block in primary pool ; 540$: mov r0,r2 ; save WB Address beq 500$ ; skip if none call gtmoff ; mov r1,-(sp) mov #NWBSTG,r1 ; call movstg mov #PKTSTG,r1 ; mov w.sndq(r2),r0 ; get transmit que entry beq 560$ ; call dopkt ; 560$: mov w.rcvq(r2),r0 beq 600$ call dopkt ; 600$: mov (sp)+,r1 500$: sob r1,520$ mov (sp)+,r3 ; ; examine the mailbox que ; mov z.dat(r3),r2 ; mov N$MBXQ(r2),r0 ; point at MBX beq 60$ ; if eq -- empty que 20$: mov r0,r2 ; save r0 call gtmoff ; get buffer entry movb #'<,(r0)+ ; mark as movb #'M,(r0)+ ; movb #'B,(r0)+ ; movb #'>,(r0)+ ; mov r2,r0 mov 2(r0),r0 ; walk along the chain bne 20$ 60$: mov z.dat(r3),r3 ; mov N$GENQ(r3),r0 ; point at delivery que beq 80$ ; if eq -- empty que 70$: mov r0,r2 CALL GTMOFF ; setup to local map mov #CCBSTG,r1 ; CALL MOVSTG movb #'E,-2(r0) mov r2,r0 mov 2(r0),r0 bne 70$ 80$: mov (sp)+,r3 mov (sp)+,r0 ; restore PDV ptr return ; ; mark line tables -- common code for ; LAT,RTH,NCT ; Input: ; r0 - Pointer to output map ; r3 - Pointer to PDV ; r1,r2 available ; doltb: mov r0,-(sp) ; save map ptr mov r3,-(sp) mov z.dat(r3),r0 ; get the pointer CALL GTMOFF ; R0 -- MAP ADR call movstg ; mov (sp)+,r3 mov (sp)+,r0 ; restore PDV ptr return ; ; common code for marking a ; chained packets ; dopkt: mov r0,-(sp) ; do the complete call gtmoff ; packet call movstg ; - mov (sp)+,r0 ; chain mov (r0),r0 bne dopkt return .SBTTL STAUCX - GET I/O PACKETS OUT OF UCB EXTENSIONS ; STAUCX: .IF DF,CBLSHR MOV STARKB,R4 ; ANY KBS BNE 5$ ; YES .ENDC MOV NXTUCX,R4 ; GET SLOT PTR 5$: MOV #UCXLST,R5 CMP R4,R5 ; DID WE GET ANY BLOS 50$ ; NO MOV #120000,R2 ; USE APR5 AND R2 TO LOOK AT UCBX 10$: TST (R5)+ ; PASS UCB MOV (R5)+,KDSAR5 ; MAP THE UCBX MOV @R5,R1 ; GET STATUS FLAGS BMI 15$ ; OUTPUT IS BUSY CLR @R5 ; NO OUTPUT PACKET BR 17$ 15$: MOV U.TOC(R2),(R5) ; GET OUTPUT PACKET 17$: TSTB R1 ; INPUT BUSY ? BMI 21$ ; YES CLR -(R5) ; NO BR 22$ 21$: ASSUME U.TIC,0 MOV (R2),-(R5) ; GET INPUT I/O PACKET 22$: CMP (R5)+,(R5)+ ; ADVANCE LIST PTR TO NEXT CMP R4,R5 ; DONE YET ? BNE 10$ ; NO .IF DF,CBLSHR MOV NXTUCX,R4 ; GET REAL END OF LIST CMP R4,R5 ; SAME IF NO KBS OR KBS ARE DONE BNE 10$ ; ELSE GO DO THE KBS .ENDC ;CBLSHR ; TAKE CARE OF TASK ACCOUNTING MOV KINAR5,KDSAR5 ; RESTORE KERNAL DATA APR 5 MOV #UCXLST,R4 ; RESCAN THE LIST 25$: TST (R4)+ ; PASS THE UCB MOV (R4)+,R0 ; DO A PACKET (INPUT) BEQ 27$ ; NO INPUT PACKET, TRY FOR OUTPUT CALL QIOTTN ; COUNT THE QIO FOR TASK ACCTNG 27$: MOV (R4)+,R0 ; AND AGAIN (OUTPUT) BEQ 30$ CALL QIOTTN ; COUNT THE QIO FOR TASK ACCTNG 30$: CMP R4,R5 ; AT LIST END ? BLO 25$ ; NO 50$: JMP NXTTHR .SBTTL END - USER MODE, PICK UP STATIC INFORMATION END: jmp user .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 ; OR AT GTTCB IF NO PCB IN R4 (AND NO SECPOL CHECK NEEDED) ; 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: BIT #PS.COM,P.STAT(R4) ; COMMON ? BEQ GTTCB ;NO GTKSEC: BIT #P2.SEC,P.ST2(R4) ; TCB IN SECONDARY POOL? BEQ GTTCB ;NO .IF DF,K$$DAS MOV R3,KDSAR5 ; LOAD TCB ADDR IN APR 5 MOV #120000+T.NAM,R3 ; AND USE IT .IFF MOV KINAR4,-(SP) ; don't use KINAR5!! MOV R3,KINAR4 MOV #100000+T.NAM,R3 ; AND USE IT .ENDC MOV (R3)+,WORK1 MOV @R3,WORK2 MOV #WORK1-T.NAM,R3 .IF DF,K$$DAS MOV KINAR5,KDSAR5 ;RESTORE DATA APR 5 .IFF MOV (SP)+,KINAR4 .ENDC GTTCB: 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 ; QIOTTN ; ENTRY FOR TERMINAL QIO PACKETS (WHICH MIGHT NOT BE IO PACKETS) ; ; CLOBBERS R3 ( SET TO TCBLST ADDR) .ENABL LSB QIOTTN: CMP #140000,R0 ; IF AN ADDR IN TTCOM BLOS 7$ ; THEN NOT AN I/O PACKET, BUT A BUFFER 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 .DSABL LSB ; ;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: ;** ; STATCB 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 ;** ; IN V 1 STACBD MUST PRECEED STAUCX .WORD STACBD ;PCB'S FOR INSTALLED COMMONS OUT OF MEM .WORD STADCB ;DCB'S / ICB'S / UCB'S / SCB'S / I/O PKT'S .IF DF,K$$DAS .WORD STAUCX ; DO UCB EXTENSIONS IN TTCOM .ENDC .WORD STAOPK ;UNUSED I/O PKT'S .WORD STACLQ ;CLOCK QUEUE CONTROL BLOCKS .WORD STALOG ;ASN CONTROL BLOCKS .WORD STAVCB ;VCB'S / FCB'S .IF DF,V1 .WORD STAMCR ;MCR CMD LINES .ENDC .WORD STAMOU ;MCB'S .WORD STACKP ;CHECKPOINT PCB'S .IF DF,V1 .WORD STAERR ;ERRLOG BUFFERS .ENDC .IF DF,U$$UMR ; UMR support (as separate from M$$EXT) ; .WORD STAUMR ;UMR ALLOCATION BLOCKS .ENDC .IF DF,G$$GEF ; Group global event flag support .WORD STAGFN ;GROUP GLOBAL EFN BLOCKS .ENDC ;?; .WORD STADMC ; DO I/O PACKETS IN XM DRIVER SPACE .WORD STAPDV ; Do DecNet structures .WORD STACLI ; CLI Parser Blocks 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 POOLWD: .WORD 0 FRGMNT: .WORD 0 POOLAD: .BLKW 1 ;STARTING ADDRESS FOR PRINTOUT MAPAD: .BLKW 1 ;STARTING MAP ADDRESS FOR SAME 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 IOP: .ASCIZ // HDRSTG: .ASCIZ /
/ XPTSTG: .ASCIZ // PLBSTG: .ASCIZ // ECLSTG: .ASCIZ // LLTSTG: .ASCIZ // LATSTG: .ASCIZ // RTHSTG: .ASCIZ // NCTSTG: .ASCIZ // EPMSTG: .ASCIZ // NWBSTG: .ASCIZ // PKTSTG: .ASCIZ // .IF DF,A$$CNT ; ACCOUNTING ADDS 1 WORD TO TCB SIZE TCBSTG: .ASCIZ /\\\\\TCB FOR / .IFF ;A$$CNT TCBSTG: .ASCIZ /\\\TCB FOR / .ENDC ;A$$CNT ;;;MCRSTG: .ASCIZ // CDPSTG: .ASCIZ /[CT]/ OFASTG: .ASCIZ /[AO]/ EFISTG: .ASCIZ /[EF]/ ;;;;ERRSTG: .ASCIZ // ;;;;ERR.SZ= .- PDVSTG: .ASCIZ /: )/ .EVEN ; OUTBUF: ;REF. LABEL TEXTBF: ; REUSE SYSTEM STATE INFO AS TEXT BUFFER BADPC: .WORD 0 ;PC WHERE TRAP OCCURRED BADR0: .WORD 0 ; R0 OF FAILURE BADR1: .BLKW 5 ; R1-R5 AT FAILURE 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 $$= .-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 TCBDOT: .RAD50 /.../ ; 1ST HALF OF NAME OF PROTOTYPE TCB TASKS BLNKLN: ; REUSE TCBCNT FOR BLANK LINE COUNT 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 FSTUCB: .WORD 0 ; ENSURE NO SYSTEM CRASHES ON ACCIDENTAL BUFFER OVERFLOWS - ; SINCE WILL GET A MEMORY PROTECT VIOLATION .PSECT $$$DAT,RW,D .NLIST BEX .NLIST ME .REPT 8. ;LEADING PAD OF BLANKS .ASCII / / .ENDR MAP:: .NLIST .REPT 1024. ;ENOUGH ROOM FOR 16.K WORDS OF POOL .ASCII /????????/ .ENDR .LIST .NLIST BEX ; UCB EXTENSION LIST - THIS MUST BE ABOVE LOC 140000 WORK1: .WORD 0 ; FAKE TCB SLOT FOR GTKSEC WORK2: .WORD 0 .WORD 0 STARKB: .WORD 0 NXTUCX: .WORD UCXLST UCXLST: ; .BLKW 500 ; ROOM FOR ALOT OF PACKETS UCX.SZ= <.-UCXLST>/2 ; NUMBER OF WORDS IN UCXLST .BLKW 100 ; (ONLY THAT PORTION OF THIS <160000 ; WILL ACTUALLY BE USED) ; ; MESSAGES THAT ARE NOT ACCESSED IN SYSTEM STATE ; (THEREFORE CAN BE IN APR7) ; APR7OK:: ; CHECK THAT THIS LABEL IS <= 160000 ; IF NOT COULD BE A PROBLEM !!! SINCE ; APR7 IS I/O PAGE IN SYSTEM STATE .NLIST BEX ;DON'T NEED TO SEE ALL THE ASCII STRINGS 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) (12) (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 INACTIVE TASKS WITH TCBS IN POOL: / 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 MAPMSG: .ASCII <14>/POOL MAP: . . . . . . . * . . . . . . . */ .ASCII / . . . . . . . * . . . . . . ./ MAPSIZ= .-MAPMSG BLKMSG: .ASCII <12><15>/ [ABOVE LINE REPEATED / BLKNUM: .ASCII / / .ASCII / TIMES]/<12><15> BLKSIZ= .-BLKMSG ODDMSG: .ASCII /ODD ADDRESS TRAP @ PC / ODDNUM: .ASCII /000000/ ODDSIZ= .-ODDMSG MPVMSG: .ASCII /MEMORY PROTECT VIOLATION @ PC / MPVNUM: .ASCII /000000/ MPVSIZ= .-MPVMSG REGMSG: .ASCII /REGISTERS:/ REGNUM: .REPT 6 .ASCII / 000000/ .ENDR REGSIZ= .-REGMSG FRGMSG: .ASCIZ <12><15>/FREE POOL FRAGMENTS/ POOLMS: .ASCIZ /TOTAL WORDS OF POOL/ NFRMSG: .ASCIZ /TOTAL FREE WORDS/ SEGMSG: .ASCIZ /FREE SEGMENT LIST:/ LRGMSG: .ASCIZ /LARGEST FRAGMENT/ .EVEN .psect $$$usr,ro,i user:: ; 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$: .IF DF,CBLSHR CMP STARKB,R5 BHI 22$ ; NOT DONE YET BNE 35$ ; ALREADY HAVE RELOADED TT NAME TO KB MOV #TTOSTG+4,R1 ; CHANGE TT TO KB MOV #TTISTG+4,R0 MOVB #'K,(R1) MOVB (R1)+,(R0)+ MOVB #'B,(R1) MOVB @R1,@R0 .ENDC ;CBLSHR 35$: CMP NXTUCX,R5 ; DONE YET ? BHI 22$ ; NO ; PUT IN THE ERROR LOG FILE POINTER 40$: .IF DF,V1 MOV $ERRSV,R0 ; GET ADDR BEQ 50$ ; NONE CALL GTMOFF ; MAP ADDR BCS 50$ MOV #EFISTG,R1 CALL MOVSTG ; MARK AS [EF] .ENDC ;V1 ; 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,R1 ;CHECK FOR TRAP WHILE ON SYSTEM STACK BEQ NOERR MOV R1,R2 ; R2 NON 0 IS NO 0 SUPPRESS MOV #ODDNUM,R0 ;OOPS, DEFAULT TO ODD ADDRESS MESSAGE ASR R2 ;CHECK FOR FLAG FOR MEM. PROT VIOLATION BCC 10$ ;FLAG CLEAR IF EVEN ADDRESS MOV #MPVNUM,R0 ;WAS MEM. PROT. VIOLATION, CHANGE MESSAGE MOV R2,R1 ASL R1 ;CONVERT BACK TO VALID PC CALL $CBOMG ;CONVERT PC TO ASCII PRINT MPV ; PRINT THE MESSAGE BR 15$ 10$: CALL $CBOMG ;CONVERT THE PC PRINT ODD ; PRINT THE ODD ADDRESS MESSAGE 15$: MOV #REGNUM,R0 ;DO REGISTER PRINTOUT MOV #BADR0,R4 ; REGISTER STORAGE MOV #6,R5 ; LOOP COUNTER 20$: MOV R4,R2 ; NO 0 SUPPRESS CMPB (R0)+,(R0)+ ; ADVANCE BUFFER PTR MOV (R4)+,R1 ; NUMBER TO CONVERT CALL $CBOMG ; CONVERT IT SOB R5,20$ PRINT REG ; PRINT REGISTERS ;+ ; OUTPUT TASK ACCOUNTING ;- NOERR: PRINT HD1 ; PRINT THE 3 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 #12.,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, INACTICVE COUNT 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 ;- CLR -(SP) ;FLAG CMPB GMCR+G.MCRB+5,#'F ;INITIATED WITH 'OPA F' COMMAND? BNE 12$ ;IF NO, DONT PRINT FRAGMENT LIST INC @SP ;FLAG TO PRINT FRAG LIST 12$: 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 FRGMNT,R5 ;SET LOOP COUNT FOR PRINTING MOV #FRLIST,R4 ;GET ADDRESS OF SEGMENT LIST CLR R3 ;ACCUMULATE SEGMENT LENGTHS IN R3 TST @SP ; PRINT NEXT BEQ PACCUM ; NO MOV #TEXTBF,R0 ;OUTPUT MESSAGE ABOUT NEXT PRINTOUT MOV #SEGMSG,R1 ;IT'S LIST OF FREE SEGMENT ADDRS. CALL MOVSTG CALL OUTIT 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 BR PFRSUM PACCUM: CLR R2 ; ACCUMULATE LARGETS FRAG IN R2 2$: TST (R4)+ MOV (R4)+,R1 ;RECOVER LENGTH TO PRINT IN DECIMAL ASR R1 ;CONVERT LENGTH TO WORDS CMP R1,R2 BLE 5$ MOV R1,R2 5$: ADD R1,R3 ;ACCUMULATE SEGMENT LENGTHS SOB R5,2$ MOV #LRGMSG,R1 CALL PRMSNM ;PRINT LARGEST SEGMENT PFRSUM: MOV R3,R2 ;PRINT TOTAL OF FREE SEGMENTS MOV #NFRMSG,R1 CALL PRMSNM TST (SP)+ ;+ ;NOW PRINT MAP IN ROWS OF 64 CHARS. W/ ADDRESS OF EACH ROW ;- PRINT MAP,RESTORE ;OUTPUT HEADER FOR MAP: 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 MOV #-5,BLNKLN ; INIT BLANK LINE COUNT MOVB #'-,R3 ; USE R3 FOR CHAR TO COMAPRE TO PRTLUP: MOV POOLAD,R1 ;SET UP TO CONVERT POOL ADDRESS TO OCTAL ADD #400,POOLAD ;BUMP POOL ADDRESS TO NEXT LINE MOV PC,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 CLR R2 ; SET UP "-" FLAG 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$: CMPB @R1,R3 ; IS IT "-" ? BEQ 7$ ; YES DEC R2 ;NO 7$: 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 TST R2 ; BLANK LINE ? BNE 15$ ; NO INC BLNKLN ; YES, COUNT IT BLE 20$ ; STILL ELIBLE TO BE PRINTED BR 25$ ; NOT PRINTING ANYMORE, JUST COUNTING 15$: CALL DOBLNK ; DO ANY REPEAT COUNT AS NECESS 20$: CALL OUTIT ;PRINT THE NON BLANK LINE 25$: TST R5 ;ANYTHING LEFT TO PRINT? BNE PRTLUP ;IF SO, BACK FOR ANOTHER RECORD CALL DOBLNK ; DO ANY REPEAT COUNT AS NECESS ; EXIT$S .SBTTL SUBROUTINES - FOR USER MODE OUTPUT ;+ ;SUBROUTINES ;- ;PRMSNM: PRINT MESSAGE W/ TRAILING DECIMAL NUMBER ; ; ENTRY W/ R1 = ADDR. OF ASCIZ STRING TO OUTPUT ; R2 = VALUE TO APPEND PRMSNM: MOV #TEXTBF,R0 ;SET START OF OUTPUT BUFFER CALL MOVSTG ;COPY IN THE TEXT MOVB #11,(R0)+ ;SEPARATE MESSAGE FROM VALUE WITH TAB MOV R2,R1 ;GET THE VALUE TO CONVERT CLR R2 ;SUPPRESS LEADING ZEROS CALL $CBDMG ;CONVERT TO DECIMAL MAGNITUDE MOVB #'.,(R0)+ ;APPEND DECIMAL POINT 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 ; ; DOBLNK ; DO THE ABOVE LINE REPEATED MESSAGE AND TIDY UP ; DOBLNK: MOV BLNKLN,R1 ;GET THE NUMBER OF REPEATED LINES BLE 20$ ;NONE, SO JUST REINIT MOV R0,-(SP) ; SAVE TEXTBF PTR MOV #BLKNUM+2,R0 ;DESTINATION FOR DECIMAL NUMBER MOVB #40,-(R0) ; BLANK IT OUT MOVB #40,-(R0) CLR R2 ; 0 SUPPRESS CALL $CBDMG ; CONVERT TO DECIMAL PRINT BLK,RESTORE ; PRINT NUMBER OF REPETITIONS MOV (SP)+,R0 ; RESTORE R0 20$: MOV #-5,BLNKLN ; RELOAD BLANK LINE COUNTER RTS PC .END OPA