1
0
mirror of https://github.com/PDP-10/stacken.git synced 2026-01-31 05:42:03 +00:00
Files
PDP-10.stacken/files/stacken-tape-backup/dskb:10_7/mon/psiser.mac
Lars Brinkhoff 6e18f5ebef Extract files from tape images.
Some tapes could not be extracted.
2021-01-29 10:47:33 +01:00

1719 lines
61 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
TITLE PSISER -- PROGRAMMED SOFTWARE INTERRUPT SERVICE V274
SUBTTL C. D. O'TOOLE/CDO/RCB 27-OCT-87
SEARCH F,S
$RELOC
$HIGH
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED
; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION
; 1973,1974,1975,1976,1977,1978,1979,1980,1982,1984,1986,1988.
;ALL RIGHTS RESERVED.
.CPYRT<1973,1988>
XP VPSISR,274
PSISER: ENTRY PSISER
XP PSIMPI,3 ;MAXIMUM PRIORITY LEVEL
IFL PSIMPI,<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
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,PITSIZ ;NUMBER OF WORDS TO GET
PUSHJ P,GETWDS## ;GO GET THEM
JRST ECOD3## ;(03) INSUFFICIENT MONITOR FREE CORE
HRLI T2,(T1) ;PREPARE TO CLEAR THE DATA BASE
HRRI T2,1(T1) ;DESTINATION
SETZM 0(T1) ;CLEAR THE BEGINNING
BLT T2,PITSIZ-1(T1) ;CLEAR THE REST
IFN PSIMPI,<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,PITSIZ ;NUMBER OF WORDS WE HAVE
PUSHJ P,GIVWDS## ;RETURN THE CORE
PUSHJ P,CLRTMR ;REMOVE ANY TIMER QUEUE REQUESTS
CLRP.1: JUMPE F,CPOPJ## ;RETURN WHEN OUT OF DDBS
SETZM DEVPSI(F) ;CLEAR INTERRUPT BITS
HLRZ F,DEVESE(F) ;STEP TO NEXT DDB
JRST CLRP.1 ;LOOP OVER ALL DDBS
;SUBROUTINE TO REMOVE ANY TIMER QUEUE ENTRIES FOR PITMR.
CLRTMR: PUSHJ P,CTXJCJ## ;GET INTERRUPT HANDLE FROM CTXSER
POPJ P, ;OK IF NONE
MOVE T2,[PSITMR,,1] ;REQUEST TO CHANGE TO EXPIRE IN 1 TICK
PUSHJ P,CLKCHG## ;SEARCH FOR/MODIFY EXISTING ENTRY
POPJ P, ;OK IF DIDN'T FIND ONE
POPJ P, ;DONE
SUBTTL UUOCON INTERFACE -- PISYS.
;CALL TO MANIPULATE THE PI SYSTEM
;CALL WITH:
; MOVE AC,[XWD FLAGS,ADDRESS]
; PISYS. AC,
; HERE ON AN ERROR
; HERE WHEN FUNCTION COMPLETE
;
;ADDR: CONDITION-REQUESTED OR DEVICE-ENABLED (CHANNEL,DEVNAM,UDX)
; OFFSET-FROM-BASE(PIINI.) ,, REASONS-IF-DEVICE
; PRIORITY LEVEL ,, 0
PISYS:: PUSHJ P,SAVE4## ;SAVE A FEW FIRST
TRNE T1,-1 ;ANY ADDRESS GIVEN?
TLNE T1,(PS.CSI!PS.RDV!PS.ADV) ;IS ARGUMENT NEEDED?
SKIPA ;YES
PJRST ECOD0## ;(0) UNNECESSARY ARG SUPPLIED
TLNN T1,(PS.ALL) ;ANYTHING TO DO?
PJRST ECOD1## ;(1) NO FUNCTION GIVEN
TLNE T1,<-1-PS.ALL>_<-^D18> ;ANY UNUSED BITS SET?
PJRST ECOD2## ;(2) UNUSED BIT IS NOT = 0
SKIPN P1,JBTPIA##(J) ;PIINI. UUO DONE?
JRST ECOD13## ;(13) PIINI. UUO NOT DONE
MOVE P2,T1 ;COPY ARGUMENT
TLNE P2,(PS.CPI) ;CLEAR PENDING INTERRUPTS?
PUSHJ P,CLRAPI ;YES, CLEAR ALL PENDING INTERRUPTS
TLNE P2,(PS.CSI) ;CLEAR FOR 1 CONDITION OR DEVICE?
JRST [PUSHJ P,CLRSPI ;YES, CLEAR PENDING INTERRUPT
POPJ P, ;ILLEGAL CONDITION OR DEVICE
JRST .+1] ;RESUME INLINE CODE
MOVSI T1,(SI.ON) ;PI SYSTEM ON BIT
TLNE P2,(PS.ON) ;WANT TO TURN ON?
JRST [TLNE P2,(PS.OFF) ;TURN SYSTEM OFF?
JRST ECOD3## ;(3) BOTH TURN OFF AND TURN ON
IORM T1,JBTPIA##(J) ;LIGHT THE BIT
JRST PISY.1] ;RESUME INLINE CODE
TLNE P2,(PS.OFF) ;WANT TO TURN OFF?
ANDCAM T1,JBTPIA##(J) ;CLEAR THE SYSTEM ON BIT
PISY.1: TLNE P2,(PS.RDV) ;WANT TO REMOVE DEVICE OR COND?
PJRST REMDEV ;YES, GO DO THAT
TLNE P2,(PS.ADV) ;WANT TO ADD?
JRST ADDDEV ;YES, GO DO THAT
JRST CPOPJ1## ;NO, ALL DONE
;SUBROUTINE CALLED BY UUOCON DURING RELEASE OF A DDB
;CALL
; F = DDB BEING RELEASED
; SKIPE DEVPSI(F)
; PUSHJ P,PSIRMV
;ALWAYS CPOPJ RETURN
;WIPES T1-T2
PSIRMV::SETZM DEVPSI(F) ;CLEAR ANY ENABLED BITS
LDB T1,PJCHN## ;GET OWNER
PUSHJ P,CTXPSI## ;GET PIT ADDRESS FROM CTXSER
POPJ P, ;NO SUCH JOB? UUOCON MESSED UP.
JUMPE T2,CPOPJ## ;NO PIT, HOW DID THOSE BITS GET LIT
PUSHJ P,SAVE2## ;SAVE A FEW REGS NOW
MOVE P1,T2 ;COPY DATA BASE ADDRESS
UNLDDB: HLRZ P2,PITCHN(P1) ;GET FIRST DDB IN PSI CHAIN
MOVEI P1,<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
SETOM CLKNEW## ;MARK A NEW ENTRY IN THE SYSTEM QUEUE
SYSPIN ;DONE STORING
JRST CPOPJ1## ;GIVE GOOD RETURN TO UUO
;HERE WHEN THE TIMER SET BY PITMR. EXPIRES, INTERRUPT THE JOB
PSITMR: PUSHJ P,CTXPSI## ;GET PIT FOR CONTEXT
POPJ P, ;WENT AWAY
JUMPE T2,CPOPJ## ;GO AWAY IF NOT STILL USING PSISER
PUSH P,J ;SAVE FOR CALLER
MOVE J,T1 ;GET JCH WHERE IT BELONGS
SIGNAL C$TMR ;CAUSE THE INTERRUPT
JFCL ;IGNORE FAIL RETURN
JRST JPOPJ## ;RETURN TO CLOCK1
SUBTTL UUOCON INTERFACE -- PIBLK.
;CALL TO RETURN USER INTERRUPT BLOCK ADDRESS FOR INTERRUPT IN PROGRESS
;CALL WITH:
; PIBLK. AC,
; HERE IF NOT INITIALIZED OR NONE IN PROGRESS
; HERE WITH AC CONTAINING ADDRESS OF INTERRUPT BLOCK
PIBLK:: PUSHJ P,SAVE2## ;SAVE A FEW FIRST
SKIPN P1,JBTPIA##(J) ;GET ADDRESS OF PI TABLE
PJRST RTZER## ;ERROR RETURN, NOT INITIALIZED
IFN PSIMPI,<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 FTMPXSER,<
JUMPN P3,PSIDV1 ;JUMP IF NOT MPX
MOVEI P1,DEPMSG ;NOT USING THE DEVICE ITSELF
TDNN P1,DEVMSG(F) ;TRY THE MPX CONTROLLING
POPJ P, ;NOT MPX'ED, IGNORE INTERRUPT
PUSH P,F ;SAVE ORIGINAL F
HRRZ F,DEVXTR(F) ;STEP TO MPX DDB
HLRZ P3,DEVPSI(F) ;GET BITS FOR THE MPX
JUMPE P3,FPOPJ## ;IGNORE IF NOT PSI'ING
PUSH P,[CAIA FPOPJ##] ;STACK RESTORE RETURN
PSIDV1:
>; END FTMPXSER
AND P2,P3 ;MASK DOWN TO ENABLED BITS
SETZ P3, ;CLEAR IN CASE WE RETURN
JUMPE P2,CPOPJ## ;RETURN IF NOT ENABLED
PUSH P,T1 ;SAVE SOME
PUSH P,T2 ;VOLATILE REGISTERS
LDB T1,PJCHN## ;GET JCH OWNING DEVICE
PUSHJ P,CTXPSI## ;JOB USING PSISER?
JRST TTPOPJ## ;NO SUCH JCH
SKIPN P1,T2 ;GET JBTPIA IN RIGHT REGISTER
JRST TTPOPJ## ;NOT USING PI SYSTEM
SETCM P3,DEVPSI(F) ;GET WHAT'S NOT LIT
TRNN P3,(P2) ;ALREADY HAVE THESE CONDITIONS
JRST PSIDV2 ;YES, BITS AND COUNTS ARE RIGHT
SETCMI P3,(P2) ;P3=NOT WHAT WE ARE SETTING
IORB P2,DEVPSI(F) ;LIGHT NEW CONDITIONS, GET EVERYTHING
TRNN P2,(P3) ;ANY OTHERS ALREADY PENDING
AOS PITNPI(P1) ;NO, BUMP PENDING COUNT
PSIDV2: MOVE P3,F ;RETURN DDB ACTUALLY USED
JUMPGE P1,TTPOPJ## ;DON'T WAKE IF PI OFF
PUSHJ P,CTXVAL## ;IS THIS THE CURRENT CONTEXT FOR THE JOB?
JRST TTPOPJ## ;CONTEXT WENT AWAY
TRNA ;YES, KEEP GOING
JRST TTPOPJ## ;DON'T WAKE IT IF NOT CURRENT
PUSH P,J ;SAVE JOB FOR CALLER
LDB J,PJOBN## ;GET JOB OF DDB
PUSHJ P,WAKEJB## ;WAKE THE JOB
POP P,J ;RESTORE
JRST TTPOPJ## ;RESTORE CALLER'S T1 AND T2 AND RETURN
SUBTTL GRANT AN INTERRUPT TO A RUNNING USER
;CALLED BY UUOCON OR CLOCK1 TO GRANT AN INTERRUPT FOR A USER
; J = JOB NUMBER
; XCT PINOJN ;SKIP IF CANNOT GRANT INTERRUPT
; PUSHJ P,PSIGEN## ;CAN, GIVE AN INTERRUPT
;
;ALWAYS CPOPJ RETURN
PSIGEN::SKIPG @JBTPIA##(J) ;ARE THERE ANY PENDING INTERRUPTS
POPJ P, ;NO, GET OUT NOW
PUSHJ P,SAVE4## ;SAVE A FEW FIRST
SKIPGE P1,JBTPIA##(J) ;GET DATA BASE
IFN PSIMPI,<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,LATPSI## ;(-40) LAT EVENT
PUSHJ P,LLMPSI## ;(-37) LLMOP EVENT
PUSHJ P,ENTPSI## ;(-36) ETHERNET EVENT
PUSHJ P,SCSPSI## ;(-35) SCS EVENT
SETZ T2, ;(-34) RESERVED TO CUSTOMER
SETZ T2, ;(-33) RESERVED TO CUSTOMER
PUSHJ P,NXTOOB## ;(-32) OUT-OF-BAND CHARACTER
PUSHJ P,GETDTC ;(-31) DATE/TIME CHANGED
PUSHJ P,GETJBI ;(-30) CROSS JOB INTERRUPTS
SETZ T2, ;(-27) NETWORK TOPOLOGY CHANGE
PUSHJ P,GETQUE ;(-26) ENQ/DEQ
MOVEI T2,DR.EVT ;(-25) DECNET EVENT
PUSHJ P,STRSIG## ;(-24) IPCF
SETZ T2, ;(-23) ADDRESS BREAK
LDB T2,[POINT 9,PITSTS(P1),17] ;(-22) WAKE UUO
PUSHJ P,GETATC ;(-21) DETACH/ATTACH
SETZ T2, ;(-20) DATASET STATUS CHANGE
MOVE T2,SYSKTM## ;(-17) KSYS WARNING
SETZ T2, ;(-16) EXTERNAL ERROR IN JOB
SETZ T2, ;(-15) USER INDUCED ERROR IN JOB
MOVE T2,DATE## ;(-14) APR CLOCK TICK
SETZ T2, ;(-13) NON-EX MEM
PUSHJ P,[IFE FTXMON,<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',,'LAT' ;(-37) LLMOP EVENT (-40) LAT EVENT
'SCS',,'ETH' ;(-35) SCS EVENT (-36) ETHERNET EVENT
'RC1',,'RC2' ;(-33) RSV'D FOR CUST (-34) RSV'D FOR CUST
'DTC',,'OOB' ;(-31) DATE/TIME CHANGE (-32) OUT-OF-BAND
'NTC',,'JBI' ;(-27) NTWRK TOPOLOGY (-30) CROSS JOB
'DVT',,'QUE' ;(-25) DECNET EVENT (-26) ENQ/DEQ
'ABK',,'IPC' ;(-23) ADR BREAK (-24) IPCF
'DAT',,'WAK' ;(-21) DET/ATTACH (-22) WAKE UUO
'KSY',,'DSC' ;(-17) KSYS WARNING (-20) DATASET STATUS
'UEJ',,'XEJ' ;(-15) USER ERROR (-16) EXTERNAL ERROR
'NXM',,'APC' ;(-13) NXM (-14) CLOCK TICK
'PDL',,'NSP' ;(-11) PDL OV (-12) DECNET NSP INTERRUPTS
'ACK',,'ARI' ;(- 7) ADR CHECK (-10) ARITHMETIC EXC
'ILU',,'IMR' ;(- 5) ILL UUO (- 6) ILL MEM REF
'STP',,'UUO' ;(- 3) ^C (- 4) ANY UUO
'TLE',,'TMR' ;(- 1) TIME LIMIT (- 2) TIMER REQUEST
LDSIX:
;SUBROUTINES CALLED BY THE PRECEDING TABLE TO FETCH STATUS
GETUDX: PUSH P,U ;SAVE U
PUSH P,P1 ;SAVE P1 AROUND IONDF
PUSHJ P,IONDF## ;GET UDX FOR DEVICE
TDZA T2,T2 ;FAILED, NONE TO RETURN
HRL T2,T1 ;INSERT IN RETURN AC
HRR T2,DEVIOS(F) ;INSERT DEVICE STATUS
POP P,P1 ;RESTORE
JRST UPOPJ## ;RESTORE U AND RETURN
GETQUE: MOVE T2,PITSTS(P1) ;GET SAVED REQUEST ID
TLZ T2,(-1-PITQAB-777777) ;ZERO UNWANTED BITS
ANDCAM T2,PITSTS(P1) ;CLEAR WHAT WE ARE SIGNALLING
TLZE T2,(PITQAB) ;WERE ANY REQUESTS ABORTED?
TLO T2,(1B0) ;YES, LIGHT SIGN BIT
POPJ P, ;AND RETURN
GETATC: MOVE T2,J ;COPY JCH
ANDI T2,JOBMSK## ;KEEP ONLY JOB NUMBER
HRRZ T2,TTYTAB##(T2) ;GET TTY DDB FOR JOB
MOVE T2,DDBLDB##(T2) ;GET ATTACHED LDB
SOJL T2,CPOPJ## ;RETURN -1 IF DETACHED
PUSH P,U ;SAVE LDB REGISTER
AOS U,T2 ;GET CORRECT ADDRESS IN U
SE1XCT <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 MS.MAP,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