Trailing-Edge
-
PDP-10 Archives
-
bb-jr93e-bb
-
7,6/ap015/psiser.x15
There are 2 other files named psiser.x15 in the archive. Click here to see a list.
TITLE PSISER -- PROGRAMMED SOFTWARE INTERRUPT SERVICE V266
SUBTTL C. D. O'TOOLE/CDO/RCB 22 JUL 86
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.
;
.CPYRT<1973,1986>
;COPYRIGHT (C) 1973,1974,1975,1976,1977,1978,1979,1980,1982,1984,1986
;BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
;ALL RIGHTS RESERVED.
;
;XP VPSISR,266
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>>>
;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>)
BITS(TMRBIT,<TMR>)
BITS(DTCBIT,<DTC>)
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 <PSIMPI+1> ;FULLWORD ADDRESS OF CURRENT INTERRUPT BLOCK
PITCIC:! BLOCK <PSIMPI+1> ;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
PIT4WD==<PITSIZ+3>/4 ;SIZE IN 4 WORD BLOCKS
IFN PITNPI,<PRINTX ? PITNPI IS NOT FIRST IN THE DATA BASE>
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,PIT4WD ;NUMBER OF 4-WORD BLOCKS TO GET
PUSHJ P,GET4WD## ;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,<SETOM PITHLP(T1)> ;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,PIT4WD ;NUMBER OF 4-WORD BLOCKS WE HAVE
PUSHJ P,GIV4WD## ;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,<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
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,<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
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,<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.
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,<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
>
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,<POPJ P,> ;RETURN DOUBLEWORD PC
IFN PSIMPI,<JRST TPOPJ##> ;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
SYSPIN ;DONE STORING
SETOM CLKNEW## ;MARK A NEW ENTRY IN THE SYSTEM QUEUE
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,<SKIPGE P2,PITHLP(P1)>;GET HIGHEST LEVEL IN PROGRESS
IFE PSIMPI,<SKIPN T1,PITCIB(P1)>;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,<SKIPN PITCIB(T2)> ;SEE IF IN PROGRESS
IFN PSIMPI,<SKIPGE T3,PITHLP(T2)> ;GET HIGHEST LEVEL IN PROGRESS
JRST ERRFNP ;NO INTERRUPT IN PROGRESS
IFE PSIMPI,<MOVEI T3,PITCIC(T2)> ;POINT TO CURRENT FLAGS
IFN PSIMPI,<ADDI T3,PITCIC(T2)> ;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,<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 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 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,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 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,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,<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
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 <SKIPA P3,.PSVNP(P4)> ;GET NEW PC FOR INTERRUPT (WITH SECTION)
EXCTUX <HRR P3,.PSVNP(P4)> ;GET NEW PC FOR INTERRUPT (IN SECTION)
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
DMOVEM P2,.JDAT+JOBPD1## ;YES, STORE FOR UUO DISMISS
DMOVEM P2,.CPPC## ;STORE FOR CLOCK1
EXCTUX <MOVE P3,.PSVFL(P4)> ;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,<MOVEI T2,PITCIB(P1)> ;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 <HRRM T1,.PSVFL(P4)> ;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 <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 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 <MOVEM P3,.PSVOP(P4)> ;STORE 30-BIT ADDRESS FROM PC FOR USER
POPJ P, ;RETURN TO GENINT
PCSTO1: HRR P2,P3 ;GET SECTION-ZERO STYLE PC
EXCTXU <MOVEM P2,.PSVOP(P4)> ;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,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,<DNCALL (SCTPSI##)>
IFN FTXMON,<SNCALL (SCTPSI##,MS.HGH)>
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',,' ' ;(-37) LLMOP EVENT (-40) UNUSED
'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 <LDB T2,LDPLNO##> ;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 <MAP T2,(T1)> ;IN-SECTION TRANSLATION
EXCTUX <MAP T1,@T1> ;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 <MOVE T4,@[IW UMAPSN,UMAPS(T4)]> ;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