TITLE ERRCON - MONITOR DETECTED ERROR HANDLING ROUTINES - V1255 SUBTTL T. HASTINGS/TH/CHW/TW/RCC/DAL 24-MAY-88 SEARCH F,S,DEVPRM $RELOC $HIGH ;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED ; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION ; 1973,1974,1975,1976,1977,1978,1979,1980,1982,1984,1986,1988. ;ALL RIGHTS RESERVED. .CPYRT<1973,1988> XP VERRCN,1255 ;THIS MACRO PUTS VERSION NO. IN STORAGE MAP AND GLOB ENTRY ERRCON ;ALWAYS LOAD ERRCON(IF LIB SEARCH) ERRCON:: SUBTTL CLOCK LEVEL APR ERROR HANDLING ;HERE ON PI 7 CLOCK INTERRUPT TO PROCESS APR ERRORS FOR INDIVIDUAL JOBS ;.CPAEF HOLDS COMMUNICATION FLAGS SET BY APR PI INTERRUPT LEVEL ;CALL: MOVE S,.CPAEF ; JUMPN S,APRILM ;COME HERE IF ANYTHING HAPPENED ; RETURN TO RESCHEDULE NEW USER APRILM::MOVEM S,.CPSAC## ;HERE ON ANY APR ERROR OR MEM PARITY SKIPN J,.CPJOB## ;CURRENT JOB ON THIS CPU SETOM .CPNJE## ;MAKE SURE NULL JOBS AC'S ARE RESTORED JUMPGE S,APRIL1 ;REQUEST TO SCAN MEMORY FOR PARITY OR NXM? TLNN S,(CP.PSX!CP.CSX) ;YES IS THIS JUST A PRINT JOB MESSAGES REQUEST? JRST APRIL2 ;YES--GO LOOP THRU JOBS AND PRINT MESSAGES TO TTY'S PUSHJ P,PARSWP ;NO--SWEEP CORE (AND FLAG JOBS ON KI10) APRIL2: MOVE J,HIGHJB## ;HIGHEST JOB NUMBER TRNE S,UE.NXM ;NXM INSTEAD OF PARITY ERROR? JRST NXMLOP ;YES--REPORT NXM TO ALL JOBS AFFECTED ;NO--REPORT PARITY TO ALL JOBS AFFECTED ; FALL INTO PARLOP ;;LOOP TO SCAN ALL JOBS, ZAP BAD ONES AND PRINT PARITY ERROR MESSAGE PARLOP: MOVEI T1,JS.MPE ;MEM PARITY FOR JOB TDNN T1,JBTSTS##(J) ;JOB HAVE MEM PAR IN LOW/HIGH SEG OR UPMP? JRST PARLO1 ;NO--KEEP LOOKING ANDCAM T1,JBTSTS##(J) ;YES, CLEAR IN JOB STATUS WORD SKIPN JBTADR##(J) ;IS LOW SEG STILL IN CORE? (NO IF SWAPOUT ERROR) JRST PARLO1 ;NO--KEEP LOOKING PUSHJ P,ZAPHIM ;RETURN ALL HIS RESOURCES PUSHJ P,PARSTP ;STOP JOB AND PRINT MESSAGE PARLO1: SOJG J,PARLOP ;LOOP OVER ALL JOBS IFN FTMP,< PUSHJ P,GETMM## ;GET THE MM JRST .-1 ;MUST WAIT > PUSHJ P,CPINXF ;FIX CORE TABLES, IF NEEDED SKIPA ;CORMAX WAS DECREASED JRST PARXIT ;ALL JOBS NOT ZAPPED CAN CONTINUE TO RUN IFN FTMP,< PUSHJ P,GIVMM## ;RETURN THE MM > ;HERE IF CORMAX WAS DECREASED SO ALL JOBS MUST BE SCANNED AND ANY ; WHICH ARE TOO BIG TO BE SWAPPED IN MUST BE ZAPPED ALSO SETZ J, ;FIRST CALL ARG. TO JBSTBG PARLP2: MOVE T1,CORMAX## ;GET CURRENT VALUE OF CORMAX PUSHJ P,JBSTBG ;SEE IF THIS JOB IS NOW TOO BIG TO RUN JRST PARXI1 ;ALL JOBS HAVE BEEN LOOKED AT PUSHJ P,PARSTP ;STOP THE JOB AND TELL THE USER JRST PARLP2 ;KEEP GOING ;EXIT FROM PARITY SWEEP AND PRINT ROUTINE PARXIT: IFN FTMP,< PUSHJ P,GIVMM## ;RETURN THE MM > PARXI1: HRROI S,UE.PEF ;CLEAR PARITY ERROR FLAG ANDCAB S,.CPAEF## ;OTHER APR ERRORS? JUMPN S,APRILM ;YES, GO PROCESS THEM POPJ P, ;RETURN NXMLOP: MOVEI T1,JS.NXM ;JOB OVERLAPS NXM BIT TDNN T1,JBTSTS##(J) ;DOES THIS JOB OVERLAP NXM? JRST NXMLP1 ;NO, KEEP LOOKING ANDCAM T1,JBTSTS##(J) ;CLEAR THE BIT CAME J,MOFLPG## ;IS THIS THE JOB THAT TYPED SET MEM ON? SKIPN JBTADR##(J) ;DOES THIS JOB HAVE CORE IN CORE? JRST NXMLP1 ;IF NO TO EITHER, DO NOTHING PUSHJ P,ZAPUSR ;ZAP THE PROGRAM IFN FTLOCK,< PUSHJ P,UNLOCK## ;UNLOCK IT IF LOCKED JFCL ;OH WELL > PUSHJ P,NXMSTP ;STOP THE JOB AND TELL THE USER WHAT HAPPENED NXMLP1: SOJG J,NXMLOP ;LOOP OVER ALL JOBS ON THE SYSTEM MOVE J,.CPJOB## ;JOB CURRENTLY RUNNING ON THIS CPU CAMN J,MOFLPG## ;JOB SETTING MEMORY ON-LINE? JRST NXMXI1 ;YES, IT CAUSED NXM, SET MEM ON WILL CALL CPINXF IFN FTMP,< PUSHJ P,GETMM## ;GET THE MM JRST .-1 ;MUST WAIT > PUSHJ P,CPINXF ;FIX CORE ALLOCATION TABLES, ETC. SKIPA ;CORMAX WAS DECREASED JRST NXMXIT ;ALL JOBS NOT ZAPPED CAN CONTINUE TO RUN IFN FTMP,< PUSHJ P,GIVMM## > ;HERE IF CORMAX WAS DECREASED SO ALL JOBS MUST BE SCANNED AND ANY ; WHICH ARE TOO BIG TOO BE SWAPPED IN MUST BE ZAPPED MOVEI J,0 ;STARTING WITH JOB 0, NXMLP2: MOVE T1,CORMAX## ; AND THE CURRENT VALUE OF CORMAX PUSHJ P,JBSTBG ;SEE IF THIS JOB IS NOW TO BIG TO BE RUN JRST NXMXI1 ;ALL JOBS HAVE BEEN LOOKED AT PUSHJ P,NXMSTP ;STOP THE JOB AND TELL THE USER JRST NXMLP2 ;SEE IF ANYMORE JOBS ARE TOO BIG NXMXIT: IFN FTMP,< PUSHJ P,GIVMM## > NXMXI1: HRROI S,UE.NXM ;CLEAR SOFTWARE NXM FLAG ANDCAB S,.CPAEF## ; .. JUMPN S,APRILM ;GO PROCESS OTHER ERRORS IF THEY EXIST POPJ P, ;OTHERWISE, RETURN ;SUBROUTINE TO PRINT MEM PAR ERROR FOR JOB N AND STOP JOB ;CALL: MOVE J,JOB NO ; PUSHJ P,PARSTP ; ALWAYS RETURN PARSTP: PUSHJ P,SVEUB## ;MAKE JOB ADDRESSABLE PUSHJ P,ZAPPGM## ;"CORE 0" JSP T1,ERRPNT ;PRINT STANDARD ERROR IN JOB MESSAGE ASCIZ /Memory parity error/ JRST NXMST1 ;PRINT MESSAGE AND STOP HIM ;SUBROUTINE TO PRINT NXM ERROR FOR JOB N AND STOP JOB NXMSTP: PUSHJ P,SVEUB## ;MAKE JOB ADDRESSABLE PUSHJ P,ZAPPGM## ;"CORE 0" JSP T1,ERRPNT ;PRINT ERROR MESSAGE FOR THE USER ASCIZ /Non-existent memory error/ AOS .CPNJA## ;COUNT NUMBER OF JOBS ZAPPED BECAUSE OF NXM NXMST1: DMOVE T1,.CPMDP## ;PC WHERE THE ERROR OCCURRED PJRST DPCPNT ;PRINT INFO FOR USER AND STOP HIM ;SUBROUTINE CALLED TO HALT CPU ON SERIOUS ERROR IN MEMORY PARHLT::CONO PI,PI.OFF ;NO INTERRUPTS DURING TYPEOUT PUSHJ P,PARHL1 ;TYPE OUT APPROPRIATE MESSAGE ON CTY DIENLK ;GIVE DIE LOCK BACK STOPCD .,HALT,FEM ;++FATAL ERROR IN MONITOR PARHL1: MOVEI T1,CTYWAT## ;NON-PI CTY TYPEOUT ROUTINE ADDRESS MOVEM T1,.CPTOA## ;MAKE IT THE ONE TO USE HERE IFN FTKL10,< PUSHJ P,SVPPC## ;MAKE SURE WE'RE IN SECONDARY PROTOCOL ON KL10 > SKIPN .CPREP## ;A PARITY ERROR? (NOT NXM) JRST NXMCTY ;NO, NXM REPORT NXM INSTEAD PUSHJ P,INLMES## ;PRINT MESSAGE TO INFORM OPER OF HALT ASCIZ / ?Non-recoverable memory parity error in monitor. [CPU Halt] / POPJ P, ;RETURN AND HALT NXMCTY: PUSHJ P,INLMES## ;INFORM OPR OF HALT ASCIZ / ?Non-existent memory detected in monitor. [CPU Halt] / POPJ P, ;RETURN AND HALT ;ROUTINE TO SCAN MEMORY FOR PARITY OR NXM ERRORS (APR PI OR PI 7) ;CALLED AT APR PI IF MAY BE A SERIOUS ERROR IN MONITOR AND PIS IN PROGRESS ;CALL: ; MOVE J,CURRENT JOB NO. ON THIS CPU ; MOVE S,.CPAEF SWEEP REQUEST BITS ; PUSHJ P,PARSWP ; ALWAYS RETURNS - LH .CPMPC SET NEG. IF SERIOUS MONITOR PARITY ; S PRESERVED PARSWP::HRRZ U,.CPCTN## ;GET CPU'S CTY LINE NUMBER MOVE U,LINTAB##(U) ;NOW GET HIS LDB TRNN S,UE.PEF ;PARITY ERROR? JRST NXMSWP ;NO, SWEEP FOR NXM PUSHJ P,ANNSWP## ;YES, TELL OPR THAT A SWEEP IS IN PROGRESS SETOM .CPREP## ;TELL REPORTERS WHICH ERROR TYPE TO REPORT SETOM .CPPAA## ;YES, SET PARITY AND OF BAD ADDRESSES TO -1 SETOM .CPPAC## ;SET PARITY AND OF BAD CONTENTS TO -1 SETZM .CPPOA## ;SET PARITY OR OF BAD ADDRESSES TO 0 SETZM .CPPOC## ;SET PARITY OR OF BAD CONTENTS TO 0 AOS .CPPSC## ;INCREMENT PARITY SWEEP COUNT SETZM .CPPTS## ;SET NO OF PARITIES THIS SWEEP TO 0 IFN FTKL10,< PUSHJ P,SVPPC## ;DON'T LET FE TIME US OUT WHILE SWEEPING > PUSHJ P,APRMPS## ;CALL MEMORY SWEEP ROUTINE SETZM .CPLPP## ;CLEAR LAST PARITY ERROR PC SKIPE .CPPTS## ;WERE SOME BAD WORDS FOUND ON SWEEP? SKIPA T1,[EDELIM] ;YES--JUST GET END DELIMITER TEXT MOVEI T1,[ASCIZ /No parity errors were found. *************** /] ;NO--TELL THEM THAT PUSHJ P,CONMES## ;PRINT IT MOVEI T1,.ERSPR ;GET CODE FOR DAEMON HRL T1,.CPSLF## ;GET CPU CDB PUSHJ P,DAEEIM## ;POKE DAEMON SKIPE .CPPTS## ;IF SOME REAL ERRORS WERE FOUND POPJ P, ; THEN JUST RETURN NOW TLNN S,(CP.PSX) ;DID PROCESSOR DETECT PARITY? AOSA .CPPCS## ;NO, COUNT CHANNEL SPURIOUS COUNT AOS .CPSPE## ;YES, COUNT PROCESSOR SPURIOUS COUNT POPJ P, ;RETURN ;ROUTINE TO PRINT WHO REQUESTED SCAN, WHERE, AND AT WHAT TIME PRCHCP::TLNN S,(CP.PSX) ;REQUESTED BY CPU? JRST PRCHC1 ;NO--BY CHANNEL MOVEI T1,[ASCIZ /CPU/] PUSHJ P,CONMES## ;APPEND "CPU" MOVEI T1,5 ;START WITH CPU 5 MOVE T2,S ;COPY OF S PRCHC0: LSH T2,-1 ;NEXT CPU TLNN T2,(CP.PS5_-1) ;IS IT THIS CPU? SOJGE T1,PRCHC0 ;NO--TRY NEXT PUSHJ P,RADX10## ;YES--APPEND CPU NUMBER JRST PRCHC3 ;CONTINUE PRCHC1: MOVEI T1,[ASCIZ /channel /] PUSHJ P,CONMES## ;APPEND "CHANNEL" MOVEI T1,7 ;START WITH CHANNEL 7 MOVE T2,S ;COPY OF S PRCHC2: LSH T2,-1 ;NEXT CHANNEL TLNN T2,(CP.CS7_-1) ;IS IT THIS CHANNEL? SOJGE T1,PRCHC2 ;NO--TRY NEXT PUSHJ P,RADX10## ;YES--APPEND CHANNEL NUMBER PRCHC3: MOVEI T1,[ASCIZ / on /] PUSHJ P,CONMES## ;APPEND "ON" MOVE T2,.CPLOG## ;SCANNING CPU'S (THIS) NAME PUSHJ P,PRNAME## ;APPEND IT MOVEI T1,[ASCIZ / on /] PUSHJ P,CONMES## ;APPEND "ON" PUSHJ P,DATIME## ;AND THE DATE AND TIME PUSHJ P,PCRLF## ;FINISH WITH A CRLF POPJ P, ;RETURN ;SUBROUTINE TO SWEEP CORE LOOKING FOR NON-EXISTENT MEMORY NXMSWP: PUSHJ P,ANNSWP## ;ANNOUNCE SWEEP SETZM .CPLNA## ;ZERO HIGHEST NXM SEEN SETZM .CPREP## ;SET NXM FLAG SETOM .CPNAA## ;CLEAR AND OF NON-EXISTENT ADDRESSES SETZM .CPNOA## ; AND OR OF NON-EXISTENT ADDRESSES SETZM .CPNJA## ;NO JOBS AFFECTED YET AOS .CPNSC## ;INCREMENT THE NUMBER OF NXM SWEEPS DONE SETZM .CPNTS## ;CLEAR THE COUNT OF NXMS SEEN THIS SWEEP IFN FTKL10,< PUSHJ P,SVPPC## ;DON'T LET FE TIME US OUT > PUSHJ P,APRMPS## ;SWEEP MEMORY SETZM .CPLPP## ;CLEAR LAST ERROR PC SKIPE T1,.CPNTS## ;ANY NON-EXISTANT MEMORY SEEN? JRST [SOSE T1 ;ANY SEEN? PUSHJ P,PRTEMS ;YES, REPORT THEM MOVEI T1,EDELIM;GET ENDING MESSAGE JRST .+2] ;PRINT THAT MOVEI T1,[ASCIZ /No non-existent memory was found. *************** /] ;NO--TELL THEM THAT PUSHJ P,CONMES## ;PRINT IT MOVEI T1,.ERSNX ;GET DAEMON CODE HRL T1,.CPSLF## ;GET CPU CDB PUSHJ P,DAEEIM## ;POKE DAEMON SKIPE .CPNTS## ;IF SOME REAL ERRORS WERE FOUND POPJ P, ; THEN JUST RETURN NOW TLNE S,(CP.PSX) ;DID THE PROCESSOR SEE THE NXM? AOSA .CPSNE## ;YES, COUNT PROCESSOR SPURIOUS COUNT AOS .CPNCS## ;NO, COUNT SPURIOUS CHANNEL NXMS POPJ P, ;RETURN PRTEMS: MOVEI T1,[ASCIZ / to /] PUSHJ P,CONMES## ;PRINT END OF RANGE TEXT MOVE T1,.CPLNA## ;LAST NXM ADDRESS IN RANGE PUSHJ P,PRTDI8## ;PRINT HIGHEST NXM ADDRESS SEEN MOVEI T1,[ASCIZ / (phys.) /] PJRST CONMES## ;PRINT THAT ;DELIMITER TEXT FOR CTY SYSTEM ERROR MESSAGES SDELIM::ASCIZ / *************** / EDELIM::ASCIZ /*************** / ;SUBROUTINE TO RECORD MEM PARITY DATA FOR EACH BAD WORD ;CALL: MOVE T1,REL ADDR WITHIN HIGH OR LOW SEG, ; -1 IF NEITHER IN MONITOR NOR HIGH NOR LOW SEG ; MOVE P1,ABS ADR OF BAD WORD (22 BITS) ; MOVE S,.CPAEF FLAG BITS ; MOVE P2,CONTENTS OF BAD WORD ; PUSHJ P,PARRBD ;RECORD BAD DATA ; ALWAYS RETURN EVEN IF SERIOUS ERROR ;CALLED FROM CPU DPENDENT MEMORY SWEEP LOOP PARRBD::TRNN S,UE.PEF ;A PARITY ERROR? JRST NXMRBD ;NO, RECORD NXM AOS .CPTPE## ;INCREMENTATION NO OF MEM PARITY ERRORS FOR SYSTEM AOS T2,.CPPTS## ;INCREMENT NO OF PARITY ERRORS THIS SWEEP SOJG T2,PARSEC ;IS THIS THE FIRST ERROR THIS SWEEP? MOVEM P1,.CPMPA## ;YES, SAVE BAD ADDRESS MOVEM P2,.CPMPW## ;BAD CONTENTS MOVEI T1,[ASCIZ /Parity errors detected: /] PUSHJ P,CONMES## ;ANNOUNCE ERRORS SEEN PARSEC: MOVEI T1,[ASCIZ / at /] PUSHJ P,CONMES## ;PRINT "AT" MOVE T1,P1 ;BAD ADDRESS PUSHJ P,PRTDI8## ;PRINT IT MOVEI T1,[ASCIZ / (phys.), Contents = /] PUSHJ P,CONMES## ;PRINT MORE MESSAGE MOVE T1,P2 ;GET BAD CONTENTS PUSHJ P,HWDPNT## ;PRINT IT IFN FTKL10,< MOVEI T1,[ASCIZ /, ERA = /] PUSHJ P,CONMES## ;CONTINUE MESSAGE MOVE T1,.CPSTE## ;GET ERA FROM LAST SCAN TRAP PUSHJ P,HWDPNT## ;PRINT IT > PUSHJ P,CRLF## ;END WITH CRLF ANDM P1,.CPPAA## ;ACCUM AND OF BAD ADDRESSES THIS SWEEP ANDM P2,.CPPAC## ;ACCUM AND OF BAD CONTENTS THIS SWEEP IORM P1,.CPPOA## ;ACCUM OR OF BAD ADDRESSES THIS SWEEP IORM P2,.CPPOC## ;ACCUM OR OF BAD CONTENTS THIS SWEEP MOVE T2,.CPPTS## ;PARITY ERRORS FOUND ON CURRENT SCAN CAIG T2,M.CBAT## ;IS THERE ROOM FOR THIS BAD ADR IN TABLE? MOVEM P1,.CPBAT##-1(T2) ;YES, STORE IN I-TH POSITION IN CDB MOVEM P1,.CPLPA## ;ALWAYS STORE LAST PARITY ADDRESS POPJ P, ;RETURN ;HERE TO RECORD NON-EXISTANT MEMORY FOUND ON THE SWEEP NXMRBD: PUSH P,T1 ;SAVE T1 AOS .CPTNE## ;COUNT TOTAL NUMBER OF NXMS SEEN AOS T2,.CPNTS## ;COUNT UP THE NUMBER SEEN THIS SWEEP SOJG T2,NXMSEC ;JUMP IF NOT THE FIRST NXM THIS SWEEP MOVEM P1,.CPMNA## ;FIRST THIS SWEEP, RECORD BAD ADDRESS MOVEI T1,[ASCIZ /Non-existent memory detected: /] PUSHJ P,CONMES## ;ANNOUNCE ERRORS NXMSEC: SKIPN T2,.CPLNA## ;SEEN A NXM? JRST NXMSE1 ;NO AOS T2 ;CONTIGUOUS WITH PREVIOUS NON-EXISTANT WORD? CAMN P1,T2 ; ... JRST NXMSE2 ;NO, JUST RECORD PUSHJ P,PRTEMS ;YES, REPORT THE NXM RANGE NXMSE1: MOVEI T1,[ASCIZ / at /] PUSHJ P,CONMES## ;PRINT "AT" MOVE T1,P1 ;GET BAD ADDRESS PUSHJ P,PRTDI8## ;PRINT IT MOVEI T1,[ASCIZ / (phys.)/] PUSHJ P,CONMES## ;AND THIS NXMSE2: ANDM P1,.CPNAA## ;AND OF BAD ADDRESSES IORM P1,.CPNOA## ;OR OF BAD ADDRESSES MOVE T2,.CPNTS## ;NUMBER OF NXM'S SEEN ON CURRENT SCAN CAIG T2,M.CBAT## ;HAVE THE MAXIMUM NUMBER OF BAD ADDRESSES BEEN STORED? MOVEM P1,.CPBAT##-1(T2) ;NO, STORE THIS ONE MOVEM P1,.CPLNA## ;ALWAYS STORE THE LAST BAD ADDRESS MOVE T1,P1 ;BAD ADDRESS TO T1 LSH T1,W2PLSH ;CONVERT TO BAD PAGE IDIVI T1,^D36 ;36 BITS/WORD MOVE T2,BITTBL##(T2) ;BIT POSITION WITHIN THE WORD IORM T2,NXMTAB##(T1) ;MARK THIS PAGE AS NON-EXISTANT POP P,T1 ;RESTORE T1 JUMPE T1,CPOPJ## ;RETURN IF BAD ADDRESS NOT IN THE MONITOR OR A JOB JUMPN J,NXMJHS ;JUMP IF BAD ADDRESS IN SOME SEGMENT HRROS .CPMPC## ;BAD ADDRESS IS IN THE MONITOR, ; FLAG THIS AS A SERIOUS ERROR POPJ P, ;AND CONTINUE THE SWEEP NXMJHS: JUMPL J,NXMJH2 ;FLAG JOB IF IN UPMP CAILE J,JOBMAX## ;BAD ADDRESS IN A HIGH SEGMENT? PJRST HGHPAR## ;YES, FLAG HIGH SEGMENT AS IN NXM NXMJH2: MOVEI T1,JS.NXM ;BAD ADDRESS IN A LOW SEGMENT, FLAG IORM T1,JBTSTS##(J) ; THE JOB TO BE STOPPED POPJ P, ;AND RETURN TO CONTINUE THE SWEEP ;SUBROUTINE TO FLAG JOB FOR MESSAGE - IF APR DETECTED (RATHER THAN CHANNEL) ;CALL: MOVE J,JOB NUMBER ; MOVE S.CPAEF ;CPU OR CHAN DETECTED PARITY ; PUSHJ P,PARJOB ; ALWAYS RETURN ;CALLED ON CPU0 AND CPU1 PARJOB: TLNN S,(CP.PSX) ;PARITY FOUND BY ANY PROCESSOR? POPJ P, ;NO, RETURN ;YES, FALL INTO PARJB1 ;SUBROUTINE TO FLAG JOB FOR MEM PAR MESSAGE - ALWAYS ;CALL: MOVE J,JOB NUMBER ; PUSHJ P,PARJB1 ; ALWAYS RETURN PARJB1::MOVSI T1,JACCT ;CLEAR JACCT SO THAT DAMAGED PROGRAM ANDCAM T1,JBTSTS##(J) ; WILL NOT HAVE PRIVILEGES MOVEI T1,JS.MPE ;MEMORY PARITY ERROR IN JOB FLAG IORM T1,JBTSTS##(J) ;SET JOB STATUS WORD POPJ P, ;RETURN ;SUBROUTINE TO RETURN ALL JOBS WHICH ARE OR WOULD BE TOO BIG TO RUN ; IF MEMORY HAS DROPPED OFF LINE OR WERE TO BE SET OFF LINE ;CALLING SEQUENCE: ; MOVE T1,NEW VALUE OF CORMAX ; MOVEI J,0 ;FIRST CALL ; PUSHJ P,JBSTBG ;RETURN CPOPJ IF NO JOB OR NONE OF THE REMAINING JOBS ARE TOO BIG, CPOPJ1 ; IF A JOB IS TOO BIG, J = JOB NUMBER OF THE JOB WHICH IS TOO BIG JBSTBG::PUSH P,T1 ;SAVE THE NEW VALUE OF CORMAX JBSTB1: ADDI J,1 ;LOOK AT THE NEXT JOB CAMLE J,HIGHJB## ;LOOKED AT ALL JOBS? JRST TPOPJ## ;YES, GIVE ALL DONE RETURN PUSHJ P,SEGSIZ## ;SIZE OF THIS JOBS LOW SEGMENT PUSH P,T2 ;SAVE IT HRRZ T1,JBTSGN##(J) ;POINT TO SEGMENT CHAIN JUMPE T1,JBTSB4 ;NO SEGS PUSH P,J ;SAVE THE JOB NUMBER JBTSB2: SKIPLE J,.HBSGN(T1) ;SEGMENT WORD FOR THIS SEGMENT PUSHJ P,SEGSIZ## ;REAL, GET THE SIZE OF THE HIGH SEGMENT ADDM T2,-1(P) ;ADD IT IN HRRZ T1,.HBLNK(T1) ;POINT TO NEXT SEGMENT JUMPN T1,JBTSB2 ;LOOP ON POP P,J ;RESTORE THE JOB NUMBER JBTSB4: POP P,T1 ;RESTORE SUMMED SIZE LSH T1,P2WLSH ;SIZE OF THE JOB IN WORDS CAMLE T1,(P) ;IS THE JOB TOO BIG TO CONTINUE TO RUN? JRST TPOPJ1## ;YES, SKIP RETURN TO CALLER JRST JBSTB1 ;NO, LOOK AT THE NEXT JOB ;HERE IF NO MEM PARITY - MUST BE APR ERROR APRIL1: SETZM .CPAEF## ;CLEAR APR ERROR FLAG (IN CASE OTHER APR ERRORS ; OCCUR BEFORE EXIT THIS CODE) DMOVE T1,.CPAPC## ;ERROR PC STORED BY APR PI LEVEL ; (REAL PC MAY HAVE BEEN ZEROED TO DISMISS INT) DMOVEM T1,.CPPC## ;STORE IN CURRENT USER PROTECTED PC ; (SO DUMP WILL KNOW REAL PC) DMOVEM T1,.JDAT+JOBPD1## ;STORE FOR POSSIBLE .JBINT TRNE S,AP.PPV ;PROPRIETARY VIOLATION? JRST APRPPV ;YES TRNN S,AP.ILM ;ILLEGAL MEMORY? JRST APRNXM ;NO SIGNAL C$IMR ;SIGNAL ILL MEM REF CONDITION SKIPA ;USER DOESN'T WANT TRAP POPJ P, ;WANTS INTERCEPT GO TO USER MOVE T1,.CPAPC##+1 ;PC STORED BY APR INTERRUPT XOR T1,.USPFW ;PAGE FAULT WORD TDNE T1,[MXSECN*++PG.BDY] JRST APRILR ;YES, GO PRINT ILL MEM REF JSP T1,ERRPTU ;NO, PRINT PC EXCEEDS MEM BOUND ASCIZ /PC out of bounds/ JRST APRSCD ;PRINT LOC, THEN STOP JOB APRILR: JSP T1,ERRPTU ASCIZ /Illegal memory reference/ JRST APRSCD ;PRINT LOC, THEN STOP JOB APRNXM: TRNN S,AP.NXM ;NON-EX MEM? JRST APRPDL ;NO SIGNAL C$NXM ;SIGNAL JOB SKIPA ;NOT INTERRESTED POPJ P, ;TRAP TO USER SKIPE J,.CPJOB## ;JOB RUNNING WHEN NXM HAPPENED PUSHJ P,GIVRES ;RETURN RESOURCES, ETC. JSP T1,ERRPTU ;YES NXMMES::ASCIZ /Non-existent memory/ JRST APRSCD ;PRINT LOC, THEN STOP JOB APRPPV: JSP T1,ERRPTU ASCIZ /Proprietary violation/ JRST APRSCD ;SUBROUTINE TO PRINT JOB NUMBER AND PROG NAME ON OPR ;CALL: MOVEI T1,JOB STATUS BIT (JS.MPE OR JS.DPM) ; MOVE U,LINE DATA BLOCK FOR CTY OR OPR ; PUSHJ P,OPRPJN ;PRINT JOB NUMBERS ; ALWAYS RETURN OPRPJN: PUSH P,T1 ;SAVE JOB STATUS BIT TO TEST FOR MESSAGE PUSHJ P,INLMES## ;TELL HIM JOB NOS. SO HE WILL RESTART ; SYSTEM JOBS IF THEY HAVE PROBLEM ASCIZ / for job/ MOVE J,HIGHJB## ;HIGHEST JOB NUMBER ;LOOP TO PRINT JOB NOS. AND PROGRAM NAME OF ALL JOBS WITH BAD PARITY ; OR DAEMON PROBLEM MESS PARLP1: MOVE T1,JBTSTS##(J) ;JOB STATUS WORD TDNE T1,(P) ;DOES THIS JOB HAVE BAD PARITY OR DAEMON ; PROBLEM? (DEPENDING ON CALLERS ARG) PUSHJ P,PRJBNM ;YES, PRINT JOB# AND PROGRAM NAME SOJG J,PARLP1 ;ANY MORE JOBS? POP P,T1 ;RESTORE STACK PJRST CRLF## ;NO, PRINT CRLF AND RETURN ;SUBROUTINE TO PRINT SWAP OUT MEM PAR ERROR ;CALL: MOVE J,JOB USING HIGH SEG (WHETHER IN CORE OR NOT) ; PUSHJ P,SWOMES ; ALWAYS RETURN JOB SWAPPED, DAEMON CALLED SWOMES::MOVSI T1,JERR ;SET JERR SO WE DO NOT IORM T1,JBTSTS##(J) ;TRY TO INTERCEPT JSP T1,ERRPNT ;PRINT MESSAGE ASCIZ /Swap out channel memory parity error/ PJRST APRSCD ;PRINT PC AND STOP JOB ;SUBROUTINE TO PRINT JOB NO. [PROG. NAME] ;CALL: ; MOVE J,JOB NUMBER ; MOVE U,LDB FOR OPR OR CTY ; PUSHJ P,PRJBNM ;PRINT JOB NO. AND PROG. NAME ; ALWAYS RETURN PRJBNM::PUSHJ P,PRSPC## ;YES, PRINT LEADING SPACE MOVE T1,J ;PRINT JOB NO. PUSHJ P,RADX10## ;AS DECIMAL PUSHJ P,PRLBK## ;PRINT LEFT BRACKET MOVE T2,JBTPRG##(J) ;PROGRAM NAME PUSHJ P,PRNAME## ;PRINT SO OPER WILL RECOGNIZE HIS JOBS PJRST PRRBK## ;PRINT RIGHT BRACKET AND RETURN TO CALLER ;SUBROUTINE TO CHECK IF JOB HAS BEEN WAITING FOR TWO SUCCESSIVE ; MINUTE CHECKS FOR DAEMON. CALLED ONCE A MINUTE FOR EACH JOB ;CALL: MOVE J,JOB NUMBER ; PUSHJ P,DPMJOB ; YES RETURN - MESSAGE PRINTED ON JOB CONSOLE ; NO RETURN DPMJOB::MOVE T1,JBTSTS##(J) ;JOB STATUS WORD TRNN T1,JS.DPM ;THIS JOB BEEN WAITING FOR 2 CONSECUTIVE MIN? JRST CPOPJ1## ;NO PUSHJ P,STDAEM## ;START DAEMON PJRST DAEDON## ;NO DAEMON PUSHJ P,TTYFND## ;YES, FIND CONTROLLING TTY JUMPE U,CPOPJ## PUSHJ P,DAEPRB ;PRINT PROBLEM WITH DAEMON PUSHJ P,INLMES## ;TELL USER WHAT SYSTEM IS DOING ABOUT IT ASCIZ /, operator action requested / PJRST TTYSTR## ;START TTY ;SUBROUTINE TO PRINT ON OPR PROBLEM WITH DAEMON ;CALLED ONCE A MIN ONLY IF A JOB IS STILL WAITING ;CALL: PUSHJ P,DPMOPR DPMOPR::MOVE U,OPRLDB## ;OPR LINE DATA BLOCK HDR PUSHJ P,DAEPRB ;PRINT PROBLEM WITH DAEMON MOVEI T1,JS.DPM ;JOB STATUS BIT - NEED DAEMON PROB MESS. PJRST OPRPJN ;TELL OPR WHICH JOBS ARE STUCK ;SUBROUTINE TO PRINT PROBLEM WITH DAEMON ;CALL: MOVE U,LINE DATA BLOCK ADR ; PUSHJ P,DAEPRB DAEPRB: PJSP T1,CONMES## ;PRINT MESSAGE AND RETURN ASCIZ / %Problem with DAEMON/ APRPDL: TRNE S,AP.POV ;PUSHDOWN OVERFLOW? JRST PRTPOV ;YES - PRINT USER ERROR MESSAGE TRNN S,AP.FOV!AP.AOV ;ARITHMETIC OR FLOATING OVERFLOW? JRST APRLTH ;NO, SEE IF LOOP JSP T1,ERRPTU ;OUTPUT MESSAGE ASCIZ /Arithmetic overflow at extended/ JRST APRSCD ;GIVE PC APRLTH: TRNN S,XP.LTH ;LOOP IN TRAP HANDLER? STOPCD CPOPJ##,DEBUG,SAC, ;++STRANGE APR CONDITION JSP T1,ERRPTU ;TYPE MESSAGE ASCIZ /Loop in trap handler/ JRST APRSCD ;AND PC OF ERROR PRTPOV: SIGNAL C$PLOV ;SEE IF USER CARES SKIPA ;DOESN'T POPJ P, ;HE DOES JSP T1,ERRPTU ;PRINT ERROR MESSAGE PDLMES::ASCIZ /Push down list overflow/ APRSCD: DMOVE T1,.CPAPC## ;PRINT APR PC JRST DPCPNT ;AS: ; 1)"AT USER LOC XXX" OR ; 2)"AT EXEC LOC XXX; EXEC CALLED FROM ; EXEC/USER LOC YYY SUBTTL PDL OVERFLOW RECOVERY CODE ;THIS CODE WILL EXTEND A UUO LEVEL PDL; IT SHOULD BE JRSTD TO (IN SECTION 1 ;FOR FTXMON MONITORS) FROM K?SER ON A PDL OVERFLOW TRAP. THE PDL IS EXTENDED ;USING FUNNY SPACE. THE FOLLOWING RESTRICTIONS APPLY: ; ;1) IF SUFFICIENT FUNNY SPACE IS NOT AVAILABLE (INSUFFICIENT CONTIGUOUS ; FREE SLOTS, NO SWAP SPACE, ETC.) THE PDLOVF STOPCODE WILL STILL OCCUR. ; ;2) IF A PDL OVERFLOW OCCURS WHILE UP.EPL IS LIT IN .USBTS, THE CODE WILL ; NOT ATTEMPT TO RECOVER AND A PDLOVF STOPCODE WILL RESULT. THIS IS ; CURRENTLY TRUE ONLY WHILE THE JOB IS IN THE RECOVERY CODE ITSELF. ; ;ADDITIONALLY, THERE IS A THIRD RESTRICTION WHICH COULD BE REMOVED IF IT IS ;DEEMED NECESSARY, AND THE APPROPRIATE CHECKS ARE MADE: ; ;3) IF THE STACK IS ALREADY EXTENDED, WE WILL NOT ATTEMPT TO EXTEND THE ; STACK AGAIN. THE CODE CAN DO THIS, HOWEVER, IN ORDER TO DO THIS, IT ; IS NECESSARY TO MOVE THE ORIGIN OF THE STACK. PAGES ALLOCATED TO THE ; OLD STACK WILL BE RECLAIMED AT THAT TIME. CODE ELSEWHERE IN THE MONITOR ; WHICH PASSES AROUND AN ADDRESS ON THE STACK WILL THEREFORE NO LONGER ; POSSESS A VALID ADDRESS IN THAT POINTER. ALTHOUGH THE STACK IS MOVED ; FROM JOBPDO WHEN EXTENDED THE FIRST TIME, PAGES ARE NOT RECLAIMED SO ; ANY POINTERS THUS SET UP ARE STILL VALID EVEN THOUGH THE STACK HAS ; MOVED. TRVAR AND OTHER T-20 MACROS USE ONE AC FOR THIS PURPOSE (FP), ; THE ROUTINES AND MACROS WHICH SET UP AND CLEAR THE USE OF FP COULD ; SET FLAGS SO THAT CODE COULD BE ADDED TO THIS ROUTINE TO GET FP ADJUSTED ; IF THE STACK MOVES. THERE ARE, HOWEVER, OTHER PLACES (AT LEAST ONE ; IN FEDSER) WHICH ALSO WOULD NEED TO BE FIXED; THE EXISTENCE OF OTHER ; PLACES NEEDS ALSO TO BE RESEARCHED FURTHER BEFORE ANY OF THIS CAN ; BE IMPLEMENTED. ; ;TO REMOVE RESTRICTION THREE, REMOVE THE LINE OF CODE UNDER "REPEAT 1" AT ;EXTPDL+1 AND ADD THE APPROPRIATE CODE ENUMERATED IN RESTRICTION 3 ABOVE. EXTPDL:: MOVEI P,UP.EPL ;ARE WE ALREADY TRYING TO RECOVER? REPEAT 1,< ;UNTIL FRAME POINTERS EXIST, SKIPN .USEPL ;WE CAN'T MOVE AN EXTENDED STACK > ;(SEE COMMENTS ABOVE) TDNE P,.USBTS ;? JRST EPOSTP ;YES, ERROR IORM P,.USBTS ;FLAG IN EMERGENCY PDL DMOVEM T1,.CPSTT## ;SAVE A COUPLE OF ACS MOVE T1,.CPAPC##+1 ;GET PC MOVEM T1,.USMUP ;PUT IT BACK IN CASE WE NEED IT LATER MOVE T1,-1(T1) ;GET INSTRUCTION WHICH OVERFLOWED TLNN T1,(,>) ;BE SURE IT'S P THAT OVERFLOWED TLNN T1,() JRST EPOSTP ;NO, ERROR MOVE P,@.CPEPL## ;GET OVERFLOWED PDL HLRE T1,P ;MAKE IT ONLY OVERFLOW BY 1 WORD (ADJSP) MOVNS T1 ADJSP P,(T1) HRLI P,-EPDLEN ;THEN SET UP FOR EMERGENCY AREA DMOVE T1,.CPSTT PUSHJ P,EXTPD2 ;MUST DO THE FOLLOWING AS A SUBROUTINE MOVE P,@.CPEPL## ;REAL PDL TO RESTART USER WITH AOS EPOREC## ;INCREMENT # OF EPOS RECOVERED FROM XJRSTF .USMUO ;RESTORE FLAGS AND RETURN ;HERE TO DO THE REAL WORK OF EXTENDING THE STACK EXTPD2: PUSHJ P,SAVT## ;SAVE ALL TS MOVE T1,@.CPEPL## ;IN CASE IT GETS CHANGED WHEN WE BLOCK IFN FTMP,< PUSHJ P,MMOWN## ;OWN MM? PUSHJ P,GGVMM## ;NO, MUST HAVE IT FOR THE FOLLOWING > PUSH P,T1 ;SAVE OVERFLOWED STACK POINTER HLRZ T2,(P) ;MINIMUM # OF WORDS WE NEED -1 SKIPN T1,.USEPL ;IF MOVING FROM JOBPDO ADDI T2,PDLLEN ;INCLUDE PDLLEN HERE (TAKEN CARE OF LATER ;IF ALREADY EXTENDED) LSH T2,W2PLSH ;MINIMUM # OF PAGES WE NEED, -1 AOS T2 ;# OF PAGES WE NEED JUMPE T1,DOPDL2 ;NOT ALREADY EXTENDED, PROCEED MOVE T3,T2 ;SAVE IT HRRZS T1 ;CLEAR LEFT HALF LSH T1,W2PLSH ;PAGE # PREVIOUS TO PAGE WHERE EPL STARTS SUBI T1,FYSORG/PAGSIZ ;PAGE # RELATIVE TO FUNNY SPACE DOPDL0: SKIPE .UPMP+.UMORG(T1) ;IS PREVIOUS PAGE FREE? JRST DOPDL1 ;NO, MUST MOVE PDL AGAIN SOJLE T2,DOPDL7 ;YES, JUST USE PREVIOUS PAGE(S) SOJGE T1,DOPDL0 ;CHECK PREVIOUS PAGE IF THERE IS ONE DOPDL1: HLRE T2,.USEPL ;# OF WORDS IN CURRENT EXTENDED STACK ASH T2,W2PLSH ;CONVERT TO PAGES SUBM T3,T2 ;# OF ADDITIONAL PAGES WE NEED DOPDL2: MOVNI T2,(T2) MOVSI T2,(T2) ;AOBJN COUNTER MOVEI T1,.UMWSB-.UMORG-1 ;START LOOKING AT THE TOP OF FUNNY SPACE DOPDL3: SKIPN .UPMP+.UMORG(T1) ;IS THIS SLOT FREE? JRST DOPDL5 ;YES TRNN T2,-1 ;ALREADY STARTED A CONTIGUOUS BLOCK? JRST DOPDL4 ;NO MOVEI T3,(T2) ;RESET THE AOBJN POINTER HRLS T3 SUB T2,T3 DOPDL4: SOJGE T1,DOPDL3 ;NO, CHECK NEXT JRST EPOSTP ;FAILED DOPDL5: AOBJN T2,DOPDL4 ;CONTINUE IF NEED MORE PAGES TLOA T1,(1B0) ;FLAG WE ALREADY KNOW ENTIER PDL SIZE ;HERE WE HAVE FOUND ENOUGH PAGES TO EXTEND THE PDL. T3=# OF PAGES, T1=FIRST ;PAGE NUMBER RELATIVE TO BEGINNING OF FUNNY SPACE ;(WE ALSO FALL INTO THIS CODE FROM ABOVE WITH T2=# OF PAGES AND IGNORE THE ;FIRST INSTR WHICH LOADS T2 FROM T3) DOPDL7: MOVEI T2,(T3) ;GET # OF PAGES FROM T3 SETZ T3, ;CACHE IT PUSH P,T1 ;SAVE RELATIVE PAGE #+FLAG MOVEI T1,.MCFV/PAGSIZ(T1) ;PAGE # OF THE PAGE DESIRED PUSH P,T2 ;SAVE T2 (# OF PAGES REQUIRED) PUSHJ P,GETMPG## ;GET PAGES FOR THE JOB'S PDL JRST EPOSTP ;LOSE IF CAN'T ALLOCATE IT POP P,T2 ;RESTORE T2 (# OF PAGES ADDED) POP P,T1 ;RESTORE STARTING ADDRESS TLZE T1,(1B0) ;ADDED PAGES OR CREATED NEW SET? JRST DOPD12 ;CREATED NEW SET HLRE T3,.USEPL ;-# OF WORDS IN OLD STACK MOVNS T3 ;# OF WORDS IN OLD STACK MOVEI T3,PG.BDY(T3) ;FOR ROUNDING TO # OF PAGES LSH T3,W2PLSH ;PAGES ADD T2,T3 ;# OF PAGES IN NEW (EXTENDED) STACK TDZA T3,T3 ;FLAG NO DELETE OF OLD STACK ;HERE ON A NON-RECOVERABLE PDL OVERFLOW EPOSTP:: MOVE P,.CPEPL## ;GET NEW PDL POINTER HRLI P,- STOPCD .,JOB,PDLOVF, ;++EXEC PDL OVERFLOW ;HERE TO MOVE THE CURRENT PDL TO SOME NEW ADDRESS. T1 CONTAINS THE ;PAGE # RELATIVE TO FYSORG/PAGSIZ WHERE NEW STACK WILL BE, T2 CONTAINS # OF PAGES DOPD12: SETO T3, ;DELETE OLD STACK IF NOT JOBPDO MOVEI T1,FYSORG/PAGSIZ(T1) ;MAKE FIRST PAGE # LSHC T1,P2WLSH ;CONVERT TO WORDS PUSH P,T3 ;SAVE DELETE FLAG PUSH P,T2 ;SAVE # OF WORDS IN NEW STACK (INCLUDES EPDLEN) HRRZ T3,P ;FINAL WORD TO MOVE FROM PUSH P,T1 ;SAVE WORD ADDR SKIPN T4,.USEPL ;ALREADY EXTENDED? MOVEI T4,.JDAT+JOBPDL## ;NO, MOVE FROM JOBPDL HRLI T1,1(T4) ;MAKE BLT POINTER SUBI T3,1(T4) ;# OF WORDS TO MOVE ADDI T3,(T1) ;FINAL ADDRESS TO MOVE TO BLT T1,(T3) ;MOVE THE STACK SUBI T2,EPDLEN ;# OF WORDS IN NEW PDL (LEAVING EMERGENCY ROOM) MOVNS T2 ;-# OF WORDS POP P,T4 ;NEW STACK POINTER ORIGIN SOS T4 HRLI T4,(T2) ;NEW STACK POINTER COUNT MOVEI T1,(P) ;CURRENT ADDRESS OF OLD TOP OF STACK HRRI P,(T3) ;NEW STACK POINTER SUBI T3,(T1) ;NEW STACK-OLDSTACK ADDM T3,-2(P) ;UPDATE OVERFLOWED POINTER POP P,T1 ;TOTAL # OF WORDS IN NEW STACK SUBI T1,EPDLEN ;SUBTRACT OUT EMERGENCY ROOM SKIPN T3,.USEPL ;# OF WORDS IN OLD STACK MOVSI T3,MJOBPD## ;IF MOVING FROM JOBPDL HLLZS T3 ;-# WORDS IN OLD STACK,,0 MOVNS T1 ;-# OF WORDS IN NEW STACK HRLZS T1 ;-# OF WORDS IN NEW STACK,,0 SUB T1,T3 ;-NEW--OLD=OLD-NEW ADDM T1,-1(P) ;-OLD+(OLD-NEW)=-NEW POP P,T3 ;NODELETE FLAG POP P,@.CPEPL ;PUT IT FOR RECOVERY CODE TO FIND EXCH T4,.USEPL ;SET NEW STACK POINTER JUMPE T4,DOPD14 ;NO OLD PAGES TO DELETE JUMPE T3,DOPD14 PUSHJ P,SAVE2## AOS P1,T4 ;-# WORDS IN OLD STACK,,1ST PAGE ASH P1,W2PLSH ;-# PAGES IN OLD STACK,,JUNK(9)1ST PAGE(9) TRZ P1,-1^! ;CLEAR JUNK DOPD13: MOVEI P2,(P1) ;PAGE TO RETURN PUSHJ P,DLTFSP## ;DELETE FUNNY PAGE AOBJN P1,DOPD13 DOPD14: MOVEI T1,UP.EPL ANDCAM T1,.USBTS POPJ P, ;HERE TO GO BACK TO THE NORMAL STACK ;THIS MAY BE CALLED AT EITHER UUO OR CLOCK LEVEL, BUT IF CALLED ;AT CLOCK LEVEL THE CPU MUST POSSESS THE MM. ZAPEPL::SKIPN T1,.USEPL ;ANY EXTENDED STACK? POPJ P, ;NO, NOTHING TO DO THEN PUSHJ P,SAVE2## ;NEED TO USE THE PS MOVEI T1,1(T1) ;ADDRESS OF STACK HRLI P1,(T1) ;FIRST WORD TO MOVE FROM MOVEI P2,(T1) ;ONE MORE COPY PUSHJ P,INTLVL## ;IF AT UUO LEVEL, JRST ZAPEP0 ;TAKE STACK FROM CURRENT P SKIPN JBTADR##(J) ;IF THERE IS NO CORE FOR JOB JRST ZAPEP1 ;JUST GET RID OF THE PAGES HRRZ T3,.JDAT+JOBDAC##+P ;GET P FROM JOB DATA AREA JRST ZAPEP3 ZAPEP0: IFN FTMP,< PUSHJ P,MMOWN## ;OWN THE MM? PUSHJ P,GGVMM## ;GET IT IF WE DON'T > MOVEI T3,(P) ZAPEP3: CAIL T3,.JDAT+JOBPDL##+1 ;IS IT IN FUNNY SPACE OR .UUPMP? JRST ZAPEP1 ;.UUPMP, SOMEONE (COMCON) MUST HAVE PUT IT BACK SUBI T1,(T3) ;-# OF WORDS IN CURRENT STACK MOVNS T3,T1 ;NEGATE AND SAVE (MAKE POSITIVE) CAILE T1,PDLLEN ;ONLY GET RID OF EXTENDED STACK IF WHAT'S THERE FITS POPJ P, ADDI T1,.JDAT+JOBPDL##+1 ;LAST WORD TO MOVE TO HRRI P1,.JDAT+JOBPDL##+1 ;FIRST WORD TO MOVE FROM BLT P1,(T1) ;MOVE THE STACK MOVE T1,[MJOBPD##,,.JDAT+JOBPDL##] ADJSP T1,1(T3) ;MAKE CURRENT PUSHJ P,INTLVL## ;AT UUO LEVEL? SKIPA P,T1 ;YES, SET UP P MOVEM T1,.JDAT+JOBDAC##+P ;NO, STORE NEW P ZAPEP1: HLRE P1,.USEPL ;# OF WORDS IN EXTENDED PDL (NEGATIVE) SUBI P1,EPDLEN ;INCLUDING EMERGENCY WORDS LSH P1,^D18+W2PLSH ;-# OF PAGES LSH P2,W2PLSH ;1ST PAGE HRRI P1,(P2) ;SAVE IN P1 SE1ENT ZAPEP2: MOVEI P2,(P1) ;PAGE # PUSHJ P,DLTFSP## ;DELETE PAGE AOBJN P1,ZAPEP2 SETZM .USEPL ;NO MORE EXTENDED PDL POPJ P, ;ADDRESS CHECK ERROR AT ANY LEVEL ;F MUST BE SET UP TO POINT TO OFFENDING DEVICE ADRERR::LDB J,PJOBN## ;OFFENDING JOB'S JOB NUMBER PUSH P,F ;GIVRES CLOBBERS F PUSHJ P,GIVRES ;RETURN ANY RESOURCES THE JOB MIGHT HAVE POP P,F ;RESTORE F SIGNAL C$ADCK ;SEE IF USER ENABLED FOR ADDRESS CHECK SKIPA ;USER DOESN'T WANT TRAP JRST ERRGOU ;GO TO USER JSP T1,ERRDEV ;GET JOB NO. FROM DEVICE DATA BLOCK ASCIZ /Address check for / JRST DEVEXC ;PRINT "DEVICE XXX; EXEC CALLED FROM ; EXEC/USER LOC YYY" ; THEN STOP JOB ;SUBROUTINE TO CLEAR ALL DDB'S, IO CHARS ;CALL WITH JOB NUMBER IN J ZAPHIM: PUSHJ P,SVEUB## ;MAKE HIM ADDRESSABLE ZAPHER::PUSHJ P,SWPCLN## ;ZAP THE ACCESS TABLES PUSHJ P,GIVRSC ;GIVE UP RESOURCES PJRST ZAPUSC ;PITCH INITED DDB'S ZAPUSR::JUMPE J,CPOPJ## PUSHJ P,GIVRSC ;GIVE UP ANY INTERLOCKS JOB MAY OWN NTGIVE ;RELEASE NETSER INTERLOCK TOO CAMN J,.CPJOB## ;CURRENT JOB? POPJ P, ;YES, GIVE UP INITED DDB'S ON RESET ; (ALL SHARED RESOURCES ALREADY GIVEN UP) ZAPUSC::PUSHJ P,CTXJCJ## ;GET CURRENT CONTEXT NUMBER FOR TARGET JOB MOVEI T1,(J) ;??? PUSH P,T1 ;SAVE PUSHJ P,ZAPDSK## ;REMOVE ALL DDBS OWNED BY JOB FROM UNI/CHN Q'S IFN FTNET, ;AVIOD WEM STOPCODES ZAPUS1: HLRZ F,DEVLST## ;LOC OF FIRST DDB ZAPUS2: LDB T1,PJCHN## ;OWNER OF DDB JUMPE T1,ZAPUS3 ;DON'T TRY TO ZAP IT IF NOT OWNED (MPXDDB) MOVEI T2,DEPMSG ;IS THIS DDB CONTROLLED BY MPX TDNN T2,DEVMSG(F) ;IF SO, GIVE IT UP WHEN WE ZAP MPX CAME T1,(P) ;RIGHT GUY OWN IT JRST ZAPUS3 ;NO, DON'T RELEASE CAIE F,DSKDDB## ;NO, DON'T RELEASE IT (TRYING TO RELEASE DSKDDB ; WILL CAUSE AN IME PUSHJ P,RELEA4## ;YES, RELEASE IT JUMPE F,ZAPUS1 ;F=0 IF NETWORK DDB WAS RELEASED ZAPUS3: HLRZ F,DEVSER(F) JUMPN F,ZAPUS2 IFN FTNET, ;CLEAR FLAG JRST TPOPJ## ;PRUNE STACK AND RETURN ;SUBROUTINE TO RESET A JOB WHOSE ASSOCIATED ;HISEG HAD A SWAP INPUT ERROR ZAPHGH::SKIPN JBTADR##(J) POPJ P, PUSHJ P,CLRJOB## PUSHJ P,ZAPUSR PJRST ERRSWP ;SUBROUTINE TO RETURN ALL RESOURCES ;CALL WITH J=JOB# GIVRES::NTGIVE ;RETURN THE NETWORK INTERLOCK JUMPE J,CPOPJ## CAMN J,.CPJOB## ;NO DEVICES ACTIVE IF NOT CURRENT JOB PUSHJ P,IOWAIT## ;WAIT FOR ANY ACTIVE DEVICES TO FINISH GIVRSC::HLRZ F,SWPDDB##+DEVSER ;START AT FIRST DSK GIVRS0: MOVE T1,DEVMOD(F) ;IS THIS A DISK? TLNN T1,DVDSK SKIPGE DEVSPL(F) ;NO, SPOOLED DDB? CAIA ;YES JRST GIVRS3 ;NO MOVE S,DEVIOS(F) LDB T1,PJOBN## ;YES, THIS JOB OWN IT? CAMN T1,J PUSHJ P,RETRES## ;YES, RETURN ANY RESOURCES IT OWNS GIVRS3: PUSHJ P,NXDDB## ;AND TRY NEXT DDB JRST [JUMPE F,GIVRS1 ;DONE IF 0 CAMN J,.USJOB JRST GIVRS0 ;CONTINUE IF JOB IS ADDRESSABLE JRST GIVRS1] ;NEXT ADDRESSABLE - DONE JRST GIVRS0 ;TRY NEXT GIVRS1: SETZ T1, ;START WITH FIRST RESOURCE DPB T1,PJBSTS## ;MAKE SURE THAT JOB DOESN'T APPEAR ; TO HAVE ACTIVE DISK I/O GIVRS2: CAMN J,USRTAB##(T1) ;OWNED BY JOB? PUSHJ P,DVFREE##(T1) ;YES--FREE IT UP CAIGE T1,AVLNUM## ;DONE YET? AOJA T1,GIVRS2 ;NO--CONTINUE PUSHJ P,ADFREE## ;RETURN AU, DA, AND FA IF OWNED PUSHJ P,IPCULK## ;GIVE ANY IPCF INTERLOCK WE OWN PUSHJ P,DTXFRE## ;AND ANY DECTAPE KONTROLLERS PUSHJ P,DWNCX## ;CX IF OWNED PUSHJ P,TPFREE## ;FREE UP TAPE KONTROLLERS IFN FTKL10,< PUSHJ P,GIVPMR## ;DOES THIS JOB HAVE THE PERFORMANCE METER? ;NO, SO DON'T GIVE IT UP. ;YES, GIVE IT BACK SO OTHERS MAY MEASURE >;END IFN FTKL10 IFN FTLOCK,< PUSHJ P,UNLOCK## ;UNLOCK THE JOB IF LOCKED JFCL > POPJ P, ;RETURN NPDUFL::STOPCD .,STOP,NPU, ;++NULL PUSH-DOWN-LIST UNDERFLOW ;JSR TO HERE FROM INTRPT LOC $LOW PIERR::0 EXCH P,PIEPDL STOPCD .,CPU,PIE, ;++PRIORITY INTERRUPT ERROR PIEPDL::XWD 0,. BLOCK 1 $HIGH SUBTTL COMMON ROUTINES FOR HANDLING ERRORS IN MEMORY ;SUBROUTINE - ABSOLUTE ADDRESS TO SEGMENT NUMBER ;CALL: MOVE P1,ABSOLUTE ADDRESS ; PUSHJ P,CPIASN ; ERROR RETURN IF NOT IN MONITOR OR A HIGH OR LOW SEGMENT OR A UPMP ; OK RETURN J=0 IF IN MONITOR, OR HIGH OR LOW SEG NO., OR -J IF JOB'S UPMP ;ENTER AT CPIASP IF T1 ALREADY CONTAINS PAGE # CPIASN::LDB T1,[POINT 13,P1,26] ;SET REL. ADR. FROM ABS. ADR IN MONITOR CPIASP::SE1ENT ;PAGTAB LIVES IN MS.MEM, HAVE TO RUN EXTENDED MOVE T3,T1 ;AND IN CASE WE NEED IT... SETZB T2,J ;ASSUME IN MONITOR (JOB 0 NOT A LEGAL JOB #) MOVE T1,@[IW MS.MEM,PAGTAB(T1)] ;GET PAGTAB ENTRY FOR THIS PAGE TLNE T1,MONTRB ;IS THIS A MONITOR PAGE? JRST CPOPJ1## ;YES, GIVE OK RETURN WITH J=0 SSX T3,MS.MEM ;POINT TO MEMTAB SECTION MOVSI T1,(P2.TRN) ;TRANSIENT PAGE? TDNN T2,PT2TAB(T3) ;? JRST CPIAS2 ;NO LDB J,[POINT MT.SJB,MEMTAB(T3),^L+MT.SJB-1] ;GET JOB JRST CPOPJ1## ;FOUND JOB CPIAS2: HRRZ T2,PT2TAB(T3) ;POINT TO PREVIOUS PAGE JUMPE T2,CPIAS3 ;FOUND STARTING PAGE HRRI T3,(T2) ;POINT BACK ANOTHER PAGE JRST CPIAS2 CPIAS3: MOVEI T2,JOBMAX## ;SCAN TO SEE IF BAD ADDRESS IS IN A UPMP AUPLOP: HRRZ T1,JBTUPM##(T2) ;T1=PAGE NUMBER OF THE UPMP CAIE T1,(T3) ;BAD WORD IN THIS UPMP OR MAP? SOJG T2,AUPLOP ;NO, SCAN ALL USER PAGE MAP PAGES AUPLO1: JUMPG T2,[MOVN J,T2 ;IF YES, NEGATIVE JOB NUMBER TO J PJRST CPOPJ1##] ;SKIP RETURN MOVEI J,1 ;NOW SCAN ALL HIGH/LOW SEGS. STARTING WITH JOB 1 ASNLOP: SKIPN JBTADR##(J) ;IS THIS JOB OR HIGH SEG IN CORE? JRST ASNAOJ ;NO, LOOK AT THE NEXT SEGMENT MOVEI T1,0 ;ASSUME PARITY ERROR IS IN PAGE 0 OF THIS SEGMENT MOVSI T2,SHRSEG ;SHARABLE SEGMENT BIT CAILE J,JOBMAX## ;IS THIS A LOW SEGMENT? TDNE T2,JBTSTS##(J) ;NO--THEN IT IS A SHARABLE HIGH SEG? CAIA ;LOW SEG OR SHARABLE HIGH SEG JRST ASNAOJ LDB T2,JBYSSA## ;;GET FIRST PAGE OF SEGMENT CAIN T2,(T3) ;IS THIS PAGE THE SAME PAGE WHICH CONTAINED AN ERROR? JRST ASNMAP ;YES--SEE IF A MAP ASNAOJ: CAIG J,JBTMAX## ;LOOKED AT ALL SEGMENTS? AOJA J,ASNLOP ;NO, LOOK AT NEXT SEGMENT POPJ P, ;NOT IN MONITOR OR ANY JOB ASNMAP: CAILE J,JOBMAX ;A JOB? JRST CPOPJ1## ;NO, NOT A MAP IF A HIGH SEG PUSHJ P,SVEUB## ;MAP THIS USER MOVE T3,P1 ;GET WORD IN QUESTION AGAIN LSH T3,W2PLSH ;CONVERT TO PAGE MOVE T1,[-,,.UPMVP/PAGSIZ] AOBJP T1,CPOPJ1## ;NOT A MAP; S0 CAUGHT ABOVE SE1ENT ;FOR PAGE MAP REFERENCES SKIPA T4,[.UPMVP/PAGSIZ] ASNMP1: AOSA T4 ;INCREMENT PUSHJ P,GMPTR## ;GET ENTRY (FIRST TIME) MOVE T2,(T4) ;GET NEXT ENTRY TLZ T2,(PM.NAD^!PM.COR) TLZE T2,(PM.COR) ;IN-CORE POINTER? CAIE T2,(T3) ;AND THE ONE WE WANT? AOBJN T1,ASNMP1 ;NO, LOOK ON SKIPGE T1 ;FIND IT? MOVNS J ;YES, IS A MAP, NEGATIVE JOB # JRST CPOPJ1## ;SUBROUTINE TO CHECK IF THE PAGE IN T1 IS A HIGH SEG MAP. IF SO, RETURN ;CPOPJ1 WITH J CONTAINING AOBJN PTR FOR SEG IN QUESTION, ;ELSE J UNCHANGED WITH CPOPJ RETURN ;CALL WITH J=0 FIRST TIME, J=PREVIOUS POINTER RETURNED SUCCEEDING TIMES CKHMAP::PUSHJ P,SAVE1## ;SAVE P1 PUSH P,J ;SAVE J SKIPN J ;IF NOT FIRST TIME MOVE J,SEGPTR## ;POINT TO HIGH SEGS CKHM1: HRRZ T2,JBTUPM##(J) ;GET MAP CAIE T1,(T2) ;PAGE MATCH? AOBJN J,CKHM1 ;NO JUMPGE J,JPOPJ## ;NOT FOUND AS ANY HIGH SEG MAP MOVEM J,(P) ;RETURN THIS VALUE FOR J JRST JPOPJ1## ;GIVE GOOD RETURN ;SUBROUTINE TO FIX CORE ALLOCATION TABLES AFTER PAGES HAVE BEEN ; MARKED OUT IN NXMTAB DUE TO PARITY ERRORS OR NXM'S ;CALLING SEQUENCE: ; MAKE NXMTAB REFLECT CURRENT STATE OF MEMORY, GIVE BACK CORE ; BELONGING TO ALL SEGMENTS WHICH OVERLAP NXM, AND ; PUSHJ P,CPLNXF ;FIX UP RELEVANT TABLES AND VARIABLES ;RETURNS CPOPJ IF NEW VALUE OF CORMAX .LE. OLD VALUE OF CORMAX (SOME ; JOB MAY BE TOO BIG TO SWAP IN), CPOPJ1 IF ALL IS OK. ;MUST HAVE THE MM RESOURCE-CALLER'S RESPONSIBILITY CPINXF::SE1ENT ;PAGTAB AND MEMTAB ARE IN THE SKYSEG PUSHJ P,SAVE2## ;SAVE WORKING ACS SETZB T1,T2 ;INITIALIZE INDEXS INTO PAGTAB AND NXMTAB MOVSI T3,400000 ;FIRST BIT TO LOOK AT IN NXMTAB LDB T4,[POINT 14,MEMSIZ##,26] MOVSI P1,NXMBIT ;LOOK FOR NON-EXISTANT PAGES HRROI P2,-PAGSIZ ;DECREASE MAXMAX BY 1 PAGE FOR EACH NON-EXISTANT PAGE SEEN CPINX1: TDNN P1,@[IW MS.MEM,PAGTAB(T1)] ;PAGE ALREADY MARKED AS NON-EXISTANT? TDNN T3,NXMTAB##(T2) ;NO, IS IT NON-EXISTANT NOW? JRST CPINX2 ;NO, FORGE AHEAD SKIPL @[IW MS.MEM,PAGTAB(T1)] ;IS THIS NON-EXISTANT PAGE ON THE FREE CORE LIST? STOPCD .,STOP,NPN, ;++NON-EXISTANT PAGE NOT FREE ADDM P2,MAXMAX## ;DECREASE MAXMAX BY 1 PAGE ADDM P2,RMCMAX## ;AND REAL MAXIMUM CORMAX HLLM P1,@[IW MS.MEM,PAGTAB(T1)] ;AND MARK THIS PAGE AS NON-EXISTANT CPINX2: ADDI T1,1 ;NEXT PAGE ROT T3,-1 ;NEXT BIT POSITION IN NXMTAB SKIPG T3 ;CROSSED A WORD BOUNDARY? ADDI T2,1 ;YES, BUMP TO NEXT WORD IN NXMTAB SOJG T4,CPINX1 ;LOOP OVER ALL PAGES CPINX3: MOVE T1,PAGPTR## ;POINTER TO THE FREE CORE LIST JUMPE T1,CPINX5 ;JUMP IF THERE ARE CURRENTLY NO PAGES ON THE FREE LIST TDNN P1,@[IW MS.MEM,PAGTAB(T1)] ;IS THIS PAGE NOW NON-EXISTANT? JRST CPINX5 ;NO MOVE T2,@[IW MS.MEM,PAGTAB(T1)] ;YES, LINK FREE CORE LIST AROUND IT HRRZM T2,PAGPTR## ;STORE NEW FIRST PAGE ON FREE CORE LIST SOS CORTAL## ;DECREMENT COUNT OF POTENTIALLY FREE PAGES SOS BIGHOL## ;DECREMENT COUNT OF FREE PAGES JRST CPINX3 ;CONTINUE TO LOOK AT PAGES AT THE BEGINNING ; OF THE FREE CORE LIST CPINX4: HRRZ T1,T2 ;CURRENT INDEX INTO PAGTAB CPINX5: HRRZ T2,@[IW MS.MEM,PAGTAB(T1)] ;NEXT PAGE IN PAGTAB JUMPE T2,CPINX6 ;JUMP IF THIS IS THE END OF THE FREE CORE LIST CPNX5A: TDNN P1,@[IW MS.MEM,PAGTAB(T2)] ;IS THIS PAGE NOW NON-EXISTANT? JRST CPINX4 ;NO HRRZ T2,@[IW MS.MEM,PAGTAB(T2)] ;YES, LINK FREE CORE LIST AROUND IT HRRM T2,@[IW MS.MEM,PAGTAB(T1)] ; .. SOS CORTAL## ;DECREMENT THE COUNT OF POTENTIALLY FREE PAGES SOS BIGHOL## ;AND THE COUNT OF FREE PAGES SKIPE T2 HRRM T1,@[IW MS.MEM,PT2TAB(T2)] JUMPN T2,CPNX5A ;LOOP OVER THE ENTIER FREE CORE LIST CPINX6: MOVEI T1,0 ;INITIALIZE COUNT OF EXISTANT UNLOCKED PAGES MOVE T2,MEMSIZ## ;PREVIOUS HIGHEST ADDRESS + 1 SUB T2,SYSSIZ## ;RANGE OF USERS CORE LSH T2,W2PLSH ;NUMBER OF PAGES FROM TOP OF THE MONITOR ; TO THE PREVIOUS TOP OF MEMORY MOVE T3,SYSSIZ## ;WHERE TO START LOOKING FOR UNLOCKED EXISTANT PAGES LSH T3,W2PLSH ;PAGE NUMBER TO START AT CPINX7: MOVE P1,@[IW MS.MEM,PAGTAB(T3)] ;PAGE DESCRIPTOR BITS FROM PAGTAB TLNE P1,LKBITS-MONTRB;IS THIS PAGE LOCKED OR NON-EXISTANT? JRST CPINX8 ;YES, DON'T CONSIDER IT IN COMPUTING NEW CORMAX MOVEI T4,1(T3) ;HIGHEST EXISTANT PAGE + 1 THAT WAS SEEN TLNN P1,MONTRB ;IS THIS A MONITOR PAGE? ADDI T1,PAGSIZ ;NO, INCREASE NEW CORMAX BY ONE PAGE CPINX8: ADDI T3,1 ;NEXT PAGE IN PAGTAB SOJG T2,CPINX7 ;LOOP OVER ALL PAGES MOVEI T2,PAGTAB-1(T4) ;BYTE POINTER TO HIGHEST PAGE SSX T2,MS.MEM ;SECTION NUMBER IN LEFT HALF MOVEM T2,CORLST## ;STORE THAT FOR CHKTAL LSH T4,P2WLSH ;HIGHEST EXISTANT ADDRESS + 1 MOVEM T4,MEMSIZ## ;STORE THAT AS THE SIZE OF MEMORY MOVE T2,RMCMAX## ;REAL MAXIMUM CORMAX INCLUDING FUNNY SPACE CAMLE T1,T2 ;ROOM FOR FUNNY PAGES? MOVE T1,T2 ;NO, MAKE ROOM CAML T1,CORMAX## ;NEW CORMAX LESS THAN THE OLD CORMAX? AOSA (P) ;NO, INDICATE ALL JOBS CAN STILL RUN MOVEM T1,CORMAX## ;YES, STORE NEW VALUE OF CORMAX AND GIVE ; A NON-SKIP RETURN TO INDICATE THAT SOME ; JOBS MAY BE TOO LARGE TO BE SWAPPED IN POPJ P, ;RETURN SUBTTL ERROR REPORTING FOR CHANNEL ERRORS IFN FTKL10,< ;SUBROUTINE TO STORE CHANNEL DATA ON ALL HARD AND SOFT ERRORS ;CALL: MOVE F,DEVICE DATA BLOCK ADR ; MOVE U,UNIT DATA BLOCK ADR ; MOVE P1,CHANNEL DATA BLOCK ADDRESS(CHN'N'CB) ; MOVE T1,ADDRESS OF FIRST CCW IN CCW LIST ; PUSHJ P,CHEMPE OR CHENXM (MEMORY PARITY OR NXM) ; RETURN WILL ALL REGISTERS PRESERVED EXCEPT T1-T4 ;SUBROUTINE FOR MEMORY PARITY CHEMPE::AOS CHNMPE(P1) ;INCREMENT NO. OF MEM PARITY ERRORS PUSHJ P,SAVE4## ;SAVE P REGISTERS SETO P4, ;INDICATE PARITY ERROR JRST CHNCOM ;JOIN COMMON CODE ;SUBROUTINE FOR NXM CHENXM::AOS CHNNXM(P1) ;INCREMENT NO. OF NXMS PUSHJ P,SAVE4## ;SAVE P REGISTERS SETZ P4, ;INDICATE NXM ERROR CHNCOM: SETOM .CPCHE## ;FLAG CHANNEL ERROR CODE IS RUNNING HRRM U,CHNLUE(P1) ;SAVE UNIT DATA BLOCK ADR HRRM F,CHNLDE(P1) ;SAVE DEVICE DATA BLOCK ADR PUSH P,U ;SAVE U HRRZ U,.CPCTN## ;GET CPU'S CTY LINE NUMBER MOVE U,LINTAB##(U) ;GET CTY'S LDB PUSHJ P,CHNCCW ;COLLECT CCW DATA SKIPE P4 ;IS THIS A NXM ERROR? PUSHJ P,CHNDAT ;NO--COLLECT DATA WORDS ALSO MOVEI T1,SDELIM ;GET ADRESS OF TEXT PUSHJ P,CONMES## ;PRINT START DELIMITER MOVE T2,.CPLOG## ;GET THIS CPU'S NAME PUSHJ P,PRNAME## ;PRINT IT SKIPE P4 ;NXM ERROR? SKIPA T1,[[ASCIZ / channel memory parity error on /]] ;NO--PARITY ERROR MOVEI T1,[ASCIZ / channel non-existent memory error on /] ; YES--NXM PUSHJ P,CONMES## ;PRINT ERROR TYPE PUSHJ P,DATIME## ;APPEND DATE AND TIME PUSHJ P,PCRLF## ;AND A CRLF MOVEI T1,[ASCIZ /Device in use is /] ;GET TEXT PUSHJ P,CONMES## ;PRINT DEVICE PREFIX MESSAGE MOVE T2,DEVMOD(F) ;GET DEVICES CHARACTERISTICS HRR T2,CHNLUE(P1) ;UDB OF DEVICE WHERE ERROR HAPPENED TLNE T2,DVDSK ;IS THIS A DISK? SKIPA T2,(T2) ;YES--GET NAME FROM UDB MOVE T2,DEVNAM(F) ;NO--GET DEVICE NAME FROM DDB PUSHJ P,PRNAME## ;APPEND IT MOVEI T1,[ASCIZ / Channel type is /] ;GET TEXT PUSHJ P,CONMES## ;PRINT CHANNEL TYPE PREFIX MESSAGE MOVE T2,CHNTYP(P1) ;GET CHANNEL TYPE BITS MOVEI T1,[ASCIZ /DF10-C/] ;ASSUME A DF10-C TLNE T2,CP.DX1 ;IS IT A DX10? MOVEI T1,[ASCIZ /DX10/] ;YES--GET ITS TEXT TLNE T2,CP.RH2 ;IS IT AN RH20? MOVEI T1,[ASCIZ /RH20/] ;YES--GET ITS TEXT TLNE T2,CP.KLP ;IS IT A KLIPA? MOVEI T1,[ASCIZ /CI20/] ;YES--GET ITS TEXT TLNE T2,CP.KNI ;IS IT A KLNI? MOVEI T1,[ASCIZ /NIA20/] ;YES--GET ITS TEXT TLNE T2,CP.SAX ;IS IT AN SA10? MOVEI T1,[ASCIZ /SA10/] ;YES--GET ITS TEXT PUSHJ P,CONMES## ;APPEND CHANNEL TYPE MOVEI T1,[ASCIZ / Termination channel program address = /] ;GET TEXT PUSHJ P,CONMES## ;PRINT TERM. CCW ADDRESS MESSAGE HLRZ T1,CHNFCW(P1) ;GET LH TERMINATION CCW LSH T1,-4 ;ONLY 14 BITS ARE CCW ADDRESS PUSHJ P,OCTPNT## ;PRINT IT MOVEI T1,[ASCIZ / Termination data transfer address = /] ;GET TEXT PUSHJ P,CONMES## ;PRINT TERM. DATA ADDRESS MESSAGE MOVE T1,CHNFCW(P1) ;GET RH TERMINATION CCW TLZ T1,777760 ;GET JUST DATA ADDRESS (22 BITS) PUSHJ P,PRT22A## ;PRINT IT MOVEI T1,[ASCIZ / Last three channel commands executed are: /] PUSHJ P,CONMES## ;PRINT THIS MOVE T1,CHNCW0(P1) ;ARE ALL CCW'S ZERO? IOR T1,CHNCW1(P1) ;... IOR T1,CHNCW2(P1) ;... SKIPE T1 ;... JRST CHNCO1 ;NO--GO PRINT THEM OUT PUSHJ P,PR3SPC## ;YES--INDENT MOVEI T1,[ASCIZ /** Indeterminate ** /] PUSHJ P,CONMES## ;TELL THEM WE DON'T KNOW JRST CHNCO3 ;CONTINUE CHNCO1: MOVSI P2,-3 ;FORM AOBJN POINTER HRRI P2,CHNCW2(P1) ; TO SAVED CCW'S CHNCO2: PUSHJ P,PR3SPC## ;INDENT MOVE T1,(P2) ;PICK UP CCW PUSHJ P,HWDPNT## ;PRINT IT PUSHJ P,CRLF## ;PRINT CRLF AOBJN P2,CHNCO2 ;LOOP IF MORE CHNCO3: MOVEI T1,EDELIM ;GET ENDING DELIMITER PUSHJ P,CONMES## ;PRINT IT POP P,U ;RESTORE U SETZM .CPCHE## ;CLEAR CHANNEL ERROR IN PROGRESS FLAG MOVEI T1,.ERCPE ;CHANNEL ERROR CODE HRL T1,P1 ;GET CDB ADDRESS PUSH P,J ;SAVE J PUSHJ P,DAEEIM## ;POKE DAEMON POP P,J ;RESTORE J POPJ P, ;RETURN ;ROUTINE TO STORE CCW DATA FOR CHANNEL ERRORS CHNCCW: MOVE T3,CHNTYP(P1) ;PICK UP CHANNEL TYPE BITS MOVE T2,0(T1) ;GET FIRST CCW IN LIST MOVEM T2,CHNICW(P1) ;SAVE IN CDB FOR F.S. TLNN T3,CP.RH2 ;IS THIS AN RH20? JRST CHNCC1 ;NO--PROCEED HRRZ T2,1(T1) ;YES--GET LAST CCW ADDR + 1 MOVE P3,2(T1) ;GET TERMINATION CCW MOVEM P3,CHNFCW(P1) ;SAVE IN CDB FOR F.S. JRST CHNCC4 ;CONTINUE CHNCC1: TLNN T3,CP.DX1 ;IS THIS A DX10? JRST CHNCC2 ;NO--PROCEED DPB P2,[POINT 14,P3,13] ;YES--COMBINE IN TERM. CHANNEL PROGRAM COUNTER JRST CHNCC3 ;CONTINUE CHNCC2: MOVE P3,1(T1) ;GET TERMINATION CCW FOR DF10/DF10-C CHNCC3: MOVEM P3,CHNFCW(P1) ;SAVE IN CDB FOR F.S. HLRZ T2,P3 ;GET ADDRESS OF LAST CCW LSH T2,-4 ;ONLY 14 BITS ARE CCW ADDRESS CHNCC4: TLNE T3,CP.RH2 ;IS THIS AN RH20? SOS T2 ;BACK UP LAST CCW ADDRESS BY 1 MOVE P2,T2 ;SAVE REAL FINAL CCW ADDRESS HERE CAIL T2,2 ;IS FIRST SOURCE ABOVE LOC 0? CAML T2,MEMSIZ## ;YES, IS LAST SOURCE ADR IN BOUNDS? JRST CHNCC6 ;NO--JUNK DATA, DON'T ATTEMPT RETRIEVAL CHNCC5: MOVE P3,CHNCW0(P1) ;PUSH EVERYBODY DOWN ONE EXCH P3,CHNCW1(P1) ;... MOVEM P3,CHNCW2(P1) ;... MOVE P3,(T1) ;GET THIS CCW MOVEM P3,CHNCW0(P1) ; AND SAVE AS LAST CCW CAMN P2,T1 ;DOES ITS ADDRESS MATCH THE CHANNEL TERM ADDR? JRST CHNCC7 ;YES--WE'RE DONE, STOP CHASING LIST TLNE P3,577777 ;IS CCW A DATA TRANSFER? AOJA T1,CHNCC5 ;YES--BUMP CCW ADDRESS AND GO AROUND AGAIN JUMPE P3,CHNCC6 ;NO--IF IT'S A HALT, WE'VE RUN OUT UNEXPECTEDLY TLNE T3,CP.DX1 ;IS THIS A DX10? TLNE P3,200000 ;YES--IS THIS A DX10 DEVICE COMMAND CCW? SKIPA ;NO--NOT DX10 OR IT'S A DX10 JUMP AOJA T1,CHNCC5 ;YES--BUMP CCW ADDRESS AND GO AROUND AGAIN MOVE T1,(T1) ;IT'S A JUMP, GET NEXT CCW ADDRESS TLZ T1,777760 ;GET JUST ADDRESS (22-BITS) JRST CHNCC5 ; AND GO AROUND AGAIN CHNCC6: SETZM CHNCW2(P1) ;ZERO THE CCW LOCATIONS SETZM CHNCW1(P1) ;... SETZM CHNCW0(P1) ;... CHNCC7: MOVE T2,CHNTCW(P1) ;GET EXPECTED TERMINATION CCW MOVEM T2,CHNETW(P1) ;SAVE FOR F.S. POPJ P, ;RETURN ;HERE TO COLLECT RELEVANT DATA WORDS ON PARITY ERROR CHNDAT: MOVE T4,CHNFCW(P1) ;GET TERMINATION CCW TLZ T4,777760 ;GET JUST ADDRESS (22-BITS) CAIL T4,2 ;IS LAST DATA ADR ABOVE 0? CAML T4,MEMSIZ## ;YES, IS IT IN BOUNDS? JRST CHNDA2 ;NO--JUNK DATA, DON'T ATTEMPT RETRIEVAL PUSHJ P,MAPLOC ;GET EVA SLOT SUBI T4,2 ;BACK UP STARTING ADDRESS BY TWO MOVEI P2,CHNDW2(P1) ;PLACE TO STORE DATA WORDS HRLI P2,-3 ;MAKE AOBJN PNTR CHNDA1: LDB P3,[POINT 13,T4,26] ;GET PAGE NUMBER TLO P3,(B2+PM.WRT+PM.PUB) ;BITS DPB P3,T1 ;MAP THIS PAGE CLRPGT ;CLEAR PAGING MEMORY DPB T4,[POINT 9,T3,35] ;SET LINE # IN PAGE MOVE P3,(T3) ;FETCH DATA WORD MOVEM P3,(P2) ;STASH IN CDB ADDI T4,1 ;ADVANCE TO NEXT LOC AOBJN P2,CHNDA1 ;LOOP TILL DONE MOVEI T2,^D50 ;WAIT FOR ANY PARITY INTERRUPTS SOJG T2,. ;TO HAPPEN (IF ANY) PUSHJ P,UNMAP ;RESTORE EXEC MAP SLOT POPJ P, ;AND RETURN CHNDA2: SETZM CHNDW0(P1) ;ZERO THE DATA LOCATIONS SETZM CHNDW1(P1) ;... SETZM CHNDW2(P1) ;... POPJ P, ;RETURN >;END IFN FTKL10 IFN FTKS10,< CHEMPE:: CHENXM::POPJ P, >;END IFN FTKS10 ;ROUTINE TO MAKE AVAILABLE A PAGE MAP SLOT IN EVA SPACE ;MAY BE CALLED AT UUO OR INTERRUPT LEVEL ;CALLING SEQUENCE: ; PUSHJ P,MAPLOC ; RETURN HERE ; C(T1) := BYTE PNTR TO EPMP SLOT ; C(T3) := VIRTUAL ADDRESS OF START OF MAPPED PAGE ;CALL UNMAP TO RETORE PREVIOUS CONTENTS OF THE MAP SLOT MAPLOC::MOVE T3,.CPMAP## ;ADDRESS OF CURRENT CPU'S EXEC MAP MOVE T1,[POINT 36,.ERPIL/PAGSIZ,35] ADD T1,T3 MOVE T2,.ERPIL/PAGSIZ(T3) ;CURRENT CONTENTS OF THE MAP SLOT EXCH T2,(P) ;SAVE CURRENT CONTENTS OF THE MAP SLOT MOVEI T3,.ERPIL ;VIRTUAL ADDRESS OF THE PAGE TO BE RETURNED PJRST (T2) ;AND RETURN ;ROUTINE TO RESTORE THE CONTENTS OF A MAP SLOT AFTER HAVING CALLED MAPLOC ;CALLING SEQUENCE: ; PUSHJ P,UNMAP ; RETURNS HERE ;PRESERVES ALL ACS UNMAP:: EXCH T1,-1(P) ;GET PREVIOUS CONTENTS OF THE MAP PUSH P,T2 ;SAVE A WORKING AC MOVE T2,.CPMAP## ;ADDRESS OF THIS CPU'S EXEC MAP MOVEM T1,.ERPIL/PAGSIZ(T2) ;RESTORE MAP SLOT CONTENTS POP P,T2 CLRPT .ERPIL ;MAKE OLD MAPPING VISABLE AGAIN POP P,T1 ;RETURN ADDRESS EXCH T1,(P) ;RESTORE T1, STORE RETURN ADDRESS ON STACK POPJ P, ;AND RETURN SUBTTL SYSTEM ERROR BLOCK SUPPORT ;ROUTINE TO ALLOCATE A SYSTEM ERROR BLOCK. ;CALL: ; T1/ LENGTH OF DATA SEGMENT (NOT INCLUDING HEADER) ; PUSHJ P,ALCSEB ;RETURN: ; CPOPJ IF CAN'T ALLOCATE BLOCK ; CPOPJ1 IF BLOCK ALLOCATED WITH: ; T1/ ADDRESS OF ERROR BLOCK $CSENT (ALCSEB::) SKIPE DINITF## ;OUT OF ONCE CODE YET? POPJ P, ;NO, TAKE IMMEDIATE ERROR RETURN IFN FTXMON,< PUSHJ P,SSEC0## ;GET OUT OF SECTION 1 IF NECESSARY >; END IFN FTXMON PUSH P,T1 ;SAVE THE LENGTH MOVEI T2,.EBHDR(T1) ;LENGTH INCLUDING HEADER TO T2 PUSHJ P,GETWDS## ;GET SOME SECTION 0 SPACE JRST TPOPJ## ;ERROR, CLEAN STACK AND RETURN POP P,T2 ;GET LENGTH BACK HRRZM T2,.EBTYP(T1) ;STORE IN TYPE WORD MOVEI T2,.EBHDR-.EBTYP ;LENGTH OF HEADER DPB T2,[POINT 3,.EBTYP(T1),26] ;STORE HEADER LENGTH MOVE T2,DATE## ;GET NOW IN UNIVERSAL FORMAT MOVEM T2,.EBDTM(T1) ;STORE MOVE T2,SYSUPT## ;GET SYSTEM UPTIME SETZ T3, ;CLEAR FOR ASHC ASHC T2,-^D17 ;JIFFIES*2**18 IN T3 MOVE T4,TICSEC## ;TICKS PER SECOND IMULI T4,^D24*^D3600 DIV T2,T4 ;DAYS IN LH, FRACTION IN RH MOVEM T2,.EBUPT(T1) ;STORE MOVE T2,.CPASN## ;GET APR SERIAL NUMBER OF THIS CPU MOVEM T2,.EBASN(T1) ;STORE JRST CPOPJ1## ;SKIP RETURN ;ROUTINE TO QUEUE A SYSTEM ERROR BLOCK TO DAEMON. ;CALL: ; T1/ ADDRESS OF ERROR BLOCK ; PUSHJ P,QUESEB ;RETURN: ; CPOPJ ALWAYS $CSENT (QUESEB::) CONI PI,T2 ;READ PI STATUS CONO PI,PI.OFF ;TURN OFF INTERRUPTS IFN FTMP,< SKIPGE SEQLOK ;GIVE OTHER CPUS A CHANCE AOSE SEQLOK ;GET THE INTERLOCK JRST .-2 ;WAIT >; END IFN FTMP SETZM .EBLNK(T1) ;MAKE SURE LINK TO NEXT BLOCK IS ZERO MOVEM T1,@SEQBOT ;APPEND THIS ENTRY TO BOTTOM OF QUEUE MOVEM T1,SEQBOT ;MAKE THIS THE NEW LAST ENTRY IFN FTMP,< SETOM SEQLOK ;RELEASE THE INTERLOCK >; END IFN FTMP TRNE T2,PI.ON ;WAS PI SYSTEM ON BEFORE? CONO PI,PI.ON ;YES, TURN IT BACK ON S0PSHJ STDAEM## ;PROD THE DEVIL INTO ACTION JFCL ;DON'T CARE IF HE'S NOT THERE POPJ P, ;RETURN $LOW SEQTOP::0 ;POINTER TO FIRST ENTRY IN QUEUE SEQBOT: SEQTOP ;POINTER TO LAST ENTRY IN QUEUE IFN FTMP,< SEQLOK: -1 ;INTERLOCK >; END IFN FTMP $HIGH ;SEBLK. UUO USED BY DAEMON TO RETURN THE NEXT ERROR BLOCK FROM THE ;SYSTEM ERROR BLOCK QUEUE. THE BLOCK IS COPIED INTO THE CALLER'S ;ARGUMENT BLOCK, AND TRUNCATED IF NECESSARY. ;CALL: ; MOVE AC,[LENGTH,,ADDRESS] ; SEBLK. AC, ; ERROR RETURN, AC/ ZERO ; NORMAL RETURN, AC/ LENGTH OF BLOCK USEBLK::PUSHJ P,PRVJ## ;IS THIS GUY PRIVILEGED? SKIPA ;YES JRST RTZER## ;NO, RETURN A ZERO HLRE T2,T1 ;GET LENGTH OF CALLER'S ARGUMENT BLOCK CAIG T2,.EBHDR ;ROOM FOR AT LEAST A ONE WORD ENTRY? JRST UADERR ;NO, ZAP THE FOOL CONO PI,PI.OFF ;PREVENT RACES IFN FTMP,< SKIPGE SEQLOK ;GIVE OTHER CPUS A CHANCE AOSE SEQLOK ;GET THE INTERLOCK JRST .-2 ;WAIT >; END IFN FTMP SKIPN T2,SEQTOP ;IS THERE A FIRST ENTRY? JRST SEBLK2 ;NO MOVE T2,.EBLNK(T2) ;GET LINK TO NEXT BLOCK JUMPN T2,SEBLK1 ;JUMP IF MORE ENTRIES IN QUEUE MOVEI T3,SEQTOP ;QUEUE NOW EMPTY, RESET BOTTOM POINTER MOVEM T3,SEQBOT ;... SEBLK1: EXCH T2,SEQTOP ;SAVE NEW FIRST BLOCK ADDRESS, GET OLD SEBLK2: IFN FTMP,< SETOM SEQLOK ;RELEASE INTERLOCK >; END IFN FTMP CONO PI,PI.ON ;ALLOW INTERRUPTS AGAIN JUMPE T2,ECOD1## ;RETURN AN ERROR IF NO BLOCKS QUEUED HLRE T4,T1 ;GET LENGTH OF CALLER'S ARGUMENT BLOCK AGAIN LDB T3,[POINT 9,.EBTYP(T2),35] ;GET LENGTH OF ERROR BLOCK BODY ADDI T3,.EBHDR-.EBTYP ;INCLUDE HEADER LENGTH PUSH P,T3 ;SAVE LENGTH FOR RETURN TO USER CAMGE T3,T4 ;IF ERROR BLOCK LONGER THAN USER'S BLOCK, MOVE T4,T3 ; ONLY COPY AS MUCH AS THEY CAN HANDLE HRRZS T1 ;KEEP JUST CALLER'S ADDRESS ADD T4,T1 ;COMPUTE END ADDRESS HRLI T1,.EBTYP(T2) ;SOURCE ADDRESS OF ERROR BLOCK HEADER EXCTXU ;COPY THE ERROR BLOCK TO THE USER ERJMP SEBLK3 ;ADDRESS CHECK, NAUGHTY USER LDB T1,[POINT 9,.EBTYP(T2),35] ;GET LENGTH OF ERROR BLOCK BODY ADDI T1,.EBHDR ;INCLUDE HEADER AND LINK WORD PUSHJ P,GIVWDS## ;RETURN THE BLOCK TO FREE CORE POP P,T1 ;RESTORE THE LENGTH OF THE BLOCK PJRST STOTC1## ;STORE IN USER'S AC AND SKIP RETURN SEBLK3: LDB T1,[POINT 9,.EBTYP(T2),35] ;GET LENGTH OF ERROR BLOCK BODY ADDI T1,.EBHDR ;INCLUDE HEADER AND LINK WORD PUSHJ P,GIVWDS## ;RETURN THE BLOCK TO FREE CORE JRST UADERR ;ZAP THE NAUGHTY USER SUBTTL STOPCODE PROCESSING ;ROUTINE TO RECOVER/RELOAD AFTER AN INTERNAL ; SYSTEM ERROR. CALLED ONLY BY STOPCD MACRO ; (SEE S.MAC) WITH: ; PUSHJ P,DIE ; ;SEE ALSO ROUTINE PERISH $CSUB ;MUST BE ADDRESSABLE BY ALL CODE SEGMENTS DIE:: AOSE .CPDWD## ;INTERLOCK STOPCD CODE STOPCD .,HALT,REH, ;++RECURSION IN ERROR HANDLER POP P,.CPSPC##+1 ;GET PC OF STOPCD XSFM .CPSPC## ; AND FLAGS JRST @[0,,DIE0] ;JOIN COMMON CODE ;ANOTHER ROUTINE TO RECOVER/RELOAD AFTER AN INTERNAL SYSTEM ERROR. ; CALLED ONLY BY TRAPCD MACRO (SEE S.MAC) WITH: ; ; XPCW CROAK ;(CROAK IS PSUEDONYM FOR .CPSPC) ; ;SEE ALSO ROUTINE DIE $HIGH ;REACHED ONLY IN SECTION 0 PERISH::AOSE .CPDWD## ;INTERLOCK STOPCD CODE STOPCD .,HALT,RID, ;++RECURSION IN DIE ; JRST @[0,,DIE0] ;JOIN COMMON CODE [ALREADY IN SECTION 0] ;RUNNING IN SECTION 0 DIE0: SKIPE .UONCE## ;IS THIS USRONC? JRST DIE00 ;YES--SKIP THE ILLEGAL UUOS CONI PI,.CPCPI## ;SAVE STATE OF MACHINE CONO PI,PI.TFP+177 ; .. JSR .CPSVA## ;SAVE ALL AC SETS JRST DIE001 ;SKIP USER-MODE STUFF DIE00: MOVEM 17,CRSHAC##+17 ;SAVE AN AC MOVEI 17,CRSHAC## ;POINT TO SAVE ACS BLOCK MOVEM 17,.CPACA## ;NOTE WHERE WE'RE SAVING THE ACS BLT 17,CRSHAC##+16 ;SAVE THE REST DIE001: MOVSI T1,^-MXSECN ;MASK OF EVERYTHING BUT PC COUNTER ANDCAB T1,.CPSPC##+1 ;CLEAR SPURIOUS BITS IFN FTXMON,< TLNE T1,MXSECN ;STOPCODE IN NON-ZERO SECTION? XJRST [MCSEC1+DIE01] ;YES, ENTER SECTION 1 FOR STOPCODE PROCESSING >; END IFN FTXMON ;RUNNING IN SECTION 1 DIE01: SKIPE .UONCE## ;IF USER-MODE, JRST DIE01A ;CAN'T REFERENCE .UPMP HRLZ T1,.USMUO ;GET MUUO OPCODE AND AC IOR T1,.USMUE ;INCLUDE EFFECTIVE ADDRESS MOVEM T1,.CPTRP## ;STORE DIE01A: SKIPN T1,.CPSPC##+1 ;GET PC OF STOPCD MOVEI T1,DIEBPC+1 ;POINT AT A GENERIC STOPCODE MOVEM T1,.CPSUP## ;STORE IN CDB MOVE M,-1(T1) ;GET XCT INSTRUCTION TLC M,(XCT) ;CLEAR THE XCT OUT OF WORD TLNE M,-1 ;MAKE SURE NOTHING IS LEFT MOVEI M,DIEBAD ;OOPS. SOMETHING BAD, POINT TO GENERIC RELOAD. IFN FTXMON,< HLL M,.CPSPC##+1 ;GET SECTION OF STOPCODE >; END IFN FTXMON MOVE P,.CPEPD## ;SET UP ERROR STACK LDB T1,[POINT 4,2(M),17] ;GET STOPCODE TYPE CAIL T1,S$STOP ;IS IT IN RANGE? CAILE T1,STPMAX ;BOTH WAYS? MOVEI T1,S$STOP ;BAD--DON'T MAKE THINGS WORSE MOVEM T1,.CPSTY## ;SAVE AS LAST STOPCODE TYPE SKIPE .UONCE## ;IS THIS USER-MODE? JRST DIE010 ;YES--SKIP BAD THINGS MOVE T1,PRCTAB(T1) ;GET CONTROL BITS TLNN T1,(S%NCSB) ;SUPPRESS CPU/DEVICE STATUS BLOCK STUFF? S0PSHJ RCDSTB## ;READ CPU AND DEVICE STATUS BLOCKS IFN FTKL10,< PUSHJ P,CSDMP## ;MAKE SURE IT'S ALL IN CORE PUSHJ P,SKPMRN## ;SKIP IF MASTER -11 IS RUNNING STOPCD .,HALT,MNR, ;++MASTER -11 NOT RUNNING > DIE010: PUSHJ P,DIE1 ;CALL MAIN PROCESSING ROUTINE AS A SUBROUTINE SKIPE .UONCE## ;USER-MODE? JRST DIE011 ;YES--SKIP JUNK PUSHJ P,DAEEST## ;TELL DAEMON OF STOPCD MOVEI T1,177 ;ALL PI BITS AND T1,.CPCPI## ;TURN ON ONLY IORI T1,PI.TNP ;ONES WHICH WERE ON MOVEM T1,.CPCPI## ;SAVE FOR CONO DIE011: HRLZ 17,.CPACA## ;WHERE TO RESTORE THE AC'S FROM BLT 17,17 ;RESTORE THEM ALL .CREF DF.SBD ;(FLAG BIT TESTED) SKIPL DEBUGF## ;WANT DDT? JRST DIE02 ;DEFINITELY NOT, DON'T WASTE TIME ; PUSH P,T1 ;SAVE T1 (CAN'T, SINCE STACK MAY NOW BE BAD) MOVE T1,.CPSTY## ;GET STOPCODE TYPE SKIPGE PRCTAB(T1) ;BUGINF IN DRAG? .CREF S%FAST ; (NOTE BIT WE TESTED) JRST [MOVE T1,.CPACA## ;WHERE THE AC'S WERE STORED MOVE T1,T1(T1) ;RESTORE T1 JRST DIE02] ;FINISH UP MOVE T1,.CPACA## ;WHERE THE AC'S WERE STORED MOVE T1,T1(T1) ;RESTORE T1 XCT .CPDDT## ;CALL ON DDT DIE02: SETOM .CPDWD## ;ALLOW STOPCD'S DIENLK ;NO LONGER THE OWNER OF THE INTERLOCK ;IF STACK IS TRASHED, THIS IS WHERE WE GENERATE ANOTHER STOPCODE. ;SINCE WE HAVE RETURNED THE INTERLOCKS, THIS IS REASONABLY SAFE. DIECON:: GOBACK::PUSH P,.CPSPC## ;SAVE RETURN FLAGS PUSH P,.CPSPC##+1 ;SAVE RETURN PC SETZM .CPSPC##+1 ;LEAVE RECOGNIZABLE TRASH SKIPN .UONCE## ;IF EXEC MODE, CONO PI,@.CPCPI## ;TURN ON PI SYSTEM SETZM SYSSNP## ;THIS COULD BE WHY WE GOT HERE. ADJSP P,-2 ;LEAVE STACK THE WAY IT WAS SKIPE 2(P) ;MAKE SURE WE HAVE A REAL RETURN ADDRESS XJRSTF 1(P) ;RETURN TO CALLER DIEBPC: STOPCD .,STOP,DIEBAD, ;++ BAD PC IN DIE ;RUNNING IN SECTION 1 IF STOPCODE WAS IN A NON-ZERO SECTION DIE1: SKIPE .UONCE## ;IF USER-MODE, JRST DIE2 ;DON'T TRY TO TALK TO THE -11 MOVE T1,.CPSTY## ;GET STOPCODE TYPE SKIPL PRCTAB(T1) ;DO WE WANT SECONDARY PROTOCOL? .CREF S%FAST ;NOTE BIT WE TESTED PUSHJ P,SVPPC## ;YES, SAVE PROTOCOL & FORCE SECONDARY DIE2: IFN FTMP,< ;DIELOK ;CAN'T USE MACRO AS WE TEST CRSHWD BELOW AOSE .CPDIE## ;ALREADY OWN THE INTERLOCK? JRST DIE2B ;YES SKIPE .UONCE## ;IF USER-MODE, JRST DIE2B ;WE OWN IT NOW DIE2A: SKIPE CRSHWD## ;RELOADING? S0JRST REBOOT## ;YES SKIPGE INTDIE## ;IS INTERLOCK AVAILABLE? AOSE INTDIE## ;YES, TRY TO GET IT JRST DIE2A ;COULDN'T, LOOP TO TRY AGAIN APRID INODIE## ;MAKE ME THE OWNER OF THE INTERLOCK DIE2B: SETZM DIEFLG## ;CLEAR TYPE FLAG (JUST IN CASE) MOVE T1,.CPSTY## ;GET STOPCODE TYPE AGAIN SKIPL PRCTAB(T1) ;IS IT REAL? .CREF S%FAST ;(FLAG BIT TESTED) SOSA DIEFLG## ;YES, GO NEGATIVE AOS DIEFLG## ;NO, GO POSITIVE > ;END IFN FTMP ;THE FOLLOWING CODE IS EXPLICITLY TO MAKE IT EASIER TO AUTOMATICALLY MAP IN ;A CRASH. THE USUAL SEQUENCE WOULD BE TO USE A DDT FILE WHICH (FOR KL PAGING) ;WOULD SAY: ; DIECDB[$Q+.CPEPT-.CPCDB[$Q'1000$U ; SPTTAB$6U ; .CPACA[$Q$5U MOVE T1,.CPSLF## ;GET PHYSICAL POINTER TO THE CDB MOVEM T1,DIECDB## ;SAVE WHERE FILDDT WILL BE ABLE TO FIND IT ;THE FOLLOWING IS TO ALLOW FILDDT TO SETUP MAPPING FOR A CRASHED CPU ;AUTOMATICALLY. THIS REQUIRES A CORRESPONDING EDIT TO FILDDT, BUT WHY NOT PUSH P,.JBEDV## ;SAVE OLD VALUE FOR SYMBOL MAPPING IN EDDT ADDI T1,.CPEDV##-.CPCDB## ;RELOCATE TO OUR EDV MOVEM T1,.JBEDV## ;SAVE FOR FILDDT MOVE T1,1(M) ;GET NAME OF STOPCODE MOVEM T1,.CPSNM## ;SAVE NAME IN CDB MOVEM T1,%SYSCD## ;AND IN SYSTEM WIDE LOCATION MOVE T1,.CPSUP## ;GET STOPCODE PC MOVEM T1,%SYSPC## ;STORE IN TRADITIONAL WORD MOVE T1,.CPSTY## ;GET STOPCODE TYPE AGAIN MOVEM T1,%SYSTY## ;STORE IN SYSTEM WIDE LOCATION MOVE T1,DATE## ;GET UDT MOVEM T1,.CPSDT## ;SAVE AS LAST STOPCD DATE-TIME MOVEM T1,%SYSDT## ;BOTH PER-CPU AND SYSTEM-WIDE MOVE T1,.CPCPN## ;GET OUR CPU NUMBER MOVEM T1,%SYSCP## ;STORE AS LAST CPU THAT DID A STOPCD HRRZ T1,2(M) ;GET CONTINUATION ADDRESS SKIPE T1 ;IS THERE ANY? HRRM T1,.CPSPC##+1 ;YES, SAVE AS SECTION LOCAL CONTINUATION PUSH P,.CPTOA## ;SAVE ADDRESS OF TYPEOUT ROUTINE MOVE T1,.CPSTY## ;RECOVER STOPCODE TYPE SKIPN DINITF## ;UNLESS IN ONCE-ONLY, SKIPL PRCTAB(T1) ;LEAVE IT ALONE FOR EVENTS .CREF S%FAST ;(NOTE TESTED BIT) SKIPA T2,[CTYWAT##] ;NOPE, REPLACE IT WITH ONE THAT DOESN'T USE PI'S MOVEI T2,DIETYO ;YEP, USE OUR OWN HANDY TYPEOUT ROUTINE SKIPE .UONCE## ;UNLESS USER-MODE, MOVEI T2,XTYO## ;THEN USE OUTCHR'S MOVEM T2,.CPTOA## ;MODIFY SCNSER MOVE T1,PRCTAB(T1) ;GET ITS CONTROL BITS TLNN T1,(S%EVNT) ;IS IT AN EVENT? JRST DIE3 ;NO, IT'S A REAL STOPCODE PUSHJ P,INLMES## ;YES, TYPE HEADER ASCIZ / %% Event / MOVE T2,.CPSNM## ;GET STOPCODE NAME PUSHJ P,PRNAME## ;PRINT IT OUT JRST DIE4 ;RE-JOIN COMMON CODE DIE3: MOVEI T2,^D10 ;TYPE SOME BELLS PUSHJ P,BELLEN ; ... PUSHJ P,INLMES## ;PRINT MESSAGE ASCIZ / ?Stopcode / MOVE T2,.CPSNM## ;GET STOPCODE NAME PUSHJ P,PRNAME## ;PRINT IT OUT PUSHJ P,INLMES## ;SAY WHICH KIND ASCIZ /, type=/ MOVE T1,.CPSTY## ;GET STOPCODE TYPE AGAIN MOVE T2,STPTYP(T1) ;GET STOPCODE TYPE NAME PUSHJ P,PRNAME## ;PRINT IT OUT MOVEI T3,"," ;A SEPARATOR PUSHJ P,COMTYO## ;TYPE IT DIE4: PUSHJ P,INLMES## ;SEPARATION ASCIZ / on / MOVE T2,.CPLOG## PUSHJ P,PRNAME## PUSHJ P,INLMES## ;SEPARATION ASCIZ / at / PUSHJ P,DATIME## ;SAY WHEN PUSHJ P,PCRLF## ;ADD A CRLF MOVE T1,.CPSTY## ;GET STOPCODE TYPE AGAIN MOVE T1,PRCTAB(T1) ;GET ITS CONTROL BITS SKIPN .UONCE## ;NO DDB STUFF IN USER MODE TLNE T1,(S%NDDB) ;SUPPRESS JOB TYPEOUT? JRST NODDB ;YES, SKIP THIS MOVE J,.CPJOB## MOVEI S,PI.IPA ;GET PI ON MASK AND S,.CPCPI## ;MASK OUT ALL ELSE SKIPN S ;INTERRUPT LEVEL? PUSHJ P,WHATJB ;NO--GIVE INFO TLZ F,-1 ;CLEAR LH BITS PUSHJ P,CHKDDB ;MAKE SURE THAT F POINTS TO A DDB JRST NODDB ;IT DOESN'T, DON'T PRINT THE INFORMATION LDB T1,PJOBN## ;GET JOB # CAILE T1,JOBMAX## ;TOO BIG? JRST NODDB ;YES--NOT A DDB JUMPE T1,NODDB ;WANT REAL JOB # PUSHJ P,INLMES## ASCIZ /File / PUSHJ P,PRTDDB## ;PRINT DDB STUFF PUSHJ P,CRLF## ;ADD CRLF JUMPE S,NODDB ;UUO LEVEL-SAID THIS LDB J,PJOBN## ;GET JOB # PUSHJ P,WHATJB ;PRINT IT NODDB: MOVE T1,2(M) ;GET BITS FIELD TLNE T1,400000 ;ADDITIONAL INFORMATION SKIPN T1,3(M) ;TYPE OUT ROUTINE JRST NOTYPE ;JUMP IF NO ADDITIONAL TYPEOUT IFN FTXMON,< HLL T1,.CPSPC##+1 ;GET CALLER'S SECTION >; END IFN FTXMON PUSH P,T1 ;PUT SOMEWHERE SO WE CAN GET AT IT IFN P-1, ;NOTE AC VALUE ASSUMPTIONS HERE!! MOVE 17,.CPACA## ;POINT TO SAVED ACS MOVE 0,0(17) ;LOAD UP S MOVSI 17,2(17) ;SOURCE ADDRESS HRRI 17,2 ;ONE PAST P BLT 17,17 ;RESTORE ALL BUT P PUSHJ P,@(P) ;CALL THE ROUTINE POP P,T1 ;BALANCE THE STACK PUSHJ P,CRLF## ;TERMINATE LINE NOTYPE: MOVSI T1,(DF.RIP) ;IS A RELOAD IN PROGRESS? TDNE T1,DEBUGF## JRST NOCSB ;YES, DON'T TYPE OUT MEANINGLESS CSB MOVE T1,.CPSTY## ;GET ERROR TYPE MOVE T1,PRCTAB(T1) ;GET CONTROL BITS SKIPN .UONCE## ;NO CSB IN USER MODE TLNE T1,(S%NCSB) ;SUPPRESS CSB TYPEOUT? JRST NOCSB ;YES, DON'T TYPE CSB FOR TRIVIAL ERRORS SKIPGE DEBUGF## ;WANT DDT? JRST NOCSB ;YES, DON'T BOTHER WITH EXTRA TYPEOUT PUSHJ P,TYPCSB## ;TYPE CPU STATUS BLOCK INFO ON THE CTY NOCSB: MOVE T1,.CPSTY## ;GET ERROR TYPE HRRZ T1,PRCTAB(T1) ;GET PROCESSOR TO HANDLE THIS PUSHJ P,(T1) ;CALL IT DIERS0: MOVE T1,.CPSTY## ;GET STOPCODE TYPE AGAIN HRRZ T2,SCTTAB(T1) ;GET COUNTER LOCATIONS AOS (T2) ;COUNT UP PER-CPU LOCATION HLRZ T2,SCTTAB(T1) ;CHANGE POINTER AOS (T2) ;COUNT UP SYSTEM-WIDE LOCATION MOVE T2,PRCTAB(T1) ;GET CONTROL BITS MOVEI T1,BUGCON ;POINT AT CONTINUATION MESSAGE TLNN T2,(S%EVNT) ;IF A STOPCODE, PUSHJ P,CONMES## ;ANNOUNCE THAT THE SHOW WILL GO ON POP P,.CPTOA## ;RESTORE SCNSER POP P,.JBEDV## ;RESTORE EDDT SYMBOL MAPPING POPJ P, ;RETURN TO RESTORE PROTOCOL LEVEL ;HERE TO TYPE OUT DURING S%FAST TYPE STOPCODES DIETYO: PUSH P,U ;SAVE LDB ADDRESS HRRZ U,.CPCTN## ;GET OUR CTY'S LINE NUMBER MOVE U,LINTAB##(U) ;POINT TO ITS LDB PUSHJ P,CCTYO## ;STUFF CHARACTER INTO A CHUNK JRST UPOPJ## ;RESTORE AC AND RETURN ;HERE ON A DEBUG STOPCD BUGCHK: PUSHJ P,STCLIM ;EXCEED STOPCD LIMIT? JRST SCLEXC ;YES MOVSI T1,(DF.RDC) ;DO WE WANT TO TDNE T1,DEBUGF## ; RELOAD? JRST RELOAD ;YES--GO RELOAD MOVSI T1,(DF.DDC) ;WANT TO DUMP ON TDNN T1,DEBUGF## ; THIS TYPE OF STOPCD? PUSHJ P,CRSDMP ;DUMP SYSTEM AND RETURN POPJ P, ;RETURN TO DIERS0 ;HERE ON A BUGINF (NODUMP STOPCD) INFSTP==CPOPJ## ;MESSAGE THAT SHOWS SYSTEM CONTINUATION BUGCON: ASCIZ /[Continuing system] / ;HERE ON A JOB ERROR STOPCD ZAPJOB: PUSHJ P,STCLIM ;STOPCD LIMIT EXCEEDED? JRST SCLEXC ;YES MOVEI S,PI.IPA ;GET PI ON MASK SKIPN .UONCE## ;IF EXEC MODE, AND S,.CPCPI## ;MASK OUT ALL ELSE MOVSI T1,(DF.RJE) ;IS RELOAD ON JOB ERROR TDNN T1,DEBUGF## ; REQUESTED? SKIPE S ; OR PI LEVEL? JRST RELOAD ;YES--GO RELOAD SKIPE .USJOB ;CAN'T STOP THE NULL JOB SKIPE .CPISF## ;IN SCHEDULER CONTEXT? JRST RELOAD ;YES, CAN'T REALLY STOP A JOB MOVSI T1,(DF.DJE) ;WANT TO DUMP ON TDNN T1,DEBUGF## ; THIS TYPE OF STOPCD? PUSHJ P,CRSDMP ;DUMP SYSTEM AND RETURN PUSHJ P,INLMES## ;NO--ZAP JOB ASCIZ /[Aborting job] / PUSHJ P,GIVLOK## ;GIVE BACK LOCKS THIS CPU OWNS MOVEI T1,BUGSTP ;ROUTINE TO KILL OFF JOB MOVEM T1,.CPSPC##+1 ;SAVE AS RETURN ADDRESS SO THIS JOB GETS NAILED POPJ P, ;RETURN TO DIERS0 ;HERE ON A CPU STOPCD IFN FTMP,< CPUSTP: PUSHJ P,STCLIM ;STOPCD LIMIT EXCEEDED? JRST SCLEXC ;YES MOVSI T2,(DF.CP1) ;BIT FORCING CPU STOPCDS TO CAUSE RELOAD PUSHJ P,LSTCPU## ;LAST OR ONLY CPU RUNNING IN SYSTEM? TDNE T2,DEBUGF## ;NO, WANT TO RELOAD ON CPU STOPCDS? JRST RELOAD ;YES, RELOAD THE SYSTEM MOVSI T1,(DF.DCP) ;WANT TO DUMP ON TDNN T1,DEBUGF## ; THIS TYPE OF STOPCD? PUSHJ P,CRSDMP ;DUMP SYSTEM AND RETURN PUSHJ P,INLMES## ;TELL OF OUR ACTION ASCIZ /[Stopping CPU] / AOS .CPSNC## ;COUNT UP NUMBER OF TIMES THIS CPU STOPPED AOS %SYNCS## ;AND NUMBER OF TIMES ANY CPU STOPPED PUSHJ P,KILUSR ;INSURE THAT THE CURRENT JOB IS STOPPED ; TO AVOID A REPEAT OF THE STOPCD IF ; HE STARTS TO RUN ON ANOTHER CPU MOVE T1,-1(P) ;GET SAVED TYPEOUT ADDRESS MOVEM T1,.CPTOA## ;RESTORE FOR SCNSER MOVE T1,-2(P) ;GET SAVED EDV MOVEM T1,.JBEDV## ;RESTORE FOR EDDT SKPCPU(1) ;SLAVE CPU? JRST CPUST2 ;NO, DO BOOT DEATH THINGS SKIPGE .CPOK## ;DID EVERYONE THINK WE WERE DEAD? SETZM .CPOK## ;NO, LET THEM KNOW (ESPECIALLY LSTCPU) HRRZ T1,.CPSLF## ;POINT TO OURSELVES PUSHJ P,BRKLOK## ;DECLARE OURSELVES DOWN (DOES A DIENLK) CPUST1: MOVEI T1,SR.DIE ;TELL CP1CRS THAT WE WANT THE OPERATOR IORM T1,.CPSBR## ; TO MANUALLY RESTART THIS CPU S0JRST REBOOT## ;SAVE STATE OF THE MACHINE CPUST2: SETOM .CPOK## ;SINCE BOOT, MAKE SURE BECOM0 WILL BE CALLED ; DIENLK ;NO LONGER HAVE INTERLOCK SETOM .CPDIE## ;RESET DIE INTERLOCK NESTING COUNT PUSHJ P,BRKDIE## ;MAKE SURE ALL LEVELS ARE RETURNED CPUST3: MOVEI T1,^D10000 ;NUMBER OF TIMES TO LOOP WHILE WAITING CPUST4: SKPCPU(0) ;STILL THE POLICY CPU? PJRST CPUST1 ;NO, SAVE STATE OF THE MACHINE SOJG T1,CPUST4 ;YES, LOOP PUSHJ P,LSTCPU## ;LOOP EXPIRED, DID ALL THE OTHERS GO AWAY? JRST CPUST3 ;NO, LOOP SOME MORE MOVEI T1,CTYWAT## ;REPLACE IT WITH ONE MOVEM T1,.CPTOA## ;THAT DOESN'T NEED PI MOVSI T1,(DF.RAD) ;RELOAD AFTER DUMP BIT IORM T1,DEBUGF## ;LIGHT IT FOR MONBTS (DON'T DUMP TWICE) PJRST RELOAD ;AND GO RELOAD THE SYSTEM > ;HERE IF WE EXCEEDED ONE OF THE STOPCD-PER-UNIT-TIME LIMITS TO RELOAD ;THE SYSTEM. SCLEXC: PUSHJ P,INLMES## ;TELL WHAT HAPPENED ASCIZ /?Stopcode limit exceeded / ;HERE TO RELOAD THE SYSTEM IFE FTMP,< CPUSTP: > RELOAD: .CREF DF.SBD ;(FLAG BIT TESTED) SKIPGE DEBUGF## ;WANT DDT? XCT .CPDDT## ;CALL ON DDT MOVSI T1,(DF.RLD) ;INDICATE RELOAD IORM T1,DEBUGF## ;FOR CRSCPY MOVE T1,.CPSNM## ;GET STOPCODE NAME MOVEM T1,CRSWHY## ;SAVE REASON FOR ONCE AFTER RELOAD SKIPE .UONCE## ;IF USER-MODE, CALLI 12 ;EXIT PUSHJ P,INLMES## ASCIZ /Reload monitor / MOVEI T2,^D20 ;20 BELLS PUSHJ P,BELLS ;.. MOVE T1,.CPSUP## ;GET CRASH PC MOVEM T1,CRSHWD ;SAVE PC SOS CRSHWD## ;FOR SYSTAT/X S0JRST REBOOT## ;RELOAD NOW COMMENT @ "Recent findings have shown bugs that are adaptive and intelligent. The study of such bugs has been hampered by the probablity that these bugs themselves have bugs, producing erratic buglike behavior. If this is indeed true, it provides the first demonstration that Murphy's Law is recursive, that it can invoke itself." IEEE Spectrum, September 1984 @ ;TABLES FOR DRIVING STOPCODE PROCESSING S%FAST==1B0 ;FLAG FOR STOPCODE VS. EVENT (SVPPC) S%NDDB==1B1 ;FLAG TO SUPPRESS DDB/JOB TYPEOUT S%NCSB==1B2 ;FLAG TO SUPPRESS CSB TYPEOUT S%EVNT==1B3 ;FLAG TO TYPE "EVENT" RATHER THAN "STOPCODE" DEFINE STPTAB,< STP HALT,RELOAD,0,0, STP STOP,RELOAD,0,0, STP JOB,ZAPJOB,.CPSNJ##,%SYNJS##, STP DEBUG,BUGCHK,.CPSND##,%SYNDS##, STP CPU,CPUSTP,.CPSNC##,%SYNCS##, STP INFO,INFSTP,.CPSNI##,%SYNIS##, STP EVENT,INFSTP,.CPSNI##,%SYNIS##, > STPTYP: DEFINE STP(TYP,RTN,CPLOC,SYLOC,FLAGS),< IFN <.-STPTYP>-S$'TYP, EXP SIXBIT \TYP\ > STPTAB STPMAX==.-STPTYP-1 ;MAXIMUM LEGAL STOPCODE TYPE PRCTAB: DEFINE STP(TYP,RTN,CPLOC,SYLOC,FLAGS),< ZZ==0 IRP FLAGS, EXP ZZ ! RTN PURGE ZZ > STPTAB SCTTAB: DEFINE STP(TYP,RTN,CPLOC,SYLOC,FLAGS), STPTAB ;HERE TO STOP AN ILL FATED USER BUGSTP: MOVE J,.USJOB ;JOB NUMBER PUSHJ P,ZAPUSR ;GIVE UP LOCKS AND DEVICES JSP T1,ERRPTU ;PRINT MESSAGE ASCIZ /Monitor error/ PJRST UUOPCP ;PRINT SOME PC'S ;ROUTINE TO KILL THE CURRENT JOB RUNNING ON THIS CPU TO MAKE SURE ;THAT IT DOESN'T CONTINUE TO CAUSE THE SAME CRASH OVER AND OVER AGAIN. ;MUST NOT BE CALLED WITH A UUO LEVEL STACK SINCE ZAPPGM WILL GIVE ;BACK THE PAGE MAP. KILUSR: PUSHJ P,GIVLOK## ;RETURN INTERLOCKS OWNED BY THIS CPU SKIPN J,.CPJOB## ;ANY JOB RUNNING ON THIS CPU? POPJ P, ;NO, JUST RETURN ZAPZAP::PUSHJ P,ZAPHER ;GIVE UP LOCKS AND DEVICES PUSH P,JBTSTS##(J) ;SAVE CURRENT STATE OF JBTSTS MOVSI T1,JLOG ;CLEAR JLOG TEMPORARILY SO THAT ANDCAM T1,JBTSTS##(J) ; ZAPPGM WILL GIVE BACK ALL OF THE ANDM T1,0(P) ; USER'S CORE. I KNOW IT'S UGLY BUT... PUSHJ P,ZAPPGM## ;GIVE BACK ALL OF HIS CORE POP P,T1 ;GET BACK STATE OF JLOG BIT IORM T1,JBTSTS##(J) ;SET IT IF IT WAS SET BEFORE POPJ P, ;RETURN ;SUBROUTINE TO SEND C(T2) BELLS ;CLOBBERS T1, T2, T3, T4 BELLEN: HRRZ T1,.CPTOA## ;GET TYPEOUT ROUTINE CAIE T1,DIETYO ;DOES IT BUFFER FOR US? BELLS: TDZA T1,T1 ;NO, FLAG IT MOVEI T1,1 ;YES, FLAG THAT PUSH P,T1 ;SAVE FLAG PUSH P,T2 ;NUMBER OF BELLS TO OUTPUT BELOOP: MOVEI T3,"G"-100 ;BELL PUSHJ P,COMTYO## ;DING SOSG (P) ;DECREMENT NUMBER OF BELLS TO OUTPUT JRST TTPOPJ## ;DONE SKIPN .UONCE## ;DON'T LOOP IN USER MODE (IT WON'T HELP) SKIPE -1(P) ;CHECK FLAG JRST BELOOP ;DON'T LOOP IF PI'S STILL ON IFN FTKL10,MOVSI T1,1 ;LOOP 2^18 TIMES ON A KL10 IFN FTKS10,MOVEI T1,200000 ;LOOP 2^16 TIMES ON A KS10 DMOVE T2,BECODE ;PUT TIMING CODE IN ACS TO AVOID ERRATIC TIMING JRST T2 ; DUE TO PRESENCE OR ABSENCE OF CACHE BECODE: SOJG T1,T2 ;(T2) DECREMENT T1 AND LOOP JRST BELOOP ;(T3) OUTPUT ANOTHER BELL WHEN DONE ;ROUTINE TO CHECK A DDB ADDRESS BEFORE USING IT TO TYPE FILE INFORMATION ;DURING DIE PROCESSING. ;CALL: MOVEI F,ADDRESS ; PUSHJ P,CHKDDB ; RETURN HERE IF ADDRESS IS ILLEGAL FOR SOME REASON ; RETURN HERE IF ADDRESS IS OK CHKDDB: CAMGE F,SYSSIZ## ;LARGER THAN THE LOW SEG? CAIG F,1000 ;OR TOO SMALL? CAIA ;YES, MAY STILL BE IN FUNNY SPACE JRST CPOPJ1## ;GIVE SKIP RETURN CAIL F,.FPMC ;LEGAL ADDRESS IN CAIL F,.FPMC+NWMCP ; FUNNY SPACE? POPJ P, ;NO, BAD DDB ADDRESS MAP T1,(F) ;MAP THE ADDRESS PUSHJ P,FLTCHK## ;WILL REFERENCE FAULT? POPJ P, ;YES, BAD ADDRESS MAP T1,DEVSFD##(F) ;LAST ADDRESS IN DDB REFERENCED BY PRTDDB PJRST FLTCHK## ;CHECK ADDRESS AND RETURN ;ROUTINE TO SEE IF THIS STOPCD HAS CAUSED US TO EXCEED ON OF THE ;STOPCDS-PER-UNIT-TIME LIMITS. ;CALL: PUSHJ P,STCLIM ; RETURN HERE IF A LIMIT HAS BEEN EXCEEDED ; RETURN HERE IF NOT STCLIM: SKIPN .UONCE## ;NO LIMITS IN USER MODE SKIPGE DEBUGF## ;IF DEBUGGING JRST CPOPJ1## ;THEN NOSTOPCD LIMITS MOVSI T1,-SCCTBL## ;BUILD AOBJN POINTER TO TABLE STCLI1: AOS T2,SCCTAB##(T1) ;INCREMENT NEXT COUNT HRRZ T3,SCLTAB##(T1) ;GET THE LIMIT CAIL T2,(T3) ;EXCEED THE LIMIT? POPJ P, ;YES AOBJN T1,STCLI1 ;NO, LOOP FOR NEXT HLRZ T1,SCLTAB##+0 ;GET PERIOD OF LOWEST ENTRY IN TABLE IMUL T1,TICSEC## ;SETUP CLOCK REQUEST TO DECREMENT THE HRLI T1,DECSCC ; 1 MINUTE STOPCD COUNT. DECSCC WILL, MOVEI T2,0 ; IN TURN, PUT IN A CLOCK REQUEST TO DECREMENT IDPB T1,CLOCK## ; THE NEXT ONE, AND SO ON, UNTIL ALL IDPB T2,CLOCK## ; LEVELS OF COUNTS HAVE BEEN DECREMENTED. SETOM CLKNEW## ;I REALIZE THE CLOCK QUEUE HASN'T BEEN ; INTERLOCKED WITH SYSPIF BUT BY THE ; TIME THE FIRST CHARACTER OF THE STOPCD ; MESSAGE HAS TYPED ON THE CTY, ALL OTHER ; CPU'S SHOULD HAVE SEEN INTDIE GO NON-ZERO JRST CPOPJ1## ;GIVE SKIP RETURN ;ROUTINE TO DECREMENT A STOPCD COUNT AND RESUBMIT A CLOCK QUEUE REQUEST ;FOR THE NEXT HIGHER COUNT, IF ONE EXISTS. ;CALL: MOVEI T1,INDEX INTO SCCTAB ; PUSHJ P,DECSCC ; RETURN HERE ALWAYS DECSCC::SOSGE SCCTAB##(T1) ;DECREMENT COUNT SETZM SCCTAB##(T1) ;LEAVE ZERO IF IT WAS ZERO AOS T1 ;INCREMENT LEVEL CAIL T1,SCCTBL## ;DONE THE LAST LEVEL? POPJ P, ;YES, RETURN NOW MOVE T2,SCLTAB##(T1) ;GET WORD WITH NEW PERIOD SUB T2,SCLTAB##-1(T1) ;SUBTRACT OLD PERIOD HLRZS T2 ;KEEP JUST DIFFERENCE IN PERIODS IMUL T2,TICSEC## ;CONVERT TO TICKS HRLI T2,DECSCC ;WANT TO COME BACK HERE SYSPIF ;INTERLOCK THE QUEUE IDPB T2,CLOCK## ;STORE REQUEST IDPB T1,CLOCK## ; AND DATA SETOM CLKNEW## ;FLAG A NEW REQUEST PJRST ONPOPJ## ;RETURN INTERLOCK AND POPJ ;ROUTINES FOR STOPCODE MACRO TYPE OUT ;ALL ROUTINES WILL HAVE THE FORM DIE???:: ;WHERE ??? ARE 3 LETTERS DESCRIPTIVE OF THE ROUTINE ;AN AUTOMATIC CARRIAGE RETURN/LINE FEED IS DONE BY CALLER ;ROUTINE TO TYPE OUT UNINAM(U) DURING STOPCD DIEUNI::PUSHJ P,INLMES## ;START THE OUTPUT ASCIZ \Unit = \ MOVE T2,UDBNAM(U) ;GET UNIT NAME PJRST PRNAME## ;PRINT OUT SIXBIT AND RETURN ; ROUTINE TO TYPE OUT STRNAM(P2) DURING A STOPCODE DIESTR::PUSHJ P,INLMES## ;TYPE INTRODUCTION ASCIZ |Structure = | MOVE T2,STRNAM##(P2) ;GET STR NAME PJRST PRNAME## ;TYPE IT AND RETURN ;ROUTINE TO TYPE OUT ADDITIONAL DATA DURING BUGINF (OR BUGCHK OR ...) ; ;CALLED VIA JSP T1,BGCTYP ;DATA TO BE TYPED FOLLOWS $CSUB ;MUST BE ADDRESSABLE BY ALL CODE SEGMENTS BGCTYP::MOVE P1,T1 ;COPY POINTER TO DATA IFN FTXMON,< TLNE T1,MXSECN ;CALLED FROM NON-ZERO SECTION? XJRST [MCSEC1+BUGTY1] ;YES, ENTER SECTION 1 FOR OUTPUT ROUTINES >; END IFN FTXMON JRST BUGTY1 ;STAY IN CALLER'S SECTION $HIGH BUGTY1: SKIPE .UONCE## ;IF USER-MODE, JRST BUGTY2 ;ASSUME WON'T FAULT MAP T1,(P1) ;MAKE SURE LOCATION IS ACCESSIBLE PUSHJ P,FLTCHK## ;MAKE SURE WON'T FAULT POPJ P, ;WILL FAULT, END LIST NOW BUGTY2: SKIPN (P1) ;HIT END OF DATA ITEMS? POPJ P, ;YES, END LIST NOW PUSHJ P,PR3SPC## ;A LITTLE SPACING MOVE T2,(P1) ;GET ITEM NAME PUSHJ P,PRNAME## ;PRINT IT PUSHJ P,INLMES## ;A LITTLE NOISE ASCIZ /: / SKIPE .UONCE## ;AGAIN, JRST BUGTY3 ;USER MODE IS BRAVE MAP T1,1(P1) ;MAKE SURE THIS WON'T FAULT PUSHJ P,FLTCHK## POPJ P, ;END OF LIST FORCED BUGTY3: MOVE T1,1(P1) ;GET ADDRESS OF ITEM MOVE T2,.CPACA## ;GET ADDRESS OF SAVED AC'S ADD T2,T1 ;OFFSET TO SAVED ITEM IF IN CRASH AC'S CAIG T1,17 ;ITEM IN CRASH AC'S? SKIPA T1,(T2) ;YES, FETCH FROM PROPER LOCATION MOVE T1,(T1) ;NO, GET DIRECTLY PUSHJ P,PRTXWD## ;PRINT IT AS HALFWORDS ADDI P1,1 ;LOOP FOR NEXT ITEM AOJA P1,BUGTY1 ;UNTIL DONE ;ROUTINE TO CALL BUGDMP TO TAKE A CONTINUABLE STOPCD DUMP ;AND THEN SET DF.RQC IN DEBUGF WHICH WILL CAUSE CRSCPY ;TO BE CALLED BY THE BOOT CPU AT THE NEXT TICK. WE ;CAN'T CALL CRSCPY DIRECTLY BECAUSE THE SCNSER INTERLOCK ;MAY NOT BE FREE. ;ENTER AT FRCCPY TO JUST SET DF.RQC (FROM ADDSDL) ;CALL: PUSHJ P,CRSDMP ; RETURN HERE ALWAYS CRSDMP: SKIPE .UONCE## ;IF USER-MODE, POPJ P, ;IGNORE THIS SE1ENT ;ENTER SECTION 1 PUSH P,JOBSYM## ;KEEP DAEMON FROM THINKING THIS IS A SETZM JOBSYM## ;RELOAD BY ZEROING THE FLAG THAT IT LOOKS AT PUSHJ P,BTDUMP## ;TAKE DUMP JFCL ;IGNORE ERROR RETURN POP P,JOBSYM## ;RESTORE SYMBOL TABLE POINTER FRCCPY::MOVSI T1,(DF.RQC) ;IF THE CRSCPY REQUEST HAS NOT BEEN MOVSI T2,(DF.DCC) ; DISABLED VIA THE /NOCOPY STARTUP TDNN T2,DEBUGF## ; SWITCH, SET DF.RQC IN DEBUGF WHICH IORM T1,DEBUGF## ; WILL CAUSE CRSCPY TO BE CALLED ON ANDCAM T2,DEBUGF## ; THE NEXT CLOCK TICK POPJ P, ;RETURN ;ROUTINE TO START UP THE CRASH COPY PROGRAM TO COPY ;A DUMP. ;CALL: PUSHJ P,CRSCPY ; RETURN HERE ALWAYS CRSCPY::SKIPGE DEBUGF## ;DON'T DO ANYTHING POPJ P, ; IF DEBUGGING PUSHJ P,FRCSET## ;SETUP TO STORE CHARACTERS IN FRCLIN MOVE T2,CCPNAM## ;GET NAME OF PROGRAM TO RUN PUSHJ P,PRNAME## ;STORE NAME PJRST CRLF## ;ADD CRLF AND RETURN WHATJB: JUMPLE J,CPOPJ## ;GET JOB NUMBER CAILE J,JOBMAX## ;RANGE CHECK IT. POPJ P, ;IGNORE IF FUNNY. PUSHJ P,INLMES## ;GIVE THE JOB NUMBER ASCIZ /Job / ; .. MOVE T1,J ; .. MOVEM T1,%SYSJN## MOVEM T1,.CPSJN## PUSHJ P,RADX10## ;IN DECIMAL PUSHJ P,INLMES## ;PRINT OUT THE ASCIZ / on / ; TTY NAME MOVE T2,@TTYTAB##(J) ;GET TTY NAME MOVEM T2,%SYSTN## MOVEM T2,.CPSTN## PUSHJ P,PRNAME## ; AND PRINT IT. PUSHJ P,INLMES## ;PRINT OUT ASCIZ / running / ; THE CUSP NAME MOVE T2,JBTPRG##(J) ; SO OPERATOR MOVEM T2,%SYSPN## MOVEM T2,.CPSPN## PUSHJ P,PRNAME## ; CAN FIND HIS JOBS PUSHJ P,INLMES## ASCIZ / User / MOVE T2,JBTPPN##(J) ;GET USER'S PPN MOVEM T2,%SYSPP## ;AND SAVE FOR DAEMON MOVEM T2,.CPSPP## PUSHJ P,PRTPPN## ;PRINT PPN JUMPN S,CRLF## PUSHJ P,INLMES## ;NEW LINE ASCIZ / UUO is / MOVE T1,.CPTRP## ;PICK UP UUO MOVEM T1,%SYSUU## MOVEM T1,.CPSUU## PUSHJ P,HWDPNT## ;PRINT IN OCTAL DMOVE T1,.JDAT+JOBPD1## ;GET PC FROM PUSH DOWN LIST MOVEM T2,%SYSUP## MOVEM T2,.CPSUP## PUSHJ P,DPCP ;LIST THE LOCATION PJRST CRLF## ;RETURN ON A NEW LINE SUBTTL UUO LEVEL ERROR ROUTINES ;INPUT UUO FOR OUTPUT DEVICE ;CALLED AT UUO LEVEL ONLY ILLINP::JSP T1,ERRPTU ASCIZ /Output / PUSHJ P,ERNAM ;PRINT "DEVICE XXX" JSP T1,UUOMES ;PRINT MESSAGE,UUOPC,STOP JOB ASCIZ / cannot do input/ ;OUTPUT UUO FOR INPUT DEVICE ;CALLED AT UUO LEVEL ONLY ILLOUT::JSP T1,ERRPTU ASCIZ /Input / PUSHJ P,ERNAM ;PRINT "DEVICE XXX" JSP T1,UUOMES ;PRINT MESSAGE,UUOPC,STOP JOB ASCIZ / cannot do output/ ;ILLEGAL DEVICE DATA MODE (INIT, OPEN, OR SETSTS UUOS) ;CALLED AT UUO LEVEL ONLY ILLMOD::JSP T1,ERRPTU ASCIZ /Illegal data mode for / JRST DEVEXC ;PRINT "DEVICE XXX",UUO PC ;ILLEGAL INBUF/OUTBUF (NON-ZERO SECTION) ILLBUF::JSP T1,ERRPTU ASCIZ \Illegal INBUF/OUTBUF for \ JRST DEVEXC ;PRINT "DEVICE XXX", UUO PC ;IO UUO TO USER CHANNEL WITH NO PREVIOUS INIT OR OPEN ;CALLED AT UUO LEVEL ONLY IOIERR::JSP T1,ERRPTU ASCIZ /IO to unassigned channel/ JRST UUOPCP ;PRINT UUO PC ;ILLEGAL UUO ;CALLED AT UUO LEVEL ONLY ;SERVES TWO PURPOSES - A) TO WARN WHEN MOVING FROM A LOCATION WITH SPECIAL INSTALLATION ;UUOS TO ONE WITH LACKS THEM ;B) TO WARN OF OLD UUO'S WITH NONSKIP "GOOD" RETURNS WHICH ;HAVE BEEN "DE-IMPLEMENTED" UUOERR::EXCH T1,.USMUO ;GET UUO PC FLAGS TLNN T1,USRMOD ;FROM EXEC? JRST EMUERR ;YES EXCH T1,.USMUO ;PUT THINGS BACK ILLUUO: PUSH P,.USMUO ;PC FLAGS PUSH P,.USMUP ;NOW PUSH USER PC ON STACK JUST LIKE UUO ; (LEAVE STACK UNTOUCHED BEFORE HALT) ; (START PRESERVES PC FLAGS IN LH) PUSHJ P,GIVRES ;GIVE UP INTERLOCKS SIGNAL C$IUUO ;SIGNAL ILLEGAL UUO SKIPA ;DOESN'T WANT THE TRAP JRST ERRGOU ;INTERCEPT THE UUO JSP T1,ERRPTU ASCIZ /Illegal UUO/ DMOVE T1,.USMUO ;GET UUO PC SOJA T2,DPCPNT ;AND PRINT, PRINT USER UUO PC IF DIFF. IFE FTMP,< ;UUO ERROR-MONITOR ERROR AT UUO LEVEL ;CALLED AT UUO LEVEL ONLY UUOER1::JSP T1,ERRPTU ASCIZ /UUO error/ JRST UUOPCP > ;HERE ON AN EXEC MODE UUO ERROR EMUERR: EXCH T1,.USMUO MOVEM P,.CPEMU##+1 ;SAVE STACK POINTER MOVEI P,.CPEMU##-1 ;GET A SHORT STACK FOR CALLING DIE CONSZ PI,PI.IPA ;AT UUO LEVEL? STOPCD .,STOP,UIL,DIEEMU, ;++UUO AT INTERRUPT LEVEL STOPCD .+1,JOB,EUE,DIEEMU, ;++EXEC UUO ERROR MOVE P,.CPEMU##+1 ;RESTORE STACK POINTER PUSHJ P,GIVLOK## ;RETURN SOFTWARE INTERLOCKS MOVE J,.CPJOB## ;GET JOB NUMBER JRST ILLUUO ;PRINT ERROR MESSAGE DIEEMU: PUSHJ P,INLMES## ASCIZ /MUUO Flags, Opcode, AC = / MOVE T1,.USMUO ;GET FLAGS,OPCODE,AC PUSHJ P,HWDPNT## ;PRINT IT PUSHJ P,INLMES## ASCIZ / MUUO PC = / MOVE T2,.USMUP ;GET PC PUSHJ P,UDPCP ;PRINT IT PUSHJ P,INLMES## ASCIZ / MUUO EA = / MOVE T2,.USMUE ;GET EA PJRST UDPCP ;PRINT IT AND RETURN ;HERE IF THE USER DIES IN GETWRD OR PUTWRD UADERR::MOVE J,.CPJOB## PUSHJ P,GIVRES ;RETURN INTERLOCKS JSP T1,ERRPTU ASCIZ /Illegal address in UUO/ JRST UUOPCP ;ILLEGAL INSTRUCTION ;HALT INSTRUCTION IS A SPECIAL CASE WHICH STOPS JOB BUT ;THE USER MAY CONTINUE FROM IT(EFFECTIVE ADR.) ;CALLED AT UUO LEVEL WITH A JRST ILLINS::LDB T1,[POINT 9,M,8] ;OPCODE IFN FTKL10,< CAIN T1,<_-^D27> ;IS THIS AN EXTEND INSTRUCTION? JRST OINKSR## ;YES, CHECK FOR GFLOAT EXTEND OPCODE. > CAIL T1,130 ;WITHIN LONG FLOATING POINT RANGE? CAILE T1,177 JRST ILLIN1 ;NO, ILLEGAL INSTRUCTION CAIL T1,133 ;A BYTE INSTR? CAILE T1,137 CAIA ;NO JRST ILLIN1 ;YES MOVSI T2,(JS.FPS) ;WANT SIMULATION BIT SKIPE [M.FPS##] ;SIMULATION ROUTINE LOADED? TDNN T2,JBTST2##(J) ;AND DOES THE USER WANT SIMULATION? CAIA ;NO JRST KALFPS## ;YES, SIMULATE THE KA FP INSTRUCTIONS SIGNAL C$IUUO ;SIGNAL ILL INSTRS CAIA ;PROGRAM ISN'T INTERESTED JRST ERRGOU ;GO TO THE USER JSP T1,ERRPTU ;TELL THE USER TO FIX THE PROGRAM ASCIZ /KA10 floating point instruction/ JRST UUOPCP ILLIN1:: SIGNAL C$IUUO ;SIGNAL ILL UUO SKIPA ;USER DOESN'T WANT THE TRAP JRST ERRGOU ;GO TO THE USER HLRZ T1,M ;ILLEGAL OPCODE TRZ T1,(SECMSK) ;CLEAR POSSIBLE SECTION NUMBER CAIN T1,(HALT) ;IS IT A HALT? JRST HALTI ;YES, PRINT DIFFERENT MESSAGE IFN FTKS10,< LSH T1,-9 ;MAKE T1=OPCODE IFN FTKS10,< KSIBEG==102 KSIEND==110 MOVSI T2,314000 ;MASK FOR KL-ONLY INSTRS CAIG T1,KSIEND ;IF TOO LARGE, DON'T SHIFT LSH T2,-KSIBEG+1(T1) ;SHIFT MASK BY OPCODE > JUMPGE T2,ILLKAI ;KA10 ILL INST IF SIGN NOT 1 JSP T1,ERRPTU ASCIZ /KL10 only instruction/ JRST UUOPCP > ;END FTKI10!FTKS10 ILLKAI: JSP T1,ERRPTU ASCIZ /Illegal instruction/ JRST UUOPCP ;PRINT UUO PC AND STOP JOB HALTI: JSP T1,ERRPTU ASCIZ /HALT/ DMOVE T1,.JDAT+JOBPD1## SOS T2 ;UUOPC=LOC OF HALT+1 PUSHJ P,DPCP ;PRINT "USER LOC XXX" HRR M,.USMUO+2 ;CHKINT CLOBBERS M HRRM M,.JDAT+JOBPD1##+1 ;SAVE EFFECTIVE ADDRESS OF HALT PUSH P,U PUSHJ P,TTYSRC## ;GETTTY STOPCD .,STOP,LNT, ;NONE?! JUMPE U,HALTI1 ;JUMP IF JOB DETACHED POP P,U PUSHJ P,TSETBI## ;CLEAR TYPE-AHEAD PUSHJ P,HOLDW## ;START TTY WITH STANDARD RESPONSE,, STOP ;JOB, LEAVE TTY IN MONITOR MODE ;DO NOT SET ERROR BIT SO CAN CONTINUE JRST ERRGOU ;RETURN TO USER HALTI1: POP P,U PUSHJ P,CRLF## ;HERE TO HANDLE HALT IN DET'D JOB PUSHJ P,ESTOP3## ;STOP JOB WITH CONTINUABILITY PUSHJ P,WSCHED## ;WAIT FOR USER JRST ERRGOU ;RESUME NORMAL FLOW ;ILLEGAL TRAP INSTRUCTION ILLTIN::MOVE P,[MJOBPD##,,.JDAT+JOBPDL##] PUSH P,.USMUO ;PC FLAGS PUSH P,.USMUP JSP T1,ERRPTU ASCIZ /Illegal trap instruction/ JRST UUOPCP ;PRINT TRAP INSTR PC AND STOP THE JOB SUBTTL I/O ERROR HANDLING ROUTINES ;ROUTINE FOR HUNG IO DEVICE ;CALL MOVE F,ADDRESS OF DEVICE DATA BLOCK ; PUSHJ P,DEVHNG DEVHNG::PUSHJ P,SVEUF## ;MAKE SURE JOB DATA AREA IS ADDRESSABLE LDB J,PJOBN## ;JOB NUMBER JUMPN J,DEVHN0 ;DON'T CLEAR IOW UNLESS JOB 0 PUSHJ P,CLRACT## ;TURN OFF IO DEVICE ACTIVE BIT IN ;MEMORY AND S JRST DEVHN2 ;GO TYPE THE MESSAGE DEVHN0: MOVEI T1,IR.HNG ;HUNG CONDITION TSNN T1,DEVPSI##(F) ;PROGRAM ENABLED? JRST DEVHN1 ;NO TRZ S,IOACT ;CLEAR IOACT (LEAVE IOW ALONE) PUSHJ P,STORS7## ;MAKE SURE IOS IS IN MEMORY PUSHJ P,PSIDVB## ;SIGNAL HUNG DEVICE PUSHJ P,RTNEVM## ;RETURN ANY EVM DEVICE HAS FOR I/O MOVE S,DEVIOS(F) ;RESTORE S TRO S,IOIMPM!IOBKTL!IODERR!IODTER ;ALL ERRORS PUSHJ P,SETIOD## ;GET THE JOB GOING HLLZS JBTDDB##(J) ;NOT IN IOWAIT NOW (FOR ^T'ERS) PJRST STOIOS## ;STORE BITS AND RETURN DEVHN1: PUSHJ P,CLRACT## ;BLOW AWAY IOACT AND IOW MOVSI T1,JERR ;FLAG SO USER DOESN'T IORM T1,JBTSTS(J) ;GET IF TRAP ENABLED DVHN1A: IFN FTMP,< CPLOCK (SCD) ;GET SCHEDULER LOCK > MOVEI T1,STOPQ## DPB T1,PJBSTS## PUSHJ P,ANYCPU## ;IS HE RUNNING ANYWHERE NOW? SKIPA ;YES MUST DELAY HANGING HIM JRST DVHN1C ;NO, CAN STOP HIM NOW MOVEI T2,1 ;GET A WORD PUSHJ P,GETWDS## ;OF FREE CORE JRST DVHN1C ;FAILED BLAST JOB ANYWAY MOVEM F,(T1) ;STORE F HRLM J,(T1) ;AND J MOVE T2,.CPCPN## DPB T2,[POINT 3,T1,3] ;CPU IS US TLO T1,400000 ;INDICATE CPU-SPECIFIC SYSPIF SETZM CLKMIN##(T2) ;INDICATE NEW REQUEST IN QUEUE MOVE T2,[DVHN1B,,1] ;COME BACK IN A TIC IDPB T2,CLOCK## IDPB T1,CLOCK## SYSPIN IFN FTMP,< CPUNLK (SCD) > POPJ P, ;AND RETURN FOR NOW DVHN1B: HLRZ J,(T1) ;RESTORE J HRRZ F,(T1) ;+F MOVEI T2,(T1) ;RETURN FREE CORE MOVEI T1,1 PUSHJ P,GIVWDS## PUSHJ P,SVEUB## ;MAKE JOB ADDRESSABLE JRST DVHN1A ;CHECK TO SEE IF HE'S STILL HERE DVHN1C: PUSHJ P,ZAPDSK## ;REMOVE ALL DDBS OWNED BY JOB FROM UNI/CHN Q'S PUSH P,F ;GIVSRC CLOBBERS F PUSHJ P,GIVRSC ;RETURN RESOURCES, COULD HAVE SOME, IF STR YANKED POP P,F ;RESTORE F MOVEI T1,STOPQ## DPB T1,PJBSTS## IFN FTMP,< CPUNLK (SCD) > DEVHN2: JSP T1,ERRDEV ASCIZ /Hung / JRST DEVEXC ;BAD DECTAPE DIRECTORY ;CALLED AT INTERRUPT AND UUO LEVELS WITH F AND J SETUP BADDIR::PUSHJ P,SVEUF## ;MAKE JOB DATA AREA ADDRESSABLE JSP T1,ERRPNT ASCIZ /Bad directory for / ;ROUTINE TO PRINT "DEVICE XXX; EXEC CALLED FOR EXEC/USER YYY" ;THEN STOP JOB ;TO BE USED BY DEVICE DEPENDENT ERROR MESSAGES AFTER JSP T1,DEVERR DEVEXC::PUSHJ P,ERNAM ;PRINT "DEVICE XXX" PUSHJ P,TTYKLQ## ;KILL OFF TTY DDB IF NECESSARY SKIPE JBTADR##(J) ;CHECK FOR JOB IN CORE JRST EXCALP ;PRINT "EXEC CALLED FROM EXEC/USER LOC YYY" JRST PCSTOP ;JUST STOP THE JOB ;ROUTINE TO HALT A JOB WHEN A DEVICE IS NOT READY FOR I/O ;CALLED FROM XXXSER AT UUO LEVEL ;CALL MOVE F,ADDR. OF DEV. DDB ; PUSHJ P,HNGSTP ;WILL DISPATCH TO USER'S AREA IF JOBINT IS NON-0 HNGSTP::PUSH P,M PUSH P,J PUSHJ P,HNGSTX POP P,J PJRST MPOPJ## HNGSTX: PUSHJ P,SAVE3## ;SAVE P1-P3 SKIPE P3,DEVEVM(F) ;DOES DEVICE HAVE EVM? SETO P3, ;NO PUSHJ P,RTNEVM## ;RETURN ANY EVM DEVICE HAS FOR I/O ; P3=-1 IF DEVICE HAD NO EVM, 0 IF IT DID SOS .JDAT+JOBPD1##+1 ;BACK UP PC HRRZ T4,DEVSER(F) ;DISK? CAIE T4,DSKDSP## JRST HNGSTZ ;NO MOVEI T4,.EROFL ;ASSUME OFF-LINE HRRZ P1,DEVUNI##(F) ;IS IT? MOVE P1,UNIDES##(P1) TLNN P1,UNPOFL## HNGSTZ: MOVEI T4,.ERIDV ;PROBLEM ON DEVICE TLO M,(1B0) PUSHJ P,PSIJBI## ;CALL PSISER PJSP P1,HNGST1 ;P1 NON-ZERO TO INDICATE INTERCEPTING TLZ M,(1B0) SETO T2, ;MAKE T2 NON-ZERO SO LATER CHECKS WILL WORK LDB J,PJOBN## SKIPE T3,JBTSTS##(J) TRNN T3,JS.ASA PUSHJ P,CHKINT ;SEE IF SET UP SETZB T2,T3 ;NO MOVE P1,T2 ;SAVE LOCATION PUSHJ P,DOINT ;PREPARE INTERCEPT JUMPN T2,HNGST1 ;IF NOT INTERCEPTING PUSHJ P,INCPD1## HNGST1: JUMPL T3,HNGST3 ;YES, DOES HE WANT THE ERROR MESSAGE? PUSH P,W PUSH P,S PUSH P,U PUSH P,F ;SAVE DEV'S S WORD & DDB PUSHJ P,FNDPDS## ;FIND PDB AND PUT IT'S ADDRESS IN W ; IF NONE HALT. EXCH F,0(P) ;GET F FROM DEVICE LDB T1,PDVSTA## ;GET JOB'S LOCATION EXCH F,0(P) ;GET F FOR TTY BACK JUMPE T1,HNGST2 ;CENTRAL SITE IF 0 (DISK) IFN FTNET,< PUSHJ P,STBOPR## ;GET OPR LINE > IFE FTNET,< MOVE U,OPRLDB## SE1XCT > SKIPA U,LINTAB##(T1) ;GET LDB ADDR HNGST2: MOVE U,OPRLDB## ;CENTRAL STA OPR PUSHJ P,INLMES## ;OUTPUT START OF MESSAGE ASCIZ / %Problem on / PUSHJ P,ERNAM ;PRINT PHYSICAL DEVICE NAME (USING -1(P)) PUSHJ P,INLMES## ;LOGICAL DEVICE OPR ASCIZ / for job / PUSHJ P,PJOB## PUSHJ P,CRLF## PUSHJ P,DETJCK ;DETACHED? JRST HNGST8 ;YES,NO MESSAGES PUSHJ P,TTYFUW## ;FIND CURRENT JOB'S TTY PUSHJ P,CRLF## ;START A NEW LINE PUSHJ P,ERNAM ;PRINT "DEVICE XXX" PUSHJ P,INLMES## ;AND MSG. ASCIZ /, OPR/ IFN FTNET,< EXCH F,(P) ;GET POINTER DDB LDB T1,PDVSTA## ;GET DEVICES LOCATION EXCH F,(P) S0PSHJ CVTSBT## ;CONVERT TO SIXBIT MOVE T2,T1 ;GET SIXBIT FOR PRNAME PUSHJ P,PRNAME## ;AND PRINT IT > PUSHJ P,INLMES## ASCIZ / action requested / MOVEI T1,TTYSTR## ;UNLESS ERROR INTERCEPTING SKIPN P1 ;CALL HOLD0 (STOP JOB,START TTY) HNGST8: MOVEI T1,HNGST4 ;SET UP ROUTINE TO CALL PUSHJ P,(T1) ;START TTY TYPING ERR MESSAGE ; LEAVE IN COMMAND MODE ;DO NOT SET JOB ERROR SO CAN CONTINUE POP P,F ;BRING BACK DEV DDB & S WORD POP P,U POP P,S POP P,W JUMPN P1,HNGST3 ;DO INTERCEPT IF WANTED PUSHJ P,WSCHED## ;RESCHEDULE HRRZ T1,DEVSER(F) ;IS THIS A DISK? CAIE T1,DSKDSP## JRST HNGST9 ;NO, SKIP THIS PUSHJ P,CHEKU## ;YES, WAS F/S YANKED? PJRST DEVHNG ;YES, SAY IT'S HUNG HNGST9: AOJN P3,CPOPJ## ;DEVICE HAVE EVM WHEN THE ERROR OCCURRED? MOVE M,-5(P) ;RESTORE M FOR ADDRESS CHECK PJRST RSTEVM## ;YES, RESTORM EVM FOR I/O HNGST3: MOVEI T1,DEPOND!DEPIND ;NON-BLOCKING I/O NOT DONE BITS ANDCAM T1,DEVAIO(F) ;CLEAR THEM SO THAT IN/OUT UUOS WILL WIN MOVEI P1,1(M) ;SAVE 1(INTERCEPT LOC) LDB T1,PIOMOD## ;MODE MOVE T4,DEVADV(F) TLNN T4,DEPADV CAIL T1,SD ;DUMP? JRST HNGST7 ;YES, NO BUFFERS TO FIX HRR M,DEVBUF(F) ;BUFFERED, FIX UP BUFFER HDR TLNE S,IO ; SO REPEATING THE UUO WILL WIN HLR M,DEVBUF(F) ; (THEY WERE ALREADY ADVANCED) HRRZ T4,M ;SAVE LOCATION OF THE HDR JUMPE T4,HNGST7 ;JUMP IF NO BUFFERS YET SET UP PUSHJ P,GETWRD## ;GET LOCATION OF FIRST BUFFER JRST HNGST7 ;ADDRESS CHECK - CAN'T FIX THE RING MOVE P2,T1 ;P2=ADDRESS OF FIRST BUFFER MOVEI T3,10000 ;END OF LOOP INSURANCE HNGST5: HRR M,T1 ;M=ADDRESS OF THIS BUFFER PUSHJ P,GETWRD## ;GET THE ADDRESS OF THE NEXT ONE JRST HNGST7 ;ADDRESS CHECK, FORGET IT CAIE P2,(T1) ;THE ONE WE WANT? SOJGE T3,HNGST5 ;NO, STEP TO NEXT JUMPL T3,HNGST7 ;YES, JUMP IF RING WAS NOT CLOSED HRR P2,M ;P2=POINTER TO NEXT BUFFER TLO T1,IOUSE ;INDICATE "FULL" FOR TEST AT INPUT PUSHJ P,PUTWDU## ;STORE THAT HRR M,T4 ;RESTORE HEADER ADDRESS MOVE T1,P2 ;T1=DEADVANCED BUFFER POINTER PUSHJ P,PUTWDU## ;STORE THAT IN THE HDR HNGST7: HRRI M,(P1) ;M=ADDRESS OF THIRD WORD OF INT. BLOCK PUSHJ P,GETWDU## ;FETCH IT HLR T1,.USCTA SKIPL M ;SKIP IF PSISER TRAP PUSHJ P,PUTWDU## ;STORE FOR INTERRUPT ROUTINE QKUSXT:: ERRGOU::HRRI P,.JDAT+JOBPD1##+1 ;SET P FOR NORMAL EXIT ;(POP P,UUO0 ; JRST @UUO0) SETZB F,.CPISF## ;NO LONGER AT SCHEDULER LEVEL SETZM .CPSCF## ;CLEAR FORCED RESCHEDULE FLAG NTGIVE ;RETURN NETWORK INTERLOCK PJRST USRXIT## ;LET UUOCON RETURN TO USER HNGST4: MOVEI T1,JDCON ;NO ERROR INTERCEPT IORM T1,JBTSTS##(J) ; SO SET DEV CONT BIT MOVSI T1,(UP.DST) ;MAKE THIS JOB LOOK DETACHED IORM T1,.USBTS ; SO IT'S TERMINAL IS NOT PUT ; AT COMMAND LEVEL. PJRST STOP1C## ;STOP JOB-SETUP TO RESCHEDULE ; BUT DO NOT CALL WSYNC ;ROUTINE TO SEE IF A JOB'S TTY IS DETACHED, CPOPJ1 IF ATTACHED ;CLOBBERS T1 DETJCK::PUSH P,U ;SAVE SOME ACS PUSH P,S PUSH P,F PUSH P,J PUSHJ P,TTYSRC## ;FIND JOB'S TTY CAIA ;NONE SKIPN U ;OR DETACHED SOS -4(P) ;DETACHED PRIV'ED JOB RETURN POP P,J POP P,F POP P,S JRST UPOPJ1## ;CHKINT -- ROUTINE TO SETUP FOR JOBINT USAGE ;CALL: MOVEI T4,ERROR TYPE (CLASS) ; PUSHJ P,,CHKINT ;SKIP RETURNS M = RELATIVE BLOCK ADDRESS+2 (WHERE OLD PC IS STORED) ; T1 = NEW PC ; T3 = CONTENTS OF BITS,,CLASS ;STORES ERROR TYPE IN BLOCK+3. CHKINT::SKIPN JBTADR##(J) ;JOB HAVE CORE? POPJ P, ;NO - THEN NO JOBINT MOVE T1,JBTSTS##(J) ;JOB STATUS TLNN T1,SWP ;IS JOB SWAPPED OR TRNE T1,JS.ASA ;EXEC MODE UUO IN PROGRESS? POPJ P, ;YES, DON'T TRAP HRR M,.JDAT+JOBINT## ;GET ERROR LOCATION ; SET M FOR GETWRD/PUTWRD HRRZ T1,M ;CHECK FIRST WORD OF INTERRUPT VECTOR TRNE M,-1 ;NO INTERRUPT IF JOBINT NOT SET PUSHJ P,FLTST## ;IN-CORE? POPJ P, ;NO ADDI T1,3 ;LAST WORD OF VECTOR PUSHJ P,FLTST## ;IN-CORE? POPJ P, ;NO PUSHJ P,GETWRD## ;GET NEW PC POPJ P, ;ADDRESS CHECK - GIVE UP HRL T4,T1 ;SAVE NEW PC PUSHJ P,GETWR1## ;GET BITS,,CLASS POPJ P, ;OUT OF BOUNDS MOVE T3,T1 ;SAVE THOSE PUSHJ P,GETWR1## ;GET OLD PC POPJ P, ;ADDRESS CHECK - GIVE UP TRNE T4,-1 ;IF SPECIAL, TRNE T3,(T4) ; SEE IF USER OMITTED IT SKIPE T1 ;SEE IF IN USE ALREADY POPJ P, ;YES - GIVE UP PUSHJ P,GETWR1## ;GET THE OLD WORD POPJ P,0 ; ADDRESS CHECK TLO T1,(T4) ;TURN ON THE NEW BIT TRNE T4,.ERQEX!.ERFUL!.EROFL!.ERIDV ;IS THERE A CHANNEL ASSOCIATED? HLR T1,.USCTA ;YES, RETURN ASSOCIATED CHANNEL PUSHJ P,PUTWRD## ; STORE ERROR BITS POPJ P, ;ADDRESS CHECK - GIVE UP HLRZ T1,T4 ;GET NEW PC JUMPE T1,CPOPJ## ;GIVE UP IF JUNK SOJA M,CPOPJ1## ;OK RETURN ;DOINT -- ROUTINE TO PERFORM THE JOBINT ;CALL: MOVE T1,NEW PC ; MOVEI M,USER VIRTUAL ADDRESS OF INTERRUPT BLOCK + 2 ;RETURN WITH JOBPD1 UPDATED DOINT:: JUMPE T2,CPOPJ## ;IF NO BLOCKS, GIVE UP DOINT1::PUSH P,T1 ;THIS COULD BE CHEAPER IF 2 ACS COULD BE USED, BUT? GETPC T1,.JDAT+JOBPD1## ;GET UUO PC TLO T1,(XC.USR) ;MAKE SURE USER MODE IS ON HLLM T1,(P) ;COPY FLAGS FOR THE USER EXCH T1,(P) ;PC TO TRAP TO PUTPC T1,.JDAT+JOBPD1## ;STORE NEW PC POP P,T1 ;RESTORE OLD PC PJRST PUTWDU## ;STORE OLD PC AND RETURN ;ROUTINE TO PRINT "SWAP READ ERROR" ;CALLED FROM SWAPPER AT CLOCK LEVEL (USUALLY) ;CALL: MOVE J,JOB NUMBER ; PUSHJ P,ERRSWP ; ALWAYS RETURN TO SWAPPER ERRSWP::PUSHJ P,SVEUB## ;LOAD UBR MOVSI T1,JERR ;SET JERR SO WE DO NOT IORM T1,JBTSTS##(J) ;TRY TO INTERCEPT AOS T1,SWETOT## ;COUNT ANOTHER ERROR CAMG T1,SWEECT## ;OVER THE THRESHOLD? JRST ERRSW1 ;NO PUSH P,U ;SAVE U MOVE U,OPRLDB## ;WHERE TO TYPE MESSAGE PUSHJ P,INLMES## ;PRINT SOME WARNING ON CTY ASCIZ / ?Swap read error for job/ PUSHJ P,PRJBNM ;PRINT THE INFO PUSHJ P,CRLF## ;END THE LINE POP P,U ;RESTORE U ERRSW1: JSP T1,ERRPNT ;PRINT MESSAGE ASCIZ /Swap read error/ PJRST PCSTOP ;START TTY AND SET JERR BIT SO ; JOB CANNOT CONTINUE. PI 7 WILL NOT ; BE REQUESTED SINCE SWAPPING JOB CANNOT ; BE CURRENT JOB. ;ERRPNT PUSHED TWO AC'S. PCSTOP REMOVES THEM SUBTTL COMMON ERROR MESSAGE ROUTINES ;COMMON ERROR MESSAGE SETUP ROUTINES ;CALL: JSP T1,ERRPTU, ERRDEV, OR ERRPNT ; ASCIZ /message/ ; RETURNS HERE WITH F SAVED 0(P) ; C(F)=TTYDDB, U TO TTY OUTPUT BUFFER POINTER ; J=JOB NUMBER, W=ADDR OF PDB ;USE ERRPTU IF AT UUO LEVEL FOR SURE ;ERRDEV IF ERROR FOR AN ASSIGNED DEVICE AT ANY LEVEL ;ERRPNT WITH J ALREADY SET TO OFFENDING JOB NUMBER ;THE JSP CALL IS USED IN CASE PUSHDOWN SPACE BECOMES CRITICAL ;AGAIN AND ERRPNT HAS TO WIPE EXISTING LIST OUT ERRPTU::SKIPA J,.CPJOB## ;BLAME CURRENT JOB IF NOT 0. ERRDEV::LDB J,PJOBN## ;JOB NO. FROM DEVICE DATA BLOCK ERRPNT::PUSHJ P,FNDPDB## ;FIND PDB FOR THIS JOB HRRZ W,JBTPDB## ;USE NULL JOB'S PDB SKIPN J ;ERROR IN NULL JOB? SETOM .CPNJE## ;YES, SET FLAG FOR ERROR IN NULL JOB ; SO STATE OF NULL JOB WILL BE REESTABLISHED ; WHEN IS IT RUN AGAIN(SEE CLOCK1) CAILE J,JBTMAX## ;JOB NUMBER OR SEGMENT NUMBER STOPCD .,STOP,SOR, ;++SEG OUT OF RANGE PUSH P,U ;SAVE CALL TO ERROR(JSP U,ERROR) PUSH P,F ;SAVE ADR. OF DEV. DATA BLOCK PUSH P,T1 ;SAVE RETURN FROM ERRPNT MOVE T1,JBTSTS##(J) TDNE T1,[JERR,,JS.ASA] JRST ERRPT1 PUSHJ P,USREIJ## ;SIGNAL USER ERROR JRST ERRGOU MOVEI T4,.EREIJ ;DOES THIS JOB WANT PUSHJ P,CHKINT ; TRAP ALL ERRORS? JRST ERRPT1 ;NO--BOMB HIM OUT JUMPGE T3,ERRPT1 ;JUMP IF HE WANTS MESSAGE MOVE T2,M ;NO MESSAGE PUSHJ P,DOINT ;PREPARE INTERCEPT ;***NEED TO STORE ERROR CODE*** PJRST QKUSXT ;BACK TO USER ERRPT1: PUSHJ P,TTYERP## ;FIND TTY FOR THIS ERROR (VIA J) PUSHJ P,ERINDJ ;ERROR IN DETACHED JOB PUSHJ P,INLMES## ASCIZ /? / PUSHJ P,PRQM## ;PRINT QUESTION MARK ON NEXT LINE ; FOR BATCH AND SCRIPT PJRST INLMES## ;PRINT MESSAGE SPECIFIED BY CALLER ; AND RETURN TO LOC. AFTER MESSAGE ERINDJ::JUMPE J,ERINNJ ;JUMP IF NULL JOB PUSHJ P,INLMES## ;PRINT ERROR MESSAGE ASCIZ /?Error in detached job/ PUSHJ P,PRJBNM ;PRINT JOB # AND PROGRAM NAME PJRST CRLF## ;PRINT AND RETURN ERINNJ: PUSHJ P,INLMESS## ;PRINT ERROR MESSAGE ASCIZ /?Error in job 0 (null job) / POPJ P, ;ROUTINE TO PRINT UUO PC AND STOP JOB ;IF IN USER MODE PC WILL PRINT AS "AT USER LOC XXX" ;IF IN EXEC MODE "AT EXEC LOC XXX; EXEC CALLED FORM EXEC/USER/ LOC YYY UUOMES: PUSHJ P,CONMES## ;PRINT MESSAGE POINTED TO BY T1 UUOPCP::DMOVE T1,.JDAT+JOBPD1## ;UUO PC STORED IN JOB DATA AREA ; FIRST LOC ON PD LIST SOJA T2,DPCPNT ;DECREMENT TO POINT TO UUO IN USER AREA ;ROUTINE TO PRINT ONE OF THREE MESSAGES AND STOP JOB ;1) "AT EXEC LOC XXX; EXEC CALLED FROM EXEC LOC YYY" ;2) "AT EXEC LOC XXX; EXEC CALLED FORM USER LOC YYY" ;3) "AT USER LOC YYY" ;CALL: MOVE T2, XXX ;WITH PC FLAGS IN LH ; PUSHJ P,PCPNT ; NEVER RETURN IF AT UUO LEVEL PCPNT: TLNE T2,USRMOD ;MAKE SURE CONTROL-T MOVEM T2,JBTPC##(J) ; GIVES CORRECT ANSWER PUSHJ P,PCP ;PRINT " AT EXEC XXX" OR " AT USER " TLNE T2,USRMOD ;WAS PC IN USER MODE? JRST PCSTOP ;YES, ENOUGH INFO. JRST EXCALP ;NO, GIVE UUO INFO ;SAME AS PCPNT EXCEPT PRINTS A DOUBLE WORD PC IN T1 AND T2 DPCPNT: TLNE T1,USRMOD ;MAKE SURE CONTROL-T MOVEM T2,JBTPC##(J) ; GIVES CORRECT ANSWER PUSH P,T1 ;DPCP WIPES T1 PUSHJ P,DPCP ;PRINT " AT EXEC XXX" OR " AT USER " POP P,T1 ;GET FLAGS BACK TLNE T1,USRMOD ;WAS PC IN USER MODE? JRST PCSTOP ;YES, ENOUGH INFO. ;ROUTINE TO PRINT "; UUO AT [EXEC or USER] PC XXXXXX" AND STOP JOB ;CALL: PUSHJ P,EXCALP ; NEVER RETURNS IF AT UUO LEVEL EXCALP: PUSHJ P,INLMES## ASCIZ /; UUO/ DMOVE T1,.JDAT+JOBPD1## ;UUO PC IN JOB DATA AREA SUBI T2,1 ;BACK IT UP TO POINT TO UUO PUSHJ P,DPCP ;PRINT "EXEC LOC " OF USER LOC PCSTOP::PUSH P,U JUMPN J,PCSTP5 ;NULL JOB? PUSHJ P,TTYERP ;YES--FIND THE OPR JRST PCSTP6 ;WE HAVE A VALID LINE STOPCD .,STOP,NJT, ;NULL JOB HAS TTY PCSTP5: PUSHJ P,TTYSRC## ;SET TTY STOPCD .,STOP,LN1, ;NONE?! JUMPE U,PCSTP2 ;IS IT DETACHED? PCSTP6: SKIPE T1,F ;SKIP IF NO DDB LDB T1,PJOBN## ;GET JOB # CAMN T1,J ;IS THIS THE TTY OF THE LOOSER PUSHJ P,TSETBI## ;CLEAR TYPE-AHEAD PCSTP2: MOVE T1,JBTSTS##(J) ;GET JOB STATUS TDNE T1,[JERR,,JS.ASA] ;CAN WE INTERCEPT JRST PCSTP1 ;NO--STOP JOB PUSHJ P,PSIERR## JRST PCSTP4 ;AT CLOCK LEVEL, CATCH IT AT CIPXIT JRST ERRGOU ;AT UUO LEVEL, CATCH IT AT USRXIT MOVEI T4,.EREIJ ;DOES THIS JOB WANT CAMN J,.CPJOB## ;CANT INTERCEPT IF ON CLOCK LEVEL PUSHJ P,CHKINT ; TRAP ALL ERRORS? JRST PCSTP1 PUSHJ P,DOINT1 ;PREPARE INTERCEPT PJRST QKUSXT ;BACK TO USER PCSTP1: JUMPN U,PCSTP3 ;IS JOB DET'D POP P,U PUSHJ P,CRLF## ;YES, PUSHJ P,ESTOP## ;STOP JOB JRST ECONT ;RESUME FLOW PCSTP3: PUSHJ P,HOLD## ;STOP JOB SET ERROR BIT PCSTP4: POP P,U ;HERE TO CONTINUE AFTER ERROR (IF AT PI LEVEL OR USER TYPES CONT) ECONT: POP P,F ;RETURN ONLY IF AT INTERRUPT LEVEL JRST TPOPJ## ;REMOVE ERROR CALL AND RETURN ;ALTHOUGH U WAS PUSHED, POP INTO T1, PERSERVE LINE NUMBER ;ROUTINE TO PRINT PC AS: ;1) "EXEC PC XXX" OR "USER PC XXX" ;CALL: MOVE T2,PC TO PRINT(LH=PC FLAGS) ; PUSHJ P,PCP XMODE: ASCIZ / at exec PC / UMODE: ASCIZ / at user PC / PCP:: MOVEI T1,XMODE ;ASSUME PC IN EXEC MODE TLNE T2,USRMOD ;IS IT? PCPU: MOVEI T1,UMODE ;NO, USER MODE PUSHJ P,CONMES## ;PRINT ONE OR OTHER HRRZ T1,T2 ;PRINT RIGHT HALF IN OCTAL PJRST OCTPNT## ; FALL INTO OCTPNT ;ROUTINE TO PRINT A DOUBLE WORD PC ;CALL: MOVEI U,LDB ; DMOVE T1,[EXP FLAGS,PC] ; PUSHJ P,DPCP DPCP:: TLNN T1,(XC.USR) ;PC IN USER MODE? SKIPA T1,[XMODE] ;NO, TYPE AT EXEC MUMBLE MOVEI T1,UMODE ;YES, TYPE AT USER MUMBLE PUSHJ P,CONMES## ;TYPE IT UDPCP:: HRRZ T1,T2 ;ONLY EIGHTEEN BITS IF NOT AN XADR TLNN T2,(SECMSK) ;NON-ZERO SECTION? PJRST OCTPNT## ;NO, PRINT IT IN THE TRADITIONAL WAY PUSH P,T1 ;SAVE LOW EIGHTEEN BITS HLRZ T1,T2 ;SECTION NUMBER PUSHJ P,PRTDI8## ;PRINT THAT MOVEI T1,[ASCIZ /,,/] ;ZERO SUPPRESSED OCTAL PAIRS PUSHJ P,CONMES## ;PRINT SEPERATER POP P,T1 ;LOW EIGHTEEN BITS OF PC PJRST OCTPNT## ;FINALLY PRINT THAT ;ROUTINE TO PRINT "DEVICE XXX" ;CALL MOVE U,ASCII OUTPUT BYTE POINTER ; PUSH P,F ; PUSHJ P,ERNAM ERNAM:: PUSHJ P,INLMES## ASCIZ /device / SKIPN T2,-1(P) ;IS F = 0? PJRST PRNAM1## ;YES, MESSAGE WITHOUT NAME (PRINT A SPACE) HRRZ T1,DEVSER(T2) ;IS THIS A DISK? CAIE T1,DSKDSP## JRST ERNAM1 ;NOT DISK, GET PHYSICAL DEVICE NAME SKIPN T1,DEVUNI##(T2) ;GET CURRENT UNIT DATA BLOCK ADDRESS SKIPE T1,DEVFUN##(T2) ;IF UNIT REMOVED, GET SAVED ADDRESS SKIPA T2,UDBNAM(T1) ;GET PHYSICAL UNIT NAME AND SKIP TO PRNAM1 ERNAM1: MOVE T2,DEVNAM(T2) ;NO, GET DEVICE NAME PJRST PRNAME## ;FALL INTO PRNAME SUBTTL THE END LIT ERREND: END