Trailing-Edge
-
PDP-10 Archives
-
dec-10-omona-u-mc9
-
psiser.mac
There are 7 other files named psiser.mac in the archive. Click here to see a list.
TITLE PSISER -- PROGRAMMED SOFTWARE INTERRUPT SERVICE V156
SUBTTL DONALD LEWINE/DAL 01 MAR 77
SEARCH F,S
$RELOC
$HIGH
;***COPYRIGHT 1973,1974,1975,1976,1977 DIGITAL EQUIPMENT CORP., MAYNARD, MASS.***
XP VPSISR,156
PSISER: ENTRY PSISER ;FOR LINK AND GLOB
; TABLE OF CONTENTS FOR PSISER
;
;
; SECTION PAGE
; 1. PROTOTYPE PROGRAM INTERRUPT TABLE......................... 2
; 2. PC POINTER TABLE.......................................... 3
; 3. BIT MASKS FOR VARIOUS CONDITIONS.......................... 4
; 4. INTERRUPT BLOCK FORMAT.................................... 5
; 5. PI SYSTEM UUO'S
; 5.1 PISAV............................................. 6
; 5.2 PIRST............................................. 8
; 5.3 DEBRK............................................. 9
; 5.4 PIINI............................................. 10
; 5.5 PISYS............................................. 11
; 5.6 SUBROUTINES....................................... 12
; 6. ROUTINES TO CAUSE INTERRUPTS
; 6.1 ANY UUO TRAP...................................... 19
; 6.2 ARITHMETIC FAULT TRAP............................. 20
; 6.3 KSYS TIME......................................... 21
; 6.4 DEVICE OFF LINE................................... 22
; 6.5 I/O DONE.......................................... 23
; 6.6 I/O ERROR AND EOF................................. 25
; 6.7 ERROR IN JOB TRAPS................................ 26
; 6.8 DEFERED INTERRUPTS................................ 27
; 7. INTERRUPT CODE
; 7.1 SIGNAL AN INTERRUPT............................... 29
; 7.2 SUBROUTINES....................................... 33
; 8. MISC. SUBROUTINES......................................... 39
SUBTTL PROTOTYPE PROGRAM INTERRUPT TABLE
;A COPY OF THIS TABLE IS BUILT FOR EACH JOB WHICH USES THE SOFTWARE
; INTERRUPT SYSTEM.
PITPRO: PHASE 0
PITINS:!JFCL ;THIS INSTRUCTION IS EXECUTED WHENEVER
; WE ARE ABOUT TO GIVE CONTROL TO THE
; USER IN USER MODE.
PITIVA::!XWD ZERO5,0 ;BITS 0-8 -- HIGHEST VECTOR IN USE + 1
;BITS 9-12 -- UNUSED
;BITS 13-17-- ZERO (I DON'T THINK ANYONE
; DEPENDS ON THIS)
;RH -- INTERRUPT VECTOR BASE ADDRESS
PITNPI:!EXP 0 ;NUMBER OF PENDING INTERRUPTS
PITNXT:!EXP 0 ;INTERRUPT WE WOULD LIKE TO GRANT
; NEXT. IF C(LH)=0 THEN THIS IS A
; DDB ADDRESS ELSE IT IS A CONDITION
; NAME
PITCIB:!XWD 0,0 ;RH - CURRENT INTERRUPT BLOCK ADDRESS
PITIPC:!XWD 0,0 ;LH - FLAG USED TO REMEMBER THAT A USER
; IS PRINTING AN ERROR MESSAGE
;RH - ADDRESS WHERE PC WAS FOUND IF WE
; ARE AT INTERRUPT LEVEL
PITWJB::!BLOCK 1 ;JOB NUMBER DOING WAKE UUO
PITENQ:!BLOCK 1 ;ENQ/DEQ REQUEST ID
PITDFR:!BLOCK <<-C$MIN>/^D36>+1 ;BIT TABLE FOR NON-I/O RELATED INTERRUPTS.
; BIT N = 1 IF CONDITION -N HAPPENED
; WHILE JOB WAS NOT IN CORE.
PITTAB:!BLOCK <<<-C$MIN+1>+3>/4> ;TABLE OF 9 BIT BYTE ONE FOR EACH NON-I/O
; CONDITION.
DEPHASE
PIT4WD==<<.-PITPRO>+3>/4 ;SIZE OF PIT IN 4-WORD BLOCKS
PITSIZ==:PIT4WD*4 ;SIZE OF PIT IN WORDS
PTMVO: POINT 9,PITIVA(P1),8 ;BYTE POINTER TO HIGHEST VECTOR IN USE
SUBTTL PC POINTER TABLE
;THIS TABLE IS EXECUTED TO LOAD THE PC OF THE INTERRUPT INTO T2.
; NOTE: SINCE CONDITIONS ARE NEGATIVE THE TABLE GOES BACKWARDS.
IFE FTVM,<
DEFINE GJOBPC,<
PUSHJ P,[CAME J,.CPJOB##(P4)
SKIPA T2,JOBPC##(R)
MOVE T2,.CPPC##(P4)
POPJ P,]
>>
IFN FTVM,<
DEFINE GJOBPC,<
MOVE T2,.JDAT+JOBPC##
>>
SALL
GJOBPC ;NETWORD TOPOLOGY CHANGE
GJOBPC ;ENQ/DEQ
GJOBPC ;REMOTE COMPUTER CONDITION
MOVE T2,JOBPD1##(R) ;IPCF
MOVE T2,.CPAPC##(P4) ;ADR BREAK
GJOBPC ;WAKE UUO -- PC IS IN JOB DATA AREA
GJOBPC ;DETACH & ATTACH
GJOBPC ;NEW DATASET STATUS
GJOBPC ;KSYS
GJOBPC ;EXTERNAL ERROR IN JOB
MOVE T2,JOBPD1##(R) ;USER INDUCED ERROR IN JOB
MOVE T2,.CPPC##(P4) ;APR CLOCK
MOVE T2,JOBPD1##(R) ;NXM TRAP
MOVE T2,.CPPC##(P4) ;TRAP TYPE 3
MOVE T2,.CPPC##(P4) ;PDL LIST OVER FLOW
GJOBPC ;ARITHMETIC VIOLATION
MOVE T2,JOBPD1##(R) ;ADDRESS CHECK
MOVE T2,.CPPC##(P4) ;ILL MEM REF
MOVE T2,UUO0## ;ILLEGAL UUO
MOVE T2,UUO0## ;ANY UUO
PUSHJ P,CTLCPC ;CONTROL-C
GJOBPC ;CONTROL-A
MOVE T2,.CPPC##(P4) ;TIME LIMIT EXCEEDED
OPCXCT: STOPCD .,HALT,ICC, ;INVALID CONDIDION CODE
SUBTTL BIT MASKS FOR VARIOUS CONDITIONS
DEFINE BTMASK(X),<
ZZ==0
IRP X,<
ZZ==ZZ!<1B<-C$'X>>
>
EXP ZZ
>
;CONDITIONS WHICH HAVE A STANDARD SYSTEM ERROR MESSAGE
ERRMSK: BTMASK <TLE,IUUO,IMR,ADCK,PLOV,NXM,UEIJ,XEIJ,ADRB>
;CONDITIONS WHICH ARE IGNORED IF THEY HAPPEN IN THE PAGE FAULT HANDLER
PFHMSK: BTMASK <AUUO,IUUO,IMR,ADCK,ARIT,PLOV,TRP3,APRC,UEIJ,XEIJ,ADRB>
SUBTTL INTERRUPT BLOCK FORMAT
IBKPRO: PHASE 0
IBKNPC:!EXP 0 ;NEW PC AND FLAGS
IBKOPC:!EXP 0 ;OLD PC AND FLAGS
IBKICF:! ;INTERRUPT CONTROL FLAGS
ICFOFF==(1B1) ;TURN INTERRUPT SYSTEM OFF DO NOT
; RESTORE ON DEBREAK
ICFTOF==(1B2) ;TURN INTERRUPT SYSTEM OFF. TURN ON
; ON DEBREAK
ICFAAI==(1B3) ;ALLOW ADDITIONAL INTERRUPTS
ICFCNI==(1B4) ;CLEAR NEXT INTERRUPT
ICFMSG==(1B5) ;PRINT STANDARD MESSAGE
ICFNOT==(1B6) ;NO TRAPS -- BLOCK IS TURNED OFF
IBKRSN:!XWD 0,0 ;REASON
IBKISW::!EXP 0 ;INTERRUPT STATUS WORD
DEPHASE
RELOC IBKPRO ;DO NOT WASTE SPACE
SUBTTL PI SYSTEM UUO'S -- PISAV.
PISAVE::PUSHJ P,SAVE4## ;SAVE P1 THRU P4
HRR M,T1 ;ARGUMENT ADDRESS
HLRZ P3,T1 ;# OF WORDS
MOVEI P4,0 ;# OF CALLS TO STORE
MOVE P1,JBTPIA##(J) ;ADDRESS OF PI TABLE
SOS P3 ;ACCOUNT FOR NOT CALLING
AOS P4 ; OF FIRST WORD TILL DONE
PUSH P,M ;SAVE ADDRESS OF FIRST ARG
JUMPE P1,PISAV5 ;JUMP IF NOT SETUP
HRRZ T1,PITIVA(P1) ;GET INTERRUPT VECTOR ADDRESS
PUSHJ P,STORE ;STORE FOR USER
HLRZ F,DEVLST## ;TELL HIM ABOUT HIS DDB'S
PISAV1: LDB T1,PJOBN## ;GET JOB NUMBER
CAIE T1,(J) ;IS IT THIS JOB?
JRST PISAV2 ;NO--LOOK AT NEXT DDB
LDB T1,PDVIVO## ;GET INTERRUPT VECTOR OFFSET
JUMPE T1,PISAV2 ;LOOK AT NEXT IF NOT ENABLED
MOVE T1,DEVNAM(F) ;GET THE DEVICE NAME
PUSHJ P,STORE ;STORE FOR USER
LDB T1,PDVIVO## ;GET THE OFFSET
SUBI T1,1 ;ADJUST
LSH T1,2 ;CONVERT TO WORDS
HRLZ T1,T1 ;PUT IN LH
HLR T1,DEVPSI(F) ;PICK UP INTERRUPT REASON BITS
AND T1,[-1,,IR.ALL] ;MASK OUT JUNK
PUSHJ P,STORE ;PUT IN USER SPACE
MOVEI T1,0 ;THIRD WORD IS ZERO
PUSHJ P,STORE ;PUT IN USER SPACE
PISAV2: HLRZ F,DEVSER(F) ;LINK TO NEXT DDB
JUMPN F,PISAV1 ;LOOP OVER ALL DEVICES
HRREI W,C$MIN ;START WITH SMALLEST COND
PISAV3: MOVE T1,W ;COPY CONDITION
PUSHJ P,CNDPTR ;GET A POINTER TO IT
LDB T2,U ;SEE IF ENABLED?
JUMPE T2,PISAV4 ;NO--LOOK FOR NEXT CONDITION
PUSHJ P,STORE ;YES--STORE CONDITION
LDB T1,U ;GET OFFSET
SUBI T1,1 ;CONVERT TO WORDS
LSH T1,2 ; ..
HRLZ T1,T1 ;PUT IN LH AND STORE
PUSHJ P,STORE ; ..
MOVEI T1,0 ;STORE WORD 3 AS ZERO
PUSHJ P,STORE ; ..
PISAV4: AOJL W,PISAV3 ;LOOP OVER ALL CONDITIONS
PISAV5: POP P,M ;RESTORE ADDRESS OF FIRST WORD
MOVE T1,P4 ;GET # OF WORDS
SKIPGE P1 ;SKIP IF SYSTEM IS OFF
TLO T1,(SI.ON) ;ELSE SET THE ON FLAG
PUSHJ P,PUTWDU## ;STORE FOR USER
JUMPL P3,RTZER## ;ERROR IF BLOCK TO SMALL
JRST CPOPJ1## ;ELSE WIN
;SUBROUTINE TO STORE A WORD IF IT WILL FIT
;CALL WITH:
; T1 = WORD TO STORE
; M = ADDRESS
; P3 = NUMBER OF WORDS LEFT
; P4 = NUMBER OF CALLS
; PUSHJ P,STORE
; RETURN HERE ALWAYS
;
;THIS ROUTINE UPDATES P2, P3 AND P4
STORE: SOSL P3 ;COUNT DOWN ROOM LEFT
PUSHJ P,PUTWD1## ;STORE IF WE CAN
AOJA P4,CPOPJ## ;RETURN
SUBTTL PI SYSTEM UUO'S -- PIRST.
PIRST:: PUSHJ P,SAVE3## ;SAVE SOME AC'S
MOVEI P2,(T1) ;ADDRESS OF BLOCK
HRR M,P2 ;GET THE FIRST WORD
PUSHJ P,GETWDU## ; ..
HLL P2,T1 ;SAVE FLAGS
HRRZ P3,T1 ;WORD COUNT
SOJE P3,[PUSHJ P,CLRPSI ;IF PIINI. WAS NOT DONE, CLEAR SYS
JRST CPOPJ1##];AND SKIP RETURN TO THE USER
PUSHJ P,GETWD1## ;ELSE GET BASE OF IV
PUSHJ P,PIINI ;AND DO PIINI
JRST RTZER## ;FAILED!!
SOJE P3,CPOPJ1## ;GOOD RETURN IF THAT IS ALL HE WANTS
HRRI P2,1(M) ;ADDRESS OF FIRST TRIPLET
MOVE P1,JBTPIA##(J) ;ADDRESS OF PI TABLE
PIRST1: SUBI P3,3 ;ACCOUNT FOR 1 TRIPLET
JUMPL P3,[HLLM P2,JBTPIA##(J)
JRST CPOPJ1] ;RESTORE FLAGS AND RETURN
PUSHJ P,ADDDEV ;ADD IN DEVICE
JRST [PUSHJ P,CLRPSI ;RESET PI SYSTEM SO NOT LEFT HALF RESTORED
PJRST RTZER##] ;GIVE ERROR RETURN
ADDI P2,3 ;COUNT UP ADDRESS
JRST PIRST1 ;TRY FOR MORE
SUBTTL PI SYSTEM UUO'S -- DEBRK.
DEBRK:: SKIPN P1,JBTPIA##(J) ;GET ADDRESS OF PI TABLE
JRST CPOPJ1## ;NO PI IN PROGRESS IF ZERO
HRRZ M,PITCIB(P1) ;GET OLD INTERRUPT ADDRESS
JUMPE M,CPOPJ1## ;NO PI IN PROGRESS
IFE FTVM,<
MOVEI T1,(M) ;GET FIRST ADDRESS
PUSHJ P,UADRCK## ;CHECK LEGALITY, DON'T RETURN IF NOT
MOVEI T1,3(M) ;LAST ADDRESS
PUSHJ P,UADRCK## ;THE SAME
> ;END IFE FTVM
IFN FTVM,<
MOVEI T1,(M) ;COPY ADDRESS
MOVEI T2,3(M) ;LAST ADDRESS
PUSHJ P,LRNGE## ;CALL PFH OR STOP JOB IF APPROPRIATE
> ;END IFN FTVM
IFN FTKA10,<
ADDI M,(R) ;RELOCATE ON KA10
>
SETZM PITCIB(P1) ;NOW CLEAR INTR ADDR
EXCTUX <MOVE T3,IBKOPC(M)> ;GET OLD PC
MOVE T4,JOBPD1##(R) ;GET UUO PC
TLNN T4,(XC.UIO) ;DOES HE HAVE USER IOT SET
TLZ T3,(XC.UIO) ;NO--CLEAR FROM OLD PC
TLNE T4,(XC.PUB) ;OLC PC PUBLIC
TLO T3,(XC.PUB) ;YES--NEW PC IS TOO
TLO T3,USRMOD ;SET USER MODE
TLZ T3,37 ;CLEAR INDEX AND @
MOVEM T3,JOBPD1##(R) ;STORE BACK FOR USER
MOVEM T3,JOBPC##(R) ;FOR GJOBPC
MOVSI T3,ICFNOT ;CLEAR PI IN PROGRESS BIT
EXCTUU <ANDCAM T3,IBKICF(M)> ; IN THE CONTROL BLOCK
PUSHJ P,DFRINT ;LOOK FOR MORE WORK
SKIPE PITNXT(P1) ;IS THERE A TRAP PENDING?
PJRST UTOUSR ;YES--TRAP HIM
POPJ P, ;RETURN TO USER
SUBTTL PI SYSTEM UUO'S -- PIINI.
;CALL TO INIT THE PI SYSTEM
;CALL WITH:
; MOVEI AC,BASE-ADDRESS-OF-INTERRUPT-VECTOR
; PIINI. AC,
; HERE IF SYSTEM NOT AVAIL
; NORMAL RETURN IS HERE
;
PIINI:: MOVEI T1,(T1) ;CLEAR JUNK FROM LH OF T1
PUSH P,T1 ;SAVE USER ARGUMENT
PUSHJ P,CLRPSI ;CLEAR OLD DATA
MOVEI T2,PIT4WD ;NUMBER OF 4-WORD BLOCKS TO GET
PUSHJ P,GET4WD## ;GO GET THEM
JRST TPOPJ## ;CAN'T
HRRZM T1,JBTPIA##(J) ;ADDRESS OF THE PIT
MOVSI T2,PITPRO ;PROTOTYPE PIT
HRR T2,T1 ;WHERE IT GOES
BLT T2,PITSIZ-1(T1) ;MOVE IT OVER
POP P,PITIVA(T1) ;BASE OF VECTOR
JRST CPOPJ1## ;GOOD RETURN
SUBTTL PI SYSTEM UUO'S -- PISYS.
PISYS:: PUSHJ P,SAVE2## ;SAVE P1 AND P2
TRNE T1,-1 ;ANY ADDRESS GIVEN?
TLNE T1,(PS.CSI!PS.RDV!PS.ADV) ;IS ARGUMENT NEEDED?
SKIPA ;YES
PJRST RTZER## ;(0) UNNECESSARY ARG SUPPLIED
TLNN T1,(PS.ALL) ;ANYTHING TO DO?
PJRST ECOD1## ;(1) NO FUNCTION GIVEN
TLNE T1,<-1-PS.ALL>_<-^D18> ;ANY UNUSED BITS SET?
PJRST ECOD2## ;(2) UNUSED BIT IS NOT = 0
SKIPN JBTPIA##(J) ;PIINI. UUO DONE?
JRST ECOD13## ;(13) PIINI. UUO NOT DONE
MOVE P2,T1 ;COPY ARGUMENT
MOVE P1,JBTPIA##(J) ;PLACE IN AN AC FOR INDEXING
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 SELECTED PENDING INTERRUPT
POPJ P,
JRST .+1]
MOVSI P1,(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
IORB P1,JBTPIA##(J) ;LIGHT THE BIT
AOS JOBPD1##(R);MAKE UUO LOOK GOOD
SKIPE PITNXT(P1) ;WERE WE WAITING FOR THIS?
PUSHJ P,UTOUSR ;YES--MAKE AN INTERRUPT HAPPEN
HRRZ P1,JOBPD1##(R) ;CHANGE RETURN
SUBI P1,1 ; ADDRESS BACK
HRRM P1,JOBPD1##(R) ; PRESERVING FLAGS
JRST PISYS1]
TLNE P2,(PS.OFF) ;WANT TO TURN OFF?
ANDCAB P1,JBTPIA##(J) ;CLEAR THE SYSTEM ON BIT
PISYS1: MOVE P1,JBTPIA##(J) ;SETUP PIT ADDRESS
TLNE P2,(PS.RDV) ;WANT TO REMOVE DEVICE OR COND?
PJRST REMDEV ;YES--GO DO THAT
TLNE P2,(PS.ADV) ;WANT TO ADD?
PJRST ADDDEV ;YES--GO ADD DEVICE
JRST CPOPJ1## ;GOOD RETURN
SUBTTL PI SYSTEM UUO'S -- SUBROUTINES
;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
MOVEI T1,PIT4WD ;NUMBER OF 4-WORD BLOCKS WE HAVE
PUSHJ P,GIV4WD## ;RETURN THE CORE
HLRZ F,DEVLST## ;POINTER TO FIRST DDB
SETZB T2,JBTPIA##(J) ;CLEAR JOB TABLE
CLPSIL: LDB T1,PJOBN## ;PICK UP JOB NUMBER
CAIN T1,(J) ;IS THIS ME
DPB T2,PDVPSI## ;YES--CLEAR PSI BYTE
HLRZ F,DEVSER(F) ;LINK TO NEXT DDB
JUMPN F,CLPSIL ;LOOP IF NOT AT END OF LIST
POPJ P,0 ;RETURN
;SUBROUTINE TO REMOVE A DEVICE OR CONDITION
;CALLED ONLY FROM PISYS UUO WITH:
; P2 = USERS ARGUMENT
; P1 = ADDRESS OF PRIORITY INTERRUPT TABLE
; 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 REMDV1 ;DEVICE CODE
PUSH P,T1 ;SAVE CONDITION
PUSHJ P,CLRPND ;CLEAR PENDING INTERRUPT IF ANY
POP P,T1 ;RETURN T1
PUSHJ P,CNDPTR ;GET A BYTE POINTER TO FIELD
MOVEI T2,0 ;STORE THE FIELD
DPB T2,U ; AS ZERO
JRST CPOPJ1## ;GOOD RETURN
REMDV1: PUSHJ P,CLRPND ;CLEAR ANY PENDING INTERRUPTS
MOVEI T1,0 ;CLEAR THE INTERRUPT BYTE
DPB T1,PDVPSI## ; IN THE DDB
JRST CPOPJ1## ;GOOD RETURN
;SUBROUTINE TO ADD A DEVICE OR CONDITION
;CALLED FROM PISYS. UUO WITH:
; P1 = ADDRESS OF PROGRAM INTERRUPT TABLE
; P2 = USERS ARG POINTER
; PUSHJ P,ADDDEV
; RETURN HERE ON ERROR
; RETURN HERE IF ALL IS OK
;
ADDDEV: PUSHJ P,CHKCND ;GO CHECK OUT ARGUMENT
POPJ P,0 ;INVALID DEVICE OR CONDITION
JRST ADDDDB ;HE WANTS TO ADD A DDB
PUSHJ P,CNDPTR ;GET A CONDITION POINTER INTO U
TDZA F,F ;CLEAR F AND DO REST OF CALL
ADDDDB: MOVE U,PDVIVO## ;BYTE POINTER TO INTERRUPT VECTOR OFFSET
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
SKIPE F ;SKIP IF CONDITION NOT DEVICE
HRLZM T1,DEVPSI(F) ;DEVICE STORE REASON BITS
HLRZ T1,T1 ;PUT VALUE IN RH
CAMG T1,CNFMVO## ;IS VALUE TOO BIG?
TRNE T1,3 ;IS HE CONFUSED?
PJRST ECOD7## ;(07)BAD VECTOR OFFSET
IFN FTVM,<
MOVEI T2,(T1) ;SAVE ADDRESS OF BLOCK
>
LSH T1,-2 ;SHIFT OFF ZERO BITS
ADDI T1,1 ;ADJUST SO ZERO IS A VALID OFFSET
DPB T1,U ;STORE OFFSET
LDB T3,PTMVO ;GET MAXIMUM VECTOR OFFSET THUS FAR
CAIGE T3,(T1) ;GREATER THAN THIS ONE?
DPB T1,PTMVO ;NO, SAVE THE GREATEST
IFN FTVM,<
HRRZ T1,PITIVA(P1) ;GET USER BASE ADDRESS FOR VECTOR
ADDI T1,(T2) ;RELOCATE TO BEGINNING OF THIS BLOCK
MOVEI T2,3(T1) ;POINT T2 TO END OF THIS BLOCK
PUSHJ P,TRNGE## ;CALL PFH IF BLOCK IS PAGED OUT
>
PUSHJ P,GETWD1## ;GET NEXT WORD
TLNE T1,-1 ;IS PRIORITY TOO BIG
PJRST ECOD11## ;(11) PROIRITY IS TOO BIG
TRNE T1,-1 ;IS RESERVED HALF WORD NON-ZERO
PJRST ECOD12## ;(12) RESERVED HALFWORD IN NON-ZERO
IFN FTKI10!FTKL10,<
PUSHJ P,APPSI ;GO SET UP TRAP INSTRUCTIONS
>
PJRST CPOPJ1## ;GOOD RETURN
;SUBROUTINE TO CLEAR ALL PENDING INTERRUPTS
;CALLED FROM PISYS UUO WITH:
; P1 = ADDRESS OF PIT
; PUSHJ P,CLRAPI
; RETURN HERE
CLRAPI: HLRZ F,DEVLST## ;GET POINTER TO FIRST DDB
CLAPIL: LDB T1,PJOBN## ;GET OWNERS JOB NUMBER
CAIE T1,(J) ;SKIP IF THIS JOB OWNS THE DEVICE
JRST CLAPIN ;NO--LOOK AT THE NEXT DEVICE
HLLZS DEVPSI(F)
CLAPIN: HLRZ F,DEVSER(F) ;STEP TO NEXT DDB
JUMPN F,CLAPIL ;LOOP OVER ALL DDB'S
SETZM PITDFR(P1) ;CLEAR ALL THE PENDING BITS
SETZM PITNXT(P1) ;CLEAR NEXT INTERRUPT FLAG
SETZM PITNPI(P1) ;NO PENDING INTERRUPTS
POPJ P,0 ;RETURN
;SUBROUTINE TO SET KI10 TRAP 1 INSTRUCTION
; RESPECTS T1
IFN FTKI10!FTKL10,<
APPSI:: HRRZ T2,JBTPIA##(J) ;GET ADDRESS OF PI TABLE
JUMPE T2,CPOPJ## ;EXIT IF NONE
LDB T2,[POINT 9,PITTAB+2(T2),8] ;GET BYTE FOR TRAP 1
JUMPE T2,CPOPJ## ;EXIT IF NOT ENABLED
MOVEI T2,APRTRP ;WHERE TO GO ON AN APR TRAP
MOVEM T2,.UPMP+.UPAOT ;STORE IN UPMP
POPJ P,0 ;RETURN
> ;END FTKI10
;SUBROUTINE TO CLEAR SELECTED PENDING INTERRUPTS
;CALLED FROM PISYS UUO WITH:
; PUSHJ P,CLRSPI
; RETURN HERE ON ERROR
; RETURN HERE IF OK
;
CLRSPI: PUSHJ P,CHKCND ;CHECK THE CONDITION WORD
POPJ P,0 ;INVALID
MOVE T1,DEVNAM(F) ;DEVICE PICK UP DEVICE NAME
PUSHJ P,CLRPND ;CLEAR PENDING INTERRUPT
JRST CPOPJ1## ;SKIP RETURN
;SUBROUTINE TO FETCH AND VALIDATE THE DEVICE OR CONDITION GIVEN BY THE USER
;CALLED WITH:
; P2 = USER ARGUMENT
; PUSHJ P,CHKCND
; RETURN HERE IF THE CONDITION IS INVALID
; RETURN HERE IF A DEVICE WAS SPECIFIED
; RETURN HERE IF A CONDITION WAS SPECIFIED
;
;UPON RETURN F=ADDRESS OF DDB (IF DEVICE)
; T1 = CONDITION NUMBER (IF CONDITION)
;
CHKCND: HRR M,P2 ;ADDRESS OF WORD
PUSHJ P,GETWDU## ;GET THE WORD
HLRE T2,T1 ;IF CONDITION T2 NOW = -1
AOJE T2,CHKCN1 ;SO IF T2+1=0 WE HAVE A CONDITION
PUSHJ P,DVCNSG## ;ELSE LOOK FOR A DEVICE
JRST ECOD4## ;(4) NOT A DEVICE
HRRZ T2,TTYTAB##(J) ;GET ADDRESS OF THIS JOBS TTY DDB
CAIN T2,(F) ;SKIP IF THIS IS NOT HIS TTY
PJRST CPOPJ1## ;GOOD RETURN
LDB T2,PJOBN## ;GET NAME OF OWNER
MOVEI T3,ASSPRG ;SEE IF DEVICE IS
TDNE T3,DEVMOD(F) ; OPEN FOR
CAIE T2,(J) ; THIS JOB.
PJRST ECOD5## ;(5) OR NOT OPEND BY THIS JOB
JRST CPOPJ1## ;SKIP RETURN
CHKCN1: CAMGE T1,[C$MIN] ;SKIP IF CODE IS NOT TOO SMALL
PJRST ECOD4## ;(4) OR CONDITION CODE TOO SMALL
JRST CPOPJ2## ;DOUBLE SKIP
; RETURN
SUBTTL ROUTINES TO CAUSE INTERRUPTS -- ANY UUO TRAP
;SUBROUTINE CALLED FROM UUOCON ON EVERY UUO
;CALL WITH:
; PUSHJ P,ANYUUO
; RETURN HERE IF UUO IS TO BE PERFORMED
; RETURN HERE TO ABORT UUO AND INTERRUPT
;
;RESPECTS ALL AC'S INVLOVED IN UUO DISPATCH
;
ANYUUO::SKIPL T3,JBTPIA##(J) ;IS HE ENABLED?
POPJ P,0 ;NO--RETURN QUICKLY
LDB T3,[POINT 9,PITTAB+1(T3),8] ;ANY UUO BYTE
JUMPE T3,CPOPJ## ;RETURN IF HE DOES NOT WANT TO
; TRAP EVERY UUO.
IFN FTMS,<
PUSHJ P,ONCPU0## ;MUST USE CPU0
>
PUSHJ P,SAVE2## ;HE WANTS TO TRAP EVERY UUO SO WE
; CAN AFFORD TO BE SLOW.
MOVE P1,M ;COPY UUO
TLZ P1,777 ;CLEAR JUNK
CAMN P1,[CALLI 137] ;IF THIS IS A DEBRK. DO NOT TRAP SINCE WE
POPJ P,0 ; CAN NOT DO THIS UUO FOR THE USER.
MOVE P1,M ;SAVE M
MOVE P2,T1 ;SAVE T1
HRREI T1,C$AUUO ;FLAG AS ANY UUO
PUSHJ P,PSISIG ;GO TRY TO INTERRUPT
JRST AUUO1 ;WANTS TO INTERRUPT
MOVE M,P1 ;RESTORE M
MOVE T1,P2 ;RESTORE P2
POPJ P,0 ;RETURN
AUUO1: TLZ P1,37 ;REMOVE R
EXCTUU <MOVEM P1,IBKISW(M)> ;STORE UUO FOR USER TO SEE
JRST CPOPJ1## ;SKIP DISPATCH
SUBTTL ROUTINES TO CAUSE INTERRUPTS -- ARITHMETIC FAULT TRAP
;HERE ON ARITHMETIC OVERFLOW
IFN FTKI10!FTKL10,<
APRTRP: MOVE P,[MJOBPD##,,.JDAT+JOBPDL##]
PUSHJ P,CPUCDB##
MOVE J,.CPJOB##(P4)
MOVE R,JBTADR##(J) ;EVA OF JOB DATA AREA
MOVE T1,.UPMP+.UPMUP ;FETCH PC
MOVEM T1,.CPPC##(P4) ;STORE PC WHERE PSISIG WILL FIND IT
IFN FTVM,<
MOVEM T1,.JDAT+JOBPC##
>
SIGNAL C$ARIT ;SIGNAL AROV
JFCL ;DON'T CARE
JEN @.CPPC##(P4) ;RETURN TO USER
> ;END FTKI10
SUBTTL ROUTINES TO CAUSE INTERRUPTS -- KSYS TIME
PSIKSY::MOVE J,HIGHJB## ;GET TOP JOB NUMBER
MOVE T3,SYSKTM## ;GET KSYS TIME
KSYSLP: SIGNAL C$KSYS ;SIGNAL KSYS
EXCTUU <MOVEM T3,IBKISW(M)>
SOJG J,KSYSLP ;LOOP OVER ALL JOBS
POPJ P,0 ;RETURN
;HERE TO SIGNAL NETWORK TOPOLOGY CHANGE
IFN FTNET,<
PSINTC::MOVE T2,J ;SAVE J FOR NETSER
MOVE J,HIGHJB## ;HIGHEST JOB NUMBER
NTCLUP: SIGNAL C$NTC ;SIGNAL NETWORK TOPOLOGY CHANGE
JFCL ;NO STATUS TO STORE
SOJG J,NTCLUP ;LOOP OVER ALL JOBS
MOVE J,T2
POPJ P, ;RETURN
>
SUBTTL ROUTINES TO CAUSE INTERRUPTS -- DEVICE OFF LINE
;SUBROUTINE TO CAUSE AN INTERRUPT FOR AN OFF LINE DEVICE
;CALL WITH:
; F = DDB
; PUSHJ P,PSIHNG
; HERE TO GO TO USER (T3 NEGATIVE IF USER WANTS MESSAGE)
; HERE IF USER NOT ENABLED
;
PSIHNG::PUSHJ P,SAVE4## ; ..
MOVEI T1,IR.DOL ;SET BIT FOR DEVICE OFF LINE
PUSHJ P,PSIDEV ;SIGNAL DEVICE CONDITION
SKIPL T3,T1 ;SKIP IF ENABLED
JRST CPOPJ1## ;NOT
AOJA T3,CPOPJ## ;ENABLED--NON-SKIP T3.LT.0IF MSG
;SUBROUTINE TO CAUSE AN INTERRUPT FOR A DOWN DEVICE
;CALL WITH:
; F = DDB
; PUSHJ P,PSIDWN
; ALWAYS RETURN HERE
;
PSIDWN::PUSHJ P,SAVT## ;SAVE T1-T4
MOVEI T1,IR.IER!IR.OER!IR.DOL ;INPUT ERROR, OUTPUT ERROR, OFF-LINE
PJRST PIIDX0 ;SIGNAL THE INTERRUPT
;SUBROUTINE TO CAUSE AN INTERRUPT WHEN A DEVICE COMES ON-LINE
;CALL WITH:
; F=DDB
; PUSHJ P,PSIONL
; ALWAYS RETURN HERE
;
PSIONL::PUSHJ P,SAVT## ;SAVE T1-T4
MOVEI T1,IR.ONL ;DEVICE ON-LINE
PJRST PIIDX0 ;SIGNAL THE INTERRUPT
SUBTTL ROUTINES TO CAUSE INTERRUPTS -- I/O DONE
;HERE FROM CLOCK1 ON CALL TO SETIOD
PSIIOD::PUSHJ P,SAVT## ;SAVE T1 THRU T4
MOVEI T1,0 ;COMPUTE CONDITION BASED ON S
PIIDX0: PUSHJ P,SAVE4## ;SAVE P1 THRU P4
IFN FTKI10!FTKL10,<
HRRZ T2,P ;IF NOT AT UUO LEVEL
CAMGE T2,SYSSIZ## ; (A PTY),
PUSHJ P,SVEUF## ; SAVE UBR/EBR VIA F
>
PSIDEV: PUSH P,J ;SAVE J
PUSH P,M ;SAVE M
PUSH P,F
HLRZ T2,DEVPSI(F) ;IS THIS DEVICE ENABLED?
IFN FTMSGSER,<
JUMPE T2,[MOVEI T2,DEPMSG ;NO--IS IT CONTROLED BY MSGSER?
TDNN T2,DEVMSG(F) ; ..
JRST PIIDX2 ;NO--PUNT NOW
HRRZ F,DEVXTR(F) ;YES--STEP TO MPX DDB
JRST .+1] ;CONTINUE
> ;END FTMSGSER
JUMPN T1,PIDEV1
TLNN S,IO ;SKIP IF DEVICE IS DOING OUTPUT
TROA T1,IR.IND ;LOAD UP INPUT BIT
MOVEI T1,IR.OUD ;LOAD UP OUTPUT BIT
PIDEV1: TSNN T1,DEVPSI(F) ;ENABLED?
JRST PIIDX2 ;NO
PUSH P,T1 ;SAVE T1 (POSITIVE NUMBER)
LDB J,PJOBN## ;SET UP JOB NUMBER
SKIPN P1,JBTPIA##(J) ;DOES USER HAVE PSISER ENABLED
JRST PIIDX1 ;NO--EXIT NOW
SKIPE T2,JBTADR##(J) ;ADDRESS OF JOBDAT
PUSHJ P,JSRPC ;GET CORRECT PC
PUSHJ P,PISIG1 ;GO SIGNAL THE INTERRUPT
SKIPA T1,(P) ;INTERRUPT GRANTED (REMEMBER REASON)
JRST PIIDX1 ;INTERRUPT REFUSED
EXCTUU <IORM T1,IBKRSN(M)> ;STORE REASON WORD
IFN FTMSGSER,<
HRRZ F,-1(P)
>
PUSHJ P,PSIUDX ;STORE UDX AND DEVICE STATUS FOR USER
HRROS (P) ;T1.LT.0 TO TELL CALLER INTERRUPT WAS GRANTED
MOVSI T1,ICFMSG ;USER WANTS STANDARD ERROR MESSAGE BIT
EXCTUX <TDNE T1,IBKICF(M)> ;DOES HE WANT THE MESSAGE?
SETOM (P) ;YES, INDICATE THAT TO THE CALLER
PIIDX1: POP P,T1 ;RESTORE T1
PIIDX2: POP P,F
POP P,M ;RESTORE M
JRST JPOPJ## ;RESTORE J AND RETURN
;SUBROUTINE TO FIND CORRECT PC FOR IO DONE INTERRUPT
;CALL WITH:
; MOVE T2,JBTADR##(J) ;****NOTE THE AC USED****
; PUSHJ P,JSRPC
; RETURN HERE (PC IS IN T2)
;
JSRPC: MOVE T2,JOBPC##(T2) ;GET THE PC FROM JOBDAT
IFN FTMS,<
SKIPN .C0ISF## ;JOBPC IS ALWAYS RIGHT IF IN THE SCHEDULER
>
CAME J,.C0JOB## ;IS HE RUNNING NOW?
POPJ P,0 ;NO--RETURN
MOVE T2,JBTADR##(J) ;RESTORE JOB'S ADDRESS
MOVE T2,JOBPD1##(T2) ;CURRENT JOB, (GET HIS PC)
CONSO PI,PI.IPA-PI.IP7 ;A PI IN PROGRESS?
POPJ P, ;NO--RETURN
CONI PI,T3 ;GET PI STATUS
ANDI T3,PI.IPA ;JUST GET THE PI BITS
LSH T3,^D20 ;POSITION SO IP.PI1 IS BIT 1
JSRPC1: JFFO T3,JSRPC2 ;T4 = OUR PI LEVEL
MOVEI T2,0 ;NO USER MODE PC STORED BY INTERRUPT
POPJ P,0 ;RETURN WITH PC HAVING USRMOD=0
JSRPC2: ANDCM T3,BITTBL##(T4) ;CLEAR THE BIT JFFO FOUND
LSH T4,1 ;MAKE *2
ADDI T4,40 ;BASE OF INTERRUPT VECTOR
HLRZ T2,(T4) ;GET THE INSTRUCTION
CAIE T2,(JSR) ;IF NOT A JSR THIS MUST HAVE BEEN A
AOS T4 ; BLKI/BLKO ADVANCE TO 40+2*N+1
MOVEI T4,@(T4) ;GET THE EFFECTIVE ADDRESS OF THE JSR
MOVE T2,(T4) ;GET OLD PC
TLNN T2,USRMOD ;STORED FROM USER?
JRST JSRPC1 ;NO--KEEP LOOKING AT LOWER PI LEVELS
HRRM T4,PITIPC(P1) ;REMEMBER WHERE WE FOUND THIS PC
POPJ P,0 ;RETURN -- T2 IS PC STORED BY JSR
SUBTTL ROUTINES TO CAUSE INTERRUPTS -- I/O ERROR AND EOF
;HERE JUST BEFORE AN INPUT OR OUTPUT RETURNS TO THE USER
PSIEDN::TLNN S,IO ;SKIP IF OUTPUT
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,740000 ;ANY ERRORS?
TRZ T1,IR.IER!IR.OER;NO--DO NOT SIGNAL ERROR
JUMPE T1,CPOPJ## ;EXIT IF NOTHING HAPPENED
MOVE T2,JOBPD1##(R) ;LOAD THE PC
PUSHJ P,PSISIG ;SIGNAL THE INTERRUPT
PUSHJ P,PSIUDX ;STORE UDX AND DEVICE STATUS
POPJ P,0 ;RETURN
SUBTTL ROUTINES TO CAUSE INTERRUPTS -- ERROR IN JOB TRAPS
;SUBROUTINE TO PROCESS EXTERNAL ERROR IN JOB INTERRUPTS
;CALL WITH:
; PUSHJ P,EXTEIJ
; RETURN HERE TO PRINT MESSAGE
;
EXTEIJ::HRREI T1,C$XEIJ ;EXTERNAL ERROR IN JOB
PUSHJ P,PSISIG ;GO SIGNAL CONDITION
JRST ERRGOU## ;WANTS THE TRAP
POPJ P,0 ;DOES NOT WANT TRAP
;SUBROUTINE TO CAUSE A USER INDUCED ERROR IN JOB INTERRUPT
;CALL WITH:
; PUSHJ P,USREIJ
; RETURN HERE TO INTERRUPT
; RETURN HERE TO STOP THE JOB
USREIJ::MOVE T1,ERRMSK ;IS THE USER ABOUT TO GET A BETTER
SKIPE T2,JBTPIA##(J) ; ERROR INTERCEPT
TDNE T1,PITDFR(T2) ; ..
JRST CPOPJ1## ;YES--DO NOT GIVE 2 INTERRUPTS
SIGNAL C$UEIJ ;SIGNAL THE CONDITION
POPJ P,0 ;ENABLED
JRST CPOPJ1## ;NOT ENABLED
SUBTTL ROUTINES TO CAUSE INTERRUPTS -- DEFERED INTERRUPTS
;SUBROUTINE CALLED WHEN USER IS ABOUT TO ENTER USER MODE AND SOMETHING
; OF INTEREST HAPPENED SINCE HE WAS IN CORE LAST
;
DFRINT:
IFN FTMS,<
HRRZ T1,P ;RH(PDL)
CAMLE T1,SYSSIZ## ;AT UUO LEVEL?
PUSHJ P,ONCPU0## ;YES, MUST BE ON CPU0
SKPCPU (0) ;MUST BE ON CPU0 SINCE IF NOT AN
POPJ P, ; INTERRUPT COULD BE BEING SIGNALED ON
; CPU0 WHILE THIS CODE IS BEING EXECUTED ON CPU1
>
PUSHJ P,SAVE4## ;SAVE P1 - P4
PUSHJ P,CPUSET## ;SETUP J AND P4
SKIPN P1,JBTPIA##(J) ;PICK UP PIT ADDRESS
POPJ P,0 ;NOT ENABLED OR NULL JOB
MOVSI T1,(JFCL) ;CLEAR THE INTERRUPT INSTRUCTION
MOVEM T1,PITINS(P1) ; ..
SKIPE PITCIB(P1) ;ANY PI IN PROGRESS
POPJ P,0 ;YES -- WAIT FOR DEBRK.
DFRLP: SKIPN T1,PITDFR(P1) ;ANY DEFERED INTERRUPTS?
JRST DFRDEV ;NO--LOOK FOR A DDB
JFFO T1,.+1 ;FIND A CONDITION
MOVN T1,T2 ;SETUP NEGATIVE CONDITION NUMBER
MOVSI T2,(1B0) ;SETUP TO CLEAR THE BIT
LSH T2,(T1) ; ..
ANDCAM T2,PITDFR(P1) ;CLEAR THE DEFFERED INTERRUPT BIT
PUSHJ P,GETDPC ;GET JOB'S PC
PUSHJ P,DFRSIG ;SIGNAL INTERRUPT
SKIPA T2,PITWJB(P1) ;INTERRUPT GRANTED, GET JOB DOING WAKE
JRST DFRLP ;TRY NEXT CONDITION
CAMN T1,[C$WAKE] ;WAS IT A WAKE INTERRUPT?
EXCTUU <MOVEM T2,IBKISW(M)> ;YES--STORE STATUS
MOVE T2,TTYTAB##(J) ;ADDRESS OF TTY DDB
HRRZ T2,DDBLDB##(T2) ;ADDRESS OF TTY LDB
SKIPE T2 ;SKIP IF DETACHED
SKIPA T2,LDBDCH##(T2) ;ELSE GET TTY NUMBER
SOSA T2 ;DETACHED USE -1
ANDI T2,777 ;ATTACHED USE TTY NUMBER
CAMN T1,[C$DATT] ;ATTACH/DETACH INTERRUPT?
EXCTUU <MOVEM T2,IBKISW(M)> ;YES--STORE STATUS
MOVE T2,SYSKTM## ;GET TIME TO KSYS
CAMN T1,[C$KSYS] ;IS IT KSYS?
EXCTUU <MOVEM T2,IBKISW(M)> ;YES--STORE STATUS
MOVE T2,PITENQ(P1)
CAMN T1,[C$QUE]
EXCTUU <MOVEM T2,IBKISW(M)>
IFN FTIPCF,<
CAMN T1,[C$IPC] ;IPC SIGNALING?
PJRST STRSIG## ;YES, STORE THE REASON WORD
>
POPJ P,0 ;RETURN
;HERE TO LOOK FOR DEFERED DEVICE INTERRUPTS
DFRDEV: HLRZ F,DEVLST## ;POINTER TO FIRST DDB
DFRDV1: LDB T1,PJOBN## ;GET JOB NUMBER
CAIE T1,(J) ;IS THIS FOR US?
JRST DFRDVX ;NO--LOOK AT THE NEXT DDB
HRRZ T1,DEVPSI(F) ;GET DEFERED BIT MASK
JUMPE T1,DFRDVX ;NOTHING HERE IF ZERO
ANDCAM T1,DEVPSI(F) ;CLEAR DEFERED BITS
PUSHJ P,GETDPC ;GET CURRENT PC
PUSHJ P,DFRSIG ;SIGNAL INTERRUPT
SKIPA ;GRANTED
JRST DFRDVX ;REFUSED
EXCTUU <IORM T1,IBKRSN(M)> ;STORE REASON
PJRST PSIUDX ;STORE THE UDX AND STATUS
DFRDVX: HLRZ F,DEVSER(F) ;STEP TO NEXT DDB
JUMPN F,DFRDV1 ;LOOP FOR MORE
POPJ P,0 ;EXIT
;SUBROUTINE TO FIND THE PC FOR A DEFERRED INTERRUPT
GETDPC: HRRZ T2,-6(P) ;PC OF CALLER TO DFRINT
CAIE T2,CIPPSI## ;FROM THE CONTEXT SWITCHER?
SKIPA T2,JOBPD1##(R) ;NO, UUOXIT, GET UUO PC
GJOBPC ;YES, GET PC AT CONTEXT SWITCH
POPJ P, ; AND RETURN
SUBTTL INTERRUPT CODE -- SIGNAL AN INTERRUPT
;SUBROUTINE TO REQUEST AN INTERRUPT.
;CALLED WHEN A CONDITION REQUIRING AN INTERRUPT IS DETECTED WITH:
; J = JOB NUMBER
; SIGNAL(COND)
; HERE IF USER WILL BE INTERRUPTED
; HERE IF USER IS NOT ENABLED
;
; - OR -
;
; J = JOB NUMBER
; F = DDB ADDRESS OF DEVICE
; SIGNAL(REASON BIT)
; HERE IF USER WILL BE INTERRUPTED
; HERE IF USER IS NOT ENABLED
;
;UPPON RETURN 'M' IS SETUP TO BE THE ADDRESS OF WORD 0 IN THE USERS
; 4-WORD INTERRUPT BLOCK. IF THIS IS A KA10 THIS ADDRESS IS RELOCATED
; AND CAN BE ACCESSED DIRECTLY. IF THIS IS A KI10 THIS IS A USER
; ADDRESS AND AN EXECUTIVE EXECUTE MUST BE USED.
;
;AC USAGE:
; BECAUSE OF THE NUMBER OF PLACES WHICH MAY WANT TO SIGNAL CONDITIONS
; ALL AC'S ARE PRESERVED EXCEPT T1 WHICH IS WIPED OUT IN THE SIGNAL
; MACRO AND M WHICH RETURNS A VALUE.
;NOTE: ON DEVICE CONDITIONS T2 CONTAINS THE OLD PC
PSISIG::PUSHJ P,PISIG0 ;DO THE SIGNAL
PJRST SVEUB## ;ENABLED--SAVE UBR
JRST CPOPJ1## ;GOOD RETURN
PISIG0::PUSHJ P,SAVT## ;SAVE T1-T3
PUSHJ P,SAVE4## ;SAVE P1 - P4
;HERE IF YOU DO NOT NEED ANYTHING SAVED
PISIG1::CAMG J,HIGHJB## ;J OK?
SKIPN P1,JBTPIA##(J) ;SETUP P1 AS ADDRESS OF PRIORITY INTERRUPT
; TABLE
PJRST CPOPJ1## ;NOT ENABLED
;FALL THROUGH TO NEXT PAGE
CAMN T1,[C$QUE] ;ENQ/DEQ CALL?
IORM T2,PITENQ(P1) ;YES--SAVE STATUS
SKIPGE T3,JBTSTS##(J) ;IN CONTROL-C STATE?
TLNE T3,SWP ;IS THIS JOB IN CORE?
JRST SIGDFR ;NO--MUST BE SOMETHING LIKE DISK OFF LINE
PUSHJ P,CPUCDB##
HRRZ T3,P
CAMG T3,SYSSIZ## ;STACK OK?
JRST PISIG2 ;YES, GO NOW
CAME J,.CPJOB##(P4) ;NO--CURRENT JOB?
PJRST SIGDFR ;NO--DEFER THE TRAP
PISIG2: IFN FTKI10!FTKL10,< ;IS THIS A KI?
PUSHJ P,SVEUB## ;YES--SAVE UBR
>;END FTKI10
PUSHJ P,SAVR## ;DO NOT CLOBBER R!
MOVE R,JBTADR##(J) ;MAKE SURE R POINTS TO JOBDATA AREA
SKIPGE T1 ;SKIP IF DEVICE CONDITION
XCT OPCXCT(T1) ;PUT OLD PC IN T2
DFRSIG: MOVSI P3,USRMOD ;SAVE THE USER MODE BIT FROM THE ORIGINAL
AND P3,T2 ; OLD PC
CONSZ PI,PI.IPA-PI.IP7 ;A PI IN PROGRESS?
JUMPE P3,SIGDFR ;YES, CAN'T FIND THE USER'S PC IF PC IS IN EXEC MODE
TLNN T2,USRMOD ;IS THIS IN USER MODE?
MOVE T2,JOBPD1##(R) ;NO--GET UUO PC
IFN FTVM,<
CAMN T2,[EXP IC.UOU+TIMFLT##] ;SEE IF HIDDEN IN UPMP
MOVE T2,.UPMP+.UPTMC ;YES--VM MAKES LIFE SO EASY
> ;END FTVM
TLNN T2,USRMOD ;IS PC IN USER MODE?
JRST CPOPJ1## ;NO USER PC. MUST BE IO DONE FROM FIN
; COMMAND OR SIMILAR HAPPENING. JUST
; IGNORE THE INTERRUPT.
PUSHJ P,ISPFH ;ARE WE IN USER PAGE FAULT ROUTINE
SKIPA T3,[1B0] ;YES--SEE IF WE SHOULD IGNORE THIS TRAP
JRST SIG05 ;NO--CHARGE AHEAD
LSH T3,(T1) ;SHOULD WE IGNORE CONDITION BECAUSE
TDNE T3,PFHMSK ; WE ARE IN PFH OR DDT?
JRST CPOPJ1## ;YES--FLUSH TRAP
TLO P3,(1B0) ;SET 1B0 OF P3 AS A FLAG
;AT THIS POINT, T1=CONDITION OR REASON, T2=OLD PC AND P1=PIT ADDRESS
; IF WE HAVE VM P3.GE.0 FOR NORMAL CASE AND .LT.0 IF INTERRUPT IS TO BE
; HELD TILL EXIT FROM USER PAGE FAULT HANDLER OR DDT
SIG05: MOVE P2,T2 ;SAVE PC IN PRESERVED AC
PUSHJ P,BLKADR ;GET THE ADDRESS OF THE BLOCK
JRST CPOPJ1## ;INVALID ADDRESS
JUMPL T1,SIG10 ;IS THIS A DEVICE CONDITION?
TSNN T1,DEVPSI(F) ;YES--IS USER ENABLED?
PJRST CPOPJ1## ;NO--DO NOT TRAP
SIG10: SKIPN PITCIB(P1) ;IF WE ARE SERVICING A TRAP NOW OR
SKIPE PITNPI(P1) ; WAITING FOR ONE TO HAPPEN, MAKE
JRST SIG15 ; THIS TRAP STAY PENDING.
MOVSI T2,ICFNOT ;TRAP IN PROGRESS BIT
EXCTUX <TDNN T2,IBKICF(M)> ;SKIP IF BLOCK IS IN USE
JRST SIG20 ;NOT IN USE
SIG15: MOVSI T2,ICFCNI ;DOES HE WANT THE NEXT INTERRUPT
EXCTUX <TDNE T2,IBKICF(M)> ; TO BE CLEARED?
PJRST CPOPJ1## ;YES--GO CLEAR IT
PJRST SETPND ;NO--CAUSE THIS INTERRUPT TO STAY PENDING
SIG20: SKIPL T1 ;SKIP IF NOT A DEVICE CONDITION
EXCTUU <IORM T1,IBKRSN(M)> ;STORE REASON IN BLOCK
MOVSI T2,ICFAAI ;ALLOW ADDITIONAL INTERRUPTS BIT
MOVSI T3,ICFNOT ;NO TRAP BIT
EXCTUX <TDNN T2,IBKICF(M)> ;DOES HE WANT THE INTERRUPTS?
EXCTUU <IORM T3,IBKICF(M)> ;NO--SET THE PI IN PROGRESS FLAG
;FALL THROUGH TO NEXT PAGE
;HERE WHEN INTERRUPT IS READY TO HAPPEN. WE HAVE TO GET THE USER TO
; RUN.
JUMPGE T1,SIG30 ;JUMP IF IT IS A DDB ADDRESS
CAMGE T1,[C$MIN] ;SKIP IF IT IS RIGHT SIZE FOR COND
JRST SIG30 ;NO--IGNORE MESSAGE IDEA
IFN FTTIME,<
CAME T1,[C$TLE] ;TIME LIMIT EXCEEDED?
JRST SIG35 ;NO
MOVE T1,J ;YES
PUSHJ P,JOBTMM## ;STATUS IS USERS RUN TIME
MOVE T2,T1
SKIPA T1,[C$TLE] ;RESTORE CONDITION
>
SIG35: SETZM T2 ;NO STATUS
CAMN T1,[C$IUUO] ;IF ILLEGAL UUO
MOVE T2,MPTRAP## ;STATUS IS UUO
CAMN T1,[C$ADCK] ;IF ADDRESS CHECK
MOVE T2,DEVNAM(F) ;STATUS IS DEVICE NAME
EXCTUU <MOVEM T2,IBKISW(M)> ;STORE STATUS FOR USER
EXCTUU <MOVE T3,IBKICF(M)> ;PICK UP FLAGS
MOVSI T2,(1B0) ;SET BIT 0
LSH T2,(T1) ;SHIFT IT
TDNE T2,ERRMSK ;IS THERE AN ERROR MESSAGE?
TLNN T3,ICFMSG ;DOES THE USER WANT THE MESSAGE?
JRST SIG30 ;NO--CHARGE AHEAD
HRLM T1,PITIPC(P1) ;REMEMBER WHY WE ARE HERE
AOS (P) ;CAUSE SKIP RETURN
PJRST SETPNX ;MAKE THIS TRAP WAIT TILL AFTER MESSAGE
SIG30: JUMPG P1,SETPND ;IF THE PI SYSTEM IS TURNED OFF THEN
; THE INTERRUPT SHOULD STAY PENDING
; UNTIL THE SYSTEM IS TURNED ON.
JUMPL P3,SETPNX ;HOLD INTERRUPT IF IN PFH OR DDT
CAME J,.CPJOB##(P4) ;CURRENT JOB?
JRST SIG40 ;NO--SEE IF WE NEED TO WAIT
HRRZ T4,PITIPC(P1) ;GET LOCATION OF OLD PC
JUMPE T4,SIG40 ;JUMP IF NONE STORED
CAMN P2,(T4) ;IS IT OUR PC?
JRST TOUSR1 ;YES--GO INTERRUPT NOW
SIG40: CAME T1,[C$KSYS] ;KSYS?
CAMN T1,[C$DATT] ;OR DETACH?
JRST SIG45 ;YES, GO IF IN TI STATE
CAME T1,[C$CTLC] ;IF NOT CONTROL C,
JRST SIG50 ; LOOK AT OTHER POSSIBILITIES
SIG45: TLNN P3,USRMOD ;IF THE JOB IS IN USER MODE
PUSHJ P,CHKUTP## ; OR IT MAKES SENSE TO STOP IT,
JRST TOUSR1 ; GO DO IT NOW
SIG50: CONSZ PI,PI.IPA ;IS THERE A PI IN PROGRESS?
PJRST SETPNX ;YES--WAIT TO NEXT CLK TICK OR UUO EXIT.
TLNN P3,USRMOD ;SKIP IF USER IS IN EXEC MODE
JRST SETPNX ;EXEC MODE--WAIT
CAME T1,[C$IPC] ;IPCF TO HIMSELF?
JRST TOUSR1 ;NO__CHANGE PC
TLZ P3,USRMOD ;USE UTOUSR
;FALL INTO SETPNX
SUBTTL INTERRUPT CODE -- SUBROUTINES
;SUBROUTINE TO CAUSE A INTERRUPT TO BECOME PENDING
;CALLED WITH:
; T1 = NEGATIVE CONDITION OR POSITIVE ANYTHING
; F = DDB ADDRESS IF T1 IS NOT NEGATIVE
; J = JOB NUMBER
; P1 = ADDRESS OF PROGRAM INTERRUPT TABLE
; P3 IS .LT. 0 IF WE ARE IN DDT OR PFH
;
; -OR-
;
; PUSHJ P,SETPNX ;TO CAUSE INTERRUPT TO BE GRANTED WHEN
; ; USER IS ABOUT TO BE STARTED IN USER
; ; MODE.
;
; PUSHJ P,SETPND ;TO CAUSE INTERRUPT TO STAY PENDING TILL DEBRK.
; ; OR PISYS. WHICH ENABLES PI SYSTEM
; RETURN HERE
;
SETPNX: PUSHJ P,PSIWAK ;WAKEUP JOB
TDZA T4,T4 ;SET T4=0 AS A FLAG
SETPND: SETOM T4 ;SET T4=-1 AS A FLAG
MOVE T2,T1
JUMPGE T1,SETPN1 ;TRANSFER IF DEVICE
MOVSI T2,(1B0)
LSH T2,(T1) ;POSITION BIT
MOVEI T3,PITDFR(P1) ;GET MASK OF PENDING INTERRUPTS
SKIPA
SETPN1: MOVEI T3,DEVPSI(F) ;WORD WITH BIT
TDNE T2,(T3) ;ALREADY 1 INTERRUPT PENDING?
POPJ P,0 ;YES--THAT IS PLENTY
IORM T2,(T3) ;NO--SET THE BIT
SKIPL T3,T1
HRRZ T3,F
AOS T2,PITNPI(P1) ;COUNT UP THE NUMBER OF PENDING
; INTERRUPTS
CAIN T2,1 ;JUST THIS INTERRUPT
MOVEM T3,PITNXT(P1) ;YES--WE MUST BE NEXT
AOJE T4,CPOPJ## ;EXIT IF WE ARE WAITING FOR DEBRK
MOVE T2,[PUSHJ P,UTOUSR] ;YES--GIVE JOBPD1 AFTER UUO AS OLD PC
; IN CASE OF AOS
SKIPGE P3 ;IN PAGE FAULT HANDLER OR DDT?
HRRI T2,PFHTRP ;YES--WAIT TILL EXIT FROM PFH OR DDT
MOVEM T2,PITINS(P1) ; TO CATCH USER ON UUO EXIT
POPJ P,0 ;RETURN
;SUBROUTINE TO SET UP TO CAUSE AN INTERRUPT FOR A NOT-IN-CORE USER
;SAME CALL AS PSISIG
SIGDFR: AOS (P)
PUSHJ P,PSIWAK
JUMPG T1,[IORM T1,DEVPSI(F) ;STORE IN DDB
JRST SGDFR1] ;SETUP PITINS AND EXIT
CAMN T1,[C$WAKE] ;WAKE UUO DONE?
JRST [MOVE T2,.CPJOB##(P4) ;YES--GET CURRENT JOB
MOVEM T2,PITWJB(P1) ;STORE FOR LATER
JRST .+1] ;CONTINUE
MOVSI T2,(1B0) ;SET THE BIT IN DEFERED TRAP MASK
LSH T2,(T1) ; ..
IORM T2,PITDFR(P1) ; ..
SGDFR1: HLRZ T2,PITINS(P1) ;PICKUP INSTRUCTION TO EXECUTE
CAIE T2,(JFCL) ;SKIP IF AVAIL TO US.
POPJ P,0
MOVE T2,[PUSHJ P,DFRINT] ;SET UP TO TRAP ON
MOVEM T2,PITINS(P1) ; SWAP IN
POPJ P,0 ;RETURN-DO NOT STORE AT (M)
;SUBROUTINE CALLED BY ERRCON AFTER PRINTING AN ERROR MESSAGE
;CALL WITH:
; J = JOB #
; PUSHJ P,PSIERR
; RETURN HERE TO STOP JOB
; RETURN HERE TO CONTINUE JOB (INTERRUPT SETUP)
;
PSIERR::SKIPGE T1,JBTPIA##(J) ;IS THIS GUY ENABLED FOR PSI TRAPS
SKIPL PITIPC(T1) ; AND IS THERE AN ERROR TRAP WAITING
JRST CPOPJ2## ;NO--STOP HIM
HRRZS PITIPC(T1) ;CLEAR FLAG
SKIPN PITNXT(T1) ;SHOULD BE SOMETHING PENDING
JRST CPOPJ2## ;NO--JUST RETURN
HRRZ T1,P
CAMLE T1,LOCORE##
AOS (P)
POPJ P,
;SUBROUTINE TO CHANGE THE USER'S PC AND RESTART HIM AT THE NEW PC
;CALL WITH:
; PUSHJ P,TOUSER ;AT UUO EXIT OR FROM CHAN 7
; -OR-
; PUSHJ P,TOUSR1 ;FROM SIGNAL IF NO UUO IN PROGRESS
; -OR-
; PUSHJ P,UTOUSR ;ON DEBRK OR PISYS
;
PFHTRP: HRRZ T1,(P) ;GET SAVED PC
SKIPGE P1,JBTPIA##(J) ;SETUP ADDRESS OF PIT
CAIE T1,UUOPSI## ;FROM UUO EXIT?
POPJ P,0 ;NO--PUNT
UTOUSR: PUSHJ P,SAVE2## ;PROTECT P2 FOR PISYS CALL
MOVE P1,JBTPIA##(J) ;GET ADDRESS OF PI TABLE
SKIPE PITCIB(P1) ;ANY INTERRUPT IN PROGRESS
POPJ P,0 ;YES -- WEIRD RACE CONDITION
SKIPL T1,PITNXT(P1) ;CONDITION CAUSED BY PISYS OR DEBRK
HRRZ F,T1 ;DEVICE -- SETUP ACCUMULATOR F
PUSHJ P,BLKADR ;SETUP M
POPJ P, ;ILLEGAL ADDRESS
PUSHJ P,CPUCDB## ;GET CDB ADDRESS
MOVE T3,JOBPD1##(R) ;GET OLD PC
HRRZ T1,-3(P) ;PICK UP SAVED PC
CAIN T1,CIPPSI## ;FROM CIPXIT
MOVE T3,.CPPC##(P4) ;YES--MAKE PC CORRECT
PUSH P,T3
MOVE T2,T3 ;GET OLD PC
PUSHJ P,ISPFH ;IN USERS PAGE FAULT HANDLER
JRST TPOPJ ;YES--WAIT TILL DONE
POP P,T3 ;GET RETURN PC FOR UUO
IFN FTVM,<
CAMN T3,[IC.UOU+TIMFLT##]
MOVE T3,.UPMP+.UPTMC
>
EXCTUU <MOVEM T3,IBKOPC(M)> ;STORE AS OLD PC FOR THIS TRAP
SKIPL P1,JBTPIA##(J) ;LOAD ADDRESS OF PI TABLE
POPJ P,0 ;SHOULD NEVER HAPPEN
SKIPL T1,PITNXT(P1) ;GET TRAP NAME
HRRZ F,T1 ;DEVICE COPY DDB ADDRESS
PUSH P,T1 ;SAVE CONDITION NAME
PUSHJ P,CLRPND ;NO LONGER PENDING
POP P,T1 ;RESTORE CONDITION NAME
PUSHJ P,BLKADR ;GET ADDRESS OF BLOCK
POPJ P,0 ;INVALID ADDRESS
HLL P2,JOBPC##(R) ;PICK UP FLAGS
CAMN J,.CPJOB##(P4) ;IS THIS THE CURRENT JOB?
HLL P2,.CPPC##(P4) ;YES--GET CURRENT FLAGS
JRST TOUSR2 ;SKIP SETUP OF P4
;MERGE IN HERE IF JOB WAS IN USER MODE WHEN CONDITION HAPPENED
TOUSR1: EXCTUU <MOVEM P2,IBKOPC(M)> ;STORE OLD PC
PUSHJ P,CPUCDB## ;SET UP P4
TOUSR2: EXCTUU <MOVE T2,IBKNPC(M)> ;GET THE NEW PC
TLNN P2,(XC.UIO) ;IS HE IN USER IOT MODE NOW?
TLZ T2,(XC.UIO) ;NO--DO NOT ALLOW USER TO SET IT
TLNE P2,(XC.PUB) ;LAST INSTRUCTION PUBLIC
TLO T2,(XC.PUB) ;YES--FORCE PUBLIC
TLO T2,USRMOD ;PUT HIM IN USER MODE
TLZ T2,37 ;CLEAR INDEX AND INDIRECT
CAMN J,.CPJOB##(P4) ;IS THIS THE CURRENT JOB?
MOVEM T2,.CPPC##(P4) ;YES--SAVE THE NEW PC
MOVEM T2,JOBPC##(R) ;STORE IN JOB DATA AREA
MOVEM T2,.CPAPC##(P4) ;FOR ADDRESS BREAK
MOVE T3,JOBPD1##(R) ;PICK UP UUO PC
IFN FTVM,<
CAMN T3,[EXP IC.UOU+TIMFLT##] ;IS IT FROM PAGE FAULT?
MOVEM T2,.UPMP+.UPTMC ;YES--UPDATE SAVED PC
> ;END FTVM
TLNE T3,USRMOD ;FROM THE USER
MOVEM T2,JOBPD1##(R) ;YES--STORE NEW PC IN JOBDAT
HRRZ T4,PITIPC(P1) ;GET THE LOCATION OF THE INTERRUPT PC
JUMPE T4,TOUSR3 ;JUMP IF NONE
CAMN P2,(T4) ;IS IT FROM US?
MOVEM T2,(T4) ;YES--ONE MORE PLACE TO PUT THE NEW PC
HLLZS PITIPC(P1) ;CLEAR FLAG
TOUSR3: MOVE T2,[WTMASK+JERR+CNTRLC,,JS.MPE+JS.JDP+JS.APE+JS.DPM+UTRP]
ANDCAM T2,JBTSTS##(J) ;BLAST JBTSTS
MOVSI T3,ICFNOT ;MAKE SURE THIS BIT IS
EXCTUU <IORM T3,IBKICF(M)> ;SET
MOVSI T2,(SI.ON) ;PI ON FLAG
MOVSI T3,ICFOFF ;TURN OFF PI SYSTEM BIT
EXCTUX <TDNE T3,IBKICF(M)> ;IS IT SET?
ANDCAM T2,JBTPIA##(J) ;YES--TURN OFF THE SYSTEM
MOVE T2,JBTPIA##(J) ;ADDRESS OF PI TABLE
HRRM M,PITCIB(T2) ;STORE ADDRESS OF INTERRUPT BLOCK
IFN FTKA10,< ;KA10?
MOVE T3,M ;COPY ADDRESS
HRRZ T2,JBTADR##(J) ;GET RELOCATION
SUBI T3,(T2) ;UNRELOCATE
HRRM T3,PITCIB(P1)
> ;END FTKI10
POPJ P,0 ;RETURN
;SUBROUTINE TO CLEAR A PENDING INTERRUPT. THIS SUBROUTINE IS
; CALLED BY ANYONE WHO WANT TO MAKE A PENDING INTERRUPT
; GO AWAY. THIS MUST BE THE ONLY ROUTINE TO CLEAR PENDING INTERRUPTS.
;CALLED WITH:
; T1 = DEVICE OR CONDITION
; F = ADDRESS OF DDB IF T1 IS DEVICE
; P1 = ADDRESS OF PROGRAM INTERRUPT TABLE
; PUSHJ P,CLRPND
; RETURN HERE
CLRPND: HLRE T2,T1 ;STANDARD TEST FOR CONDITION OR DEVICE
AOJE T2,CLPND1 ;JUMP IF CONDITION
HRRZ T2,DEVPSI(F) ;PENDING INTERRUPT BIT
JUMPE T2,CPOPJ## ;NOTHING PENDING CALLER IS CONFUSED
ANDCAM T2,DEVPSI(F) ;CLEAR THE BIT
HRRZ F,F ;MAKE SURE LH OF F = 0
CAMN F,PITNXT(P1) ;WAS THIS TO BE NEXT INTERRUPT?
SETZM PITNXT(P1) ;YES--IS NOT ANY MORE
JRST CLPND2 ;FINISH UP
CLPND1: MOVSI T2,(1B0) ;GET BIT IN CORRECT
LSH T2,(T1) ; POSITION
CAMN T1,[C$QUE]
SETZM PITENQ(P1)
TDNN T2,PITDFR(P1) ;IS THE BIT SET?
POPJ P,0 ;NO--DO NOT TRY TO CLEAR IT
ANDCAM T2,PITDFR(P1) ;CLEAR THE BIT
CAMN T1,PITNXT(P1) ;WAS THIS TO BE NEXT INTERRUPT?
SETZM PITNXT(P1) ;YES--CLEAR SINCE NO LONGER NEXT
CLPND2: MOVSI T2,(JFCL) ;CLEAR THE TRAP INSTRUCTION
MOVEM T2,PITINS(P1) ; ..
SOSLE PITNPI(P1) ;ONE LESS PENDING INTERRUPT
SKIPE PITNXT(P1) ;SEE IF SOMETHING NEXT
POPJ P,0 ;NO MORE PENDING INTERRUPTS OR THIS
; INTERRUPT NOT NEXT.
;HERE TO FIND INTERRUPT WE WANT TO GRANT NEXT.
MOVE T1,PITDFR(P1) ;GET MASK OF PENDING INTERRUPTS
JFFO T1,CLRPN5 ;JUMP IF A CONDITION IS PENDING
PUSH P,F ;SAVE F
HLRZ F,DEVLST## ;POINT TO FIRST DDB
CLRPN3: HRRZ T1,DEVPSI(F) ;SKIP IF INTERRUPT PENDING FOR THIS DDB
JUMPE T1,CLRPN4 ;ELSE LOOK AT NEXT DDB
LDB T1,PJOBN## ;GET JOB NUMBER OF OWNER
MOVEM F,PITNXT(P1) ;SAVE AS NEXT INTERRUPT
CAMN T1,J ;FOR THIS JOB?
JRST FPOPJ## ;YES--ALL DONE--RESTORE F AND RETURN
CLRPN4: HLRZ F,DEVSER(F) ;STEP TO THE NEXT DDB
JUMPN F,CLRPN3 ;LOOK AT NEXT DDB
;HERE IF THE COUNT OF PENDING INTERRUPTS IS TO HIGH. WHILE A STOPCD COULD
; BE USED HERE WE WILL JUST DECREMENT THE COUNT AND RETURN
SOS PITNPI(P1)
JRST FPOPJ## ;RESTORE F AND RETURN
;HERE IF A NON-I/O CONDITION IS PENDING
CLRPN5: MOVNM T2,PITNXT(P1) ;STORE NEGATIVE CONDITION NUMBER
POPJ P,0 ;RETURN
SUBTTL MISC. SUBROUTINES
;SUBROUTINE TO FIGURE OUT OLD PC ON A CONTROL-C
;CALL WITH:
; PUSHJ P,CTLCPC
; RETURN HERE PC IN T2
CTLCPC: LDB T2,PJBSTS## ;GET WAIT STATE
CAIN T2,TIOWQ## ;IN TTY IO WAIT
SKIPA T2,JOBPD1##(R) ;YES--GET UUO PC
GJOBPC ;NO--GET CURRENT PC
POPJ P,0 ;RETURN
PSIWAK: PUSH P,T1
PUSHJ P,WAKEJB##
JRST TPOPJ##
;SUBROUTINE TO SEE IF A USER IS ENABLED FOR AN INTERRUPT
;CALL WITH:
; HRREI T1,C$????
; PUSHJ P,PSITST
; HERE IF NOT ENABLED
; HERE IF ENABLED
;
; -OR-
;
; MOVEI T1,DEVICE-BITS
; MOVE F,DDB-ADDRESS
; PUSHJ P,PSITST
; HERE IF NOT ENABLED
; HERE IF ENABLED
;
;
;USES T2 AND T3 MAY BE CALLED FOR ANY USER AT ANY TIME
;
PSITST::PUSHJ P,SAVE1## ;SAVE P1
SKIPN P1,JBTPIA##(J) ;PIINI. UUO DONE?
POPJ P,0 ;NO--NOT ENABLED
SKIPN JBTADR##(J)
JRST CPOPJ1##
PUSH P,U ;SAVE U FOR OUTSIDE WORLD
PUSHJ P,CNDPTR ;GET POINTER FOR CONDITION
LDB U,U ;GET BYTE OFFSET
JUMPN U,UPOPJ1## ;JUMP IF ENABLED FOR THE CONDITION
JRST UPOPJ## ;NOT ENABLED
;SUBROUTINE TO SET UP M WITH ADDRESS OF INTERRUPT BLOCK
;CALL WITH:
; MOVE T1,CONDITION OR DEVICE
; PUSHJ P,BLKADR
; RETURN HERE IF ADDRESS IS NO GOOD
; RETURN HERE WITH M SETUP
;
BLKADR: PUSH P,U ;SAVE U
PUSHJ P,CNDPTR ;GET POINTER FOR CONDITION
LDB U,U ;GET OFFSET
JUMPE U,UPOPJ## ;ZERO IS INVALID
SUBI U,1 ;ACCOUNT FOR ADDI IN ADDDEV
LSH U,2 ;CONVERT TO WORD ADDRESS
ADD U,PITIVA(P1) ;ADD IN BASE OF VECTOR
HRR M,U
PUSH P,F ;F MIGHT GET ZAPPED
PUSHJ P,BLKCHK ;CHECK THE INTERRUPT BLOCK
JRST FUPOPJ## ;BAD ADDRESS
IFN FTKI10!FTKL10,<
JRST FUPOJ1## ;GOOD RETURN IF KI OR KL
>
IFN FTKA10,<
HRRZ U,JBTADR##(J) ;ADDRESS OF JOB
ADDI M,(U) ;RELOCATE
JRST FUPOJ1## ;GOOD ADDRESS
>
;SUBROUTINE TO TEST AN INTERRUPT BLOCK POINTED TO BY M AND STOP JOB IF
; ANY ADDRESS CHECKS
;CALL WITH:
; M = ADDRESS OF BLOCK
; T1 = NEGATIVE CONDITION OR POSITIVE ANYTHING
; F = DDB ADDRESS IF ANY
; PUSHJ P,BLKCHK
; RETURN HERE IF NO GOOD
; RETURN HERE IF GOOD
;
BLKCHK: PUSHJ P,VCTSTS ;BLOCK OK?
JRST CPOPJ1## ;YES, BLOCK IS BEAUTIFUL
PUSH P,M ;SAVE ASCII STRING,,VECTOR ADDRESS
SKIPL T1 ;SKIP IF CONDITION
MOVEI T1,(F) ;NO CONDITION, GET DDB ADDRESS
PUSH P,T1 ;AND SAVE IT
MOVSI T1,JERR ;CAN'T CONTINUE BIT
IORM T1,JBTSTS##(J) ;WILL PREVENT ANY ATTEMPT TO TRAP
PUSHJ P,GIVRES## ;PLAY IT SAFE AND GIVE UP RESOURCES
JSP T1,ERRPNT## ;START ERROR MESSAGE
ASCIZ/PSI interrupt vector at /
HRRZ T1,-3(P) ;ERRPNT PUSHED F AND U
PUSHJ P,PRTDI8## ;PRINT ADDRESS THAT WE COULDN'T GET
SKIPL T2,-2(P) ;SKIP IF CONDTION
JRST BLKCK1 ;DEVICE, USE NAME
ROT T2,-1 ;DIVIDE BY TWO TO GET TABLE ADDR
SKIPGE T2 ;LH OR RH ENTRY?
SKIPA T2,PSISBT(T2) ;LH
MOVS T2,PSISBT(T2) ;RH
TRZA T2,-1 ;CLEAR OUT UNUSED HALF
BLKCK1: SKIPA T2,DEVNAM(T2) ;GET SIXBIT NAME INSTEAD
SKIPA T1,[[ASCIZ/ for condition /]]
MOVEI T1,[ASCIZ/ for device /]
PUSHJ P,CONMES## ;EXPLAIN REASON
PUSHJ P,PRNAME## ;TYPE SIXBIT (CONMES DIDN'T HURT T2)
HLRZ T1,-3(P) ;ADDRESS OF FINAL STRING
PUSHJ P,CONMES## ;FIX
SUB P,[2,,2] ;REMOVE F AND U FROM STACK
JRST PCSTOP## ;WON'T RETURN UNLESS AT INTERRUPT LEVEL.
; IN THAT CASE, IT WILL POP THE LAST
; TWO LOCATIONS ON THE STACK (WHICH
; ARE NOW JUNK) AND POPJ, GIVING THE
; ERROR RETURN BACK TO BLKADR.
;SIXBIT TABLE OF ABBREVIATIONS FOR ERROR CONDTIONS
;USED IF USER'S JOB STOPPED DUE TO ERROR
'NTC',,0 ;(-27) NTWRK TOPOLOGY (-30)
'RMC',,'QUE' ;(-25) REMOTE COMPUTER (-26) ENQ/DEQ
'ABK',,'IPC' ;(-23) ADR BREAK (-24) IPCF
'DAT',,'WAK' ;(-21) DET/ATTACH (-22) WAKE UUO
'KSY',,'DSC' ;(-17) KSYS WARNING (-20) DATASET STATUS
'UEJ',,'XEJ' ;(-15) USER ERROR (-16) EXTERNAL ERROR
'NXM',,'APC' ;(-13) NXM (-14) CLOCK TICK
'PDL',,0 ;(-11) PDL OV (-12) TRAP TYPE 3
'ACK',,'ARI' ;(- 7) ADR CHECK (-10) ARITHMETIC EXC
'ILU',,'IMR' ;(- 5) ILL UUO (- 6) ILL MEM REF
'STP',,'UUO' ;(- 3) ^C (- 4) ANY UUO
'TLE',,0 ;(- 1) TIME LIMIT (- 2) ^A
PSISBT:
;SUBROUTINE CALLED BY BLKCHK TO CHECK LEGALITY OF INTERRUPT BLOCK
; PUSHJ P,VCTSTS
; RETURN HERE IF EVERYTHING IS FINE
; RETURN HERE IF SOMETHING BAD, ASCII ADDR IN LH OF M
;TEMPORARY AC'S PRESERVED
VCTSTS: PUSHJ P,SAVT## ;SAVE TEMP AC'S
MOVEI T1,(M) ;COPY ADDRESS OF BLOCK
SETO T3, ;T3 COUNTS LOOPS, WANT TO LOOP TWICE
VCTST1: HLRZ T2,JBTADR##(J) ;GET HIGH LEGAL ADDRESS
CAIG T1,(T2) ;TOO BIG?
CAIG T1,JOBPFI## ;OR TOO SMALL?
JRST VCTST2 ;YES, INT BLOCK IS AT ILLEGAL ADDRESS
IFN FTVM,<
MOVEI T4,(T1) ;GET ADDRESS IN T4
LSH T4,W2PLSH## ;MAKE A PAGE ADDRESS
PUSHJ P,GTPM4## ;GET PAGE MAP ENTRY IN T4
JUMPE T4,VCTST2 ;IF NONE, ILLEGAL ADDRESS
PUSHJ P,FLTST## ;PAGE EXISTS, IS IT IN CORE?
JRST VCTST3 ;NO, PAGED OUT!
>
ADDI T1,3 ;POINT TO END OF BLOCK
AOJE T3,VCTST1 ;HAVE TO CHECK BOTH ENDS
POPJ P, ;HE PASSED CHECKS, GOOD RETURN
VCTST2: HRLI M,[ASCIZ/ illegal/]
JRST CPOPJ1## ;BAD RETURN
IFN FTVM,<
VCTST3: HRLI M,[ASCIZ/ paged out/]
JRST CPOPJ1## ;BAD RETURN
>
;SUBROUTINE TO SEE IF USER IS IN PFH OR DDT
;CALL WITH:
; T2 = PC
; PUSHJ P,ISPFH
; HERE IF IN PFH OR DDT
; HERE IF NOT
;
; RESPECTS ALL AC'S EXCEPT T3
;
ISPFH: IFN FTVM,< ;IF THIS IS A VM MONITOR
PUSHJ P,INPFH## ;SEE IF WE ARE IN PFH
POPJ P,0 ;YES--INDICATE THAT
> ;END FTVM
HRRZ T3,JOBDDT##(R) ;GET START OF DDT
SKIPE JOBDDT##(R) ;DDT LOADED?
CAIL T3,(T2) ;ABOVE START OF DDT?
JRST CPOPJ1## ;NO--ALL IS WELL
HLRZ T3,JOBDDT##(R) ;GET END OF DDT
CAIG T3,(T2) ;ABOVE END?
AOS (P) ;YES--NOT IN DDT
POPJ P,0 ;IN DDT
;SUBROUTINE TO STORE UDX AND DEVICE STATUS IN INTERRUPT BLOCK
;CALL WITH:
; M = ADDRESS IF INTERRUPT BLOCK
; S = DEVICE STATUS
; F = DDB ADDRESS
; PUSHJ P,PSIUDX
; RETURN HERE STATUS STORED
;
PSIUDX: PUSH P,U
PUSHJ P,IONDF## ;GET I/O INDEX
MOVEI T1,0
HRLZ T1,T1 ;PUT IN LEFT HALT
HRR T1,DEVIOS(F) ;ADD IN DEVICE STATUS
EXCTUU <MOVEM T1,IBKISW(M)> ;STORE FOR USER TO SEE
JRST UPOPJ## ;RETURN
IFN FTVM,<
;SUBROUTINE TO RETURN PITIVA OR ZERO IF NOT PSIING
PSIIVA::SKIPE T1,JBTPIA(J) ;PSIING?
MOVE T1,PITIVA(T1) ;YES
POPJ P,
>
;SUBROUTINE TO BUILD A BYTE POINTER TO THE VECTOR OFFSET BYTE IN
; THE PROGRAM INTERRUPT TABLE OR DDB.
;CALL WITH:
; T1 = CONDITION NUMBER OR DEVICE NAME
; PUSHJ P,CNDPTR
; RETURN HERE POINTER IN U
;
;PRESERVES T1 WIPES T2,T3
;
CNDPTR: MOVE U,PDVIVO## ;ASSUME DEVICE
HLRE T2,T1 ;IF SMALL NEGATIVE NUMBER T2=-1
AOJN T2,CPOPJ## ;RETURN IF DEVICE
MOVM T2,T1 ;GET POSITIVE CONDITION
IDIVI T2,4 ;T2 := WORD AND T3 := QUARTER
MOVE U,CNPTTB(T3) ;GET A GOOD POINTER
ADDI U,(T2) ;ADD IN WORD OFFSET
POPJ P,0 ;RETURN
CNPTTB: POINT 9,PITTAB(P1),8 ;BYTE 0
POINT 9,PITTAB(P1),17 ;BYTE 1
POINT 9,PITTAB(P1),26 ;BYTE 3
POINT 9,PITTAB(P1),35 ;BYTE 4
PSILIT::XLIST ;LITERALS IN PSISER
LIT
PSIEND::LIST ;END OF PSISER
END