Trailing-Edge
-
PDP-10 Archives
-
PCL_FOR_701
-
psiser.mac
There are 7 other files named psiser.mac in the archive. Click here to see a list.
TITLE PSISER -- PROGRAMMED SOFTWARE INTERRUPT SERVICE V216
SUBTTL C. D. O'TOOLE/CDO 08 JUL 79
SEARCH F,S
$RELOC
$HIGH
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1973,1974,1975,1976,1977,1978,1979,1980 BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
XP VPSISR,216
PSISER: ENTRY PSISER
XP PSIMPI,3 ;MAXIMUM PRIORITY LEVEL
IFL PSIMPI,<PRINTX ? PSIMPI CANNOT BE NEGATIVE
XP PSIMPI,0>
IFG <PSIMPI-3>,<PRINTX ? PSIMPI CANNOT BE .GT. 3
XP PSIMPI,3>
IFL <^D35+C$MIN>,<PRINTX ? TOO MANY CONDITIONS FOR THIS EDIT
XP C$MIN,-^D35>
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),<NAME==0
IRP X,<NAME==NAME!1B<-C$'X>>>
;REPRESENT ALL VALID PSI CONDITIONS (CAN REMOVE WHEN NO HOLES)
BITS(ZZ1,<TLE,CTLC,AUUO,IUUO,IMR,ADCK,ARIT,PLOV,APRC,UEIJ,XEIJ>)
BITS(ZZ2,<KSYS,DSET,DATT,WAKE,ADRB,IPC,QUE,NTC,NXM,JBI>)
VLDBIT==ZZ1!ZZ2
;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,<AUUO,TLE,IUUO,IMR,ADCK,ARIT,PLOV,APRC,UEIJ,XEIJ,ADRB,NXM>)
;THE FOLLOWING IMMEDIATE CONDITIONS FIND THE USERS PC IN JOBPD1.
; ALL OTHERS GET THE PC FROM .CPPC
BITS(PD1BIT,<AUUO,IUUO,ADCK,UEIJ>)
;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,<TLE,IUUO,IMR,ADCK,PLOV,UEIJ,XEIJ,ADRB,NXM>)
IFN <<IMBITS&MSGBIT>-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,<ARIT>)
BITS(AUUBIT,<AUUO>)
BITS(TLEBIT,<TLE>)
BITS(JBIBIT,<JBI>)
BITS(QUEBIT,<QUE>)
BITS(WAKBIT,<WAKE>)
BITS(CTCBIT,<CTLC>)
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 1 IF ^C FROM TI WAIT
; 1-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
PITIVA:! BLOCK 1 ; 0-8 HIGHEST VECTOR IN USE
; 9-17 MUST BE ZEROS
;18-35 ADDRESS OF USERS BASE
IFN PSIMPI,<
PITHLP:! BLOCK 1 ;HIGHEST LEVEL IN PROGRESS ( -1 IF NONE )
>
PITCIB:! BLOCK <PSIMPI+1> ;RH = CURRENT INTERRUPT BLOCK
;LH = CURRENT CONDITION
;***** IF DDB ADDRESS GO BEYOND 377777,
; THIS WON'T WORK ANYMORE *****
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
; CONTAINS RELATIVE OFFSET INTO USERS VECTOR
PITSIZ::! ;SIZE OF THE DATA BASE IN WORDS
PIT4WD==<PITSIZ+3>/4 ;SIZE IN 4 WORD BLOCKS
IFN PITNPI,<PRINTX ? PITNPI IS NOT FIRST IN THE DATA BASE>
DEPHASE
RELOC PSISER
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:: MOVEI T1,(T1) ;ISOLATE THE BASE ADDRESS
PUSH P,T1 ;SAVE USER ARGUMENT
PUSHJ P,CLRPSI ;CLEAR OLD DATA
MOVEI T2,PIT4WD ;NUMBER OF 4-WORD BLOCKS TO GET
PUSHJ P,GET4WD## ;GO GET THEM
JRST TPOPJ## ;CAN'T
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,<SETOM PITHLP(T1)> ;SET INTERRUPT LEVEL TO -1
POP P,PITIVA(T1) ;BASE OF VECTOR
HRRZM 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,PIT4WD ;NUMBER OF 4-WORD BLOCKS WE HAVE
PUSHJ P,GIV4WD## ;RETURN THE CORE
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
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 RTZER## ;(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
PSIRMV::SETZM DEVPSI(F) ;CLEAR ANY ENABLED BITS
LDB T1,PJOBN## ;GET OWNER
SKIPN T1,JBTPIA##(T1) ;USING PSI
POPJ P, ;NO, HOW DID THOSE BITS GET LIT
PUSHJ P,SAVE2## ;SAVE A FEW REGS NOW
MOVE P1,T1 ;COPY DATA BASE ADDRESS
UNLDDB: HLRZ P2,PITCHN(P1) ;GET FIRST DDB IN PSI CHAIN
MOVEI P1,<PITCHN-DEVESE>(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
TDNN T2,[VLDBIT] ;*** A VALID CONDITION
PJRST ECOD6## ;*** (6) ILLEGAL CONDITION
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
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,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 IN NON-ZERO
IFE PSIMPI,<PJUMPN T1,ECOD11##> ;(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
HRRZ P2,PITIVA(P1) ;GET BASE OF VECTOR
ADDI P2,.PSVFL(T1) ;POINT TO CONTROL FLAGS
HRRI M,(P2) ;...
MOVE P2,T1 ;SAVE OFFSET
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
TDNN T2,[VLDBIT] ;*** A VALID CONDITION
PJRST ECOD6## ;*** (6) ILLEGAL CONDITION
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,.UPMP+.UPAOT ;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: 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,PJOBN## ;GET NAME OF OWNER
MOVEI T3,ASSPRG ;SEE IF DEVICE IS
TDNE T3,DEVMOD(F) ; OPEN FOR
CAIE T2,(J) ; THIS JOB.
PJRST ECOD5## ;(5) OR NOT OPEND 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
CHKC.3: 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
HRRZ T1,PITIVA(P1) ;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,<SETZ T1,> ;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,<PUSH P,T1> ;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,<SETZ T1,> ;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.
PUSHJ P,PUTWDU## ;STORE IN BEGINNING OF USERS BLOCK
JUMPL P2,RTZER## ;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
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 RTZER##] ;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,<SKIPGE P4,PITHLP(P1)> ;GET HIGHEST LEVEL IN PROGRESS
IFE PSIMPI,<SKIPN P2,PITCIB(P1)> ;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
>
HRRI M,.PSVOP(P2) ;OLD PC
PUSHJ P,GETWDU## ;FETCH IT
MOVE P3,T1 ;SAVE FOR NOW
HRRI M,.PSVFL(P2) ;FLAG WORD
PUSHJ P,GETWDU## ;GET THAT TOO
MOVE T4,.JDAT+JOBPD1## ;GET UUO PC
TLNN T4,(XC.UIO) ;DOES HE HAVE USER IOT SET
TLZ P3,(XC.UIO) ;NO, CLEAR FROM OLD PC
IFE FTKS10,<
TLNE T4,(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 @
MOVEM P3,.JDAT+JOBPD1## ;STORE BACK FOR USER
IFE PSIMPI,<SETZM PITCIB(P1)> ;CLEAR INTERRUPT IN PROGRESS
IFN PSIMPI,<
SETZM 0(P4) ;CLEAR INTERRUPT IN PROGRESS
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
HLRE P2,P2 ;GET CONDITION NUMBER OR DDB ADDRESS
JUMPGE P2,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
SUBTTL UUOCON INTERFACE -- PIJBI.
;CALL TO INTERRUPT ANOTHER JOB AND GIVE STATUS
;CALL WITH:
; MOVE AC,[XWD JOB 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:: HLRZ J,T1 ;GET JOB TO INTERRUPT
HRL T1,.CPJOB## ;STATUS RETURNED IS JOB WHO DID IT,,STATUS
CAIN J,-1 ;INTERRUPTING YOURSELF
HLRZ J,T1 ;YES, SET BOTH JOB NUMBERS TO CURRENT
CAILE J,JOBMAX## ;GOOD JOB NUMBER
JRST ECOD0## ;(0) ILLEGAL JOB NUMBER
MOVEI T2,JBIBIT ;BIT FOR ENABLED THIS TYPE OF INTERRUPT
SKIPE T3,JBTPIA##(J) ;TARGET JOB USING PSISER
TDNN T2,PITENB(T3) ;YES, USER ENABLED FOR CROOS JOB INTERRUPTS
JRST ECOD0## ;(0) NOT ENABLED FOR INTERRUPT
UUOLOK ;PREVENT RACES WITH OTHER CPUS
SKIPN T2,PITST2(T3) ;TARGET ALREADY HAVE ONE PENDING
MOVEM T1,PITST2(T3) ;NO, GIVE HIM THIS ONE
UUONLK ;ALLOW OTHER CPUS BACK IN NOW
JUMPN T2,ECOD1## ;(1) TARGET IS BUSY, TRY LATER
SIGNAL C$JBI ;CAUSE THE INTERRUPT
JRST ECOD0## ;REALLY OUGHT TO STOPCD HERE SINCE JUST CHECKED
JRST CPOPJ1## ;GIVE GOOD RETURN TO CALLER
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$WAKE = JOB NUMBER OF WAKER
; C$QUE = REQUEST ID
; 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
PUSHJ P,SAVE4## ;SAVE A FEW FIRST
CAML T1,[C$MIN] ;CONDITION TOO SMALL
SKIPN P1,JBTPIA##(J) ;USER DOING PSISER
POPJ P, ;NOT USING PSISER OR BAD CONDITION
MOVSI P3,(1B0) ;GET A BIT
LSH P3,(T1) ;POSITION IT CORRECTLY
TDNN P3,PITENB(P1) ;USER ENABLE FOR THIS INTERRUPT
POPJ P, ;NO, QUIT NOW
TDNE P3,[IMBITS] ;IS THIS AN IMMEDIATE CONDITION
JRST PSIIMM ;YES, GO DIRECTLY TO GENERATOR
TRNE P3,QUEBIT ;ENQ/DEQ
IORM T2,PITSTS(P1) ;REMEMBER REQUEST ID
TRNE P3,WAKBIT ;WAKE UUO.
DPB T2,[POINT 9,PITSTS(P1),17] ;YES, REMEMBER WAKING JOB
TLNN P3,(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
SKIPA P2,.JDAT+JOBPD1## ;YES, GET UUO PC
MOVE P2,USRPC## ;NO, GET SAVED PC
TLNN P2,USRMOD ;BETTER BE A USER PC
MOVE P2,.JDAT+JOBPD1## ;GET LAST UUO PC
PUSHJ P,ISDDT ;USER IN DDT
POPJ P, ;YES, LET CONTROL C STOP THE JOB
PSIAGN: AOS (P) ;USER WANTS INTERRUPT
PSIAG1: TDNE P3,PITPND(P1) ;ALREADY HAVE THIS ONE PENDING
JRST PSIAG2 ;YES, JUST WAKE THE JOB
IORM P3,PITPND(P1) ;LIGHT ONE FOR THIS INTERRUPT
AOS PITNPI(P1) ;BUMP PENDING COUNT
PSIAG2: JUMPGE P1,CPOPJ## ;DON'T WAKE THE JOB IF PI OFF
PJRST WAKEJB## ;WAKE UP JOB AND RETURN
;HERE WHEN A CONDITION MUST BE GRANTED IMMEDIATELY (APR STUFF)
PSIIMM: JUMPGE P1,CPOPJ## ;CANNOT GRANT IF PS IS OFF
TDNE P3,[PD1BIT] ;WHERE IS THE CURRENT PC
SKIPA P2,.JDAT+JOBPD1## ;GET PC OF ALL UUOS
MOVE 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,<SKIPN PITCIB(P1)> ;ONE ALREADY IN PROGRESS
IFN PSIMPI,<TLNN P1,(SI.DBK)> ;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 P3,PITMSG(P1) ;USER WANT STANDARD ERROR MESSAGE
JRST PSIMSG ;YES, REMEMBER THAT
AOS PITNPI(P1) ;KEEP THE COUNT STRAIGHT
PJRST GENCND ;EXIT, CAUSING THE INTERRUPT
PSITLE: TLNN P3,(TLEBIT) ;WAS THIS TIME LIMIT EXCEEDED
POPJ P, ;NO, IGNORE TRAP
TDNN P3,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, ANY 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 RELEATED 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 ;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/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: HLRZ P3,DEVPSI(F) ;GET ENABLED FOR DEVICE
IFN FTMSGSER,<
JUMPE P3,[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
JRST .+1] ;RETURN INLINE
>; END FTMSGSER
AND P2,P3 ;MASK DOWN TO ENABLED BITS
SETZ P3, ;CLEAR IN CASE WE RETURN
JUMPE P2,CPOPJ## ;RETURN IF NOT ENABLED
PUSH P,J ;SAVE J
LDB J,PJOBN## ;GET OWNER OF DEVICE
SKIPN P1,JBTPIA##(J) ;OWNER ENABLED
JRST JPOPJ## ;NO, IGNORE REQUEST
SETCM P3,DEVPSI(F) ;GET WHAT'S NOT LIT
TRNN P3,(P2) ;ALREADY HAVE THESE CONDITIONS
JRST PSIDV1 ;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
PSIDV1: MOVE P3,F ;RETURN DDB ACTUALLY USED
JUMPGE P1,JPOPJ## ;DON'T WAKE IF PI OFF
DMOVE P1,T1 ;SAVE T1,T2 IN P1,P2
PUSHJ P,WAKEJB## ;WAKEUP JOB
DMOVE T1,P1 ;RESTORE CALLERS T1 AND T2
JRST JPOPJ## ;RESTORE J 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,<TLNE P1,(SI.DBK)> ;SYSTEM OFF UNTIL DEBRK.
IFE PSIMPI,<SKIPE PITCIB(P1)> ;ALREADY ONE IN PROGRESS
POPJ P, ;CANNOT GRANT INTERRUPT NOW
HRRZ P2,-5(P) ; ***** GET CALLERS PC
CAIN P2,CIPPSI## ;FROM CLOCK1
SKIPA P2,.CPPC## ;YES, GET CURRENT PC
MOVE P2,.JDAT+JOBPD1## ;NO, GET UUO RETURN PC
TLNE P2,(XC.USR) ;BETTER BE A USER MODE PC HERE
PUSHJ P,ISPFH ;CHECK IF IN PFH OR DDT
POPJ P, ;DEFER UNTIL USER GETS OUT
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 = CURRENT USER MODE PC
;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(P3),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
PUSHJ P,VALVEC ;VALIDATE THE ADDRESS
POPJ P, ;INVALID, GAVE ERROR
EXCTUU <MOVEM P2,.PSVOP(P4)> ;STORE INTERRUPTED PC FOR USER
EXCTUU <HRR P2,.PSVNP(P4)> ;GET NEW PC FOR INTERRUPT
TLZ P2,(<-1,,0>-<XC.USR!XC.UIO!IFE FTKS10,<XC.PUB>>) ;CLEAR ALL BUT THESE
MOVSI T2,(XC.USR) ;GET USER MODE BIT
TDNE T2,.JDAT+JOBPD1## ;A USER PC IN JOBDAT
MOVEM P2,.JDAT+JOBPD1## ;YES, STORE FOR UUO DISMISS
MOVEM P2,.CPPC## ;STORE FOR CLOCK1
EXCTUU <MOVE P2,.PSVFL(P4)> ;GET CONTROL FLAGS
MOVSI T2,(SI.ON) ;PI SYSTEM ON
TLNE P2,(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 P2,(PS.VTO) ;USER WANT IT DONE
IORM T2,JBTPIA##(J) ;YES, MARK WAITING FOR DEBRK.
PUSH P,P4 ;SAVE USERS ADDRESS A MOMENT
SKIPL T1 ;DEVICE OR CONDITION
SKIPA P4,[POINT 2,DEVESE(P3),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,<MOVEI T2,PITCIB(P1)> ;POINT TO ONLY CURRENT BLOCK
HRRM P4,0(T2) ;STORE CURRENT INTERRUPT BLOCK
HRLM T1,0(T2) ;AND CURRENT CONDITION
EXCTUU <HRRM T1,.PSVFL(P4)> ;STORE REASONS OR CONDITION FOR USER
JUMPGE T1,[SETZ T1, ;CLEAR T1 FOR STATUS DISPATCH
HRLM P3,0(T2) ;STORE REAL CURRENT CONDITION
JRST .+1] ;RETURN INLINE
XCT LDSTS(T1) ;LOAD STATUS WORD FOR USER
EXCTUU <MOVEM T2,.PSVIS(P4)> ;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 CPOPJ1## ;RETURN
;SUBROUTINE TO FIGURE OUT WHICH INTERRUPT TO GIVE NOW
;CALL WITH:
; P1 = ADDRESS OF PSI DATA BASE
; P2 = 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
; P3 = 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 P3,PITCHN(P1) ;POINT TO FIRST DDB
GEND.1: JUMPE P3,[SOSG PITNPI(P1) ;COUNT WAS TOO HIGH
POPJ P, ;BUT IT'S RIGHT NOW
JRST GENNXT] ;LOOK AGAIN IF STILL UP
HLLZ T1,DEVPSI(P3) ;GET CURRENT ENABLED BITS
EXCH T1,DEVPSI(P3) ;GET PENDING CONDITIONS, CLEAR THEM
TLZ T1,-1 ;CLEAR ENABLED BITS
JUMPN T1,CPOPJ1## ;USE IT IF ANY INTERRUPTS PENDING
HLRZ P3,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 P3, ;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 P3,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 P3,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, P3=BEST SO FAR, T4=IMPORTANT ONLY IF P3 = 0
GENWAT: JUMPE P3,[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,P3 ;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(P3) ;GET ENABLED CONDITIONS FROM DDB
EXCH T1,DEVPSI(P3) ;LEAVE THEM ALONE, GET SIGNALLED CONDITIONS
TLZ T1,-1 ;CLEAR JUNK FROM LEFT HALF
JRST CPOPJ1## ;RETURN WITH P3 = 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,GETJBI ;(-30) CROSS JOB INTERRUPTS
SETZ T2, ;(-27) NETWORK TOPOLOGY CHANGE
PUSHJ P,GETQUE ;(-26) ENQ/DEQ
SETZ T2, ;(-25) ***RESERVED
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
SETZ T2, ;(-12) ***RESERVED
SETZ T2, ;(-11) PDL OVERFLOW
SETZ T2, ;(-10) APR CONDITIONS
MOVE T2,DEVNAM(F) ;(-7) ADDRESS CHECK
SETZ T2, ;(-6) ILL MEM REF
MOVE T2,.UPMP+.UPMUO ;(-5) ILLEGAL UUO
MOVE T2,.UPMP+.UPMUO ;(-4) ANY UUO
PUSHJ P,GETIOW ;(-3) ^C
SETZ T2, ;(-2) ***RESERVED
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.
'NTC',,'JBI' ;(-27) NTWRK TOPOLOGY (-30) CROSS JOB
0,,'QUE' ;(-25) ***RESERVED (-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',,0 ;(-11) PDL OV (-12) ***RESERVED
'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',,0 ;(- 1) TIME LIMIT (- 2) ***RESERVED
LDSIX:
;SUBROUTINES CALLED BY THE PRECEDING TABLE TO FETCH STATUS
GETUDX: PUSH P,U ;SAVE U
PUSH P,F ;SAVE F
PUSH P,P1 ;SAVE P1 AROUND IONDF
MOVE F,P3 ;MOVE DDB ADDRESS INTO F
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 FUPOPJ## ;RESTORE F&U AND RETURN
GETQUE: HRRZ T2,PITSTS(P1) ;GET SAVED REQUEST ID
ANDCAM T2,PITSTS(P1) ;CLEAR WHAT WE ARE SIGNALLING
POPJ P, ;AND RETURN
GETATC: HRRZ T2,TTYTAB##(J) ;GET TTY DDB FOR JOB
HRRZ T2,DDBLDB##(T2) ;GET ATTACHED LDB
SOJL T2,CPOPJ## ;RETURN -1 IF DETACHED
LDB T2,[POINT 9,LDBDCH##+1(T2),35] ;GET LINE NO (T2 OFF BY 1)
ADDI T2,.UXTRM ;MAKE IT A UDX
POPJ P, ;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
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
HRLI J,-1(J) ;HIGHEST ADDRESS USED TO LEFT HALF
HRR J,PITIVA(T1) ;INSERT LOWEST ADDRESS
TLZ J,PG.BDY## ;ONLY WANT PAGE NUMBERS
LSH J,W2PLSH## ;SO CONVERT ADDRESSES
PSIIV1: EXCH J,(P) ;RESTORE J, STORE ANSWER
JRST TPOPJ## ;RETURN XWD LAST-PAGE,,FIRST-PAGE OF PSI VECTOR
;SUBROUTINE TO CHECK IF A USER IS ENABLED FOR A CONDITION
;CALL T1 = CONDITION ( NEGATIVE ONES ONLY )
; J = JOB NUMBER INTERRESTED IN
;RETURN CPOPJ IF NOT ENABLED
; CPOPJ1 IF SO
;USES T2 & T3
PSITST::JUMPGE T1,CPOPJ## ;ONLY NEGATIVE CONDITIONS HERE
CAML T1,[C$MIN] ;AND THEN ONLY IN RANGE
SKIPN T2,JBTPIA##(J) ;AND ONLY IF USER IS PSI'ING
POPJ P, ;NONE OF THE ABOVE
MOVSI T3,(1B0) ;GET A BIT
LSH T3,(T1) ;POSITION IT CORRECTLY
TDNE T3,PITENB(T2) ;USER ENABLED FOR THIS TRAP
AOS (P) ;YES, GIVE SKIP RETURN
POPJ P, ;RETURN
;SUBROUTINE TO TELL ALL INTERESTED ABOUT NETWORK TOPOLOGY CHANGES
IFN FTNET,<
PSINTC::PUSH P,J ;SAVE J FOR NETSER
MOVE J,HIGHJB## ;GET HIGHEST JOB NUMBER ASSIGNED
NTC.1: SIGNAL C$NTC ;SIGNAL FOR THAT JOB
JFCL ;DON'T CARE IF NOT ENABLED
SOJG J,NTC.1 ;CONTINUE FOR ALL JOBS
JRST JPOPJ## ;RESTORE J AND RETURN
>; END FTNET
;SUBROUTINE TO INFORM JOBS OF KSYS TIMER
PSIKSY::PUSH P,J ;SAVE J FOR COMCON
MOVE J,HIGHJB## ;GET HIGHEST JOB NUMBER ASSIGNED
KSY.1: SIGNAL C$KSYS ;SIGNAL FOR THAT JOB
JFCL ;DON'T CARE IF NOT ENABLED
SOJG J,KSY.1 ;CONTINUE FOR ALL JOBS
JRST JPOPJ## ;RESTORE J AND RETURN
;HERE ON HARDWARE TRAP FOR ARITHMATIC INTERRUPTS
PSIAPR::MOVE P,[MJOBPD##,,.JDAT+JOBPDL##] ;SET UP A PUSH DOWN LIST
MOVE J,.CPJOB## ;GET JOB NUMBER RUNNING
MOVE T1,.UPMP+.UPMUP ;GET PC OF INTERRUPT
MOVEM 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
JEN @.CPPC## ;BACK TO USER OR INTERRUPT
;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
MOVE T3,M ;GET UUO ISSUED
TLZ T3,777 ;CLEAR OUT JUNK
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
SIGNAL C$AUUO ;SIGNAL A UUO IS DONE
JRST TPOPJ## ;USER CANNOT TAKE IT, DO UUO
JRST TPOPJ1## ;SKIP DISPATCH, USER WANTS IT
;SUBROUTINE CALLED BY PSIGEN TO VALIDATE THE INTERRUPT VECTOR ADDRESS
;RETURNS CPOPJ IF INVALID
; CPOPJ1 IF OK
VALVEC: PUSH P,T1 ;SAVE CONDITION
MOVEI T1,(P4) ;POINT TO ADDRESS
SETO T2, ;LOOP COUNTER
VALV.1: CAIG T1,JOBPFI## ;ADDRESS TOO SMALL
JRST VALV.2 ;YES, SAY ILLEGAL TO USER
MOVEI T4,(T1) ;COPY ADDRESS
LSH T4,W2PLSH## ;CONVERT TO PAGE NUMBER
PUSHJ P,GTPM4## ;GET PAGE MAP ENTRY FOR THIS PAGE
JUMPE T4,VALV.2 ;SAY ILLEGAL IF NOT THERE
PUSHJ P,FLTST## ;CHECK IF PAGE CAUSES FAULT
JRST VALV.3 ;YES, SAY PAGED OUT
TRNN T4,PM.WRT ;IS THE PAGE WRITTABLE
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
MOVEI T1,(P4) ;GET LOCATION OF VECTOR
PUSHJ P,PRTDI8## ;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(P3) ;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 = PC
; PUSHJ P,ISPFH
; HERE IF IN PFH OR DDT
; HERE IF NOT
;WIPES T2
ISPFH: MOVE T2,P2 ;MOVE PC FOR VMSER
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,(P2) ;ABOVE START OF DDT?
JRST CPOPJ1## ;NO, ALL IS WELL
HLRZ T2,.JDAT+JOBDDT## ;GET END OF DDT
CAIG T2,(P2) ;ABOVE END?
AOS (P) ;YES, NOT IN DDT
POPJ P,0 ;IN DDT
PSILIT::XLIST ;FORCED OUT LITERAL POOL HERE
$LIT
LIST
PSIEND::END