Google
 

Trailing-Edge - PDP-10 Archives - BB-V552A-SB_1983 - xdl10.p11
There is 1 other file named xdl10.p11 in the archive. Click here to see a list.
	.SBTTL	XDL10 - driver for a decsystem-10 through a DL10

; THIS SECTION CONTAINS THE DL10 MEMORY-SHARING INTERFACE
;  CODE.  THIS IS USED BY THE DN61-DA AND DN61-DB HARDWARE
;  ON A DECSYSTEM-10.
;
; AT THE FRONT ARE SUBROUTINES CALLED FOR INTERRUPT,
;  STOP CODE STOREING,
;  INITIALIZATION, ONCE-A-CLOCK-TICK PROCESSING AND 
;  ONCE-A-SECOND PROCESSING.  AFTER THESE IS THE TASK.

.REPT 0


                          COPYRIGHT (c) 1982,1981, 1980, 1979
            DIGITAL EQUIPMENT CORPORATION, maynard, mass.

THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND  COPIED
ONLY  IN  ACCORDANCE  WITH  THE  TERMS  OF  SUCH  LICENSE AND WITH THE
INCLUSION OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE OR  ANY  OTHER
COPIES  THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
OTHER PERSON.  NO TITLE TO AND OWNERSHIP OF  THE  SOFTWARE  IS  HEREBY
TRANSFERRED.

THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE  WITHOUT  NOTICE
AND  SHOULD  NOT  BE  CONSTRUED  AS  A COMMITMENT BY DIGITAL EQUIPMENT
CORPORATION.

DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR  RELIABILITY  OF  ITS
SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.

.ENDR
;
;
;	REVISION HISTORY
;
;
; 4(006) RLS	17-OCT-80	initial creation of new dl10 driver to be used
;				with new TENTSK common code module(TENCOM.P11).
;
;
VDL10=006
;
;
;
VEDIT=VEDIT+VDL10
;
;
;
;
;
	.SBTTL		DL10 INTERRUPT AND STOP CODE SUBROUTINE

DL.INT:	INTSKD
	CLKOFF			;flush clock
	MTPS	#PR.TEN*40	;set dl int service priority
	MOV	R0,-(SP)	;SAVE R0
	SAVE	NXMSP		;save possible stack trap pointer
	MOV	#11$,-(SP)	;save address for NXM
	MOV	SP,NXMSP	;save pointer to it
	MOV	DL.STS,R0	;GET STATUS REGISTER
	MOV	R0,DLSSAV	;SAVE FOR ERROR TRACE
	TRACE	TRCDTE,<R0,DLGONE>
	BIT	#DL.NXM!DL.PAR!DL.WCO,R0 ;ANY ERROR BITS?
	BNE	12$		;YES, FATAL ERROR.
	TST	DLGONE		;is -10 supposedly down?
	BEQ	1$		;no, skip initialization stuff
	CALL	INITDL		;yes, try to bring it up
	TST	DLGONE		;still gone?
	BNE	10$		;yes, just dismiss interrupt
1$:	BIS	#DL.11C,DL.STS	;NO, CLEAR 11-INTERRUPT BIT
	PIOFF
	CALL	DLFNCH		; check for things to do
	PION
10$:	TST	(SP)+		;pop error recovery point off stack
11$:	RESTOR	NXMSP
	MOV	(SP)+,R0	;RESTORE R0
	CLKON			;reenable  clock
	RTI			;EXIT THE INTERRUPT

; HERE IF THE DL10 HAS AN ERROR

12$:	STOPCD	DL10		;DL10 ERROR.

DLSSAV:	0		;DL.STS at crash time

; SUBROUTINE TO STORE THE STOP CODE.  CALLED BY THE "TRAP"
;  INSTRUCTION TO MAKE THE STOP CODE VISIBLE TO THE PDP-10.
;  AFTER RETURN, THE PDP-11 HALTS.
;
; R1 CONTAINS THE STOP CODE.

DLSTCS:	TST	DLGONE		;make sure trap wasn't dl10 nxm
	BNE	15$		;if so, don't do anything
	MOV	NXMSP,R0	;SAVE OLD VALUE OF NXMSP
	MOV	SP,NXMSP	;THIS IS A DL10 SUBROUTINE
	BIT	#DL.PEN,DL.STS	;IS THE DL10 WINDOW OPEN?
	BEQ	11$		;NO, CAN'T STORE STOP CODE.
	MOV	R1,DLXHLT	;YES, PUT STOP CODE WHERE PDP-10 CAN SEE IT
