Google
 

Trailing-Edge - PDP-10 Archives - BB-R775E-BM - sources/dil/xpnpsi.mac
There are 26 other files named xpnpsi.mac in the archive. Click here to see a list.
;<LCAMPBELL.BLSNET>XPNPSI.MAC.2 11-Feb-82 20:11:10, Edit by LCAMPBELL
; Converted to modern (BLISS-36) calling conventions.
;<LCAMPBELL.BLSNET>BLSPS2.MAC.12 11-Feb-82 19:38:10, Edit by LCAMPBELL
; Majorly hacked, removed most routines except PSIINT, PSISIR, PSIRST, PSIWAI.
;<WEBBER>BLSPSI.MAC 8-May-80 12:30, Edit by WHEELER
;Changed references to .ENT0., .EXT0 to ENT0, EXT0 to correspond to new OTS
;<WEBBER>BLSPSI.MAC.24, 12-Mar-79 14:11, Edit by WEBBER
;Changed WAIT in PSIWAI and PSIRST to DISMS for 50 ms
;<WEBBER>BLSPSI.MAC.19, 22-Feb-79 09:47:52, Edit by GUNN
;Changed table sizes to be decimal 36 from octal 36
;Added code to check for valid channel number in PSIINT
; 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 1986.
; ALL RIGHTS RESERVED.


	TITLE XPNPSI - XPN's interface to software interrupt system
	SEARCH MONSYM,MACSYM
	TWOSEG

	ENTRY PSIINT,PSISIR,PSIWAI,PSIWXX,PSIRST

;This module supplies an interface to the tricky parts of the software
; interrupt system.  Only those functions that cannot be performed in
; BLISS reliably are here (saving/restoring registers, etc.)
;
; Calls:
;	CC = PSIINT( PRIORITY, ROUTINE, CHANNEL);
;	CC = PSISIR( PROCESS_HANDLE);
;	PSIWAI();
;	PSIRST();
;
;	Call PSIINT for each routine that will service an interrupt
; occurring in the specified channel at the specified priority
; level. PSIINT modifies "CHNTAB" so that the routine will be
; invoked on an interrupt.
;	The routine, when entered, will have the channel number on which
; the interrupt is occurring on the stack.  No register except the stack
; pointer need be preserved.
;	Call PSISIR to set up the interrupt system.  PSISIR first checks
; to see if an SIR has already been done;  if so, it uses the already-set-up
; LEVTAB and CHNTAB instead of its own.
;	Call PSIWAI to dismiss the process.  PSIRXX should be stuffed with
; either a WAIT or DISMS JSYS.  Interrupt routines desiring to wake up the
; process should put a JFCL in PSIRXX, in case the interrupt occurs before
; the process about to dismiss calls PSIWAI.
;	Call PSIRST to wake up the dismissed process.  It forces the PC past
; the DISMS or WAIT.

; Register definitions:

SP==17				; Stack pointer
V==1				; Value return register

	RELOC 400000

;Call:	PSIINT(Channel_number,Service_routine,Priority)

PSIINT::PUSH SP,2		; Protect endangered registers
	MOVE 1,-4(SP)		; Get channel
	SKIPN LEVPTR		; Fail if we haven't yet inited tables
	JRST BAD2		;  ..
	SKIPN CHNPTR		;  ..
	JRST BAD2		;  ..
	CAIL 1,0		; Check for valid chan #
	CAILE 1,^D35		; 0 - 35 OK
	JRST BAD2		; Fail on bad chan #
	MOVEI 2,DISPAT		; Get my servicer address
	ADDI 2,(1)		; Add the channel # call is for
	PUSH P,1		; Save channel number
;**; [@@@] Insert at PSIINT + 13 1/2	CLR	4-Jan-83
	HRL	2,-3(P)		;[@@@] Get priority as well as dispatch address
	PUSH P,2		; Save dispatch address
	MOVEI 1,.FHSLF		; See if PA1050 is around to muck things up
	PUSH P,3
	GCVEC			;  ..
	POP P,3
	JUMPLE 2,PSIIN0		; No, thank God, just do simple things
	MOVEI 1,6		; COMPT. function code
	MOVEM 1,COMPTA		; Into arg block
	HRL 1,-4(SP)		; Get level number
	HRR 1,(SP)		; Handler address
	MOVEM 1,COMPTA+1	; Set up COMPT. arg block
	HRRZ 1,-4(SP)		; Get level number again
	ADDI 1,PC1-1		; Get PC save address
	HRL 1,-1(SP)		; Get channel number
	MOVEM 1,COMPTA+2	; Stuff into arg block
	MOVE 1,[3,,COMPTA]	; Length,,address of arg block
	COMPT. 1,		; Shazzam!
	 JFCL			; Who cares ??
	ADJSP P,-1		; Adjust stack
	POP P,1			; Get channel number
	MOVE 2,-3(P)		; Get service routine address
	MOVEM 2,BLSTAB(1)	; Set up dispatch pointer
	POP P,2			; Restore reg 2
	JRST GOOD		; Give good return

