Trailing-Edge
-
PDP-10 Archives
-
decuslib10-08
-
43,50512/intr.bli
There are no other files named intr.bli in the archive.
%IF %DECLARED(FTSIG)
%THEN %IF NOT(FTSIG) %THEN %ERROR('INTR.BLI with FTSIG off??') %FI
%ELSE LITERAL FTSIG=1
%FI;
!To trigger conditional compilation
FIELD INT_FIELDS=SET !INTERRUPT block fields
DFF[INT$PISYS,0,0,36,0], !PISYS. block starts here
DFF[INT$WHAT,0,0,36,0], !Device or non-I/O condition
DFF[INT$CONDITION,0,0,36,0], !synonym
DFF[INT$OFFSET,1,18,18,0], !Offset within interrupt vector
DFF[INT$REASONS,1,0,18,0], !Reasons for I/O interrupt, as follows:
DFF[INT$IN_DONE,1,16,1,0], !Input done
DFF[INT$OUT_DONE,1,15,1,0], !Output done
DFF[INT$EOF,1,14,1,0], !End of File
DFF[INT$IN_ERROR,1,13,1,0], !Input Error
DFF[INT$OUT_ERROR,1,12,1,0], !Output Error
DFF[INT$OFFLINE,1,11,1,0], !Device went off-line
DFF[INT$FULL,1,10,1,0], !Device Full
DFF[INT$QUOTA_EX,1,9,1,0], !Quota exceeded
DFF[INT$IO_WAIT,1,8,1,0], !I/O Wait
DFF[INT$ONLINE,1,7,1,0], !Device On-line
!DFF[INT$ZERO,2,0,36,0], !Spare word in PISYS. block MUST BE 0
DFF[INT$PROCESS,3,0,18,0], !Process that owns this interrupt
DFF[INT$NEXT,4,0,18,0], !Next interrupt in chain for process
DFF[INT$S_REASONS,4,18,18,0], !Signal associated condition if these occur
DFF[INT$S_ALWAYS,4,18,1,0], !Signal always
DFF[INT$S_ALLIO,4,25,10,0], !All I/O conditions
DFF[INT$S_IN_DONE,4,34,1,0], !Input done
DFF[INT$S_OUT_DONE,4,33,1,0], !Output done
DFF[INT$S_EOF,4,32,1,0], !End of File
DFF[INT$S_IN_ERROR,4,31,1,0], !Input error
DFF[INT$S_OUT_ERROR,4,30,1,0], !Output error
DFF[INT$S_OFFLINE,4,29,1,0], !Device went offline
DFF[INT$S_FULL,4,28,1,0], !No more room
DFF[INT$S_QUOTA_EX,4,27,1,0], !Quota exceeded
DFF[INT$S_IO_WAIT,4,26,1,0], !I/O wait
DFF[INT$S_ONLINE,4,25,1,0], !Device came online
DFF[INT$PENDING,5,35,1,0], !This block has a pending SIGNAL already
DFF[INT$TEMP,5,34,1,0], !This block is temporary (delete it when done)
DFF[INT$SIGNAL_ARGS,5,0,18,0], !If non-zero, condition to signal
DFF[INT$CODE,6,0,36,0], !First signal argument, fields within follow
DFF[INT$SEVERITY,6,0,3,0], !Warning/Error/Fatal error/Success
DFF[INT$SUCCESS,6,0,1,0], !TRUE bit, success bit
DFF[INT$STSCODE,6,3,22,0], !Status code
DFF[INT$FACCODE,6,25,11,0], !Facility code
DFF[INT$STATUS,7,0,36,0], !Status word from vector block
DFF[INT$PC,8,0,36,0], !PC that interrupt happened at
DFF[INT$REASON,9,0,18,0], !Reason for interrupt (I/O interrupts only)
DFF[INT$R_IN_DONE,9,16,1,0], !Input done
DFF[INT$R_OUT_DONE,9,15,1,0],!Output done
DFF[INT$R_EOF,9,14,1,0], !End of File
DFF[INT$R_IN_ERROR,9,13,1,0],!Input Error
DFF[INT$R_OUT_ERROR,9,12,1,0],!Output Error
DFF[INT$R_OFFLINE,9,11,1,0], !Device went off-line
DFF[INT$R_FULL,9,10,1,0], !Device Full
DFF[INT$R_QUOTA_EX,9,9,1,0], !Quota exceeded
DFF[INT$R_IO_WAIT,9,8,1,0], !I/O Wait
DFF[INT$R_ONLINE,9,7,1,0], !Device On-line
DFF[INT$FILBLK,9,18,18,0] !File block for device
TES;
LITERAL INT_LEN=10; !Minimum length of interrupt block
MACRO INT_BLOCK=BLOCK[INT_LEN] FIELD(INT_FIELDS) %;
FIELD INTVEC_FIELDS=SET !Fields in the interrupt vector blocks
DFF[INTVEC$NEWPC,0,0,36,0], !Usually points to [CALL INTSIG(INTBLK)]
DFF[INTVEC$OLDPC,1,0,36,0], !PC where it happened
DFF[INTVEC$REASON,2,0,18,0],!What kind of I/O condition was it?
DFF[INTVEC$RID,2,16,1,0], !Input done
DFF[INTVEC$ROD,2,15,1,0], !Output done
DFF[INTVEC$IODONE,2,15,2,0], !I/O done (sum of the previous 2)
DFF[INTVEC$REF,2,14,1,0], !End of File
DFF[INTVEC$EOF,2,14,1,0], ! " "
DFF[INTVEC$RIE,2,13,1,0], !Input Error
DFF[INTVEC$ROE,2,12,1,0], !Output Error
DFF[INTVEC$IOERR,2,12,2,0],!I/O Error
DFF[INTVEC$RDO,2,11,1,0], !Device went off-line
DFF[INTVEC$OFFLINE,2,11,1,0],! " "
DFF[INTVEC$RDF,2,10,1,0], !Device Full
DFF[INTVEC$RQE,2,9,1,0], !Quota exceeded
DFF[INTVEC$RWT,2,8,1,0], !I/O Wait
DFF[INTVEC$RON,2,7,1,0], !Device came on-line
DFF[INTVEC$ONLINE,2,7,1,0],! " "
DFF[INTVEC$ERROR,2,9,5,0], !I/O error, dev full or Quota ex or offline
DFF[INTVEC$FLAGS,2,18,18,0],!Control flags as follows
DFF[INTVEC$VPO,2,34,1,0], !Disable all interrupts on interrupt
DFF[INTVEC$VTO,2,33,1,0], !Disable until DEBRK.
DFF[INTVEC$VAI,2,32,1,0], !Don't disable even this block (do not set)
DFF[INTVEC$VDS,2,31,1,0], !Dismiss additional interrupts
DFF[INTVEC$VPM,2,30,1,0], !Print standard message if any
DFF[INTVEC$VIP,2,29,1,0], !Interrupt in progress (clear on restart)
DFF[INTVEC$STATUS,3,0,36,0] !Status word
TES;
STRUCTURE INTVECSTR[I,O,P,S,E;N]=
[N*4]
(INTVECSTR+I+O)<P,S,E>;
MACRO IOWAIT(INT,COND)=
BEGIN
MAP INT: REF INT_BLOCK;
INT[INT$S_ALWAYS]=-1; !Set all the error signal bits
INT[%NAME(INT$S_,COND)]=0; !If it wasn't what we're waiting for,error.
WAIT(.INT)
END%;
MACRO BUILD_LIST (ARGLST)[ARG]=ARGLST[%COUNT]=ARG %;
MACRO COND_LST=FREG<18,18> %; !LH of FREG
MACRO ESTABLISH(RTN)= !Must be before first executable statement!!
STACKLOCAL ARGLST: VECTOR[%LENGTH+1];
BUILD_LIST (ARGLST,RTN,%LENGTH-1,%REMAINING);
COND_LST=ARGLST; !Handler now established
% ;
MACRO INTERRUPTS(FLAGS,BLOCK)=PISYS(%NAME(PISYSF_,FLAGS),BLOCK) %;
LITERAL
PISYSF_OFF=%O'200000',
PISYSF_ON=%O'100000',
PISYSF_CLEAR=%O'40000',
PISYSF_CLEARDEV=%O'20000',
PISYSF_REMOVE=%O'10000',
PISYSF_ADD=%O'4000',
PISYSF_ON_ADD=%O'104000', !Turn on & add device
PISYSF_REMOVEC=PISYSF_REMOVE+PISYSF_CLEARDEV;
!Field defs for SIGNAL_ARGS
FIELD SA_FIELDS=
SET
DFF[SA$LENGTH,FIRSTWORD,WRD], !Length of argument block
DFF[SA$CODE,NEXTWORD,WRD], !Condition code
DFF[SA$SEVERITY,THISWORD,SEVERITY], !Severity field
DFF[SA$STSCODE,THISWORD,STSCODE], !code describing error
DFF[SA$FACCODE,THISWORD,FACCODE], !Facility code
DFF[SA$STATUS,NEXTWORD,WRD], !Status info from interrupt
DFF[SA$FORK,THISWORD,WRD], !Fork that is aborting
DFF[SA$FB,THISWORD,WRD], !FILE BLOCK FOR errors but not interrupts
DFF[SA$PC,NEXTWORD,WRD], !PC from interrupt
DFF[SA$QUIT_CODE,THISWORD,WRD], !abort code as follows
DFF[SA$QUIT_STSCODE,THISWORD,STSCODE], !Reason process aborted
DFF[SA$QUIT_SEVERIT,THISWORD,SEVERITY], !Severity indicator
DFF[SA$QUIT_FACCODE,THISWORD,FACCODE], !Facility code
DFF[SA$REASON,NEXTWORD,RH], !Reason for interrupt
DFF[SA$IN_DONE,THISWORD,16,1,0], !Input done
DFF[SA$OUT_DONE,THISWORD,15,1,0], !Output done
DFF[SA$EOF,THISWORD,14,1,0], !End of File
DFF[SA$IN_ERROR,THISWORD,13,1,0], !Input Error
DFF[SA$OUT_ERROR,THISWORD,12,1,0], !Output Error
DFF[SA$OFFLINE,THISWORD,11,1,0], !Device went off-line
DFF[SA$FULL,THISWORD,10,1,0], !Device Full
DFF[SA$QUOTA_EX,THISWORD,9,1,0], !Quota exceeded
DFF[SA$IO_WAIT,THISWORD,8,1,0], !I/O Wait
DFF[SA$ONLINE,THISWORD,7,1,0], !Device On-line
DFF[SA$FILBLK,THISWORD,LH] !File block for interrupts
TES;
LITERAL !Offsets for SIGNAL_ARGS
SA_LENGTH=0, !Length of argument block
SA_CODE=1, !What happened
SA_STATUS=2,
SA_PC=3,
SA_REASON=4;
LITERAL !Offsets for MECHANISM_ARGS
MA_LENGTH=0,
MA_FRAME=1,
MA_DEPTH=2,
MA_VREG=4,
MA_T2=5,
MA_T3=6,
MA_T4=7,
MA_T5=8,
MECH_ARGS_LEN=8;
MACRO $CODE= BLOCK[.SIGNAL_ARGS,SA$STSCODE]%,
$SEVERITY=BLOCK[.SIGNAL_ARGS,SA$SEVERITY]%,
$FACCODE=BLOCK[.SIGNAL_ARGS,SA$FACCODE]%;
MACRO SIGNAL[]=
BEGIN
%IF NOT %DECLARED (%NAME('.SIGNL')) %THEN EXTERNAL %NAME('.SIGNL'); %FI
LOCAL SIGNAL_ARGS: VECTOR[%LENGTH+1];
BUILD_LIST(SIGNAL_ARGS,%LENGTH,%REMAINING);
%NAME('.SIGNL')(SIGNAL_ARGS);
END;
%;
LITERAL SS$_CONTINUE=1; !Handler wants to continue
LITERAL SS$_RESIGNAL=0; !Handler passes the buck
LITERAL SS$_UNWIND=8; !Facility code for UNWIND condition
!Process block offsets
FIELD PROCESS_FIELDS=SET
DFF[P$NEXT,0,0,18,0], !Next process to run
DFF[P$LINK,0,18,18,0], !Next process at this level or 0
DFF[P$STKL,1,18,18,0], !Length of stack
DFF[P$STK,1,0,18,0], !Address of stack
DFF[P$WAIT,2,0,36,0], !If non-zero, what process is waiting for
DFF[P$INTERRUPTS,3,0,18,0], !Head of signal chain for process
DFF[P$FREE,3,18,18,0], !How much storage to free when cleaning up
DFF[P$SUPERIOR,4,0,18,0], !Process who created this one
DFF[P$INFERIORS,4,18,18,0], !Pointer to linked list of inferiors
DFF[P$NAME,5,0,36,0], !Name of process
DFF[P$NDB,6,0,18,0], !NDB for process, if any
DFF[P$DISPLAY,6,18,18,0] !Routine to call to display more stuff
TES;
LITERAL P_LEN=7;
MACRO PROCESS_BLOCK=BLOCK[P_LEN] FIELD(PROCESS_FIELDS) %;
%(
FIELD STACK_FIELDS=SET
DFF[S$SREG,3,0,36,0], !Stored SREG
DFF[S$FREE,17,0,36,0] !First free location on stack
TES;
MACRO STACK=BLOCK[STACK_LENGTH] FIELD(STACK_FIELDS) %;
)%
LITERAL STACK_LENGTH=1024;
MACRO FORK(RTN)[]=
BEGIN
LOCAL V: REF PROCESS_BLOCK;
EXTERNAL ROUTINE CPROC;
LOCAL ARGLST: VECTOR[%LENGTH];
BUILD_LIST(ARGLST,%LENGTH-1,%REMAINING); !Build argument list
V=CPROC(RTN,ARGLST,STACK_LENGTH);
V[P$NAME]=%SIXBIT %STRING(RTN);
.V
END%;
MACRO WAKESET(IB)[REASON]=IB[%NAME(INT$,REASON)]=1%,
ERRSET(IB)[REASON]=IB[%NAME(INT$,REASON)]=IB[%NAME(INT$S_,REASON)]=1%;
MACRO NOINTS[]= BEGIN
LOCAL NOINTS_VAL; !Value of block
EXTERNAL INTENC;
INTERRUPTS(OFF);
INTENC=.INTENC+1;
NOINTS_VAL=(%REMAINING);
IF (INTENC=.INTENC-1) LEQ 0 THEN
INTERRUPTS(ON);
.NOINTS_VAL
END%;
!System-dependant macro to represent name of process
MACRO PNAME(NAM)=%SIXBIT %STRING(NAM) %;