11$:	MOV	R0,NXMSP	;END OF DL10 SUBROUTINE
	RETURN
15$:	MOV	#-6,DLGONE	;set dlgone for once/sec initdl try
	RETURN
	.SBTTL		DL10 INITIALIZATION

; SUBROUTINE TO INITIALIZE THE DL10.   RETURN WITH DLGONE SET TO
;  THE STATE OF THE DL10.  0=OK, -1=FAILED.  CALLED ONCE A SECOND
;  IF DL10 GOES AWAY (I.E., PDP-10 CRASHES).

INITDL:	MOV	#16$,NXMGO	;QUIT ATTEMPT ON BUS ERROR.
	MOV	#10000.,R2 	;TIMES TO TRY
11$:	BIT	#DL.PEN,DL.STS	;WAIT FOR DL10 TO GO AWAY
	BEQ	12$		;IT IS GONE
	DEC	R2		;TRIED LONG ENOUGH?
	BNE	11$		;NO, TRY AGAIN.

; HERE WHEN THE DL10 WINDOW IS CLOSED
;  OR IT REMAINS OPEN FOR A VERY LONG TIME.

12$:	BIS	#DL.10I,DL.STS	;REQUEST PDP-10 INTERRUPT
	MOV	#100.,R2 	;TIMES TO TRY.
13$:	BIT	#DL.PEN,DL.STS	;WAIT FOR PDP-10 TO ENABLE PORT
	BNE	14$		;PORT NOW ENABLED.
	DEC	R2		;TRIED OFTEN ENOUGH?
	BNE	13$		;NO, TRY AGAIN.
	BR	16$		;YES, FORGET IT.

; HERE WHEN THE PDP-10 HAS OPENED THE DL10 WINDOW.

14$:	BIS	#DL.B00!DL.INE!DL.ERE!DL.CWC!DL.CPE!DL.CNX,DL.STS
				;TURN ON DL10
	MOV	#WINVER,DLXMOD	;SET MODIFICATION NUMBER
	MOVB	#'D-40,DLXNAM	;STORE SIXBIT OF NAME
	MOVB	#'N-40,DLXNAM	;IN THE BYTE POINTER
	MOVB	#'6-40,DLXNAM	;THIS WILL GO INTO ONE
	MOVB	#'0-40,DLXNAM	;PDP-10 WORD
	MOVB	#' -40,DLXNAM	;OF SIX SIX-BIT BYTES
	MOVB	#' -40,DLXNAM
	MOV	#1,DLXES	;SET INITIALIZATION FLAG
	BIS	#DL.10I,DL.STS	;SIGNAL THE PDP10
15$:	MOV	DLXTS,R0 	;WAIT FOR 10 TO START
	INC	R0		;CHECK FOR -1
	BNE	15$		;ITS INITIALIZATION
	MOV	#1,DLXDWN	;INDICATE WE ARE UP
	CLR	DLGONE		;NO LONGER IN LOCAL MODE.
	MOV	#-1,TENALV	;let all know it has happened at least once
	CLR	DLGNTM		;CLEAR TIME SINCE DL10 WENT
	CLR	DLFN		;clear within function flag
16$:	MOV	#NXMNRM,NXMGO	;HALT ON BUS ERROR
	RETURN			;AND RETURN, DONE WITH DL10 INIT.
	.SBTTL		DL10 ONCE-A-TICK

; SUBROUTINE TO CHECK ON THE DL10 ONCE A JIFFIE

DSPDLT:	MOV	SP,NXMSP	;RETURN FROM THIS SUBR IF BUS ERR
	TST	DLGONE		; check if -10 is already down
	BNE	10$		; yes, make sure loop tries every second
	MOV	#-1,DLXES	;THE PDP-11 IS RUNNING
11$:	MOV	DLXTS,R0	; check if the 10 is alive
	CLR	DLXOK		;NOTE THAT PDP-11 IS ALIVE
	INC	R0
	BNE	11$		;KEEP WAITING FOR "RUNNING"
	PIOFF			; protect from interrupts
	CALL	DLFNCH		; check if rest period is over
	PION
14$:	CLR	NXMSP		;DONE WITH DL10
	RETURN			; carry is clear
10$:	MOV	#-6,DLGONE	; make sure INITDL gets called once a sec
	BR	14$
	.SBTTL		DLFNCH - check for new ten requests

;this function is called with interrupts disabled