PSIIN0:	POP P,2			; Restore handler address
;**; [@@@] Insert at PSIIN0 + 1/2	CLR	3-Jan-83
	SKIPE	XFLAG		;[@@@] Using extended JSYSes?
	 JRST	NOTX		;[@@@] No, skip this
	HRRZ	2,2		;[@@@] Yes, clear left half of CHNTAB entry
	MOVE	1,-3(P)		;[@@@] ... and get the priority
	DPB	1,[POINT 6,2,5]	;[@@@] ... put it into bits 0-5 of entry
NOTX:				;[@@@] Here for non-extended JSYS case
	MOVE 1,CHNPTR		; Get CHNTAB address
	ADD 1,(P)		; Add channel number
	MOVEM 2,(1)		; Store in table for monitor
	POP P,1			; Restore channel number
	MOVE 2,-3(SP)		; Get caller's servicer routine addr
	MOVEM 2,BLSTAB(1)	; Store in table for my servicer
;**; [@@@] Remove three lines at GOOD - 4	CLR	4-Jan-83
;[@@@]	MOVE 2,-2(SP)		; Get priority
;[@@@]	ADD 1,CHNPTR		; Add CHNTAB address to channel number
;[@@@]	HRLM 2,(1)		;  and put priority in table for monitor
	POP SP,2
GOOD:	MOVEI V,1		; Return value is successful
	POPJ SP,


;Call: PSISIR(Process_handle)

PSISIR::PUSH SP,2		; Get a register
	MOVE 1,-2(SP)		; Get process handle
	RIR			; Are LEVTAB and CHNTAB already declared?
;**; [@@@] Insert at PSISIR + 2 1/2	CLR	4-Jan-83
	 ERJMP	[		;[@@@] RIR% lost, better try XRIR%
		MOVEI	2,3		;[@@@] Size of XRIR% block
		MOVEM	2,XBLOCK	;[@@@] ... store it
		MOVEI	2,XBLOCK	;[@@@] Argument block address
		MOVE	1,-2(SP)	;[@@@] Get process handle
		XRIR%			;[@@@] Try XRIR% now
		 ERJMP	BAD		;[@@@] Lose gracelessly
		SETZM	XFLAG		;[@@@] Remember to use extended JSYSes
		MOVE	2,XBLOCK+1	;[@@@] Get level table address
		MOVEM	2,LEVPTR	;[@@@] ... and store it
		MOVE	2,XBLOCK+2	;[@@@] Get channel table address
		MOVEM	2,CHNPTR	;[@@@] ... and store it
		JRST	PSISI0		;[@@@] Join common exit
		]			;[@@@] End of trying XRIR%
	SETOM	XFLAG		;[@@@] Remember not to use extended JSYSes
	SKIPE 2 		; If they are,
	JRST [	HLRZM 2,LEVPTR		; Remember their addresses
		HRRZM 2,CHNPTR		;  ..
		JRST PSISI0]
	MOVEI 2,LEVTAB		; Not already set up, assume we own the world
	MOVEM 2,LEVPTR
	MOVEI 2,CHNTAB
	MOVEM 2,CHNPTR
;**; [@@@] Insert at PSISIR + 10 1/2	CLR	3-Jan-83
	MOVE	1,-2(SP)	;[@@@] Get process handle
	MOVEI	2,3		;[@@@] Size of XSIR% block
	MOVEM	2,XBLOCK	;[@@@] ... store it
	MOVEI	2,LEVTAB	;[@@@] Level table address
	MOVEM	2,XBLOCK+1	;[@@@] ... store it
	MOVEI	2,CHNTAB	;[@@@] Channel table address
	MOVEM	2,XBLOCK+2	;[@@@] ... store it
	XSIR%			;[@@@] Try XSIR% first
	 ERJMP	NOXSIR		;[@@@] ... must be a KS or something
	SETZM	XFLAG		;[@@@] Remember to use extended JSYSes
	JRST	PSISI0		;[@@@] Join common exit
NOXSIR:	MOVE	1,-2(SP)	;[@@@] Get process handle
	SETOM	XFLAG		;[@@@] Remember to not use extended JSYSes
	MOVE 2,[LEVTAB,,CHNTAB]
	SIR
	 ERJMP BAD2
PSISI0:	POP SP,2
	JRST GOOD

BAD2:	POP SP,2
BAD:	SETZM V			; 0 = FAILURE
	POPJ SP,

;This routine is called (via PUSHJ SP,) when an interrupt occurs

