	.TITLE	PBDRV
	.IDENT	/01/

;
; COPYRIGHT   1976,  DIGITAL  EQUIPMENT  CORP.,  MAYNARD,   MASS.
;
; THIS SOFTWARE IS FURNISHED TO PURCHASER UNDER A LICENSE FOR USE
; ON A  SINGLE COMPUTER SYSTEM AND CAN BE  COPIED (WITH INCLUSION
; OF DEC'S COPYRIGHT  NOTICE) ONLY FOR USE IN SUCH SYSTEM, EXCEPT
; AS MAY OTHERWISE BE PROVIDED IN WRITING BY DEC.
;
; THE  INFORMATION  IN THIS DOCUMENT IS SUBJECT TO CHANGE WITHOUT
; NOTICE  AND  SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL
; EQUIPMENT CORPORATION.
;
; DEC  ASSUMES NO  RESPONSIBILITY  FOR  THE  USE  OR  RELIABILITY
; OF  ITS  SOFTWARE ON  EQUIPMENT WHICH  IS  NOT SUPPLIED BY DEC.
;
; LK11 PUSH BUTTON BOX DRIVER
;
; VERSION 01
;
; NOTE:	THIS IS A SINGLE CONTROLLER DRIVER
;
; WRITTEN  BY HANK MAURER 28-FEB-77
;
;
; EQUATED SYMBOLS
;

	PBCSR=160060		;LK11 CSR
	PBIBUF=2		;LK11 INPUT BUFFER
	PBOBUF=4		;LK11 OUTPUT BUFFER
	PBVEC=360		;LK11 VECTOR
;
; LOCAL DATA  *** WARNING *** THE ORDER OF THE LOCAL DATA IS FIXED
;


LOCAL:				;REFERENCE TAG
CSRAD:	.WORD	PBCSR		;ADDRESS OF LK11 CSR
PBLCTL:	.WORD	0		;PB LIGHT CONTROL FLAG

	.IF DF	M$$MGE

BUFRB:	.WORD	0		;PUSH BUTTON BUFFER RELOCATION BIAS
BUFDB:	.WORD	0		;PUSH BUTTON BUFFER DIB

	.IFF

BUFAD:	.WORD	0		;PUSH BUTTON BUFFER ADDRESS

	.ENDC

EFNAD:	.WORD	0		;EVENT FLAG ADDRESS WORD
EFNMK:	.WORD	0		;EVENT FLAG MASK WORD (FOR PB HITS)
CONTK:	.WORD	0		;TCB ADDRESS OF CONNECTED TASK
FRKIP:	.WORD	0		;PB FORK IN PROGRESS
PBFRK:	.BLKW	3		;PB INTERRUPT FORK BLOCK

;
; DRIVER DISPATCH TABLE
;

$PBTBL::.WORD	PBCHK		;DEVICE INITIATOR ENTRY POINT
	.WORD	PBCAN		;CANCEL I/O OPERATION ENTRY POINT
	.WORD	PBOUT		;DEVICE TIMEOUT ENTRY POINT
	.WORD	PBPWF		;POWERFAIL ENTRY POINT

;+
; **-PBCHK-LK11 DRIVER PARAMETER CHECKING
;
; THIS ROUTINE IS ENTERED FROM THE QUEUE I/O DIRECTIVE WHEN AN I/O
; REQUEST IS RECEIVED FOR THE LK11 PUSH BUTTON BOX.
; LK11 I/O REQUESTS CONTAIN DEVICE DEPENDENT INFORMA-
; ATION THAT MUST BE CHECKED IN THE CONTEXT OF THE ISSUING TASK.
; THEREFORE THE I/O REQUEST IS NOT QUEUED BEFORE CALLING THE DRIVER.
;
; INPUTS:
;
;	R1=ADDRESS OF THE I/O REQUEST PACKET.
;	R4=ADDRESS OF THE STATUS CONTROL BLOCK.
;	R5=ADDRESS OF THE UNIT CONTROL BLOCK.
;
; OUTPUTS:
;
;	DEPENDENT UPON FUNCTION TO BE PERFORMED.
;
; LK11 FUNCTION INDEPENDENT I/O PACKET FORMAT:
;
;	WD. 00 -- I/O QUEUE THREAD WORD.
;	WD. 01 -- REQUEST PRIORITY, EVENT FLAG NUMBER.
;	WD. 02 -- ADDRESS OF THE TCB OF THE REQUESTER TASK.
;	WD. 03 -- POINTER TO SECOND LUN WORD IN REQUESTER TASK HEADER.
;	WD. 04 -- CONTENTS OF THE FIRST LUN WORD IN REQUESTER TASK HEADER (UCB).
;	WD. 05 -- I/O FUNCTION CODE .
;	WD. 06 -- VIRTUAL ADDRESS OF I/O STATUS BLOCK.
;	WD. 07 -- RELOCATION BIAS OF I/O STATUS BLOCK.
;	WD. 10 -- I/O STATUS BLOCK ADDRESS (REAL OR DISPLACEMENT + 140000).
;	WD. 11 -- VIRTUAL ADDRESS OF AST SERVICE ROUTINE.
;-

PBCHK:	MOV	R1,-(SP)	;SAVE IO PACKET ADDRESS
	MOVB	I.FCN+1(R1),R2	;GET IO FUNCTION CODE
	MOV	I.TCB(R1),R0	;GET REQUESTING TASK'S TCB ADDRESS
	CMPB	R2,#IO.CON/256.	;CONNECT ?
	BEQ	PBCON		;YES
	CMP	R0,CONTK	;IS THE REQUESTING TASK CONNECTED ?
	BNE	PBNCN		;NO, IT CAN'T REQUEST THINGS
	CMPB	R2,#IO.DIS/256.	;DISCONNECT ?
	BEQ	PBDIS		;YES
	BR	PBWLB		;NO, WRITE LIGHTS
;+
; **-PBCON-CONNECT PUSH BUTTON BUFFER TO DRIVER
;
; INPUTS:
;
;	R1=ADDRESS OF THE I/O REQUEST PACKET.
;	R4=ADDRESS OF THE STATUS CONTROL BLOCK.
;	R5=ADDRESS OF THE UNIT CONTROL BLOCK.
;
; FUNCTION DEPENDENT I/O REQUEST PACKET FORMAT:
;
;	WD. 12 -- RELOCATION BIAS OF PUSH BUTTON BUFFER (OR 0).
;	WD. 13 -- DIB OF BUFFER  (OR PHYSICAL ADDRESS).
;	WD. 14 -- SIZE OF BUFFER.
;	WD. 15 -- PB HIT EFN.
;	WD. 16 -- NOT USED.
;	WD. 17 -- NOT USED.
;	WD. 20 -- NOT USED.
;-

PBCON:	TST	CONTK		;ANOTHER TASK ALREADY CONNECTED?
	BNE	PBNCN		;IF NE YES
	MOV	#LOCAL,R3	;SET UP POINTER TO LOCAL DATA BASE
	MOV	S.CSR(R4),(R3)+	;SAVE LK11 CSR ADDRESS
	CLR	(R3)+		;CLEAR PB LIGHT CONTROL FLAG

	.IF DF	M$$MGE

	ADD	#I.PRM,R1	;MOVE POINTER TO ADDRESS DOUBLEWORD
	MOV	(R1)+,(R3)+	;SAVE RB OF PB BUFFER
	MOV	(R1)+,(R3)+	;AND DIB

	.IFF

	ADD	#I.PRM+2,R1	;MOVE POINTER TO BUFFER ADDRESS
	MOV	(R1)+,(R3)+	;SAVE PB BUFFER ADDRESS

	.ENDC

	CMP	(R1)+,#6	;BUFFER BIG ENOUGH ?
	BLO	PBSPC		;NO, SPACE ERROR
	MOV	(R1)+,R0	;GET PB HIT EFN
	BEQ	PBIEF		;ZERO IS ILLEGAL
	CMP	R0,#64.		;CHECK AGAINST MAX
	BGT	PBIEF		;>64 IS ILLEGAL
	MOV	R5,-(SP)	;SAVE UCB ADDRESS
	MOV	I.TCB-I.PRM-10(R1),R5 ;GET CONNECTING TASK'S TCB ADDR
	CALL	$CEFI		;CONVERT EFN TO MASK AND POINTER
	MOV	R1,(R3)+	;SAVE EFN ADDRESS
	MOV	R0,(R3)+	;SAVE EFN MASK
	BIC	R0,(R1)		;CLEAR THE USER'S EVENT FLAG
	INCB	T.IOC(R5)	;INCREMENT IO PENDING COUNT
	MOV	R5,(R3)		;CONNECT TASK TO DRIVER
	MOV	(SP)+,R5	;RESTORE UCB ADDRESS
	BIS	#40000,@S.CSR(R4) ;ENABLE LK11 INTERRUPTS
	BR	PBSUC		;TAKE COMMON EXIT
;+
; **-PBWLB-WRITE LK11 LIGHTS
;
; INPUTS:
;
;	R1=ADDRESS OF THE I/O REQUEST PACKET.
;	R4=ADDRESS OF THE STATUS CONTROL BLOCK.
;	R5=ADDRESS OF THE UNIT CONTROL BLOCK.
;	CONNECT BUFFER+2 = ON LIGHT PATTERN
;	CONNECT BUFFER+4 = OFF LIGHT PATTERN
;
; FUNCTION DEPENDENT I/O PACKET FORMAT:
;
;	WD. 12 -- NOT USED.
;	WD. 13 -- NOT USED.
;	WD. 14 -- NOT USED.
;	WD. 15 -- NOT USED.
;	WD. 16 -- NOT USED.
;	WD. 17 -- NOT USED.
;	WD. 20 -- NOT USED.
;-

PBWLB:
	.IF DF	M$MGE

	MOV	KISAR6,-(SP)	;SAVE ADDRESS REG 6
	MOV	BUFRB,KISAR6	;PUT IN RB FOR CONNECT BUFFER
	MOV	BUFDB,R0	;GET POINTER TO BUFFER

	.IFF

	MOV	BUFAD,R0	;GET POINTER TO CONNECT BUFFER

	.IFTF

	TST	(R0)+		;POINT AT ONS
	CLR	PBLCTL		;ASSUME DRIVER WILL REGAIN CONTROL
	CMP	(R0)+,#-1	;ALL ON ?
	BNE	10$		;NO
	CMP	(R0),#-1	;AND ALL OFF ?
	BEQ	PBSUC		;YES, RETURN CONTROL TO DRIVER
10$:	INC	PBLCTL		;DRIVER NOT IN CONTROL OF LIGHTS
	MOV	CSRAD,R2	;GET ADDRESS OF LK11 CSR
	BIC	(R0),PBOBUF(R2)	;TURN OFF THESE LIGHTS
	BIS	-(R0),PBOBUF(R2) ;AND TURN THESE ON

	.IFT

	MOV	(SP)+,KISAR6	;RESTORE SAR 6

	.ENDC

	BR	PBSUC		;COMMON EXIT
;+
; **-PBDIS-DISCONNECT TASK FROM DRIVER
;
; INPUTS:
;
;	R1=ADDRESS OF THE I/O REQUEST PACKET.
;	R4=ADDRESS OF THE STATUS CONTROL BLOCK.
;	R5=ADDRESS OF THE UNIT CONTROL BLOCK.
;
; FUNCTION DEPENDENT I/O PACKET FORMAT:
;
;	WD. 12 -- NOT USED.
;	WD. 13 -- NOT USED.
;	WD. 14 -- NOT USED.
;	WD. 15 -- NOT USED.
;	WD. 16 -- NOT USED.
;	WD. 17 -- NOT USED.
;	WD. 20 -- NOT USED.
;-

PBDIS:	CALL	PBCAN		;DISCONNECT TASK FROM DRIVER
	BR	PBSUC		;TAKE COMMON EXIT
;
; EXITS FROM LK11 DRIVER
;
;
; ILLEGAL CONNECT/DISCONNECT TO/FROM DRIVER
;

PBNCN:	MOV	#IE.CNR&377,R0	;SET CONNECT REFUSED STATUS
	BR	PBCMN		;BUT DON'T DISTURB THE DISPLAY

;
; ILLEGAL EVENT FLAG NUMBER
;

PBIEF:	MOV	#IE.IEF&377,R0	;SET ILLEGAL EVENT FLAG STATUS
	BR	PBCMN		;

;
; PRIVILEGE VIOLATION
;

PBPRI:	MOV	#IE.PRI&377,R0	;SET PRIVILEGE VIOLATION STATUS
	BR	PBCMN		;

;
; ILLEGAL BUFFER SPECIFICATION
;

PBSPC:	MOV	#IE.SPC&377,R0	;SET ILLEGAL BUFFER STATUS
	BR	PBCMN		;TAKE COMMON EXIT

;
; SUCCESSFUL COMPLETION
;

PBSUC:	MOV	#IS.SUC&377,R0	;SET SUCCESSFUL COMPLETION STATUS

;
; COMMON FUNCTION EXIT
;

PBCMN:	CLR	R1		;CLEAR SECOND I/O STATUS WORD
	MOV	(SP)+,R3	;RETRIEVE I/O PACKET ADDRESS
	CALLR	$IOFIN		;FINISH I/O OPERATION
;
; CANCEL I/O OPERATION
;
; THIS ROUTINE IS CALLED TO CANCEL ALL I/O IN PROPBESS FOR THE CURRENT
; TASK. IF THE TASK IS CONNECTED TO THE DRIVER, IT WILL BE
; DISCONNECTED AND THE LK11 WILL BE TURNED OFF.
;
; INPUTS:
;
;	R1=ADDRESS OF TCB OF CURRENT TASK
;	R4=ADDRESS OF SCB
;	R5=ADDRESS OF UCB
;

PBCAN:	MOV	#CONTK,R2	;;;POINT AT LOCAL DATA
	CMP	R1,(R2)		;;;IS THIS THE CONNECTED TASK ?
	BNE	PBOUT		;;;NO, DON'T DO ANYTHING
	CLR	(R2)		;;;YES, DISCONNECT IT
	CLR	-(R2)		;;;CLEAR EFN MASK
	CLR	-(R2)		;;;AND ADDRESS IN CASE FORK ALREADY QUEUED
	DECB	T.IOC(R1)	;;;DECREMENT OUTSTANDING I/O COUNT
	BIC	#40000,@S.CSR(R4) ;;;TURN OFF LK11 INTERRUPTS
	RETURN			;;;
;
; POWERFAILURE
;
;
;	NULL ROUTINE
;

PBPWF:

;
; DEVICE TIMEOUT
;
; DEVICE TIMEOUT CANNOT OCCUR SINCE THE TIMEOUT COUNT IS NEVER SET.
;

PBOUT:	RETURN
;
; LK11 INTERRUPT
;
; THE LK11 INTERRUPT OCCURS WHEN A BUTTON OF THE LK11 IS HIT.
; THE SERVICE ROUTINE MERELY RETURNS THE LK11 BUTTON STATUS TO
; THE CONNECTED BUFFER, AND SETS THE LIGHTS TO REFLECT THE
; NEW BUTTON STATUS (UNLESS LIGHTS ARE UNDER USER CONTROL).
;

$PBINT::CALL	$INTSV,PR4	;;;START INTERRUPT CODE
	TST	FRKIP		;;;FORK CURRENTLY IN PROGRESS ?
	BNE	65$		;;;YES, FORGET INTERRUPT

	.IF DF	M$$MGE

	MOV	KISAR6,-(SP)	;;;SAVE SAR6
	MOV	BUFRB,KISAR6	;;;SETUP SAR FOR BUFFER
	MOV	BUFDB,R4	;;;ALSO DIB

	.IFF

	MOV	BUFAD,R4	;;;GET ADDRESS OF BUFFER

	.ENDC

	MOV	CSRAD,R5	;;;GET ADDRESS OF PBCSR
	MOV	PBIBUF(R5),(R4)	;;;RETURN NEW BUTTON STATUS
	TST	PBLCTL		;;;IS DRIVER CONTROLLING THE LIHTS ?
	BNE	10$		;;;NO
	MOV	PBIBUF(R5),PBOBUF(R5) ;;;YES, WRITE LIGHTS
10$:

	.IF DF	M$$MGE

	MOV	(SP)+,KISAR6	;;;RESTORE MAPPING

	.ENDC

	MOV	#PBFRK+6,R4	;;;SET ADDRESS OF FORK BLOCK
	MOV	#FRKIP,R5	;;;POINT AT LOCAL DATA
	INC	(R5)		;;;SET FORK IN PROGRESS FLAG
	CALL	$FORK1		;;;FORK


	CLR	(R5)		;CLEAR FORK IN PROGRESS FLAG
	MOV	-(R5),R4	;GET TCB ADDRESS OF CONNECTED TASK
	BITB	#TS.ABO,T.STAT+2(R4) ;TASK CURRENTLY BEING ABORTED ?
	BNE	55$		;YES, DON'T MEDDLE
	BIS	-(R5),@-(R5)	;SET PB HIT EVENT FLAG
	MOV	R4,R0		;COPY TCB ADDRESS
	CALLR	$SETCR		;REQUEST USER'S TASK
55$:	RETURN			;RETURN FROM FORK


65$:	JMP	$INTXT		;;;EXIT

	.END
                                                                                                                                                                                                  