DLFNCH:				; check for possible ten requests
	TRACE	TRCDTE,(SP)	;trace caller of dlfnch

	SAVE	NXMSP		;save previous NXM return stack pointer
	MOV	SP,NXMSP	;set up to return to caller if NXM
	BIT	#DLS.EX,DLXSWD	;EXAMINE REQUEST?
	BEQ	12$		;NO.
	MOV	@DLXADR,DLXDAT	;YES, SHOW THE LOCATION
	BIC	#DLS.EX,DLXSWD	;CLEAR THE EXAMINE FLAG
	BR	15$

12$:	BIT	#DLS.DP,DLXSWD	;DEPOSIT?
	BEQ	13$		;NO.
	MOV	DLXDAT,@DLXADR	;YES, STORE THE DATA
	BIC	#DLS.DP,DLXSWD	;CLEAR THE DEPOSIT FLAG

15$:	BIS	#DL.10I,DL.STS	;AND INTERRUPT THE PDP-10.
				; examine/deposit is independent of DN60 functions
13$:	MOV	DLXOPX,R0	; get the function code
	BEQ	50$		; nothing new
	TSTB	DLFN		; new ten request - check if too soon
	BEQ	10$		; no - set it up for TENTSK
	STOPCD	TER		; ten protocol error

10$:	MOV	R0,DLFN		; ok to do it
	MOV	#DLFN+1,R0	; where to put the rest of the header
	CLRB	(R0)+		; result code
	MOVB	DLXDVX,(R0)+	; deivce
	MOVB	DLXLNX,(R0)+	; line number
	CALL	TOTBP		; total up byte pointers
	MOV	REQSTD,(R0)+	; requested transfer size in bytes
				; trace the ten command here
	TRACE	TRCTEN,<DLFN,DLDEV,DLLNG>
				; init data xfer cruft
	MOV	#DLXCBP,DLPAIR	; next pair to use
	CLR	DLCNT		; no data left in current pair
	CLR	DLXOPX		; declare operation has begun

	MOV	#DLFN,R0	; send the header to TENTSK
	CALL	WAKFNC		; and wake him also
	SETSKD	TCDLDR		;force scheduling pass

50$:	RESTOR	NXMSP		;restore old NXM trap stack pointer
	RETURN			; done


DLPAIR:	.WORD	0		; address of next pair to use
DLCNT:	.WORD	0		; byte count left in current pair
DLPTR:	.WORD	0		; address of current data window

DLHDR:				;BEG OF ARG BLOCK FROM XDRIVER
DLFN:	.BYTE	0		;PRIMARY FUNCTION CODE - TENTSK DISPATCHES ON IT
DLRES:	.BYTE	0		;RESULT CODE RETURNED TO TEN
DLDEV:	.BYTE	0		;DEVICE(0 FOR 2780/3780,COMPONENT CODE FOR HASP)
DLLIN:	.BYTE	0		;LINE NUMBER
DLLNG:	.WORD	0		;REQUESTED NUMBER OF BYTES TO TRANSFER

REQSTD:	.WORD	0		;generated by TOTBP, total bytes wanted

TOTBP:				;subroutine to total up all byte counts
	SAVE	<R0,R1>		;save registers
	CLR	REQSTD		;count is zero at first
	MOV	#DLXCBP,R1	;point to first byte pointer
10$:	MOV	(R1)+,R0	;get size of next piece
	BEQ	20$		;if no more, we are done
	ADD	R0,REQSTD	;add to total
	ADD	#2,R1		;skip over pointer
	BR	10$		; and continue
20$:	RESTOR	<R1,R0>		;restore registers
	RETURN
	.SBTTL		DL10 ONCE-A-SECOND

; ONCE-A-SECOND SUBROUTINE FOR DL10 THINGS

DSPDLS:	TST	DLGONE		;check if ten dead
	BNE	DLSERR
	MOV	SP,NXMSP	;THIS IS A DL10 SUBROUTINE
	INC	DLXTA		;IS THE PDP-10 ALIVE?
	BGT	12$		;NO, WAIT FOR IT TO DIE OR RETURN.
11$:	JMP	DLSEOK		;SUCCESS RETURN FROM DL10 SUBR

; COME HERE WHEN THE PDP-10 DIES.

12$:	MOV	JIFCLK,-(SP)	;DONT LET TIME ACCUMULATE
	MOV	#14$,NXMGO	;DONT LOSE OUT ON BUS ERROR
13$:	BIT	#DL.PEN,DL.STS	;IS PORT STILL ENABLED?
	BEQ	14$		;NO, PDP-10 IS REALLY DEAD.
	CLR	JIFCLK		;YES, BE SURE LOOP CATCHER DOESN'T GO OFF
	TST	DLXTA		;HAS 10 COME ALIVE?
	BGT	13$		;NO, WAIT FOR ONE OR THE OTHER.