HANDLR:	AOS PTR			; In case i get interrupted here
	POP SP,@PTR		; Save entry address
	HRRZS @PTR		;   (minus flags)
	PUSH SP,16		; Get a work register
	MOVEI 16,15		; Set up to save all registers
	PUSH SP,(16)		; Preserve register on stack
	SOJGE 16,.-1		; and again... until AC0 has been...
	MOVE 1,@PTR		; Subtract entry vector base address
	SUBI 1,DISPAT+1		;   from actual entry address
	PUSH  SP,1		; Put channel # on the stack
	PUSHJ SP,@BLSTAB(1)	; Call user's BLISS routine
	POP  SP,1		; Get channel # off of stack
	SETZM 16		; Prepare to pop all register
	POP  SP,(16)		; Restore AC
	AOS 16			; Get next AC
	CAIE 16,16		; Restored AC15 yet?
	JRST .-3		; No - go pop again
	POP  SP,16		; Now restore AC16
	SOS PTR			; Restore 'frame' of entry vector
	DEBRK			; Return to interrupted routine

; Call: PSIWAI();
;     - Suspends process.  Caller must set up PSIWXX to either WAIT
;	or DISMS (this because interrupt routine will change it to JFCL
;	to prevent fast interrupts from causing infinite sleep).

PSIWAI::MOVE 1,-1(SP)		;Get wait time
	JRST PSIWXX		;Go to low seg

	RELOC
PSIWXX::HALT			;set up by caller
	 JFCL
	JRST GOOD		;Return to caller
	RELOC

; Call: PSIRST();
;     - Called from an interrupt routine, resumes the suspended process if
;	it is at a WAIT.

PSIRST::PUSH SP,2		; Protect the registers
	MOVE 1,@PTR		; Calculate the
	SUBI 1,DISPAT+1		;   channel number
	MOVE 2,CHNPTR		; Address of CHNTAB
	ADD 2,1			; Add channel number
	HLRZ 1,(2)		; Pick up the priority on the channel
;**; [@@@] Insert at PSIRST + 5 1/2	CLR	3-Jan-83
	SKIPN	XFLAG		;[@@@] Extended JSYSes?
	 LSH	1,-14		;[@@@] Yes, move priority over
	MOVE 2,LEVPTR		; Get address of LEVTAB
	ADDI 2,-1(1)		; Compute offset (zero-origin)
	MOVE 1,@(2)		; Get PC for interrupted routine
;**; [@@@] Insert at PSISRT + 10 1/2	CLR	4-Jan-83
	SKIPN	XFLAG		;[@@@] Skip if not extended
	 JRST	[MOVEI 1,@0(2)	;[@@@] Get PC address (first word)
		 AOS   1	;[@@@] Get second word (real PC)
		 MOVE  1,0(1)	;[@@@] Get instruction at real PC
		 JRST  .+1]	;[@@@] Join main code
	MOVE 1,-1(1)		; If the last instruction
	CAME 1,[DISMS]		;  was WAIT or DISMS
	CAMN 1,[WAIT]		;  ..
;**; [@@@] Change at PSIRST + 14	CLR	4-Jan-83
	 JRST	[MOVE 2,0(2)	;[@@@] Get PC (flags only if extended)
		 SKIPN XFLAG	;[@@@] Skip if not extended
		  AOS  2	;[@@@] Get second word (user PC address only)
		 AOS  0(2)	;[@@@] Increment the user PC
		 JRST .+1]	;[@@@] Leave literal
	POP SP,2
	JRST GOOD		; Return to caller

DISPAT:	REPEAT ^D36,<PUSHJ SP,HANDLR> ; Create entry table (so I can
				; figure out which chan interrupted)

	RELOC

BLSTAB:	REPEAT ^D36,<EXP 0>	; Dispatch to BLISS routines
CHNTAB:	REPEAT ^D36,<EXP 0>	; Dispatch to my servers
LEVTAB:	XWD 0,PC1
	XWD 0,PC2
	XWD 0,PC3
LEVPTR:	BLOCK 1
CHNPTR:	BLOCK 1
;**; [@@@] Change at PC1	CLR	3-Jan-83
PC1:	BLOCK	2		;[@@@] If using extended addressing JSYSes:
PC2:	BLOCK	2		;[@@@] word 0: flags
PC3:	BLOCK	2		;[@@@] word 1: PC
;**; [@@@] Insert after PC3	CLR	3-Jan-83
XBLOCK:	BLOCK	3		;[@@@] XRIR%/XSIR% argument block:
				;[@@@]    count
				;[@@@]    level table pointer
				;[@@@]    channel table pointer
XFLAG:	BLOCK 1			;[@@@] If 0, use extended JSYSes;
				;[@@@]  if 1, use old JSYSes

COMPTA:	BLOCK 3

PTR:	EXP ADDR3-1		; Pointer to where to save entry
				;  address when a high-P interrupt
				;  occurs.
ADDR3:	EXP 0
ADDR2:	EXP 0
ADDR1:	EXP 0

	END