TITLE PSISER -- PROGRAMMED SOFTWARE INTERRUPT SERVICE V274 SUBTTL C. D. O'TOOLE/CDO/RCB 27-OCT-87 SEARCH F,S $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 VPSISR,274 PSISER: ENTRY PSISER XP PSIMPI,3 ;MAXIMUM PRIORITY LEVEL IFL PSIMPI, IFG , IFL <^D35+C$MIN>, IFN PSIMPI,< CNDSIZ==7 ;SIZE OF BYTE FOR OFFSET PSIMVO==:^D127*4 ;MAX VECTOR OFFSET ( FOR GETTAB ) > IFE PSIMPI,< CNDSIZ==9 ;SIZE OF BYTE FOR OFFSET PSIMVO==:^D511*4 ;MAX VECTOR OFFSET ( FOR GETTAB ) > DEFINE BITS(NAME,X),>> ;THE FOLLOWING CONDITIONS ARE IGNORED WHEN IN PFH OR CANNOT BE ; GRANTED IMMEDIATELY. C$TLE IS INCLUDED AND IS SPECIAL CASED. ; IF A CONDITION IS IGNORED, IT CAN BE FATAL TO THE JOB (C$IMR). BITS(IMBITS,) ;THE FOLLOWING IMMEDIATE CONDITIONS FIND THE USERS PC IN JOBPD1. ; ALL OTHERS GET THE PC FROM .CPPC BITS(PD1BIT,) ;THE FOLLOWING CONDITIONS HAVE A STANDARD MESSAGE ASSOCIATED WITH THEM ; AND WILL BE DEFERRED UNTIL AFTER PRINTING IF THE USER REQUESTED ; THE MESSAGE. ALL CONDITIONS HERE MUST ALSO BE IN IMBITS. BITS(MSGBIT,) IFN <-MSGBIT>,< IMBITS==IMBITS ;SHOW BITS IN LISTING MSGBIT==MSGBIT ;SHOW BITS IN LISTING PRINTX ? MESSAGE CONDITIONS MISSING FROM IMMEDIATE CONDITIONS> ;SOME BITS FOR EASY TESTS AGAINST ENABLED CONDITIONS FOR THE USER BITS(APRBIT,) BITS(AUUBIT,) BITS(TLEBIT,) BITS(JBIBIT,) BITS(QUEBIT,) BITS(WAKBIT,) BITS(CTCBIT,) BITS(TMRBIT,) BITS(DTCBIT,) SUBTTL DATA STRUCTURES ;USER INTERRUPT BLOCK FORMAT PHASE 0 .PSVNP:! BLOCK 1 ;USERS NEW PC .PSVOP:! BLOCK 1 ;USERS OLD PC .PSVFL:! BLOCK 1 ;INTERRUPT CONTROL FLAGS ; 0-17 ARE CONTROL FLAGS ;18-35 ARE REASONS FOR DEVICE INTERRUPTS PS.XXX==1B0 ;*** RESERVED PS.VPO==1B1 ;TURN OFF UNTIL PISYS. TURNS IT BACK ON PS.VTO==1B2 ;TURN OFF HIGHER LEVELS UNTIL DEBRK. PS.XXX==1B3 ;*** RESERVED PS.VDS==1B4 ;DISMISS ANY OTHER PENDING AT DEBRK. ; FOR THE CONDITION IN PROGRESS PS.VPM==1B5 ;PRINT APPROPRIATE MESSAGE FOR THIS CONDITION PS.XXX==1B6 ;*** RESERVED .PSVIS:! BLOCK 1 ;INTERRUPT STATUS WORD DEPHASE ;THE FOLLOWING DATA BASE IS BUILT FOR EACH USER OF PSISER. ;JBTPIA(J) CONTAINS CONTROL FLAGS AND THE ADDRESS OF THE TABLE. PHASE 0 PITNPI:! BLOCK 1 ;NUMBER OF PENDING INTERRUPTS (MUST BE FIRST) PITSTS:! BLOCK 1 ; 0 ON IF ^C FROM TI WAIT PITQAB==1B1 ; 1 ON IF C$QUE IS ABORTING REQUEST ; 2-8 FREE ; 9-17 WAKING JOB FOR C$WAKE ;18-35 REQUEST ID FOR C$QUE PITST2:! BLOCK 1 ;ENTIRE WORD USED FOR PIJBI. UUO PITST3:! BLOCK 1 ;ENTIRE WORD USED FOR C$DTC PITIVA:! BLOCK 1 ; 0-8 HIGHEST VECTOR IN USE ; 9-17 SECTION OF USER'S BASE ;18-35 ADDRESS OF USER'S BASE IFN PSIMPI,< PITHLP:! BLOCK 1 ;HIGHEST LEVEL IN PROGRESS ( -1 IF NONE ) > PITCIB:! BLOCK ;FULLWORD ADDRESS OF CURRENT INTERRUPT BLOCK PITCIC:! BLOCK ;LH = PC FLAGS IF EXTENDED ADDRESSING MODE ;RH = CURRENT INTERRUPT CONDITION OR DDB PITCHN:! BLOCK 1 ;LH = DEVICE CHAIN FOR "ADDED" DEVICES ;RH = FLAG DURING PRINTING OF ERROR MESSAGE PITENB:! BLOCK 1 ;BIT MAP FOR ENABLED CONDITIONS (NON-DEVICE) PITPND:! BLOCK 1 ;BIT MAP FOR PENDING CONDITIONS (NON-DEVICE) PITMSG:! BLOCK 1 ;BIT MAP FOR WANTED MESSAGES (NON-DEVICE) PITTAB:! BLOCK <<-C$MIN+1>+3>/4 ;9 BITS FOR EACH NON-DEVICE CONDITION PITSIZ::! ;SIZE OF THE DATA BASE IN WORDS IFN PITNPI, DEPHASE RELOC PSISER ;SAVE SPACE VECBAS: POINT 23,PITIVA(P1),35 ;GLOBAL ADDRESS OF USER'S VECTOR VECBS2: POINT 23,PITIVA(T1),35 ;ANOTHER WAY OF ADDRESSING IT SUBTTL UUOCON INTERFACE -- PIINI. ;CALL TO INIT THE PI SYSTEM ;CALL WITH: ; MOVEI AC,BASE-ADDRESS-OF-INTERRUPT-VECTOR ; PIINI. AC, ; HERE IF SYSTEM NOT AVAIL ; NORMAL RETURN IS HERE PIINI:: PUSHJ P,SAVE1## ;SAVE AN AC TLNN T1,(PS.IEA) ;USER REQUESTING EXTENDED ADDRESSING? HRRZS T1 ;NO, USE SECTION 0 MOVE P1,T1 ;PRESERVE THE USER'S ARGUMENT TLZ T1,(PS.IEA) ;CLEAR ILLEGAL ADDRESSING BIT IFN FTXMON,< PUSHJ P,SSPCS## ;SAVE PCS (FOR PIRST) > PUSHJ P,SXPCS## ;CHECK FOR VALID SECTION/BIT COMBINATION JRST ECOD1## ;(01) ILLEGAL SECTION NUMBER/BIT COMBINATION HRRZS T1 ;IADRCK ADDS IN PCS PUSHJ P,IADRCK## ;CHECK ADDRESS VALIDITY JRST ECOD2## ;(02) BAD ADDRESS JFCL ;PAGED OUT. ASSUME IT WILL COME IN. IFN FTXMON,< XSFM T1 ;GET CURRENT PCS TLNE P1,(PS.IEA) ;IF USER REQUESTED EXTENDED ADDRESSING, TRO T1,(PS.IEA) ;PROPAGATE THE BIT HRL P1,T1 ;UPDATE LH OF ARGUMENT REGISTER > PUSHJ P,CLRPSI ;CLEAR OLD DATA MOVEI T2,PITSIZ ;NUMBER OF WORDS TO GET PUSHJ P,GETWDS## ;GO GET THEM JRST ECOD3## ;(03) INSUFFICIENT MONITOR FREE CORE HRLI T2,(T1) ;PREPARE TO CLEAR THE DATA BASE HRRI T2,1(T1) ;DESTINATION SETZM 0(T1) ;CLEAR THE BEGINNING BLT T2,PITSIZ-1(T1) ;CLEAR THE REST IFN PSIMPI, ;SET INTERRUPT LEVEL TO -1 TLZE P1,(PS.IEA) ;USING EXTENDED ADDRESSING? TLOA T1,(SI.UEA) ;YES, MARK IT TLZA P1,-1 ;NO, CLEAR LH OF USER'S VECTOR ORIGIN TLZ P1,^-<(SECMSK)> ;YES, LEAVE SECTION NUMBER ALONE MOVEM P1,PITIVA(T1) ;STORE IN PIT MOVEM T1,JBTPIA##(J) ;STORE ADDRESS IN HANDY PLACE JRST CPOPJ1## ;GOOD RETURN ;SUBROUTINE TO CLEAR THE SOFTWARE INTERRUPT SYSTEM ;CALL WITH: ; J = JOB # ; PUSHJ P,CLRPSI ; RETURN HERE ALWAYS CLRPSI::HRRZ T2,JBTPIA##(J) ;GET ADDRESS OF PIT JUMPE T2,CPOPJ## ;RETURN IF ZERO HLRZ F,PITCHN(T2) ;GET START OF PSI DDBS SETZM JBTPIA##(J) ;CLEAR USERS TABLE NOW MOVEI T1,PITSIZ ;NUMBER OF WORDS WE HAVE PUSHJ P,GIVWDS## ;RETURN THE CORE PUSHJ P,CLRTMR ;REMOVE ANY TIMER QUEUE REQUESTS CLRP.1: JUMPE F,CPOPJ## ;RETURN WHEN OUT OF DDBS SETZM DEVPSI(F) ;CLEAR INTERRUPT BITS HLRZ F,DEVESE(F) ;STEP TO NEXT DDB JRST CLRP.1 ;LOOP OVER ALL DDBS ;SUBROUTINE TO REMOVE ANY TIMER QUEUE ENTRIES FOR PITMR. CLRTMR: PUSHJ P,CTXJCJ## ;GET INTERRUPT HANDLE FROM CTXSER POPJ P, ;OK IF NONE MOVE T2,[PSITMR,,1] ;REQUEST TO CHANGE TO EXPIRE IN 1 TICK PUSHJ P,CLKCHG## ;SEARCH FOR/MODIFY EXISTING ENTRY POPJ P, ;OK IF DIDN'T FIND ONE POPJ P, ;DONE SUBTTL UUOCON INTERFACE -- PISYS. ;CALL TO MANIPULATE THE PI SYSTEM ;CALL WITH: ; MOVE AC,[XWD FLAGS,ADDRESS] ; PISYS. AC, ; HERE ON AN ERROR ; HERE WHEN FUNCTION COMPLETE ; ;ADDR: CONDITION-REQUESTED OR DEVICE-ENABLED (CHANNEL,DEVNAM,UDX) ; OFFSET-FROM-BASE(PIINI.) ,, REASONS-IF-DEVICE ; PRIORITY LEVEL ,, 0 PISYS:: PUSHJ P,SAVE4## ;SAVE A FEW FIRST TRNE T1,-1 ;ANY ADDRESS GIVEN? TLNE T1,(PS.CSI!PS.RDV!PS.ADV) ;IS ARGUMENT NEEDED? SKIPA ;YES PJRST ECOD0## ;(0) UNNECESSARY ARG SUPPLIED TLNN T1,(PS.ALL) ;ANYTHING TO DO? PJRST ECOD1## ;(1) NO FUNCTION GIVEN TLNE T1,<-1-PS.ALL>_<-^D18> ;ANY UNUSED BITS SET? PJRST ECOD2## ;(2) UNUSED BIT IS NOT = 0 SKIPN P1,JBTPIA##(J) ;PIINI. UUO DONE? JRST ECOD13## ;(13) PIINI. UUO NOT DONE MOVE P2,T1 ;COPY ARGUMENT TLNE P2,(PS.CPI) ;CLEAR PENDING INTERRUPTS? PUSHJ P,CLRAPI ;YES, CLEAR ALL PENDING INTERRUPTS TLNE P2,(PS.CSI) ;CLEAR FOR 1 CONDITION OR DEVICE? JRST [PUSHJ P,CLRSPI ;YES, CLEAR PENDING INTERRUPT POPJ P, ;ILLEGAL CONDITION OR DEVICE JRST .+1] ;RESUME INLINE CODE MOVSI T1,(SI.ON) ;PI SYSTEM ON BIT TLNE P2,(PS.ON) ;WANT TO TURN ON? JRST [TLNE P2,(PS.OFF) ;TURN SYSTEM OFF? JRST ECOD3## ;(3) BOTH TURN OFF AND TURN ON IORM T1,JBTPIA##(J) ;LIGHT THE BIT JRST PISY.1] ;RESUME INLINE CODE TLNE P2,(PS.OFF) ;WANT TO TURN OFF? ANDCAM T1,JBTPIA##(J) ;CLEAR THE SYSTEM ON BIT PISY.1: TLNE P2,(PS.RDV) ;WANT TO REMOVE DEVICE OR COND? PJRST REMDEV ;YES, GO DO THAT TLNE P2,(PS.ADV) ;WANT TO ADD? JRST ADDDEV ;YES, GO DO THAT JRST CPOPJ1## ;NO, ALL DONE ;SUBROUTINE CALLED BY UUOCON DURING RELEASE OF A DDB ;CALL ; F = DDB BEING RELEASED ; SKIPE DEVPSI(F) ; PUSHJ P,PSIRMV ;ALWAYS CPOPJ RETURN ;WIPES T1-T2 PSIRMV::SETZM DEVPSI(F) ;CLEAR ANY ENABLED BITS LDB T1,PJCHN## ;GET OWNER PUSHJ P,CTXPSI## ;GET PIT ADDRESS FROM CTXSER POPJ P, ;NO SUCH JOB? UUOCON MESSED UP. JUMPE T2,CPOPJ## ;NO PIT, HOW DID THOSE BITS GET LIT PUSHJ P,SAVE2## ;SAVE A FEW REGS NOW MOVE P1,T2 ;COPY DATA BASE ADDRESS UNLDDB: HLRZ P2,PITCHN(P1) ;GET FIRST DDB IN PSI CHAIN MOVEI P1,(P1) ;PRIME THE PUMP UNLD.1: JUMPE P2,CPOPJ## ;RETURN WHEN OUT OF DDBS CAIN P2,(F) ;ONE WE'VE BEEN LOOKING FOR JRST [HLL P2,DEVESE(F) ;YES, GET POINTER TO NEXT HLLM P2,DEVESE(P1) ;STORE IN PREVIOUS POPJ P,] ;AND RETURN WITH CHAIN UNLINKED MOVE P1,P2 ;NO, REMEMBER HOW WE GOT HERE HLRZ P2,DEVESE(P2) ;STEP TO NEXT PSI DDB JRST UNLD.1 ;CONTINUE SEARCH ;SUBROUTINE TO REMOVE A DEVICE OR CONDITION ;CALLED ONLY FROM PISYS UUO WITH: ; P1 = ADDRESS OF PRIORITY INTERRUPT TABLE ; P2 = USERS ARGUMENT ; PUSHJ P,REMDEV ; RETURN HERE ON ERROR ; RETURN HERE IF OK ; REMDEV: TLNE P2,(PS.ADV) ;ALSO WANT TO ADD DEVICE PJRST ECOD14## ;(14) BOTH ADD AND REMOVE SELECTED PUSHJ P,CHKCND ;CHECK THE CONDITION/DEVICE WORD POPJ P,0 ;INVALID JRST REMD.1 ;DEVICE CODE MOVSI T2,(1B0) ;GET A BIT LSH T2,(T1) ;POSITION IT CORRECTLY ANDCAM T2,PITENB(P1) ;CLEAR ENABLED BIT TRNE T2,JBIBIT ;IF THIS IS CROSS JOB INTERRUPT SETZM PITST2(P1) ;CLEAR PIJBI. UUO INTERLOCK ANDCAM T2,PITPND(P1) ;AND DEFERRED PENDING BIT TLNE T2,(TMRBIT) ;IF THIS IS TIMER INTERRUPTS PUSHJ P,CLRTMR ;REMOVE ANY CLOCK REQUEST QUEUE ENTRIES JRST CPOPJ1## ;GOOD RETURN REMD.1: SETZM DEVPSI(F) ;CLEAR INTERRUPT INFORMATION AOS (P) ;GOING TO GIVE GOOD RETURN PJRST UNLDDB ;UNLINK DDB AND RETURN ;SUBROUTINE TO ADD A DEVICE OR CONDITION ;CALLED FROM PISYS. UUO WITH: ; P1 = ADDRESS OF PROGRAM INTERRUPT TABLE ; P2 = USERS ARG POINTER ; PUSHJ P,ADDDEV ; RETURN HERE ON ERROR ; RETURN HERE IF ALL IS OK ; ADDDEV: PUSHJ P,SAVUM## ;PRESERVE M FOR THE REST OF THE WORLD PUSHJ P,CHKCND ;GO CHECK OUT ARGUMENT POPJ P,0 ;INVALID DEVICE OR CONDITION JRST ADDD.1 ;HE WANTS TO ADD A DDB MOVE P3,T1 ;COPY CONDITION WANTED PUSHJ P,CNDPTR ;GET A CONDITION POINTER INTO P4 TDZA F,F ;INDICATE CONDITION ENABLE AND SKIP ADDD.1: MOVE P4,[POINT CNDSIZ,DEVESE(F),26] ;GET POINTER FOR OFFSET HRRI M,2(P2) ;GET PRIORITY INFORMATION PUSHJ P,GETWDU## ;... TRNE T1,-1 ;IS RESERVED HALF WORD NON-ZERO PJRST ECOD12## ;(12) RESERVED HALFWORD IS NON-ZERO IFE PSIMPI, ;(11) PRIORITY IS TOO BIG IFN PSIMPI,< HLRZS T1 ;GET PRIORITY LEVEL CAILE T1,PSIMPI ;CHECK IT PJRST ECOD11## ;(11) PRIORITY IS TOO BIG HRL P3,T1 ;SAVE IN LH OF P3, RH = CONDITION > HRRI M,1(P2) ;GET THE VECTOR OFFSET WORD PUSHJ P,GETWDU## ; .. MOVEI T2,-1 ;ASSUME CONDITION SKIPE F ;ARE WE RIGHT? MOVEI T2,-1-IR.ALL ;NO, LOAD BITS FOR INVALID REASONS TRNE T1,(T2) ;ANY BITS SET PJRST ECOD10## ;(10) UNIMPLEMENTED BIT IS ON LSHC T1,-^D18 ;T1 = 0,,OFFSET T2 = REASONS,,0 CAIG T1,PSIMVO ;IS VALUE TOO BIG? TRNE T1,3 ;MUST BE MULTIPLE OF 4 WORDS (.PSVIS+1) PJRST ECOD7## ;(7) BAD VECTOR OFFSET LDB P2,VECBAS ;GET BASE OF VECTOR ADDI P2,.PSVFL(T1) ;POINT TO CONTROL FLAGS MOVE M,P2 ;... MOVE P2,T1 ;SAVE OFFSET HLRZ T1,M ;GET SECTION OF BLOCK PUSHJ P,SVPCS## ;SET IT UP PUSHJ P,GTWST2## ;GET CONTROL FLAGS ( GETWDU AND SAVE T2 ) EXCH P2,T1 ;RESTORE, GET FLAGS JUMPE F,ADDD.2 ;DEVICE OR REGULAR CONDITION PJUMPE T2,ECOD10## ;(10) DEVICE, NO ENABLED BITS IS AN ERROR TLNE P2,(PS.VPM) ;USER WANT ANY MESSAGE PRINTED TLO T2,(1B0) ;YES, LIGHT FLAG IN DDB EXCH T2,DEVPSI(F) ;SET ENABLED, GET PREVIOUS STATE TLNE T2,-1 ;ANY PREVIOUS CONDITIONS JRST ADDD.3 ;YES, ALREADY IN DEVICE CHAIN HLL T2,PITCHN(P1) ;GET FIRST IN CHAIN HLLM T2,DEVESE(F) ;LINK THAT IN HRLM F,PITCHN(P1) ;THIS IS NOW THE FIRST JRST ADDD.3 ;RESUME ADDD.2: MOVSI T2,(1B0) ;GET A BIT LSH T2,(P3) ;POSITION IT CORRECTLY IORM T2,PITENB(P1) ;NOT DEVICE, LIGHT ENABLED CONDITION TDNN T2,[MSGBIT] ;THIS CONDITION HAVE A MESSAGE JRST ADDD.3 ;NO, SKIP TEST ANDCAM T2,PITMSG(P1) ;CLEAR JUST IN CASE TLNE P2,(PS.VPM) ;USER WANT IT PRINTED IORM T2,PITMSG(P1) ;YES, LIGHT BIT FOR PSIIMM ADDD.3: LSH T1,-2 ;SHIFT OFF ZERO BITS DPB T1,P4 ;STORE OFFSET AOS T1 ;BUMP FOR PFH LDB T2,[POINT 9,PITIVA(P1),8] ;GET MAX SO FAR CAIGE T2,(T1) ;GREATER THAN THIS ONE? DPB T1,[POINT 9,PITIVA(P1),8] ;SAVE THE GREATEST FOR PFH IFN PSIMPI,< HRRE T1,P3 ;GET CONDITION TO ADD SKIPE F ;DDB OR CONDITION SKIPA P4,[POINT 2,DEVESE(F),19] ;DDB, GET POINTER TO PRIORITY PUSHJ P,CNDLVL ;CONDITION, COMPUTE POINTER TO PRIORITY HLRZ T1,P3 ;RESTORE SAVED PRIORITY LEVEL DPB T1,P4 ;STORE IT > AOS (P) ;GOING TO GIVE GOOD RETURN ; PJRST APPSI ;FALL INTO ENABLE HARDWARE TRAP CODE ;SUBROUTINE TO SET UP HARDWARE TRAP1 INTERCEPT ;FALLEN INTO BY ADDDEV ABOVE, ALSO CALLED BY KISER/KLSER APPSI:: HRRZ T2,JBTPIA##(J) ;GET BASE OF TABLE JUMPE T2,CPOPJ## ;RETURN IF NOT USING PSI MOVE T2,PITENB(T2) ;GET ENABLED CONDITIONS TLNN T2,(APRBIT) ;WANT APR TRAPS POPJ P, ;NO, GET OUT NOW MOVEI T2,UI.AOT ;YES, SET DISPATCH FOR PSIAPR MOVEM T2,.USAOT ;STORE FOR HARDWARE TRAP POPJ P, ;RETURN ;SUBROUTINE TO CLEAR A SPECIFIC CONDITION FOR THE USER ;CALLED FROM PISYS UUO ; P1 = ADDRESS OF DATA BASE ; P2 = USERS ARGUMENT ; PUSHJ P,CLRSPI ; RETURN HERE IF ERROR ; NORMAL RETURN CLRSPI: PUSHJ P,CHKCND ;FETCH/CHECK CONDITION WORD POPJ P, ;BAD DEVICE OR CONDITION JRST [HLLZS DEVPSI(F) ;CLEAR DEVICE PENDING BITS JRST CPOPJ1##] ;GOOD RETURN MOVSI T2,(1B0) ;GET A BIT LSH T2,(T1) ;POSITION IT CORRECTLY TRNE T2,JBIBIT ;IF THIS IS CROSS JOB INTERRUPT SETZM PITST2(P1) ;CLEAR PIJBI. UUO INTERLOCK ANDCAM T2,PITPND(P1) ;CLEAR PENDING INTERRUPT JRST CPOPJ1## ;AND GOOD RETURN ;SUBROUTINE TO CLEAR ALL PENDING INTERRUPTS FOR A JOB ;CALLED FROM PISYS UUO ; P1 = ADDRESS OF DATA BASE CLRAPI: SETZM PITNPI(P1) ;CLEAR PENDING COUNT SETZM PITST2(P1) ;CLEAR PIJBI. UUO INTERLOCK SETZM PITPND(P1) ;CLEAR PENDING CONDITIONS HLRZ F,PITCHN(P1) ;POINT TO FIRST PSI'ED DDB CLRA.1: JUMPE F,CPOPJ## ;RETURN WHEN OUT OF DDBS HLLZS DEVPSI(F) ;CLEAR ANY PENDING INTERRUPTS HLRZ F,DEVESE(F) ;STEP TO NEXT IN THE CHAIN JRST CLRA.1 ;LOOP OVER ALL DDBS ;SUBROUTINE TO FETCH AND VALIDATE THE DEVICE OR CONDITION GIVEN BY THE USER ;CALLED WITH: ; P2 = USER ARGUMENT ; PUSHJ P,CHKCND ; RETURN HERE IF THE CONDITION IS INVALID ; RETURN HERE IF A DEVICE WAS SPECIFIED ; RETURN HERE IF A CONDITION WAS SPECIFIED ; ;UPON RETURN F=ADDRESS OF DDB (IF DEVICE) ; T1 = CONDITION NUMBER (IF CONDITION) CHKCND: PUSHJ P,CTXJCJ## ;GET CURRENT JCH FOR JOB POPJ P, ;CONTEXT WENT AWAY MOVE T4,T1 ;SAVE JCH FOR COMPARES HRR M,P2 ;ADDRESS OF WORD PUSHJ P,GETWDU## ;GET THE WORD HLRE T2,T1 ;CHECK IF CONDITION OR DEVICE NAME AOJE T2,CHKC.1 ;GO IT CONDITION WAS SPECIFIED PUSHJ P,DVCNSG## ;ELSE LOOK FOR A DEVICE JRST ECOD5## ;(5) NOT A DEVICE CHKC.0: HRRZ T2,TTYTAB##(J) ;GET ADDRESS OF THIS JOBS TTY DDB CAIN T2,(F) ;SKIP IF THIS IS NOT HIS TTY PJRST CPOPJ1## ;GOOD RETURN LDB T2,PJCHN## ;GET NAME OF OWNER TRNN T2,CTXMSK## ;IF NO CONTEXT OWNS IT, TRZ T4,CTXMSK## ;THEN DON'T COMPARE CONTEXT NUMBERS MOVEI T3,ASSPRG ;SEE IF DEVICE IS TDNE T3,DEVMOD(F) ; OPEN FOR CAIE T2,(T4) ; THIS JOB. PJRST ECOD5## ;(5) OR NOT OPENED BY THIS JOB JRST CPOPJ1## ;SKIP RETURN CHKC.1: CAML T1,[C$MIN] ;SKIP IF CODE IS TOO SMALL JRST CPOPJ2## ;DOUBLE SKIP RETURN ;HERE COULD BE "-1,,DDB" FROM PISAV., CHECK FOR THAT HLRZ F,DEVLST## ;HEAD OF DDB CHAIN CHKC.2: CAIN F,(T1) ;THE ONE WE WANT JRST CHKC.0 ;AND CHECK OWNERSHIP PUSHJ P,NXDDB## ;STEP TO NEXT DDB JUMPE F,ECOD6## ;(6) OR CONDITION CODE TOO SMALL JRST CHKC.2 ;AND LOOK AT IT SUBTTL UUOCON INTERFACE -- PISAV. ;CALL TO SAVE THE CURRENT PSI SYSTEM ;CALL WITH: ; MOVE AC,[XWD LENGTH,ADDRESS] ; PISAV. AC, ; HERE ON AN ERROR ; HERE OLD SYSTEM IS SAVED AND CLEARED ; ;ADDRESS GETS FLAG,,NUMBER OF WORDS STORED ; (OR WOULD HAVE IF BLOCK WERE LONG ENOUGH) ;ADDRESS+1 GETS BASE OF CURRENT INTERRUPT VECTOR ; ;ADDRESS+2 THROUGH ;ADDRESS+N GETS SAVED STATE, 3 WORD BLOCKS, SUITABLE FOR PIRST. (OR PISYS.) PISAVE::PUSHJ P,SAVE4## ;SAVE A FEW FIRST HRR M,T1 ;ADDRESS OF BLOCK HLRZ P2,T1 ;AND LENGTH OF IT SOJL P2,ECOD1## ;(1) BLOCK SIZE ZERO MOVEI P3,1 ;ADJUST BOTH COUNTERS SKIPN P1,JBTPIA##(J) ;GET DATA BASE JRST PISA.5 ;OK IF SAVING AN EMPTY SYSTEM PUSH P,M ;REMEMBER ADDRESS OF FIRST WORD PUSH P,F ;AND SAVE F LDB T1,VECBAS ;GET BASE OF SYSTEM CURRENTLY IN USE PUSHJ P,STORE ;STORE IN THE BLOCK HLRZ P4,PITCHN(P1) ;GET START OF THE PSI DDBS JUMPE P4,PISA.2 ;NONE, GET NON-DEVICE CONDITIONS PISA.1: HRROI T1,(P4) ;GET -1,,DDB ADDRESS PUSHJ P,STORE ;STUFF THAT AWAY LDB T1,[POINT CNDSIZ,DEVESE(P4),26] ;GET VECTOR OFFSET LSH T1,^D20 ;*4, WANT IT IN LEFT HALF HLR T1,DEVPSI(P4) ;INSERT CONDITIONS ENABLED TRZ T1,-1-IR.ALL ;CLEAR RESIDUE PUSHJ P,STORE ;DROP IT IN IFE PSIMPI, ;CLEAR PRIORITY INFORMATION IFN PSIMPI,< LDB T1,[POINT 2,DEVESE(P4),19] ;GET PRIORITY LEVEL HRLZS T1 ;WANT IN LEFT HALF FOR UUO > PUSHJ P,STORE ;STORE PRIORITY INFORMATION HLRZ P4,DEVESE(P4) ;STEP TO NEXT PSI'ED DDB JUMPN P4,PISA.1 ;CONTINUE UNTIL DONE PISA.2: SKIPN F,PITENB(P1) ;ANY NON-DEVICE CONDITIONS ENABLED JRST PISA.4 ;NOPE, ALL DONE WITH THE SAVE PISA.3: MOVE T1,F ;COPY CURRENT BITS JFFO T1,.+1 ;FIND ONE ENABLED MOVN T1,T2 ;WANT NEGATIVE CONDITION NUMBER TDZ F,BITTBL##(T2) ;AND CLEAR WHAT WE FOUND ENABLED IFN PSIMPI, ;SAVE CONDITION NUMBER PUSHJ P,CNDPTR ;COMPUTE A CONDITION POINTER PUSHJ P,STORE ;STORE CONDITION NUMBER LDB T1,P4 ;GET OFFSET PROPER LSH T1,^D20 ;*4 AND MOVE TO THE LEFT HALF PUSHJ P,STORE ;STORE THAT IFE PSIMPI, ;CLEAR PRIORITY INFORMATION IFN PSIMPI,< POP P,T1 ;RESTORE CONDITION NUMBER PUSHJ P,CNDLVL ;GET PRIORITY LEVEL LDB T1,P4 ;GET IT HRLZS T1 ;WANT IN LEFT HALF FOR UUO > PUSHJ P,STORE ;STORE PRIORITY INFORMATION JUMPN F,PISA.3 ;CONTINUE UNTIL EXHAUSTED ENABLED CONDITIONS PISA.4: POP P,F ;RESTORE F POP P,M ;RESTORE ADDRESS OF FIRST WORD PISA.5: MOVE T1,P3 ;NUMBER OF WORDS STORED (OR TRIED TO) SKIPGE P1 ;IS THE PSI SYSTEM CURRENTLY TURNED ON TLO T1,(SI.ON) ;YES, LIGHT BIT FOR PIRST. TLNE P1,(SI.UEA) ;EXTENDED USER? TLO T1,(SI.UEA) ;YES, LIGHT BIT FOR PIRST. PUSHJ P,PUTWDU## ;STORE IN BEGINNING OF USERS BLOCK JUMPL P2,ECOD0## ;(0) WAS THIS TRIP REALLY WORTH IT PUSHJ P,CLRPSI ;HAVING SAVED THE SYSTEM, CLEAR OLD DATA JRST CPOPJ1## ;AND RETURN SUCCESS ;LOCAL ROUTINE FOR STORING DATA INTO THE BLOCK FOR PISAV. STORE: SOSL P2 ;ROOM LEFT IN THE BLOCK PUSHJ P,PUTWD1## ;YES, STORE THIS VALUE AOJA P3,CPOPJ## ;COUNT THE WORD AND RETURN SUBTTL UUOCON INTERFACE -- PIRST. ;CALL TO RESTORE THE PI SYSTEM FROM BLOCK SAVED BY PISAV. ;CALL WITH: ; MOVEI AC,BLOCK USED DURING PISAV. ; PISAV. AC, ; HERE ON AN ERROR ; HERE PI SYSTEM SUCCESSFULLY RESTORED ; ;THIS UUO CAN ALSO BE USED TO BUILD AN ENTIRE PI SYSTEM AVOIDING PIINI AND ; MULTIPLE PISYS. UUOS. PIRST:: PUSHJ P,SAVE4## ;SAVE A FEW FIRST HRRI M,(T1) ;ADDRESS OF THE BLOCK PUSHJ P,GETWDU## ;GET FLAG AND WORD COUNT HLL P4,T1 ;SAVE FLAG FOR NOW HRRZ P3,T1 ;COPY COUNT SOJLE P3,[PUSHJ P,CLRPSI ;SAVED AN EMPTY SYSTEM JRST CPOPJ1##] ;SO CLEAR OLD AND RETURN PUSHJ P,GETWD1## ;GET BASE OF OLD SYSTEM TLNE P4,(SI.UEA) ;IF EXTENDED USER TLO T1,(PS.IEA) ;LIGHT UUO BIT PUSHJ P,PIINI ;AND DO A PIINI. FOR IT JRST ECOD1## ;(1) NO MONITOR CORE SOS P3 ;ADJUST COUNTER MOVEI P2,1(M) ;POINT TO FIRST BLOCK TO RESTORE MOVE P1,JBTPIA##(J) ;BASE FROM PIINI. TLNE P4,(SI.ON) ;WAS OLD SYSTEM ON TLO P1,(SI.ON) ;YES, RESTORE STATE PIRS.1: SUBI P3,3 ;DEDUCT 1 BLOCK FROM COUNT JUMPL P3,PIRS.2 ;ALL DONE PUSHJ P,[PUSHJ P,SAVE3## ;SAVE MY P REGS FIRST JRST ADDDEV] ;AND CALL PISYS. ADD ROUTINE JRST [PUSHJ P,CLRPSI ;FAILED, CLEAR SO NOT HALF RESTORED PJRST ECOD0##] ;(0) AND GIVE FAIL RETURN TO UUO ADDI P2,3 ;POINT TO NEXT GROUP JRST PIRS.1 ;AND PROCESS THAT PIRS.2: MOVEM P1,JBTPIA##(J) ;STORE BACK WITH "ON" FLAG JRST CPOPJ1## ;AND GIVE GOOD RETURN SUBTTL UUOCON INTERFACE -- DEBRK. DEBRK:: PUSHJ P,SAVE4## ;SAVE A FEW FIRST SKIPE P1,JBTPIA##(J) ;GET ADDRESS OF PI TABLE IFN PSIMPI, ;GET HIGHEST LEVEL IN PROGRESS IFE PSIMPI, ;GET INT BLOCK ADDRESS JRST CPOPJ1## ;NO PI IN PROGRESS IFN PSIMPI,< ADDI P4,PITCIB(P1) ;POINT TO CORRECT PITCIB FOR LEVEL IN PROGRESS MOVE P2,0(P4) ;AND GET INT BLOCK ADDRESS > HLRZ T1,P2 ;GET SECTION NUMBER OF BLOCK PUSHJ P,SVPCS## ;SET IT FOR FOLLOWING MOVEI M,.PSVOP(P2) ;OLD PC PUSHJ P,GETWDU## ;FETCH IT MOVE P3,T1 ;SAVE FOR NOW MOVEI M,.PSVFL(P2) ;FLAG WORD PUSHJ P,GETWDU## ;GET THAT TOO DMOVE T3,.JDAT+JOBPD1## ;GET UUO PC PUSH P,P4 ;SAVE AC USED FOR PC PUSHJ P,DEBRPC ;ADJUST PC FOR EXTENDED USER TLNN T3,(XC.UIO) ;DOES HE HAVE USER IOT SET TLZ P3,(XC.UIO) ;NO, CLEAR FROM OLD PC IFE FTKS10,< TLNE T3,(XC.PUB) ;OLD PC PUBLIC TLO P3,(XC.PUB) ;YES, NEW PC IS TOO > TLO P3,(XC.USR) ;SET USER MODE TLZ P3,37 ;CLEAR INDEX AND @ DMOVEM P3,.JDAT+JOBPD1## ;STORE BACK FOR USER POP P,P4 ;RESTORE PC REGISTER IFE PSIMPI,< SETZM PITCIB(P1) ;CLEAR INTERRUPT IN PROGRESS SETZ P2, ;GET A ZERO EXCH P2,PITCIC(P1) ;GET AND CLEAR CURRENT CONDITION/DEVICE > IFN PSIMPI,< SETZM 0(P4) ;CLEAR INTERRUPT IN PROGRESS SETZ P2, ;GET A ZERO EXCH P2,PITCIC-PITCIB(P4) ;GET AND CLEAR INTERRUPT REASON DEBR.1: SOSGE PITHLP(P1) ;NOW FIND NEXT HIGHEST IN PROGRESS JRST DEBR.2 ;THIS WAS THE LAST, PITHLP IS NOW BACK TO -1 SKIPN -1(P4) ;IS THIS LEVEL IN PROGRESS SOJA P4,DEBR.1 ;NO, KEEP LOOKING DEBR.2: MOVSI T3,(SI.DBK) ;SYSTEM OFF UNTIL DEBRK. ANDCAM T3,JBTPIA##(J) ;THIS WAS THE DEBRK. > TLNN T1,(PS.VDS) ;DISMISS OTHERS POPJ P, ;NO, RETURN, CATCH NEW INTERRUPTS AT UUOXIT HRRZ P2,P2 ;GET CONDITION NUMBER OR DDB ADDRESS CAIGE P2,C$MIN ;CONDITION OR DEVICE JRST DEBR.3 ;YES, GO IF A DEVICE CONDITION MOVSI T1,(1B0) ;GET A BIT LSH T1,(P2) ;POSITION IT CORRECTLY TRNE T1,JBIBIT ;IF THIS IS CROSS JOB INTERRUPT SETZM PITST2(P1) ;CLEAR PIJBI. UUO INTERLOCK ANDCAM T1,PITPND(P1) ;CLEAR THE PENDING BIT POPJ P, ;RETURN DEBR.3: HLRZ F,PITCHN(P1) ;GET HEAD OF PSI DDBS DEBR.4: JUMPE F,CPOPJ## ;RETURN WHEN OUT OF DDBS CAMN P2,F ;THIS THE ONE WE'RE LOOKING FOR JRST [HLLZS DEVPSI(F) ;YES, CLEAR PENDING BITS POPJ P,] ;AND RETURN HLRZ F,DEVESE(F) ;STEP TO THE NEXT ONE JRST DEBR.4 ;TRY THE NEXT ;HERE TO ADJUST PC FOR EXTENDED ADDRESSING DEBRPC: IFN PSIMPI,< PUSH P,T1 ;SAVE A BASE REGISTER MOVE T1,P4 ;BEFORE WE CLOBBER IT > MOVE P4,P3 ;COPY PC FOR DOUBLEWORD TLNN P1,(SI.UEA) ;EXTENDED USER? JRST DEBRP1 ;NO, HANDLE OTHER WAY IFE PSIMPI,< HLLZ P3,PITCIC(P1) ;GET FLAGS FROM STORAGE POPJ P, ;AND RETURN ALL FIXED UP > IFN PSIMPI,< HLLZ P3,PITCIC-PITCIB(T1) ;GET FLAGS FROM RIGHT LEVEL BLOCK JRST TPOPJ## ;RETURN DOUBLEWORD PC > DEBRP1: TRZ P3,-1 ;CLEAR JUNK HLL P4,T4 ;STAY IN SAME SECTION IFE PSIMPI, ;RETURN DOUBLEWORD PC IFN PSIMPI, ;RETURN DOUBLEWORD PC SUBTTL UUOCON INTERFACE -- PIJBI. ;CALL TO INTERRUPT ANOTHER JOB AND GIVE STATUS ;CALL WITH: ; MOVE AC,[XWD JCH TO INTERRUPT,STATUS TO GIVE] ; PIJBI. AC, ; HERE ON AN ERROR ; HERE WHEN INTERRUPT HAS BEEN POSTED FOR THE JOB ; ;JOB NUMBER OF -1 IS INTERRUPT YOURSELF, UUO WILL FAIL (ERROR 1) IF THE JOB ; ALREADY HAS ONE PENDING, CALLER MUST TRY AGAIN, CAN'T JUST LET IT ; STACK SINCE YOU WILL LOSE STATUS (ONLY 1 PLACE TO STORE IT) PIJOB:: PUSHJ P,SAVE1## ;PLACE TO SAVE ARGUMENT MOVE P1,T1 ;SAVE IT HLRZ T1,P1 ;GET JUST HANDLE TO INTERRUPT CAIN T1,-1 ;SELF POINTER? MOVE T1,J ;YES, USE JOB NUMBER MOVE T4,T1 ;SAVE CONTEXT TO INTERRUPT TRNE T4,CTXMSK## ;CONTEXT NUMBER GIVEN? PUSHJ P,CTXJCJ## ;YES, GET CURRENT HANDLE FROM CTXSER MOVE T1,J ;NO, DON'T INCLUDE IT IN STATUS HRL P1,T1 ;PUT HANDLE INTO STATUS WORD MOVE T1,T4 ;GET TARGET AGAIN PUSHJ P,CTXPSI## ;GET PIT FROM CTXSER JRST ECOD0## ;(0) ILLEGAL JOB NUMBER JUMPE T2,ECOD0## ;(0) NOT ENABLED FOR INTERRUPT MOVEI T3,JBIBIT ;BIT FOR ENABLED THIS TYPE OF INTERRUPT TDNN T3,PITENB(T2) ;YES, USER ENABLED FOR CROSS JOB INTERRUPTS JRST ECOD0## ;(0) NOT ENABLED FOR INTERRUPT UUOLOK ;PREVENT RACES WITH OTHER CPUS SKIPN T3,PITST2(T2) ;TARGET ALREADY HAVE ONE PENDING MOVEM P1,PITST2(T2) ;NO, GIVE HIM THIS ONE UUONLK ;ALLOW OTHER CPUS BACK IN NOW JUMPN T3,ECOD1## ;(1) TARGET IS BUSY, TRY LATER MOVE J,T4 ;GET HANDLE INTO J FOR SIGNAL SIGNAL C$JBI ;CAUSE THE INTERRUPT JRST ECOD0## ;(0) REALLY OUGHT TO STOPCD HERE SINCE JUST CHECKED JRST CPOPJ1## ;GIVE GOOD RETURN TO CALLER SUBTTL UUOCON INTERFACE -- PITMR. ;CALL TO INTERRUPT THE CURRENT JOB WHEN SPECIFIED TIMER EXPIRES ;CALL WITH: ; MOVE AC,[XWD FLAGS,INTERVAL] ; PITMR. AC, ; HERE ON AN ERROR ; HERE WHEN TIMER REQUEST HAS BEEN ENTERED ;FLAG BITS: ; 1B0 ON = INTERVAL IS IN MILLISECONDS (BETTER RESOLUTION) ; OFF = INTERVAL IS IN SECONDS (LONGER REQUESTS AVAILABLE) PITMR:: MOVSI T2,(TMRBIT) ;BIT FOR ENABLED THIS TYPE OF INTERRUPT SKIPE T3,JBTPIA##(J) ;JOB USING PSISER TDNN T2,PITENB(T3) ;YES, USER ENABLED FOR TIMER INTERRUPTS JRST ECOD0## ;(0) NOT ENABLED FOR INTERRUPT TLNE T1,377777 ;ONLY 1 FLAG BIT DEFINED AT THE MOMENT JRST ECOD1## ;(1) UNIMPLEMENTED BIT IS SET TLZN T1,(1B0) ;ALREADY IN MILLISECONDS IMULI T1,^D1000 ;NO, GET IT THERE IMUL T1,TICSEC## ;CONVERT FROM MILISECONDS IDIVI T1,^D1000 ; TO JIFFIES SKIPE T1 ;REQUEST FOR 0 TIME BECOMES 1 TICK SKIPE T2 ;ANY REMAINDER AOS T1 ;YES, ROUND UP TO FULL JIFFY TLNE T1,-1 ;ONLY 18 BITS IN THE CLOCK REQUEST QUEUE MOVEI T1,-1 ;SO ROUND DOWN TO MAXIMUM TIMER HRLI T1,PSITMR ;WHERE TO GO WHEN IT EXPIRES PUSH P,T1 ;SAVE FROM CTXSER PUSHJ P,CTXJCJ## ;GET HANDLE TO INTERRUPT FROM CTXSER JFCL ;CAN'T FAIL POP P,T2 ;CLKCHG WANTS STATUS IN T2 PUSHJ P,CLKCHG## ;FIND, MODIFY ANY PREVIOUS PITMR. CALLS CAIA ;NONE, ADD A NEW ONE JRST CPOPJ1## ;GIVE GOOD RETURN TO UUO PUSH P,T1 ;SAVE FROM CTXSER PUSHJ P,CTXJCJ## ;GET HANDLE AGAIN JFCL ;CAN'T FAIL POP P,T2 ;GET CLKCHG VALUE BACK SYSPIF ;2 WORDS PER ENTRY IDPB T2,CLOCK## ;STORE ADDRESS AND INTERVAL IDPB T1,CLOCK## ;DATA ITEM IS THE CONTEXT HANDLE SETOM CLKNEW## ;MARK A NEW ENTRY IN THE SYSTEM QUEUE SYSPIN ;DONE STORING JRST CPOPJ1## ;GIVE GOOD RETURN TO UUO ;HERE WHEN THE TIMER SET BY PITMR. EXPIRES, INTERRUPT THE JOB PSITMR: PUSHJ P,CTXPSI## ;GET PIT FOR CONTEXT POPJ P, ;WENT AWAY JUMPE T2,CPOPJ## ;GO AWAY IF NOT STILL USING PSISER PUSH P,J ;SAVE FOR CALLER MOVE J,T1 ;GET JCH WHERE IT BELONGS SIGNAL C$TMR ;CAUSE THE INTERRUPT JFCL ;IGNORE FAIL RETURN JRST JPOPJ## ;RETURN TO CLOCK1 SUBTTL UUOCON INTERFACE -- PIBLK. ;CALL TO RETURN USER INTERRUPT BLOCK ADDRESS FOR INTERRUPT IN PROGRESS ;CALL WITH: ; PIBLK. AC, ; HERE IF NOT INITIALIZED OR NONE IN PROGRESS ; HERE WITH AC CONTAINING ADDRESS OF INTERRUPT BLOCK PIBLK:: PUSHJ P,SAVE2## ;SAVE A FEW FIRST SKIPN P1,JBTPIA##(J) ;GET ADDRESS OF PI TABLE PJRST RTZER## ;ERROR RETURN, NOT INITIALIZED IFN PSIMPI,;GET HIGHEST LEVEL IN PROGRESS IFE PSIMPI,;GET INT BLOCK ADDRESS PJRST ECOD1## ;ERROR RETURN, NO PI IN PROGRESS IFN PSIMPI,< ADDI P2,PITCIB(P1) ;POINT TO PITCIB FOR LEVEL IN PROGRESS MOVE T1,0(P2) ;AND GET INT BLOCK ADDRESS >;END IFN PSIMPI JRST STOTC1## ;GIVE GOOD RETURN WITH BLOCK ADDRESS SUBTTL UUOCON INTERFACE -- PIFLG. UUO ;CALL TO SET OR READ FLAGS FOR INTERRUPTED PC FOR A USER TAKING INTERRUPTS ; IN A MULTI-SECTION ENVIRONMENT ;CALL WITH: ; SETZ AC, ;TO READ FLAGS ; -OR- ; MOVE AC,[FLAGS,,1] ;TO WRITE FLAGS ; -THEN- ; PIFLG. AC, ; HERE IF NOT EXTENDED USER OR NO INTERRUPT IN PROGRESS ; HERE WITH AC CONTAINING THE PC FLAGS ;PIFLG. ERROR CODES PSFNI%==0 ;PSI SYSTEM NOT INITIALIZED PSFNP%==1 ;NO INTERRUPT IN PROGRESS PSFEA%==2 ;NOT USING EXTENDED ADDRESSING FORMAT FOR PI SYSTEM PSFIF%==3 ;ILLEGAL FUNCTION CODE ERCODE ERRFNI,PSFNI% ERCODE ERRFNP,PSFNP% ERCODE ERRFEA,PSFEA% ERCODE ERRFIF,PSFIF% PIFLG:: HRRZ T4,T1 ;EXTRACT FUNCTION CODE FROM USER'S ARGUMENT CAIL T4,FLGTBL ;WITHIN RANGE OF DISPATCH TABLE? JRST ERRFIF ;ILLEGAL FUNCTION CODE SKIPN T2,JBTPIA##(J) ;GET PIT ADDRESS AND FLAGS JRST ERRFNI ;NOT INITIALIZED TLNN T2,(SI.UEA) ;EXTENDED USER? JRST ERRFEA ;NOT INITIALIZED FOR EXTENDED ADDRESSING IFE PSIMPI, ;SEE IF IN PROGRESS IFN PSIMPI, ;GET HIGHEST LEVEL IN PROGRESS JRST ERRFNP ;NO INTERRUPT IN PROGRESS IFE PSIMPI, ;POINT TO CURRENT FLAGS IFN PSIMPI, ;POINT TO CURRENT FLAGS JRST @FLGTAB(T4) ;FINISH BY FUNCTION-SPECIFIC ROUTINE FLGTAB: IFIW FLGRED ;(0) READ FLAGS IFIW FLGWRT ;(1) WRITE FLAGS FLGTBL==.-FLGTAB ;LENGTH OF TABLE FLGWRT: HLLM T1,(T3) ;SET THE FLAGS AS REQUESTED FLGRED: HLLZ T1,(T3) ;GET FLAGS,,0 JRST STOTC1## ;RETURN TO USER SUBTTL SUPPORT FOR THE SIGNAL MACRO -- PSICND ;ROUTINE TO CAUSE A NON-DEVICE CONDITION ;CALL VIA THE SIGNAL MACRO ; J = JOB TO BE SIGNALLED ; T1 = THE CONDITION ( NEGATIVE ) SET UP BY SIGNAL MACRO ; T2 = STATUS IF NOT RECONSTRUCTABLE ; C$DTC = UNIVERSAL DATE/TIME OFFSET ; C$WAKE = JOB NUMBER OF WAKER ; C$QUE = REQUEST ID (AND 1B0=1 IF ABORTING) ; C$CTLC = 1B0 ON IF JOB WAS IN TI STATE ;RETURN CPOPJ USER DOESN'T WANT THE TRAP ; CPOPJ1 IF USER DOES (AND WE WOKE UP THE JOB) PSICND::JUMPGE T1,CPOPJ## ;ONLY NEGATIVE CONDITIONS HERE CAMGE T1,[C$MIN] ;CONDITION TOO SMALL POPJ P, ;BAD CONDITION IFN FTXMON,< PUSHJ P,SSEC0## ;MUST BE IN SECTION 0 HERE > PUSHJ P,SAVE4## ;SAVE A FEW FIRST PUSHJ P,SAVJW## ;SIMILARLY DMOVE P1,T1 ;PRESERVE CONDITION & STATUS MOVE T1,J ;GET JCH IN RIGHT REGISTER PUSHJ P,CTXPSI## ;GET PIT FROM CTXSER POPJ P, ;NO SUCH JOB JUMPE T2,CPOPJ## ;NOT USING PSISER MOVE J,T1 ;PUT JCH WHERE IT BELONGS MOVE T1,P1 ;RESTORE CONDITION MOVE P1,T2 ;GET PIT WORD WHERE WE WANT IT MOVE T2,P2 ;RESTORE STATUS PUSH P,F ;SAVE F FOR CALLER MOVSI F,(1B0) ;GET A BIT LSH F,(T1) ;POSITION IT CORRECTLY TDNN F,PITENB(P1) ;USER ENABLE FOR THIS INTERRUPT JRST FPOPJ## ;NO, QUIT NOW TDNE F,[IMBITS] ;IS THIS AN IMMEDIATE CONDITION JRST PSIIMM ;YES, GO DIRECTLY TO GENERATOR TRNE F,DTCBIT ;SET DATE/DAYTIME? ADDM T2,PITST3(P1) ;YES, ACCUMULATE TIME OFFSET TRNE F,QUEBIT ;ENQ/DEQ JRST [SKIPGE T2 ;WERE ANY REQUESTS ABORTED? HRLI T2,(PITQAB) ;YES, REMEMBER FOR LATER IORM T2,PITSTS(P1) ;REMEMBER REQUEST ID JRST .+1] TRNE F,WAKBIT ;WAKE UUO. DPB T2,[POINT 9,PITSTS(P1),17] ;YES, REMEMBER WAKING JOB TLNN F,(CTCBIT) ;^C JRST PSIAGN ;NO, GO POST INTERRUPT MOVSI P2,(1B0) ;GET "FROM TI WAIT" BIT ANDCAM P2,PITSTS(P1) ;CLEAR OLD STATUS IORM T2,PITSTS(P1) ;SET NEW STATUS SKIPGE T2 ;FROM "TI" WAIT JRST [DMOVE P2,.JDAT+JOBPD1## ;YES, GET UUO PC JRST .+2] ;AND SKIP SAVED PC DMOVE P2,USRPC## ;NO, GET SAVED PC TLNN P2,USRMOD ;BETTER BE A USER PC DMOVE P2,.JDAT+JOBPD1## ;GET LAST UUO PC PUSHJ P,ISDDT ;USER IN DDT JRST FPOPJ## ;YES, LET CONTROL C STOP THE JOB PSIAGN: AOS -1(P) ;USER WANTS INTERRUPT PSIAG1: TDNE F,PITPND(P1) ;ALREADY HAVE THIS ONE PENDING JRST PSIAG2 ;YES, JUST WAKE THE JOB IORM F,PITPND(P1) ;LIGHT ONE FOR THIS INTERRUPT AOS PITNPI(P1) ;BUMP PENDING COUNT PSIAG2: POP P,F ;DON'T NEED THIS ANY MORE JUMPGE P1,CPOPJ## ;DON'T WAKE THE JOB IF PI OFF MOVE T1,J ;COPY JCH PUSHJ P,CTXVAL## ;VALIDATE IT POPJ P, ;CONTEXT WENT AWAY TRZA J,CTXMSK## ;CURRENT, SET FOR UUOCON POPJ P, ;NOT CURRENT, WE'LL CATCH IT AT ITS RESTORE PJRST WAKEJB## ;WAKE JOB AND RETURN ;HERE WHEN A CONDITION MUST BE GRANTED IMMEDIATELY (APR STUFF) PSIIMM: JUMPGE P1,FPOPJ## ;CANNOT GRANT IF PS IS OFF DMOVE P3,T1 ;SAVE CONDITION AND STATUS AGAIN MOVE T1,J ;COPY JCH PUSHJ P,CTXVAL## ;SEE IF CURRENT JRST FPOPJ## ;CONTEXT WENT AWAY TRNA ;CURRENT IS OK JRST PSITLE ;CANNOT GRANT IF NOT CURRENT DMOVE T1,P3 ;RESTORE CONDITION AND STATUS TDNE F,[PD1BIT] ;WHERE IS THE CURRENT PC JRST [DMOVE P2,.JDAT+JOBPD1## ;GET PC OF ALL UUOS JRST .+2] ;AND SKIP APR CONDITION PC DMOVE P2,.CPPC## ;ALL OTHERS ARE APR CONDITIONS TLNN P2,(XC.USR) ;PC IN USER MODE JRST PSITLE ;NO, SEE IF TIME LIMIT EXCEEDED IFE PSIMPI, ;ONE ALREADY IN PROGRESS IFN PSIMPI, ;SYSTEM TURNED OFF PUSHJ P,ISPFH ;CHECK FOR USERS PFH JRST PSITLE ;CAN'T GRANT IT NOW IFN PSIMPI,< PUSHJ P,CNDLVL ;GET POINTER TO PRIORITY INFORMATION LDB P4,P4 ;GET LEVEL FOR CONDITION CAMG P4,PITHLP(P1) ;HIGHER THAN ONE IN PROGRESS JRST PSITLE ;NO, CAN'T GRANT IT NOW > TDNE F,PITMSG(P1) ;USER WANT STANDARD ERROR MESSAGE JRST PSIMSG ;YES, REMEMBER THAT AOS PITNPI(P1) ;KEEP THE COUNT STRAIGHT POP P,F ;BALANCE STACK FOR CALLER PJRST GENCND ;EXIT, CAUSING THE INTERRUPT PSITLE: TLNN F,(TLEBIT) ;WAS THIS TIME LIMIT EXCEEDED JRST FPOPJ## ;NO, IGNORE TRAP TDNN F,PITMSG(P1) ;CALLER STANDARD MESSAGE JRST PSIAGN ;NO, JUST POST IT PSIMSG: HLLOS PITCHN(P1) ;MARK PRINTING A MESSAGE JRST PSIAG1 ;GO POST BUT GIVE DOESN'T WANT RETURN ;SUBROUTINE CALLED AFTER PRINTING THE STANDARD MESSAGE FOR A USER ; J = JOB ; PUSHJ P,PSIERR ; HERE IF AT CLOCK LEVEL AND WANTS THE INTERRUPT ; HERE IF AT UUO LEVEL AND WANTS THE INTERRUPT ; HERE IF TIME TO STOP THE JOB PSIERR::SKIPGE T1,JBTPIA##(J) ;GET BASE OF DATA HRL T1,PITCHN(T1) ;GET FLAG THAT WE WERE PRINTING JUMPGE T1,CPOPJ2## ;QUIT IF NOT PSIING OR NOT PRINTING HLLZS PITCHN(T1) ;CLEAR FLAG HRRZ T1,P ;FIND OUT IF UUO OR CLOCK LEVEL CAMLE T1,LOCORE## ;CHECK STACK ADDRESS AOS (P) ;IN JOBDAT, GIVE CPOPJ1 RETURN POPJ P, ;RETURN TO INTERRUPT USER ;SUBROUTINE CALLED TO GRANT USER INDUCED ERROR IN JOB, I.E. THINGS NOT COVERED ; BY SPECIFIC CONDITIONS LIKE PDLOVERFLOW, ETC.. ; ; J = JOB NUMBER ; PUSHJ P,USREIJ ; RETURN HERE TO GRANT INTERRUPT ; RETURN HERE TO STOP JOB ( PRINT MSG, AND MAYBE BACK THROUGH PSIERR ) USREIJ::MOVE T1,[MSGBIT] ;GET CONDITIONS THAT HAVE ERROR MESSAGES SKIPE T2,JBTPIA##(J) ;USER PSI'ING TDNE T1,PITPND(T2) ;OR WERE WE JUST PRINTING A MESSAGE JRST CPOPJ1## ;GO STOP THE JOB (OR RETURN THROUGH PSIERR) SIGNAL C$UEIJ ;SIGNAL CONDITION AOS (P) ;DOESN'T WANT OR CAN'T GRANT, STOP THE JOB POPJ P, ;RETURN SUBTTL SUPPORT FOR DEVICE RELATED CONDITIONS ;HERE FOR DEVICE RELATED TRAPS ALSO IN .JBINT (AND SOME THAT AREN'T) ; T4 = .JBINT TYPE ; F = DDB INVOLVED ; PUSHJ P,PSIJBI ; HERE IF USER WANTS INTERRUPT (AVOID .JBINT) ; T3 = POSITIVE IF USER WANTS ERROR MESSAGE AS WELL ; HERE IF USER DOESN'T WANT THE TRAP (TRY .JBINT,T4 STILL OK) PSIJBI::PUSHJ P,SAVE3## ;SAVE A FEW LDB P2,PJOBN## ;GET JOB NUMBER MOVE P2,JBTSTS##(P2) ;THEN STATUS OF JOB TRNE P2,JS.ASA ;EXEC UUO IN PROGRESS JRST CPOPJ1## ;YES, NO USER TO GIVE IT TO SETZ P2, ;CLEAR INTERRUPT BITS CAIE T4,.EROFL ;DISK OFF-LINE CAIN T4,.ERIDV ;INTERVENTION REQUIRED MOVEI P2,IR.DOL ;YES, DEVICE OFF-LINE TRAP CAIN T4,.ERFUL ;DISK FULL MOVEI P2,IR.DFL ;YES, SET TRAP CAIN T4,.ERQEX ;QUOTA EXCEEDED MOVEI P2,IR.QTE ;YES, SET TRAP CAIN T4,'IDC' ;I/O TO DETACHED CPU MOVEI P2,IR.IER!IR.OER!IR.DOL ;ERROR CONDITION PUSHJ P,PSIDEV ;CALL SIGNALLER JUMPE P3,CPOPJ1## ;RETURN IF NOT PSIING MOVE T3,DEVPSI(P3) ;GET BITS FROM CORRECT DDB TLC T3,(1B0) ;FLIP SO NEGATIVE IS "NO MESSAGE" POPJ P, ;GO CLEAN UP AND GIVE INTERRUPT ;HERE JUST BEFORE AN INPUT OR OUTPUT RETURNS TO THE USER PSIEDN::TLNN S,IO ;DETERMINE DIRECTION OF THE IO PSIIDN::SKIPA T1,[IR.IER] ;INPUT ERROR PSIODN::MOVEI T1,IR.OER ;OUTPUT ERROR TRNE S,IODEND ;END OF FILE? TRO T1,IR.EOF ;YES, FLAG THAT CONDITION TRNN S,IOBKTL!IODTER!IODERR!IOIMPM!IOTEND ;AND ERRORS LIT TRZ T1,IR.IER!IR.OER;NO, DO NOT SIGNAL ERROR JRST PSIDVB ;GO SIGNAL CONDITION ; HERE WHEN A REEL SWITCH OCCURS PSIRSW::MOVEI T1,IR.RSW ;FLAG THAT CONDITION ; JRST PSIDVB ;FALL INTO DEVICE BITS SET UP ROUTINE ;HERE WHEN CALLER ALREADY HAS DETERMINED WHAT TYPE OF INTERRUPT TO GIVE PSIDVB::JUMPE T1,CPOPJ## ;EXIT IF NOTHING HAPPENED PUSHJ P,SAVE3## ;SAVE A FEW NOW HRRZ P2,T1 ;MOVE CONDITIONS JRST PSIDEV ;ENTER COMMON CODE ;SUBROUTINE TO SIGNAL DOWN DEVICE PSIDWN::PUSHJ P,SAVE3## ;SAVE A FEW MOVEI P2,IR.IER!IR.OER!IR.DOL ;SET INPUT ERR, OUTPUT ERR, OFF-LINE JRST PSIDEV ;ENTER COMMON CODE ;SUBROUTINE TO SIGNAL DEVICE ON-LINE PSIONL::PUSHJ P,SAVE3## ;SAVE A FEW MOVEI P2,IR.ONL ;DEVICE ON-LINE JRST PSIDEV ;ENTER COMMON CODE ;SUBROUTINE TO SIGNAL INPUT AVAILABLE PSIAVL::PUSHJ P,SAVE3## ;SAVE A FEW MOVEI P2,IR.IAL ;INPUT AVAILABLE JRST PSIDEV ;ENTER COMMON CODE ;SUBROUTINE TO SIGNAL INPUT/OUTPUT DONE INTERRUPTS ;CALLED BY SETIOD PSIIOD::PUSHJ P,SAVE3## ;SAVE A FEW TLNN S,IO ;GET THE DIRECTION OF THE IO SKIPA P2,[IR.IND] ;INPUT MOVEI P2,IR.OUD ;OUTPUT ; JRST PSIDEV ;FALL INTO COMMON CODE ;ROUTINE CALLED BY THE ABOVE SIGNALLERS TO CAUSE A DEVICE RELEATED INTERRUPT ;RETURNS P3 = 0 OR DDB USED (USEFUL ONLY TO PSIJBI) PSIDEV: IFN FTXMON,< PUSHJ P,SSEC0## ;MUST RUN ONLY IN SECTION 0 > HLRZ P3,DEVPSI(F) ;GET ENABLED FOR DEVICE IFN FTMPXSER,< JUMPN P3,PSIDV1 ;JUMP IF NOT MPX MOVEI P1,DEPMSG ;NOT USING THE DEVICE ITSELF TDNN P1,DEVMSG(F) ;TRY THE MPX CONTROLLING POPJ P, ;NOT MPX'ED, IGNORE INTERRUPT PUSH P,F ;SAVE ORIGINAL F HRRZ F,DEVXTR(F) ;STEP TO MPX DDB HLRZ P3,DEVPSI(F) ;GET BITS FOR THE MPX JUMPE P3,FPOPJ## ;IGNORE IF NOT PSI'ING PUSH P,[CAIA FPOPJ##] ;STACK RESTORE RETURN PSIDV1: >; END FTMPXSER AND P2,P3 ;MASK DOWN TO ENABLED BITS SETZ P3, ;CLEAR IN CASE WE RETURN JUMPE P2,CPOPJ## ;RETURN IF NOT ENABLED PUSH P,T1 ;SAVE SOME PUSH P,T2 ;VOLATILE REGISTERS LDB T1,PJCHN## ;GET JCH OWNING DEVICE PUSHJ P,CTXPSI## ;JOB USING PSISER? JRST TTPOPJ## ;NO SUCH JCH SKIPN P1,T2 ;GET JBTPIA IN RIGHT REGISTER JRST TTPOPJ## ;NOT USING PI SYSTEM SETCM P3,DEVPSI(F) ;GET WHAT'S NOT LIT TRNN P3,(P2) ;ALREADY HAVE THESE CONDITIONS JRST PSIDV2 ;YES, BITS AND COUNTS ARE RIGHT SETCMI P3,(P2) ;P3=NOT WHAT WE ARE SETTING IORB P2,DEVPSI(F) ;LIGHT NEW CONDITIONS, GET EVERYTHING TRNN P2,(P3) ;ANY OTHERS ALREADY PENDING AOS PITNPI(P1) ;NO, BUMP PENDING COUNT PSIDV2: MOVE P3,F ;RETURN DDB ACTUALLY USED JUMPGE P1,TTPOPJ## ;DON'T WAKE IF PI OFF PUSHJ P,CTXVAL## ;IS THIS THE CURRENT CONTEXT FOR THE JOB? JRST TTPOPJ## ;CONTEXT WENT AWAY TRNA ;YES, KEEP GOING JRST TTPOPJ## ;DON'T WAKE IT IF NOT CURRENT PUSH P,J ;SAVE JOB FOR CALLER LDB J,PJOBN## ;GET JOB OF DDB PUSHJ P,WAKEJB## ;WAKE THE JOB POP P,J ;RESTORE JRST TTPOPJ## ;RESTORE CALLER'S T1 AND T2 AND RETURN SUBTTL GRANT AN INTERRUPT TO A RUNNING USER ;CALLED BY UUOCON OR CLOCK1 TO GRANT AN INTERRUPT FOR A USER ; J = JOB NUMBER ; XCT PINOJN ;SKIP IF CANNOT GRANT INTERRUPT ; PUSHJ P,PSIGEN## ;CAN, GIVE AN INTERRUPT ; ;ALWAYS CPOPJ RETURN PSIGEN::SKIPG @JBTPIA##(J) ;ARE THERE ANY PENDING INTERRUPTS POPJ P, ;NO, GET OUT NOW PUSHJ P,SAVE4## ;SAVE A FEW FIRST SKIPGE P1,JBTPIA##(J) ;GET DATA BASE IFN PSIMPI, ;SYSTEM OFF UNTIL DEBRK. IFE PSIMPI, ;ALREADY ONE IN PROGRESS POPJ P, ;CANNOT GRANT INTERRUPT NOW HRRZ P2,-5(P) ; ***** GET CALLERS PC CAIN P2,CIPPSI## ;FROM CLOCK1 JRST [DMOVE P2,.CPPC## ;YES, GET CURRENT PC JRST .+2] ;AND SKIP DMOVE P2,.JDAT+JOBPD1## ;NO, GET UUO RETURN PC TLNN P2,(XC.USR) ;BETTER BE A USER MODE PC HERE POPJ P, ;DEFER UNTIL USER GETS OUT PUSHJ P,VALPC ;VALIDITY CHECK THE PC POPJ P, ;ILLEGAL (MESSAGE ALREADY TYPED) PSIGN1: PUSHJ P,ISPFH ;CHECK IF IN PFH OR DDT POPJ P, ;DEFER UNTIL USER GETS OUT HLRZ T1,PITIVA(P1) ;GET VECTOR EXTENT ANDI T1,(SECMSK) ;JUST ITS SECTION NUMBER PUSHJ P,SVPCS## ;DO THINGS TO THE RIGHT SECTION PUSHJ P,GENINT ;CAUSE INT JFCL ;NONE TO GIVE POPJ P, ;RETURN ;SUBROUTINE TO ACTUALLY GRANT THE INTERRUPT, CALLED BY PSIGEN AND PSIIMM ;CALL WITH: ; P1 = ADDRESS OF PSI DATA BASE ; P2-P3 = CURRENT USER MODE PC DOUBLEWORD ;ENTER AT GENCND WITH T1 ALREADY SET UP AS CONDITION TO GIVE (PSIIMM) ; CPOPJ CAN'T GIVE THE INTERRUPT ; CPOPJ1 DID, USER IS OFF AND RUNNING GENINT: PUSHJ P,GENNXT ;HERE WHEN WE DON'T KNOW WHAT'S NEXT, GO FIND IT POPJ P, ;NONE TO GIVE OR LOWER LEVELS WAITING FOR DEBRK. SKIPL T1 ;DEVICE OR CONDITION INTERRUPT SKIPA P4,[POINT CNDSIZ,DEVESE(F),26] ;DEVICE, GET POINTER TO OFFSET GENCND: PUSHJ P,CNDPTR ;GET POINTER FOR OFFSET LDB P4,P4 ;GET OFFSET PROPER LSH P4,2 ;BACK TO 4 WORD BLOCKS ADD P4,PITIVA(P1) ;PLUS VECTOR BASE TLZ P4,^-<(SECMSK)> ;CLEAR EXTRANEOUS BITS IFN FTXMON,< PUSHJ P,SAVR## ;NEED ANOTHER REGISTER MOVE R,T1 ;PRESERVE CONDITION HLRZ T1,P4 ;GET SECTION FOR VECTOR PUSHJ P,SVPCS## ;SET FOR PXCT AND FLTST MOVE T1,R ;RESTORE INTERRUPT REASON > ;END OF IFN FTXMON PUSH P,J ;SAVE J ANDI J,JOBMSK## ;GET ONLY JOB # PUSHJ P,VALVEC ;VALIDATE THE ADDRESS JRST JPOPJ## ;INVALID, GAVE ERROR PUSHJ P,PCSTOR ;STORE INTERRUPTED PC FOR USER TLNE P1,(SI.UEA) ;EXTENDED USER? EXCTUX ;GET NEW PC FOR INTERRUPT (WITH SECTION) EXCTUX ;GET NEW PC FOR INTERRUPT (IN SECTION) TLZ P2,(<-1,,0>->) ;CLEAR ALL BUT THESE MOVSI T2,(XC.USR) ;GET USER MODE BIT TDNE T2,.JDAT+JOBPD1## ;A USER PC IN JOBDAT DMOVEM P2,.JDAT+JOBPD1## ;YES, STORE FOR UUO DISMISS DMOVEM P2,.CPPC## ;STORE FOR CLOCK1 EXCTUX ;GET CONTROL FLAGS MOVSI T2,(SI.ON) ;PI SYSTEM ON TLNE P3,(PS.VPO) ;USER WANT IT TURNED OFF ANDCAM T2,JBTPIA##(J) ;YES, TURN IT OFF TILL PISYS. IFN PSIMPI,< MOVSI T2,(SI.DBK) ;OFF UNTIL DEBRK TLNE P3,(PS.VTO) ;USER WANT IT DONE IORM T2,JBTPIA##(J) ;YES, MARK WAITING FOR DEBRK. PUSH P,P4 ;SAVE USERS ADDRESS A MOMENT CAML T1,[C$MIN] ;DEVICE OR CONDITION SKIPL T1 ; .. SKIPA P4,[POINT 2,DEVESE(F),19] ;DEVICE, POINT TO PRIORITY INFORMATION PUSHJ P,CNDLVL ;CONDITION, GET POINTER TO PRIORITY LDB T2,P4 ;GET IT POP P,P4 ;RESTORE USERS BLOCK ADDRESS MOVEM T2,PITHLP(P1) ;STORE LEVEL IN PROGRESS ADDI T2,PITCIB(P1) ;POINT TO CORRECT "IN PROGRESS" BLOCK > IFE PSIMPI, ;POINT TO ONLY CURRENT BLOCK MOVEM P4,0(T2) ;STORE CURRENT INTERRUPT BLOCK HRR P2,T1 ;GET PC FLAGS,,CONDITION MOVEM P2,PITCIC-PITCIB(T2) ;STORE CONDITION AND FLAGS EXCTUU ;STORE REASONS OR CONDITION FOR USER CAML T1,[C$MIN] ;DEVICE OR CONDITION SKIPL T1 ; .. JRST [SETZ T1, ;CLEAR T1 FOR STATUS DISPATCH HRRM F,PITCIC-PITCIB(T2) ;STORE REAL CURRENT CONDITION (DDB) JRST .+1] ;RETURN INLINE XCT LDSTS(T1) ;LOAD STATUS WORD FOR USER EXCTUU ;STORE STATUS WORD MOVE T2,[WTMASK+JERR+CNTRLC,,JS.MPE+JS.DPM+UTRP] ANDCAM T2,JBTSTS##(J) ;CLEAR ALL ERROR CONDITIONS SOS PITNPI(P1) ;ONE LESS PENDING INTERRUPT JRST JPOPJ1## ;RETURN ;SUBROUTINE TO STORE THE INTERRUPT-FROM PC FOR GENINT ;CALL WITH: ; P1 = PIT POINTER ; P2-P3 = USER'S PC DOUBLEWORD ; P4 = START OF BLOCK IN USER'S VECTOR FOR THIS CONDITION ;RETURNS: ; CPOPJ ALWAYS, WITH THE PC STORED IN THE USER'S INTERRUPT VECTOR PCSTOR: TLNN P1,(SI.UEA) ;EXTENDED USER? JRST PCSTO1 ;NO, DO IT THE OTHER WAY EXCTXU ;STORE 30-BIT ADDRESS FROM PC FOR USER POPJ P, ;RETURN TO GENINT PCSTO1: HRR P2,P3 ;GET SECTION-ZERO STYLE PC EXCTXU ;STORE OLD-STYLE PC FOR USER TRZ P2,-1 ;CLEAR TRASH POPJ P, ;RETURN TO GENINT ;SUBROUTINE TO FIGURE OUT WHICH INTERRUPT TO GIVE NOW ;CALL WITH: ; P1 = ADDRESS OF PSI DATA BASE ; P2-P3 = USERS PC ( FYI, WE REALLY LEAVE IT ALONE HERE ) ;RETURNS: ; CPOPJ IF NONE TO GIVE NOW (MAYBE PRIORITIES) ; CPOPJ1 WITH THE FOLLOWING ; T1 = CONDITION NUMBER OR DEVICE BITS TO CAUSE ; F = DDB USED IF T1 IS DEVICE BITS, ELSE INDETERMINATE (READ WIPED) ;WIPES T2,T3,T4 AND P4 ;*** OF SPECIAL NOTE, THERE ARE 2 COPIES OF THIS ROUTINE UNDER CONDITIONALS ; FOR NUMBER OF PRIORITY LEVELS, ANY CHANGES TO ONE BETTER BE LOOKED AT ; FOR THE OTHER LEAST SOMEBODY FLIPPING CONDITIONAL WILL GET IT. IFE PSIMPI,< ;FIRST THE ONE FOR NO LEVELS, ITS EASIER GENNXT: SKIPN T1,PITPND(P1) ;ANY NON-DEVICE PENDING JRST GENDEV ;NO, TRY DEVICE CHAIN JFFO T1,.+1 ;YES, DETERMINE CONDITION MOVN T1,T2 ;GET CONDITION NUMBER MOVE T2,BITTBL##(T2) ;GET BIT FOR THIS CONDITION ANDCAM T2,PITPND(P1) ;NO LONGER PENDING JRST CPOPJ1## ;AND RETURN WITH IT GENDEV: HLRZ F,PITCHN(P1) ;POINT TO FIRST DDB GEND.1: JUMPE F,[SOSG PITNPI(P1) ;COUNT WAS TOO HIGH POPJ P, ;BUT IT'S RIGHT NOW JRST GENNXT] ;LOOK AGAIN IF STILL UP HLLZ T1,DEVPSI(F) ;GET CURRENT ENABLED BITS EXCH T1,DEVPSI(F) ;GET PENDING CONDITIONS, CLEAR THEM TLZ T1,-1 ;CLEAR ENABLED BITS JUMPN T1,CPOPJ1## ;USE IT IF ANY INTERRUPTS PENDING HLRZ F,DEVESE(P3) ;STEP TO NEXT DDB JRST GEND.1 ;LOOP FOR ALL PSI'ED DDBS > IFN PSIMPI,< ;NOW FOR MULTIPLE LEVELS, ITS HARDER GENNXT: MOVE T4,PITHLP(P1) ;GET HIGHEST LEVEL IN PROGRESS CAIN T4,PSIMPI ;QUICK CHECK FOR HIGHEST POSSIBLE POPJ P, ;WOULDN'T FIND ONE HIGHER ANYWAY SETZ F, ;CLEAR BEST SO FAR MOVE T3,PITPND(P1) ;GET NON-DEVICE PENDING GENN.1: SKIPN T1,T3 ;ANY WE HAVEN'T LOOKED AT YET JRST GENDEV ;NO, TRY DEVICE CHAIN JFFO T1,.+1 ;YES, DETERMINE CONDITION MOVN T1,T2 ;GET CONDITION NUMBER TDZ T3,BITTBL##(T2) ;DON'T LOOK AT THIS CONDITION AGAIN PUSHJ P,CNDLVL ;COMPUTE LEVEL POINTER LDB P4,P4 ;GET PRIORITY OF THIS CONDITION CAMG P4,T4 ;HIGHER THAN BEST SO FAR JRST GENN.1 ;NO, LOOK SOME MORE MOVE F,T1 ;WHICH ONE IT IS CAIN P4,PSIMPI ;QUICK CHECK, HIGHEST POSSIBLE JRST GENW.1 ;CAN'T GET ANY BETTER, STOP NOW MOVE T4,P4 ;COPY HIGHEST PRIORITY FOUND SO FAR JUMPN T3,GENN.1 ;LOOK FOR MAYBE A BETTER ONE GENDEV: HLRZ T1,PITCHN(P1) ;POINT TO FIRST DDB JUMPE T1,GENWAT ;LAST DDB, FIGURE OUT WHAT HAPPENED GEND.1: HRRZ T2,DEVPSI(T1) ;GET CURRENT PENDING BITS JUMPE T2,GEND.2 ;TRY ANOTHER IF NONE PENDING LDB T3,[POINT 2,DEVESE(T1),19] ;GET PRIORITY OF THIS DDB CAMG T3,T4 ;BEST SO FAR JRST GEND.2 ;NO, TRY ANOTHER MOVE F,T1 ;WHICH DDB HAS IT CAIN T3,PSIMPI ;SAME QUICK CHECK AS ABOVE JRST GENW.2 ;... MOVE T4,T3 ;REMEMBER HIGHEST LEVEL SO FAR GEND.2: HLRZ T1,DEVESE(T1) ;STEP TO NEXT PSI DDB JUMPN T1,GEND.1 ;AND TAKE A LOOK AT IT ;HERE WHEN ALL DONE LOOKING, F=BEST SO FAR, T4=IMPORTANT ONLY IF F = 0 GENWAT: JUMPE F,[JUMPGE T4,CPOPJ## ;NONE FOUND, OK IF BECAUSE OF PRIORITIES SOSG PITNPI(P1) ;PENDING COUNT WAS TOO HIGH POPJ P, ;BUT ITS OK NOW JRST GENNXT] ;DO THIS ALL OVER AGAIN IF COUNT IS STILL UP SKIPL T1,F ;A DDB OR CONDITION FOUND JRST GENW.2 ;A DDB, GO CLEAR PENDING BITS GENW.1: MOVSI T2,(1B0) ;GET A BIT LSH T2,(T1) ;POSITION IT CORRECTLY ANDCAM T2,PITPND(P1) ;NO LONGER PENDING JRST CPOPJ1## ;AND RETURN TO GIVE THE INTERRUPT GENW.2: HLLZ T1,DEVPSI(F) ;GET ENABLED CONDITIONS FROM DDB EXCH T1,DEVPSI(F) ;LEAVE THEM ALONE, GET SIGNALLED CONDITIONS TLZ T1,-1 ;CLEAR JUNK FROM LEFT HALF JRST CPOPJ1## ;RETURN WITH F = DDB, T1 = DEVICE BITS > ;TABLE EXECUTED DURING PSIGEN TO FETCH THE CORRECT STATUS WORD ; FOR THE CONDITION ABOUT TO BE GRANTED. ; CONDITIONS ARE NEGATIVE.. THIS TABLE GOES BACKWARDS.. PUSHJ P,LATPSI## ;(-40) LAT EVENT PUSHJ P,LLMPSI## ;(-37) LLMOP EVENT PUSHJ P,ENTPSI## ;(-36) ETHERNET EVENT PUSHJ P,SCSPSI## ;(-35) SCS EVENT SETZ T2, ;(-34) RESERVED TO CUSTOMER SETZ T2, ;(-33) RESERVED TO CUSTOMER PUSHJ P,NXTOOB## ;(-32) OUT-OF-BAND CHARACTER PUSHJ P,GETDTC ;(-31) DATE/TIME CHANGED PUSHJ P,GETJBI ;(-30) CROSS JOB INTERRUPTS SETZ T2, ;(-27) NETWORK TOPOLOGY CHANGE PUSHJ P,GETQUE ;(-26) ENQ/DEQ MOVEI T2,DR.EVT ;(-25) DECNET EVENT PUSHJ P,STRSIG## ;(-24) IPCF SETZ T2, ;(-23) ADDRESS BREAK LDB T2,[POINT 9,PITSTS(P1),17] ;(-22) WAKE UUO PUSHJ P,GETATC ;(-21) DETACH/ATTACH SETZ T2, ;(-20) DATASET STATUS CHANGE MOVE T2,SYSKTM## ;(-17) KSYS WARNING SETZ T2, ;(-16) EXTERNAL ERROR IN JOB SETZ T2, ;(-15) USER INDUCED ERROR IN JOB MOVE T2,DATE## ;(-14) APR CLOCK TICK SETZ T2, ;(-13) NON-EX MEM PUSHJ P,[IFE FTXMON, IFN FTXMON, POPJ P,] ;(-12) DECNET NSP UUOS SETZ T2, ;(-11) PDL OVERFLOW SETZ T2, ;(-10) APR CONDITIONS MOVE T2,DEVNAM(F) ;(-7) ADDRESS CHECK LDB T2,[POINT 23,.USPFW,35] ;(-6) ILL MEM REF PUSHJ P,GETUUO ;(-5) ILLEGAL UUO PUSHJ P,GETUUO ;(-4) ANY UUO PUSHJ P,GETIOW ;(-3) ^C MOVE T2,DATE## ;(-2) TIMER REQUEST PUSHJ P,GETJRT ;(-1) TIME LIMIT EXCEEDED LDSTS: PUSHJ P,GETUDX ;(0) DEVICE CONDITIONS COME HERE ;TABLE OF SIXBIT ABBREVIATIONS FOR NON-DEVICE CONDITIONS ; USED FOR PRINTING ERROR MESSAGES. 'LLM',,'LAT' ;(-37) LLMOP EVENT (-40) LAT EVENT 'SCS',,'ETH' ;(-35) SCS EVENT (-36) ETHERNET EVENT 'RC1',,'RC2' ;(-33) RSV'D FOR CUST (-34) RSV'D FOR CUST 'DTC',,'OOB' ;(-31) DATE/TIME CHANGE (-32) OUT-OF-BAND 'NTC',,'JBI' ;(-27) NTWRK TOPOLOGY (-30) CROSS JOB 'DVT',,'QUE' ;(-25) DECNET EVENT (-26) ENQ/DEQ 'ABK',,'IPC' ;(-23) ADR BREAK (-24) IPCF 'DAT',,'WAK' ;(-21) DET/ATTACH (-22) WAKE UUO 'KSY',,'DSC' ;(-17) KSYS WARNING (-20) DATASET STATUS 'UEJ',,'XEJ' ;(-15) USER ERROR (-16) EXTERNAL ERROR 'NXM',,'APC' ;(-13) NXM (-14) CLOCK TICK 'PDL',,'NSP' ;(-11) PDL OV (-12) DECNET NSP INTERRUPTS 'ACK',,'ARI' ;(- 7) ADR CHECK (-10) ARITHMETIC EXC 'ILU',,'IMR' ;(- 5) ILL UUO (- 6) ILL MEM REF 'STP',,'UUO' ;(- 3) ^C (- 4) ANY UUO 'TLE',,'TMR' ;(- 1) TIME LIMIT (- 2) TIMER REQUEST LDSIX: ;SUBROUTINES CALLED BY THE PRECEDING TABLE TO FETCH STATUS GETUDX: PUSH P,U ;SAVE U PUSH P,P1 ;SAVE P1 AROUND IONDF PUSHJ P,IONDF## ;GET UDX FOR DEVICE TDZA T2,T2 ;FAILED, NONE TO RETURN HRL T2,T1 ;INSERT IN RETURN AC HRR T2,DEVIOS(F) ;INSERT DEVICE STATUS POP P,P1 ;RESTORE JRST UPOPJ## ;RESTORE U AND RETURN GETQUE: MOVE T2,PITSTS(P1) ;GET SAVED REQUEST ID TLZ T2,(-1-PITQAB-777777) ;ZERO UNWANTED BITS ANDCAM T2,PITSTS(P1) ;CLEAR WHAT WE ARE SIGNALLING TLZE T2,(PITQAB) ;WERE ANY REQUESTS ABORTED? TLO T2,(1B0) ;YES, LIGHT SIGN BIT POPJ P, ;AND RETURN GETATC: MOVE T2,J ;COPY JCH ANDI T2,JOBMSK## ;KEEP ONLY JOB NUMBER HRRZ T2,TTYTAB##(T2) ;GET TTY DDB FOR JOB MOVE T2,DDBLDB##(T2) ;GET ATTACHED LDB SOJL T2,CPOPJ## ;RETURN -1 IF DETACHED PUSH P,U ;SAVE LDB REGISTER AOS U,T2 ;GET CORRECT ADDRESS IN U SE1XCT ;GET LINE NUMBER ADDI T2,.UXTRM ;MAKE IT A UDX JRST UPOPJ## ;RESTORE LDB REGISTER AND RETURN GETIOW: HLLZ T2,PITSTS(P1) ;GET SAVED STATUS TLZ T2,377777 ;WANT ONLY THE SIGN BIT POPJ P, ;RETURN GETJRT: PUSH P,W ;SAVE W MOVE T1,J ;COPY JOB NUMBER PUSHJ P,JOBTMM## ;DO "RUNTIME UUO" MOVE T2,T1 ;PUT RESULT IN RETURN AC JRST WPOPJ## ;RESTORE W AND RETURN GETJBI: SETZ T2, ;PITST2 INTERLOCKS PIJBI. UUO EXCH T2,PITST2(P1) ;GET STATUS, ALLOW OTHERS NOW POPJ P, ;RETURN GETUUO: HRLZ T2,.USMUO ;GET UUO OPCODE IOR T2,.USMUE ;INCLUDE ADDRESS CALCULATION POPJ P, ;RETURN UUO GETDTC: SETZ T2, ;SET TO CLEAR STATUS EXCH T2,PITST3(P1) ;GET THE DATE/TIME OFFSET POPJ P, ;RETURN SUBTTL PSISER SUBROUTINES ;SUBROUTINE TO RETURN PSI INFO FOR VMSER AND PFH PSIIVA::SKIPE T1,JBTPIA##(J) ;GET ADDR OF DATA BASE MOVE T1,PITIVA(T1) ;USING, GET VECTOR INFORMATION POPJ P, ;RETURN FOR STORE INTO PFH ;SUBROUTINE TO RETURN RANGE OF PAGES THAT INCLUDE THE USERS PSI VECTOR PSIIVR::SKIPN T1,JBTPIA##(J) ;GET ADDRESS OF DATA BASE POPJ P, ;NONE, RETURN ZERO PUSH P,J ;SAVE A WORK AC LDB J,[POINT 9,PITIVA(T1),8] ;GET HIGHEST OFFSET IN USE JUMPE J,PSIIV1 ;RETURN ZERO IF NO CONDITIONS YET LSH J,2 ;TO WORDS FROM BASE ADD J,PITIVA(T1) ;TO FIRST ADDRESS BEYOND VECTOR TLZ J,^-<(SECMSK)> ;CLEAR EXTRANEOUS BITS LDB T1,VECBS2 ;GET LOWEST ADDRESS USED LSH T1,W2PLSH ;MAKE A PAGE NUMBER LSH J,W2PLSH ;SIMILARLY HRL T1,J ;MAKE XWD LAST-PAGE,,FIRST-PAGE OF PSI VECTOR JRST JPOPJ## ;RESTORE J AND RETURN ANSWER PSIIV1: EXCH J,(P) ;RESTORE J, STORE ANSWER (ZERO) JRST TPOPJ## ;RETURN ZERO WHEN NO CONDITIONS YET ;SUBROUTINE TO CHECK IF A USER IS ENABLED FOR A CONDITION ;CALL T1 = CONDITION ( NEGATIVE ONES ONLY ) ; J = JCH INTERESTED IN ;RETURN CPOPJ IF NOT ENABLED ; CPOPJ1 IF SO ;USES T2 & T3 PSITST::JUMPGE T1,CPOPJ## ;ONLY NEGATIVE CONDITIONS HERE CAMGE T1,[C$MIN] ;AND THEN ONLY IN RANGE POPJ P, ;NONE OF THE ABOVE MOVE T3,T1 ;SAVE CONDITION MOVE T1,J ;GET JOB NUMBER WHERE WE NEED IT PUSHJ P,CTXPSI## ;GET JBTPIA FOR JCH JRST PSITS1 ;RESTORE T1 AND SAY NO JUMPE T2,PSITS1 ;IF NO SUCH JCH OR NOT USING PSISER MOVSI T1,(1B0) ;GET A BIT LSH T1,(T3) ;POSITION IT CORRECTLY TDNE T1,PITENB(T2) ;USER ENABLED FOR THIS TRAP AOS (P) ;YES, GIVE SKIP RETURN PSITS1: MOVE T1,T3 ;RESTORE CONDITION (JUST IN CASE) POPJ P, ;RETURN ;SUBROUTINE TO TELL ALL INTERESTED ABOUT NETWORK TOPOLOGY CHANGES IFN FTNET,< PSINTC::HRROI T2,C$NTC ;GET CONDITION TO SIGNAL JRST PSITEL ;GO TELL ALL JOBS AND CONTEXTS >; END FTNET ;SUBROUTINE TO TELL ALL INTERESTED ABOUT DECNET EVENT IFN FTDECNET,< PSIDVT::HRROI T2,C$DEVT ;GET CONDITION TO SIGNAL JRST PSITEL ;TELL ALL JOBS AND CONTEXTS >;END OF IFN FTDECNET ;SUBROUTINE TO INFORM JOBS OF KSYS TIMER PSIKSY::HRROI T2,C$KSYS ;GET CONDITION TO SIGNAL JRST PSITEL ;GO TELL ALL JOBS AND CONTEXTS ;SUBROUTINE TO INFORM JOBS OF SET DATE/DAYTIME COMMAND PSISDT::HRROI T2,C$DTC ;GET CONDITION TO SIGNAL TO THE WORLD PSITEL: IFN FTXMON,< PUSHJ P,SSEC0## ;NOT IN SECTION ONE YET > PUSHJ P,SAVE3## ;SAVE JOB LOOP INDEX AND SCRATCH REGISTERS PUSH P,J ;SAVE J FOR COMCON MOVE P2,T2 ;SAVE CONDITION MOVE P3,T1 ;SAVE POSSIBLE STATUS (UDT OFFSET) MOVE P1,HIGHJB## ;GET HIGHEST JOB NUMBER ASSIGNED TELL.1: MOVE J,P1 ;COPY JOB FOR JCH LOOP PUSHJ P,TELLJB ;INFORM ALL JCHS FOR THIS JOB SOJG P1,TELL.1 ;CONTINUE FOR ALL JOBS MOVE T1,P3 ;RESTORE UDT OFFSET JRST JPOPJ## ;RESTORE J AND RETURN ;SUBROUTINE TO INFORM ALL OF A JOB'S CONTEXTS ABOUT AN EVENT ;CALLED LIKE PSICND ;RETURNS NON-SKIP ALWAYS PSIJOB:: IFN FTXMON,< PUSHJ P,SSEC0## ;ALLOW CALLS FROM SECTION ONE > PUSHJ P,SAVE3## ;PRESERVE REGISTERS MOVE P1,J ;RETURN SAME JOB NUMBER DMOVE P2,T1 ;SAVE CONDITION & STATUS PUSHJ P,TELLJB ;TELL ALL JCHS FOR THE JOB MOVE J,P1 ;RESTORE THE JOB NUMBER DMOVE T1,P2 ;RESTORE STATUS POPJ P, ;RETURN TO CALLER ;SUBROUTINE TO NOTIFY ALL JCHS FOR JOB IN J OF CONDITION & STATUS IN P1 & P2 TELLJB: MOVE T1,J ;GET JCH BACK TLO T1,(1B0) ;SET STEP FLAG FOR CTXSER PUSHJ P,CTXPSI## ;GET JCH AND PIT POPJ P, ;NO SUCH JOB MOVE J,T1 ;MOVE JCH FOR SIGNAL DMOVE T1,P2 ;GET CONDITION AND STATUS PUSHJ P,PSICND ;SIGNAL THE CONDITION JFCL ;DON'T CARE IF NOT ENABLED TRNE J,CTXMSK## ;CTXSER LOADED? JRST TELLJB ;YES, LOOP OVER ALL JOB'S CONTEXTS POPJ P, ;NO, RETURN NOW ;HERE ON HARDWARE TRAP FOR ARITHMETIC INTERRUPTS PSIAPR::MOVE P,[MJOBPD##,,.JDAT+JOBPDL##] ;SET UP A PUSH DOWN LIST MOVE J,.CPJOB## ;GET JOB NUMBER RUNNING DMOVE T1,.USMUP-1 ;GET PC OF INTERRUPT TRZ T1,-1 ;CLEAR JUNK DMOVEM T1,.CPPC## ;STORE FOR SIGNALLER SIGNAL C$ARIT ;SIGNAL TRAP JFCL ;CANNOT GRANT IT MOVSI T1,(XC.OVF+XC.FOV+XC.FUF+XC.NDV) ANDCAM T1,.CPPC## ;CLEAR CONDITION THAT CAUSED TRAP USERAC ;BACK TO USERS ACS XJEN .CPPC## ;SUBROUTINE CALLED TO SIGNAL ANY UUO ;CALLED BY UUOCON JUST BEFORE DISPATCHING ; PUSHJ P,ANYUUO ; HERE TO PROCESS THE UUO ; HERE TO SKIP DISPATCH AND INTERRUPT USER ANYUUO::SKIPL T3,JBTPIA##(J) ;GET BASE OF PSI DATA POPJ P, ;NOT USING PSI OR SYSTEM OFF MOVE T3,PITENB(T3) ;GET ENABLED CONDITIONS TLNN T3,(AUUBIT) ;USER WANT TO TRAP EVERY UUO POPJ P, ;NO, RETURN NOW HRLZ T3,.USMUO ;GET UUO OPCODE IOR T3,.USMUE ;INCLUDE EFFECTIVE ADDRESS TDZ T3,[777,,200000] ;CLEAR OUT JUNK CAME T3,[CALLI 216] ;PIFLG. CAMN T3,[CALLI 212] ;PIBLK. POPJ P, ;DON'T WANT BLK ADDR FOR UUO INTERRUPTED CAML T3,[CALLI 135] ;PIINI. CAMLE T3,[CALLI 141] ;PIRST. SKIPA ;OK IF NOT ONE THAT CHANGES THE STATE POPJ P, ; OF THE PI SYSTEM PUSH P,T1 ;SAVE DISPATCH AC PUSH P,T2 SIGNAL C$AUUO ;SIGNAL A UUO IS DONE JRST TTPOPJ## ;USER CANNOT TAKE IT, DO UUO POP P,T2 ;RESTORE REGISTER JRST TPOPJ1## ;SKIP DISPATCH, USER WANTS IT ;SUBROUTINE CALLED BY PSIGEN TO VALIDATE THE INTERRUPT-FROM PC ;RETURNS CPOPJ IF INVALID ; CPOPJ1 IF OK VALPC: TLNN P1,(SI.UEA) ;EXTENDED USER? TLNN P3,(SECMSK) ;OR SECTION 0 PC? JRST CPOPJ1## ;PC OK, KEEP GOING HLRZ T1,P3 ;GET PC SECTION PUSHJ P,SVPCS## ;SET UP FOR PXCTS HRRZ T1,P3 ;GET A COPY OF THE PC EXCTUX ;IN-SECTION TRANSLATION EXCTUX ;SECTION-ZERO TRANSLATION ; TLZ T1,^-<(SECMSK)> ;GET JUST PHYSICAL ADDRESS IN SECTION ZERO ; TLZ T2,^-<(SECMSK)> ;AND IN PC SECTION CAMN T1,T2 ;IF THE SAME, JRST CPOPJ1## ;THEN THIS IS LEGAL AFTER ALL MOVSI T1,JERR ;JOB ERROR BIT IORM T1,JBTSTS##(J) ;PREVENT TRAPS PUSHJ P,GIVRES## ;GIVE UP ANY RESOURCES JSP T1,ERRPNT## ;START UP AN ERROR MESSAGE (WILL PUSH F & U) ASCIZ/Illegal non-zero section PSI interrupt/ DMOVE T1,P2 ;COPY THE USER PC PUSHJ P,DPCP## ;CALL PC TYPER JRST PCSTOP## ;STOP JOB, NOT CONTINUABLE ;SUBROUTINE CALLED BY PSIGEN TO VALIDATE THE INTERRUPT VECTOR ADDRESS ;RETURNS CPOPJ IF INVALID ; CPOPJ1 IF OK VALVEC: PUSH P,T1 ;SAVE CONDITION HRRZ T1,P4 ;POINT TO ADDRESS (IN-SECTION FOR IADRCK) SETO T2, ;LOOP COUNTER VALV.1: PUSHJ P,IADRCK## ;HAVE UUOCON SEE IF ABOVE JOBPFI JRST VALV.2 ;YES, SAY ILLEGAL TO USER JFCL ;CHECK OURSELVES ABOUT OTHER PROBLEMS HLLZ T4,P4 ;GET SECTION NUMBER OF VECTOR ADD T4,T1 ;GET GLOBAL ADDRESS LSH T4,W2PLSH ;CONVERT TO PAGE NUMBER SE1XCT ;GET MAP ENTRY FOR PAGE PUSHJ P,FLTST## ;CHECK IF PAGE CAUSES FAULT JRST VALV.3 ;YES, SAY PAGED OUT TDNN T4,[PM.WRT] ;IS THE PAGE WRITABLE JRST [MOVEI T2,[ASCIZ/, is write protected/] JRST VALV.4] ;DIFFERENT ERROR IF VECTOR IN THE HIGH SEG ADDI T1,.PSVIS ;STEP TO LAST WORD IN VECTOR AOJE T2,VALV.1 ;CHECK IT NOW JRST TPOPJ1## ;RETURN IF PASSED BOTH TESTS VALV.2: SKIPA T2,[[ASCIZ/, is illegal/]] VALV.3: MOVEI T2,[ASCIZ/, is paged out/] VALV.4: PUSH P,T2 ;SAVE ADDRESS OF MESSAGE MOVSI T1,JERR ;CAN'T CONTINUE BIT IORM T1,JBTSTS##(J) ;PREVENT TRAPS PUSHJ P,GIVRES## ;GIVE UP ANY RESOURCES JSP T1,ERRPNT## ;FIRE UP AN ERROR MESSAGE ASCIZ/PSI Interrupt Vector at / ;**** ERRPNT WILL PUSH F & U MOVE T2,P4 ;GET LOCATION OF VECTOR PUSHJ P,UDPCP## ;OUTPUT IT SKIPL T2,-3(P) ;GET CONDITION NUMBER JRST VALV.5 ;ITS A DDB ROT T2,-1 ;DIVIDE TO GET TABLE ENTRY SKIPGE T2 ;WHICH HALF SKIPA T2,LDSIX(T2) ;LEFT MOVS T2,LDSIX(T2) ;RIGHT TRZA T2,-1 ;CLEAR OTHER VALV.5: SKIPA T2,DEVNAM(F) ;GET DEVICE NAME SKIPA T1,[[ASCIZ/, for Condition /]] MOVEI T1,[ASCIZ/, for Device /] MOVEM T2,-3(P) ;STORE FOR SAFE KEEPING PUSHJ P,CONMES## ;OUTPUT CORRECT STRING MOVE T2,-3(P) ;RESTORE PUSHJ P,PRNAME## ;OUTPUT SIXBIT DEVICE OR CONDITION MOVEI T1,TPOPJ## ;FOR CLEANUP EXCH T1,-2(P) ;GET CORRECT ENDING PUSHJ P,CONMES## ;APPEND "ILLEGAL" OR "PAGED OUT" JRST PCSTOP## ;AND STOP THE JOB, NON-CONTINUABLE ;SUBROUTINE TO BUILD A BYTE POINTER TO THE VECTOR OFFSET BYTE ;CALL WITH: ; P1 = ADDRESS OF PSI DATA BASE ; T1 = CONDITION NUMBER (ONLY NEGATIVE ONES HERE) ; PUSHJ P,CNDPTR ; RETURN HERE POINTER IN P4 ;PRESERVES T1 WIPES T2 CNDPTR: PUSH P,T1 ;SAVE CONDITION MOVM T1,T1 ;GET POSITIVE CONDITION IDIVI T1,4 ;T1 := WORD AND T2 := QUARTER MOVE P4,CNDP.A(T2) ;GET A GOOD POINTER ADDI P4,(T1) ;ADD IN WORD OFFSET JRST TPOPJ## ;RESTORE T1 AND RETURN CNDP.A: POINT CNDSIZ,PITTAB(P1),8 ;BYTE 0 POINT CNDSIZ,PITTAB(P1),17 ;BYTE 1 POINT CNDSIZ,PITTAB(P1),26 ;BYTE 3 POINT CNDSIZ,PITTAB(P1),35 ;BYTE 4 ;SUBROUTINE TO BUILD A BYTE POINTER TO THE PRIORITY BYTE ; ;SAME CALL AND RETURN AS CNDPTR IFN PSIMPI,< CNDLVL: PUSHJ P,CNDPTR ;LET CNDPTR FIGURE OUT BYTE AND WORD OFFSETS HLL P4,CNDP.B(T2) ;BUT INSERT DIFFERENT SIZE AND POSITION INFO POPJ P, ;RETURN CNDP.B: POINT 2,0(P1),1 ;BYTE 0 POINT 2,0(P1),10 ;BYTE 1 POINT 2,0(P1),19 ;BYTE 2 POINT 2,0(P1),28 ;BYTE 3 > ;SUBROUTINE TO SEE IF USER IS IN PFH OR DDT ;CALL WITH: ; P2-P3 = PC DOUBLEWORD ; PUSHJ P,ISPFH ; HERE IF IN PFH OR DDT ; HERE IF NOT ;WIPES T2 ISPFH: TLNE P3,(SECMSK) ;IN SECTION ZERO? JRST ISDDT ;NO, NOT IN PFH MOVE T2,P2 ;MOVE PC FOR VMSER HRR T2,P3 ;GET REST OF PC PUSH P,T3 ;SAVE T3 AROUND VMSER PUSHJ P,INPFH## ;SEE IF WE ARE IN PFH JRST T3POPJ## ;YES, RESTORE T3 AND RETURN POP P,T3 ;RESTORE NOW ISDDT: HRRZ T2,.JDAT+JOBDDT## ;GET START OF DDT SKIPE .JDAT+JOBDDT## ;DDT LOADED? CAILE T2,(P3) ;ABOVE START OF DDT? JRST CPOPJ1## ;NO, ALL IS WELL HLRZ T2,.JDAT+JOBDDT## ;GET END OF DDT CAIG T2,(P3) ;ABOVE END? AOS (P) ;YES, NOT IN DDT POPJ P,0 ;IN DDT PSILIT::XLIST ;FORCED OUT LITERAL POOL HERE $LIT LIST PSIEND::END