; COME HERE WHEN THE PDP-10 DIED BUT CAME ALIVE AGAIN WITHOUT
;  BEING RESET.  ASSUME THAT IT WAS IN DDT OR SOMETHING
;  AND HAS BEEN CONTINUED.  WE THEREFORE CONTINUE HERE WITHOUT
;  PREJUDICE.  THE CLOCK IS SET BACK TO THE TIME OF THE STOP.
;
	MOV	(SP)+,JIFCLK	;RESTORE CLOCK
	MOV	#NXMNRM,NXMGO	;RESTORE BUS ERROR TRAP LOCN
	BR	11$		;PRETEND NOTHING HAPPENED.

; COME HERE IF THE PDP-10 GETS RESET.  SET OUR FLAG SO THE
;  STATIONS WILL BE INFORMED.

14$:	MOV	(SP)+,JIFCLK	;RESTORE CLOCK
	MOV	#-6,DLGONE	;SET FLAG TO SAY THE DL10 IS GONE
	CLR	DLGNTM		;CLEAR TIME SINCE DL10 WENT
	MOV	#NXMNRM,NXMGO	;RESTORE BUS ERROR TRAP LOCN
	CALL	WAKTEN		; wake up the TENTSK so he can abort

DLSERR:				;ERROR RETURN FROM DL10 SUBROUTINE
	CLR	NXMSP		;leaving DL10 routine
	SEC
	RETURN
	.SBTTL		DLRESP - end of ten operation

;DLRESP		- CALLED TO INITIATE A RESPONSE TO A TEN REQUEST
;
; ARGS:		R0/result code to return
;		R1/transfer size to return
;
; RETURNS:	CARRY CLEAR IF ALL COPASETIC
;		CARRY SET IF TEN DOWN

DLRESP:	MOV	SP,NXMSP	;THIS IS A DL10 SUBROUTINE
	MOV	R1,DLXXFR 	;STORE NUMBER OF BYTES TRANSFERED
	MOV	R0,DLXRST	;STORE RESULT CODE
	TRACE	TRCTEN,<R0,R1>	;TRACE RESULT CODE
	CLRB	DLFN		; clear ten function interlock
	BIS	#DL.10I,DL.STS	;AND INTERRUPT THE PDP-10.

; HERE TO GIVE THE "OK" RETURN FROM A DL10 SUBROUTINE

DLSEOK:	CLR	NXMSP		;END OF DL10 INTERACTION
	CLC			;SIGNAL SUCCESS
	RETURN			;RETURN.
	.SBTTL		DATA TRANSFER INTERFACE FUCNTIONS FOR TENTSK USE

;DRIVER FUNCTIONS CALLED


;BLECHI,BLECHO	- READ FROM,SEND TO TEN A STRING
;
; ARGS:		R0/BYTE COUNT
;		R1/BEGINNING BYTE PTR
;
; RETURNS:	CARRY CLEAR, R0/UPDATED BYTE COUNT
;			     R1/UPDATED BYTE PTR
;			     CONDITION CODES REFLECT "TST R0"
;		CARRY SET IF FATAL ERROR HAS OCCURRED(TEN DEAD,PROTOCOL ERROR)

;BYTCHI,BYTCHO	- 1 BYTE XFER FROM,TO TEN
;
; ARGS:		R0/BYTE (OUT TO TEN)
;
; RETURNS:	CARRY CLEAR,Z CLEAR - BYTE TRANSFERRED:  R0/BYTE (INPUT FROM TEN)
;		CARRY CLEAR,Z SET - BYTE NOT TRANSFERRED
;		CARRY SET IF MORTALLY WOUNDED

	.ENABL	LSB

BYTCHI:	MOV	SP,NXMSP	; set special NXM exit
1$:	TST	DLGONE		; check if ten dead first
	BEQ	5$		; yes - try to do something

BYTERR:	CLR	NXMSP		; no longer need special NXM exit
	SETC	CZ		; we din't do nuthin return
	RETURN

5$:	DEC	DLCNT		; check if anything left in current window
	BGE	10$		; yes - go
	CALL	BYCYCL		; no - try next window
	BCC	1$		; more data available

BREFUS:	TRACE	TRCTEN,R0	; trace failure
	CLR	NXMSP		; no longer need special NXM check
	CLC			; politely refuse to do more
	SEZ
	RETURN

10$:
	.IF	NE,DTBUG
	DEC	DLLNG		; paranoid check on common code
	BGE	11$
	STOPCD	BUG
11$:
	.ENDC

	CLR	R0		; all ok - get the byte
	BISB	@DLPTR,R0

