Trailing-Edge
-
PDP-10 Archives
-
decuslib10-08
-
43,50512/intsig.b36
There are no other files named intsig.b36 in the archive.
MODULE INTSIG=
!Code to pass a software interrupt to a process in NETSPL
!FACILITY: NETSPL
!ENVIRONMENT: TOPS-10 only
!SPECIAL INSTRUCTIONS: DO NOT COMPILE WITH /DEBUG!!!
BEGIN
%IF %SWITCHES(DEBUG) %THEN %WARN('INTSIG compiled with /DEBUG') %FI
COMPILETIME FTDEBUG=(%VARIANT AND %O'1000') NEQ 0;
COMPILETIME FTINTOFF=(%VARIANT AND %O'200') NEQ 0;
FORWARD ROUTINE
INTSIG; !Inform a process of the occurrance of an interrupt of interest to it
REQUIRE 'INTR.REQ'; !Interrupt processing stuff
! this also REQUIREs TBL
THIS_IS[INTS] VERSION [1] EDIT [3] DATE [4,APR,78]
%( R E V I S I O N H I S T O R Y
[3] Put in some defensive and/or debugging code for possible PSISER problems
[2] Use WAKE routine
[1] Separate INTSIG from INT so INT can compile /DEBUG
END R E V I S I O N H I S T O R Y )%
EXTERNAL ROUTINE
INTCOPY,!Make copy of int block
WAKE; !Put a process on the RUNlist
GLOBAL ROUTINE INTSIG(INT)=
!Routine to find the process to handle an interrupt and signal it
!Argument:
!INT: Interrupt block. (INT[INT$PROCESS] contains process to bother)
BEGIN
LOCAL SAVE_TEMPS: VECTOR[4];
EXTERNAL RUN: REF PROCESS_BLOCK; !Running process
SAVE_TEMPS[0]=.VREG;
SAVE_TEMPS[1]=.T2;
SAVE_TEMPS[2]=.T3;
SAVE_TEMPS[3]=.T4;
BEGIN
MAP INT: REF INT_BLOCK;
BIND IFORK=.INT[INT$PROCESS]: PROCESS_BLOCK;
LOCAL I;
%IF FTDEBUG %THEN
BEGIN
IF .INT LSS 140
THEN BEGIN
TYPE('%NETISI Ignoring spurious interrupt',CRLF);
RETURN
END;
IF IFORK LSS 140
THEN BEGIN
TYPE('%NETIPB Invalid process block',CRLF);
RETURN
END;
END %FI;
I=.INT[INT$OFFSET]; !Offset in interrupt vector
IF ((.INT[INT$STSCODE] NEQ 0) AND
(.INT[INT$SALWAYS] OR (.INT[INT$SREASONS] EQL 0) OR
((.INT[INT$S_REASONS] AND .INTVEC[.I,INTVEC$REASON]) NEQ 0)))
THEN BEGIN
!First see if the block is in use
IF .INT[INT$PENDING] THEN
INT=INTCOPY(.INT); !It was so copy it
!We have to signal something
!First save the PC & status info for the interrupt
!from the 4-word block PSISER puts the info in
INT[INT$PC]=.INTVEC[.I,INTVEC$OLDPC];
INT[INT$REASON]=.INTVEC[.I,INTVEC$REASON];
INT[INT$STATUS]=.INTVEC[.I,INTVEC$STATUS];
IF IFORK NEQ .RUN
THEN BEGIN
FSIGNL(IFORK,.INT) !Force it for process
!Since it was not the running process, we just
!give it a signal when it runs next
END
ELSE BEGIN
%IF FTINTOFF %THEN
CRASH('Interrupt to running process');
%FI
%NAME('.SIGNL')(INT[INT$SIGNAL_ARGS])
!If it was the running process then signal it
END;
END
ELSE IFORK[P$WAIT]=0; !Must have been a wait
WAKE(IFORK); !Put this on the runlist
!See if we have to signal a condition somewhere
INTVEC[.I,INTVEC$REASON]=0; !Zero out reason bits (noone else will)
END;
T2=.SAVE_TEMPS[1];
T3=.SAVE_TEMPS[2];
T4=.SAVE_TEMPS[3];
.SAVE_TEMPS[0]
END;
END ELUDOM