BSUC:	TRACE	TRCTEN,R0	; trace success
	CLR	NXMSP		; no longer need special NXM exit
	CLRC	CZ		; just as politely suc
	RETURN

	.DSABL	LSB

	.ENABL	LSB
BYCYCL:	MOV	@DLPAIR,DLCNT	; try to get new window
	BEQ	10$		; nothing left
	ADD	#2,DLPAIR	; advance interface register ptr
	MOV	DLPAIR,DLPTR	; new current data window address
	TRACE	TRCDTE,<(SP),DLPTR,DLCNT>
BYCSUC:	ADD	#2,DLPAIR	; stop at next possible pair
	CLC			; suc
	RETURN

10$:	TRACE	TRCDTE,<(SP),DLPAIR>
BYCFAL:	SEC			; fail
	RETURN

	.ENABL	LSB

BYTCHO:	TRACE	TRCTEN,R0	; trace output attempt
	MOV	SP,NXMSP	; start special DL10 NXM exit
1$:	TST	DLGONE		; check if ten dead first
	BNE	BYTERR		; too bad

5$:	DEC	DLCNT		; check if anything left in current window
	BGE	10$		; yes - go
	CALL	BYCYCL		; no - try next window
	BCC	1$		; more data available
	BR	BREFUS		; one bad

10$:
	.IF	NE,DTBUG
	DEC	DLLNG		; paranoid check on common code
	BGE	11$
	STOPCD	BUG
11$:
	.ENDC

	MOVB	R0,@DLPTR	; hooray!
	BR	BSUC

	.DSABL	LSB


BLECHI:	TRACE	TRCTEN,<R0,R1>	; trace block input
	TST	R0		; check if null input
	BEQ	BLSUC		; that was easy enough!
	MOV	SP,NXMSP	; set up special exit on NXM
	SAVE	<R2,R3>

10$:	TST	DLGONE		; check if ten dead first
	BNE	40$		; too bad
	MOV	DLPTR,R2	; get parameters in regs
	MOV	DLCNT,R3
	BGT	20$		; more in current window

15$:	CALL	BYCYCL		; no - try next window
	BCC	10$		; more data available
	BR	35$		; all she wrote!

20$:
	.IF	NE,DTBUG
	DEC	DLLNG		; paranoid check on common code
	BGE	11$
	STOPCD	BUG
11$:
	.ENDC

	MOVB	(R2),(R1)+	; now we can get down to business
	DEC	R0		; count byte into 11
	BLE	30$		; check surfeit
				; TENTSK still hungry
	SOB	R3,20$		; count byte out of ten
	BR	15$		; pause that refreshes

30$:	DEC	R3		; TENTSK full - count byte out of ten

35$:	MOV	R2,DLPTR	; time to hang it up
	MOV	R3,DLCNT	; carefully restore current window pars

	RESTOR	<R3,R2>
	BR	BLSUC		; return success

40$:	RESTOR	<R3,R2>		; loser
	JMP	BYTERR

	.ENABL	LSB

BLECHO:	TRACE	TRCTEN,<R0,R1>	; trace block output
	TST	R0		; check if null input
	BEQ	BLSUC		; that was easy enough!
	MOV	SP,NXMSP	; start special DL10 NXM exit
	SAVE	<R2,R3>

10$:	TST	DLGONE		; check if ten dead first
	BNE	40$		; too bad
	MOV	DLPTR,R2	; get parameters in regs
	MOV	DLCNT,R3
	BGT	20$		; more in current window

15$:	CALL	BYCYCL		; no - try next window
	BCC	10$		; more data available
	BR	35$		; all she wrote!

20$:
	.IF	NE,DTBUG
	DEC	DLLNG		; paranoid check on common code
	BGE	11$
	STOPCD	BUG
11$:
	.ENDC

	MOVB	(R1)+,(R2)	; now we can get down to business
	DEC	R0		; count byte out of 11
	BLE	30$		; check emptiness
				; TENTSK still full
	SOB	R3,20$		; count byte into ten
	BR	15$		; pause that refreshes

30$:	DEC	R3		; TENTSK empty - count byte into ten

35$:	MOV	R2,DLPTR	; time to hang it up
	MOV	R3,DLCNT	; carefully restore current window pars

	RESTOR	<R3,R2>
BLSUC:	CLR	NXMSP		; end of special NXM handling
	TST	R0		; set condition codes
	CLC			; and suc
	RETURN

40$:	RESTOR	<R3,R2>		; loser
	JMP	BYTERR

	.DSABL	LSB