Google
 

Trailing-Edge - PDP-10 Archives - BB-4170G-SM - sources/device.mac
There are 53 other files named device.mac in the archive. Click here to see a list.
;<3-MONITOR>DEVICE.MAC.96,  7-Nov-77 12:59:55, EDIT BY KIRSCHEN
;MORE COPYRIGHT UPDATING...
;<3-MONITOR>DEVICE.MAC.95, 10-Oct-77 10:09:09, EDIT BY KIRSCHEN
;UPDATE COPYRIGHT FOR RELEASE 3
;<3-MONITOR>DEVICE.MAC.94,  5-Jul-77 14:18:41, EDIT BY HURLEY
;FIX MAGTAPE ASSIGNMENT SO JOB 0 GETS ALL NON-EXISTENT DRIVES
;<3-MONITOR>DEVICE.MAC.93,  6-May-77 10:52:16, EDIT BY MILLER
;TCO 1795. ADD DUMMY ROUTINES TO HANDLE BIDIRECTIONAL I/O
;<3-MONITOR>DEVICE.MAC.92,  2-May-77 19:38:24, EDIT BY BOSACK
;ELIMINATE USE MACRO
;<3-MONITOR>DEVICE.MAC.91, 22-Apr-77 18:11:28, EDIT BY HELLIWELL
;CHANGE ASCSIX & ASC3SX TO TEST MASK FOR COMPLETION AT ASCSX3
;<3-MONITOR>DEVICE.MAC.90,  6-Apr-77 14:30:38, EDIT BY HALL
;TCO 1768 - FIX CHKDSS TO REQUIRE VALID DESIGNATOR
;<3-MONITOR>DEVICE.MAC.89, 23-Feb-77 20:00:02, EDIT BY HALL
;TCO 1740 - REMOVED TTYASN AND TTYDAS, CHANGED CHECKING FOR PTY'S IN
;DEVAV TO CALL INTO TTYSRV
;<3-MONITOR>DEVICE.MAC.88, 23-Jan-77 15:10:49, Edit by MCLEAN
;<3-MONITOR>DEVICE.MAC.87, 27-Dec-76 17:31:13, EDIT BY HURLEY
;<3-MONITOR>DEVICE.MAC.86,  8-Dec-76 16:39:33, EDIT BY KIRSCHEN
;INITIALIZE STRLOK IN DEVINI
;<3-MONITOR>DEVICE.MAC.84, 28-Nov-76 22:30:30, Edit by MCLEAN
;<3-MONITOR>DEVICE.MAC.83, 25-Nov-76 01:15:40, Edit by MCLEAN
;<3-MONITOR>DEVICE.MAC.83, 25-Nov-76 01:15:35, Edit by MCLEAN
;TCO 1669 EXTENDED ADDRESSING
;<2-MONITOR>DEVICE.MAC.82, 29-Oct-76 09:42:42, Edit by HESS
;CHANGE STR INITING FORK TO JOB #
;<2-MONITOR>DEVICE.MAC.81,  1-Oct-76 12:11:57, Edit by HESS
;<2-MONITOR>DEVICE.MAC.80, 30-Sep-76 18:04:15, Edit by HESS
;<2-MONITOR>DEVICE.MAC.79, 30-Sep-76 17:19:51, Edit by HESS
;CHANGE DEVLUX TO RETURN STR UNIQUE CODE.
;<2-MONITOR>DEVICE.MAC.78, 29-Sep-76 15:37:13, Edit by HESS
;CHANGE CHKDEV/CHKDES TO RETURN STR UNIQUE CODE IN LH(DEV)
;<2-MONITOR>DEVICE.MAC.77, 27-Sep-76 16:33:16, Edit by HESS
;<2-MONITOR>DEVICE.MAC.76, 23-Sep-76 16:36:02, Edit by HESS
;USE STR UNIQUE CODE INSTEAD OF STR # IN DEVICE DESIGNATORS
;<2-MONITOR>DEVICE.MAC.75, 16-Sep-76 13:19:03, EDIT BY HURLEY
;MADE RECOGNITION OF DIR NAMES WORK DURING "PARSE ONLY" GTJFNS
;<2-MONITOR>DEVICE.MAC.3,  7-JUN-76 17:10:17, EDIT BY HALL
;CHANGED CHKDEV TO TAKE ERROR RETURN IF STRUCTURE IS BEING INITIALZED
;<2-MONITOR>DEVICE.MAC.2, 24-MAY-76 17:31:17, EDIT BY HALL
;FIXED CHKDEV TO FAIL IF SLOT IS NOT IN USE (STRUCTURES ONLY)
;<2-MONITOR>DEVICE.MAC.1,  6-MAY-76 14:53:40, EDIT BY HALL
;MAKE DEVICE UNDERSTAND STRUCTURES
;<1MONITOR>DEVICE.MAC.62, 23-MAR-76 19:43:19, EDIT BY HURLEY
;TCO 1218 - ALLOW GTJFN TO WIN EVEN IF DEV ASSIGNED TO ANOTHER JOB
;<2MONITOR>DEVICE.MAC.61, 16-JAN-76 17:42:39, EDIT BY MURPHY
;<2MONITOR>DEVICE.MAC.60, 23-DEC-75 12:46:17, EDIT BY LEWINE


;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
;  OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1976, 1977, 1978 BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.

	SEARCH PROLOG
	TTITLE DEVICE
	SWAPCD

;SPECIAL AC DEFINITIONS

DEFAC (STS,P1)
DEFAC (JFN,P2)
DEFAC (DEV,P4)			;DEVICE PTR
DEFAC (F1,P5)
; Initialize device tables

;CALLED AT SYSTEM STARTUP TO INITIALIZE DEVNAM,ETC.

;ACCEPTS: NONE

;RETURNS +1: ALWAYS

;	CALL DEVINI

;USE OF REGISTERS
;C/ POINTER TO DEVXXX TABLES, INCREMENTED ONCE FOR EACH UNIT
;D/ POINTER TO INIDVT, INCREMENTED ONCE PER DEVICE TYPE

DEVINI::SE1CAL
	SETOM DEVLCK
	SETOM STRLOK		;INITIALIZE STRUCTURE DISMOUNTING LOCK
	MOVSI C,-NDEV
	MOVSI D,-NINIDV
INIDVL:	HRRZ A,INIDVT+3(D)	;GET NUMBER OF UNITS FOR THIS DEVICE
	PUSH P,A		;SAVE COUNT OF UNITS

;HERE ON NEXT UNIT FOR A MULTI-UNIT DEVICE

INIDV0:	MOVE A,INIDVT+1(D)	;GET NUMBER OF DEVICES AND DISPATCH
	MOVEM A,DEVDSP(C)	;SET UP DISPATCH TABLE
	MOVE A,INIDVT+2(D)	;GET MODES AND CHAR1
	MOVEM A,DEVCHR(C)	;SET UP DEVCHR WORD FOR THIS DEVICE
	HLLZ A,INIDVT+3(D)	;GET CHAR2 BITS
	MOVEM A,DEVCH1(C)	;STORE IN SECOND CHARACTERISTICS TABLE
	MOVE A,INIDVT(D)	;GET DEVICE NAME
	MOVEM A,DEVNAM(C)	;STORE SIXBIT NAME (WITHOUT UNIT #)
	SKIPG 0(P)		;THIS A MULTIPLE UNIT DEVICE?
	JRST INIDV2		;NO, SET UNIT # TO -1

;DEVICE HAS UNITS

	SOS B,0(P)		;GET UNIT # OF THIS DEVICE
	HRRZ A,INIDVT+3(D)	;GET TOTAL # OF UNITS
	SUBI A,1(B)		;GET UNIT # TO PUT IN TABLE
	HRRZ B,C		;GET INDEX INTO DEVXXX TABLES
	CAIL B,DVXST0		;ARE WE WITHIN THE 'STR' DEFINITIONS?
	CAIL B,DVXSTN
	JRST INIDV6		;NO.
	MOVX B,D1%NIU		;YES. INDICATE SLOT NOT IN USE BECAUSE
	IORM B,DEVCH1(C)	; NOT YET ASSIGNED TO A STRUCTURE
	HRRZM A,DEVUNT(C)	;SET OWNING JOB TO 0 SO EXEC WON'T THINK
				; IT IS AVAILABLE, ALSO SET UNIT NUMBER
	JRST INIDV7		;DON'T MESS AROUND WITH DEVUNT
INIDV6:	HRROM A,DEVUNT(C)	;MARK THAT DEVICE IS FREE ALSO
	MOVE B,DEVCH1(C)	;SEE IF THIS IS A SPOOLED DEVICE
	TLNE B,(D1%SPL)		;...
	SETOM DEVUNT(C)		;YES, NO UNIT NUMBER FOR SPOOLED DEV'S
INIDV7:	CALL NUMSIX		;CONVERT UNIT # TO SIXBIT
	MOVSI B,770000		;NOW SET UP TO BUILD DEVICE NAME
INIDV1:	LSH B,-6		;SHIFT MASK TO NEXT SIXBIT CHAR POSITION
	LSH A,-6		;SHIFT SIXBIT UNIT NUMBER ALSO
	TDNE B,INIDVT(D)	;SEE IF AT FIRST BLANK CHAR YET
	JRST INIDV1		;NO, LOOP BACK TIL BLANK CHAR FOUND
	IORM A,DEVNAM(C)	;CREATE FULL DEVICE NAME PLUS UNIT #
	AOBJN C,.+1		;STEP TO NEXT DEVICE ENTRY IN TABLES
	SKIPLE 0(P)		;ANY MORE UNITS FOR THIS DEVICE?
	JRST INIDV0		;YES, LOOP BACK AND SET UP TABLES
	JRST INIDV3		;NO, GO ON TO NEXT DEVICE TYPE

;DEVICE HAS NO UNITS

INIDV2:	SETOM DEVUNT(C)		;MARK THAT THIS IS A NO UNIT DEVICE
	AOBJN C,INIDV3		;AND GO TO NEXT DEVICE

;HERE WHEN DONE WITH A PARTICULAR DEVICE (ALL UNITS DONE)

INIDV3:	ADD D,BHC+DVTSTP	;STEP TO NEXT DEVICE IN INIDVT TABLE
	POP P,0(P)		;CLEAR OUT STACK
	JUMPL D,INIDVL		;LOOP BACK FOR ALL DEVICES

;ADD DEVICES ARE DONE.  CLEAR UNUSED ENTRIES IF THERE ARE ANY

	JUMPGE C,INIDV5		;ANY MORE ENTRIES IN TABLE?
INIDV4:	SETZM DEVNAM(C)		;YES, ZERO ALL UNUSED ENTRIES
	SETZM DEVCHR(C)
	SETZM DEVCH1(C)
	SETZM DEVUNT(C)
	SETZM DEVDSP(C)
	AOBJN C,INIDV4		;LOOP BACK TILL ALL ENTRIES CLEARED
INIDV5:	MOVE A,JOBNO
	MOVE B,CTRLTT
	CALL TTYASN		;ASSIGN CTRLTT NOW THAT DEV TABLES EXIST
	 BUG(HLT,TTNAC8,<CAN'T ASSIGN TERMINAL AT DEVINI>)
	RET
; Device lookup

;ACCEPTS:
;	A/ADDRESS OF STRING BLOCK CONTAINING DEVICE NAME IN ASCIZ,
;	  STARTING AT C(A)+1

;RETURNS +1: DEVICE NAME NOT FOUND IN DEVNAM
;		A/ERROR CODE
;	 +2: DEVICE FOUND
;		A/FIRST WORD OF DEVICE CHARACTERISTICS
;		B/OFFSET IN DEVXXX TABLES FOR THIS DEVICE
;		C/ UNIQUE CODE IF STRUCTURE

;LOOKS IN DEVNAM FOR NAME MATCHING THAT POINTED TO BY AC1
;SUCCESS INDICATES ONLY THAT DEVICE EXISTS.  NOTE THAT FOR 
;STRUCTURES, UNUSED SLOTS HAVE ENTRIES IN DEVNAM OF THE FORM STRN AND
;BIT D1%NIU SET IN DEVCH1

DEVLUX:: SE1CAL
	HRRZ B,A		;ONLY ADDRESS FOR EXADR
	MOVE B,1(B)		;GET FIRST WORD OF STRING
	TLNN B,774000		;SEE IF FIRST CHARACTER IS NULL
	JRST DEVLK5		; Null name not ok
	ANDCMI B,377		;CLEAR 5TH BYTE TO LOOK FOR EXACTLY
	CAMN B,[ASCIZ /CTY/]	; 'CTY' (4TH BYTE MUST BE NULL)
	JRST [	MOVE A,CTYLNO	;FOUND 'CTY'
		JRST DEVLK4]
	CAME B,[ASCIZ /TTY/]	;IS IT 'TTY'?
	JRST DEVLK0		;NO.
	MOVE B,JOBNO		;YES
	HLRZ A,JOBPT(B)
	CAIN A,777777
	JRST DEVLK5

;FOUND CTY

DEVLK4:	ADD A,DEVTT0		;ADD INDEX OF TTY0
	MOVE B,A
	JRST DEVLK3

;FOUND NOTHING SPECIAL

DEVLK0:	CALL ASCSIX		; Convert to sixbit
	JRST DEVLK5		; Non-sixbit or too many
	MOVSI B,-NDEV

;SEARCH FOR MATCHING DEVNAM

DEVLK1:	CAME A,DEVNAM(B)	;IS THIS THE DEVICE?
DEVLK2:	AOBJN B,DEVLK1		;NO. KEEP LOOKING
	JUMPGE B,DEVLK5		;DID WE FIND IT?
	MOVE A,DEVCH1(B)	;YES. GET 2ND CHARACTERISTICS WORD
	TXNE A,D1%NIU		;IS SLOT IN USE?
	JRST DEVLK2		;NO. NO MATCH
	HRRZ C,B		;GET INDEX ONLY
	CAIL C,DVXST0		;IS IT A STRUCTURE
	CAIL C,DVXSTN
	 JRST DEVLK3		;NO - PROCEED
	PUSH P,B		;SAVE INDEX
	HRRZ A,DEVUNT(B)	;GET STR # (TEMP)
	CALL STRCNV		;GET STR UNIQUE CODE (TEMP)
	 JRST [	POP P,B		;FAILED - NO MATCH
		JRST DEVLK2]
	MOVE C,A		;RETURN IN C
	POP P,B			;RESTORE B
DEVLK3:	MOVE A,DEVCHR(B)	;YES. RETURN CHARACTERISTICS
	RETSKP

DEVLK5:	MOVEI A,GJFX16		;RETURN NO SUCH DEVICE
	RET
;LOOKUP DEVICE AND CHECK ASSIGNMENT, MOUNT IF NECESSARY

;ACCEPTS:
;	A/ADDRESS OF STRING BLOCK CONTAINING DEVICE NAME IN ASCIZ,
;	  STARTING AT C(A)+1

;	CALL DEVLUX

; RETURN +1: IF NOT FOUND, OR NOT MOUNTABLE
; RETURN +2: SUCCESS,
;  A/ DEVICE CHARACTERISTICS
;  B/ DEV TABLE INDEX
;  C/ UNIQUE CODE IF STRUCTURE
;  DEV/ UNIT #,,DISPATCH TABLE

DEVLUK::SE1CAL
	STKVAR <DVLKIN,DVLKUC>
	SETZ DEV,		;INIT DEV IN CASE OF FAILURE
	CALL DEVLUX		;LOOKUP NAME
				;RETURNS: 1/CHARACTERISTICS, 2/INDEX TO DEVXXX
	 JRST DEVLKE		;NOT FOUND
	MOVE DEV,DEVDSP(B)	;DEV/(UNIT,,DISPATCH ADDRESS)
	HRL DEV,DEVUNT(B)	;SET UP UNIT NUMBER IN DEV
	HRRZ D,B		;GET INDEX INTO DEVICE TABLES
	CAIL D,DVXST0		;IS IT A STRUCTURE?
	CAIL D,DVXSTN
	 JRST DEVLK7		;NO - GO ON
	MOVEM B,DVLKIN		;SAVE INDEX
	MOVEM C,DVLKUC		;SAVE UNIQUE CODE
	MOVE A,C		;GET UNIQUE CODE
	CALL CNVSTR		;LOCK STR AND VALIDATE CODE
	 JRST DEVLK9		;RETURN NO SUCH DEVICE
	MOVE B,DVLKIN		;RESTORE INDEX
	MOVX D,D1%INI		;SEE IF BEING INITED
	TDNN D,DEVCH1(B)	;...
	JRST DEVLK6		;NO - OK THEN
	MOVE D,STRTAB(A)	;GET SDB ADDRESS
	LOAD D,STRJB,(D)	;GET JOB INITING STR
	CAMN D,JOBNO		;THIS JOB?
	JRST DEVLK6		;YES - OK
	CALL ULKSTR		;NO - ULKOCK STR
	JRST DEVLK9		;RETURN ERROR

DEVLK6:	CALL ULKSTR		;UNLOCK STRUCTURE
	MOVE C,DVLKUC		;RESTOR UNIQUE CODE
	MOVE A,DEVCHR(B)	;RETURN DEVICE CHARACTERISTICS
	RETSKP

DEVLK7:	CALL DEVAV		;IS DEVICE AVAILABLE?
	 RETSKP			;NO SO DON'T MOUNT
	TLNE A,(DV%MDV)		;DEVICE MOUNTABLE BUT NOT MOUNTED?
	TLNE A,(DV%MNT)
	 RETSKP
	TLZ 1,777000		;YES. CONSTRUCT DEV DESIG
	TLO 1,.DVDES
	HRR 1,DEVUNT(B)
	MOUNT			;MOUNT IT
	 JRST DEVLKE		;FAILED, RETURN ERROR CODE
	MOVE A,DEVCHR(B)	;A/CHARACTERISTICS
	RETSKP

DEVLK9:	MOVEI A,GJFX16		;DEVICE NOT KNOWN
DEVLKE:	TQNE <ASTF>		;OUTPUT STARS ON?
	RETSKP			;YES, ALWAYS SUCCEED THEN
	RETBAD			;NO, GIVE ERROR RETURN
;CHKDEV AND CHKDES - Check device designator
;ACCEPTS:
;	A/ Device designator

;	CALL CHKDEV		;THIS CHECKS IF DEVICE IS AVAILABLE
;	     OR
;	CALL CHKDES		;JUST CHECKS IF DESIGNATOR IS LEGAL

;ReturnS +1: Error, number in a
;  	 +2:Ok,
;		A/ Unit number
;		B/ Index into device tables
;		C/ Device characteristics word (DEVCHR)
;		DEV/ (UNIT NUMBER,,DISPATCH ADDRESS)

CHKDEV::TRVAR <STRNXX>
	SETOM STRNXX		;ASSUME NO STR YET
	CALL CHKDSS		;SEE IF DESIGNATOR IS VALID
	 RETBAD ()		;ILLEGAL DESIGNATOR
	SE1CAL
	MOVX D,D1%INI		;SEE IF DEVICE IS BEING INITIALIZED
	TDNN D,DEVCH1(B)	; (CURRENTLY FOR STRUCTURES ONLY)
	JRST CHKDV2		;NO. PROCEED AS USUAL
	HRRZ D,DEVUNT(B)	;YES. GET UNIT NUMBER
	MOVE D,STRTAB(D)	;POINT TO START OF SDB FOR THIS STRUCTURE
	LOAD D,STRJB,(D)	;GET JOB THAT IS ININIALIZING
	CAMN D,JOBNO		;IS IT THIS JOB?
	JRST CHKDEX		;YES - SUCCESS
	JRST CHKDV3 		;NO. TAKE ERROR RETURN
CHKDV2:	CALL DEVAV		;DEVICE AVAILABLE?
	 CAIA			;NO
	JRST CHKDEX		;DEVICE IS AVAILABLE
CHKDV3:	SKIPL A,STRNXX		;SEE IF STR #
	CALL ULKSTR		;UNLOCK IF HAVE ONE
	MOVEI A,DEVX2		;NOT AVAILABLE
	RET			;GIVE ERROR RETURN

;CHKDES - CHECK FOR EXISTING DEVICE

;SEARCHES DEVXXX TABLES FOR MATCHING DEVICE TYPE AND UNIT NUMBER.
;NOTE THAT FOR STRUCTURES, UNUSED SLOTS HAVE ENTRIES IN DEVNAM OF THE
;FORM STRN AND BIT D1%NIU SET IN DEVCH1

CHKDES::TRVAR <STRNXX>
	SETOM STRNXX		;MARK NONE SEEN YET
	CALL CHKDSS		;CHECK DESIGNATOR AND LOCK STR
	 RETBAD ()		;NO SUCH DEVICE
	SE1CAL
CHKDEX:	SKIPGE STRNXX		;IF .GE. 0 THEN UNLOCK STR
	RETSKP			;GOOD RETURN
	MOVE T1,STRNXX		;GET STR #
	MOVE T1,STRTAB(T1)	;GET SDB PNTR
	LOAD T1,STRUC,(T1)	;GET UNIQUE CODE
	EXCH T1,STRNXX		;SAVE IT A GET STR # BACK
	CALL ULKSTR		;UNLOCK STRUCTURE
	MOVE T1,STRNXX		;RETURN UNIQUE CODE
	HRL DEV,T1		;...
	RETSKP			;GOOD RETURN
;CHKDSS - INTERNAL ROUTINE TO CHECK DEVICE DESIGNATOR. ASSUMES THAT
;A TRVAR NAMED "STRNXX" EXISTS IN THE CALLING ROUTINE.

;ACCEPTS:
;	A/ DEVICE DESIGNATOR

;	CALL CHKDSS

;RETURNS +1: INVALID DEVICE DESIGNATOR
;		A/ ERROR CODE
;	 +2: VALID DEVICE DESIGNATOR
;		A/ UNIT NUMBER
;		B/ INDEX INTO DEVICE TABLES
;		C/ DEVICE CHARACTERISTICS (DEVCHR)
;		DEV/ (UNIT NUMBER,,DISPATCH ADDRESS)

;VALID DESIGNATORS ARE:
;	(0,,-1) -- CONTROLLING TERMINAL
;	(0,,.TTDES+N) -- TERMINAL N
;	(.DVDES+.DVDSK,,UNIQUE CODE) -- STRUCTURE MOUNTED WITH THIS UNIQUE CODE
;	(.DVDES+.DVDSK,,-1) -- CONNECTED STRUCTURE
;	(.DVDES+M,,N) -- UNIT N OF DEVICE TYPE M
;	(.DVDES+M,,-1) -- DEVICE TYPE M (NON-UNIT DEVICE)

CHKDSS:	TLNN A,777777		; Left half zero means tty designator
	JRST TTYDEV
	TLZN A,.DVDES		; These bits always on
	RETBAD (DEVX1)		;NOT ON - INVALID DESIGNATOR
	TLNN A,777777		;THIS WILL BE ZERO IF A DISK TYPE

;DEVICE TYPE IS .DVDSK.  IF RH IS -1, GET CONNECTED STRUCTURE.
;IN EITHER CASE, CONVERT UNIQUE CODE TO STRUCTURE NUMBER, WHICH IS
;THE UNIT NUMBER FOR THE DEVICE TABLES. LEAVE THE STRUCTURE LOCKED

	JRST [	CAIN A,-1	;CHECK SPECIAL
		CALL [CALL GTCSCD ;GET CONNECTED DIR #
		      HLRZS A	;UNIQUE CODE ONLY
		      RET]
		CALL CNVSTR	;GET STR #
		 RETBAD (DEVX1)
		MOVEM A,STRNXX	;SAVE STR # FOR RELEASE
		JRST .+1]

;SEARCH THE DEVICE TABLES FOR THE UNIT SPECIFIED BY THE DEVICE DESIGNATOR
;(IF NON-UNIT DEVICE, DEVUNT WILL CONTAIN -1)

	MOVNI B,NDEV		; Movsi b,-ndev the hard way...
	HRLZS B
CHKDVL:	HLLZ C,DEVCHR(B)	; Construct device designator for this dev
	TLZ C,777000		;SAVE DEVICE TYPE WITHOUT .DVDES
	HRR C,DEVUNT(B)
	CAME C,A		; Is it the same as user's
	AOBJN B,CHKDVL		; No, continue scan
	JUMPGE B,CHKDV1

;DEVICE HAS BEEN FOUND. LOAD DEV AND C TO RETURN TO CALLER

	MOVE A,DEVCH1(B)	;GET SECOND CHARACTERISTICS WORD
	TXNE A,D1%NIU		;IS SLOT IN USE?
	JRST CHKDV1		;NO
	HRRZ A,C		; Leave unit in a
	MOVE DEV,DEVDSP(B)	;GET DISPATCH ADDRESS
	HRL DEV,A		;DEV/ (UNIT,,DISPATCH ADDRESS)
	MOVE C,DEVCHR(B)	;C/ CHARACTERISTICS
	RETSKP

;LEFT HALF IS ZERO. THIS IS EITHER (0,,-1) FOR CONTROLLING TERMINAL
;OR 400000+TERMINAL NUMBER. IF THE LATTER, MAKE UP 600012,,TERMINAL NUMBER AND
;TRY IT AGAIN

TTYDEV:	CAIN A,.CTTRM		;WANT CONTROLLING TERMINAL
	JRST CTTYDV		;YES - GET IT
	TRZN A,.TTDES		;NO. GET TERMINAL NUMBER
	RETBAD (DEVX1)		;RETURN INVALID DESIGNATOR
	HRLI A,.DVDES+.DVTTY	;GENERATE ordinary device designator
	JRST CHKDES		; And try again

;GET CONTROLLING TERMINAL AND GO TRY AGAIN

CTTYDV:	MOVE B,JOBNO
	HRLZI A,JOBPT(B)
	HRRI A,DISGET
	SKIPGE B,JOBPT(B)
	MDISMS
	HLRZ A,B		;GET CONTROLLING TERMINAL (MAY BE -1 AGAIN)
	TXO A,.TTDES		;MAKE IT A TERMINAL DESIGNATOR
	JRST TTYDEV

;DEVICE NOT KNOWN

CHKDV1:	SKIPL A,STRNXX		;IF STR FOUND - RELEASE IT
	CALL ULKSTR		;UNLOCK STRUCTURE
	MOVEI A,DEVX1
	RET			; Illegal designator
;FIND INDEX FOR SPECIFIC UNIT
; JFN/ A JFN, SHIFTED TO POINT TO JFN BLOCK
; RETURN +1: A/ INDEX TO DEVICE TABLES

;FILDEV AND INIDVT+3 HAVE (UNIT NUMBER,,DISPATCH ADDRESS)
;IF THERE ARE NO UNITS, FILDEV HAS -1; INIDVT HAS 0

FNDUNT::MOVSI B,-NINIDV		;SETUP TO SCAN INITIAL DEVICE TABLE
FNDU1:	HRRZ C,FILDEV(JFN)	;GET DISPATCH TABLE ADDRESS FOR JFN
	HRRZ A,INIDVT+1(B)	;GET DISPATCH TABLE ADDRESS FOR DEVICE
	CAMN A,C		;SAME AS JFN?
	JRST FNDU2		;YES, HAVE FOUND PROPER DEVICE
FNDU3:	ADDI B,DVTSTP-1		;SKIP TO NEXT DEVICE 
	AOBJN B,FNDU1
	BUG(HLT,NOFNDU,<FNDUNT-CAN'T FIND DEVICE FOR JFN>)

;DISPATCH ADDRESSES MATCH.  SEE IF AGREE ON UNIT VS NON-UNIT DEVICE

FNDU2:	HLRZ A,FILDEV(JFN)	;GET UNIT NUMBER FOR JFN
	HLRZ C,INIDVT+1(B)	;GET OFFSET IN DEVXXX TABLES FOR FIRST UNIT
	HRRZ D,INIDVT+3(B)	;GET UNIT NUMBER FOR DEVICE IN TABLE
	CAIN A,-1		;DOES DEVICE IN JFN BLOCK HAVE UNITS?
	JRST FNDU4		;NO.
	JUMPE D,FNDU3		;YES. DOES THIS DEVICE HAVE UNITS?
	ADD A,C			;YES. GET OFFSET IN DEVXXX TABLES FOR THIS UNIT
	RET

;NOT A UNIT DEVICE

FNDU4:	JUMPN D,FNDU3		;DOES THIS DEVICE HAVE UNITS?
	MOVE A,C		;NO. POINT TO ENTRY IN DEVXXX TABLES
	RET
; Convert number to sixbit characters

NUMSIX:	PUSH P,C
	PUSH P,B
	PUSH P,D
	MOVE C,[POINT 6,D]
	MOVEI D,0
	ANDI A,777
	CALL NUMSI1
	MOVE A,D
	POP P,D
	POP P,B
	POP P,C
	RET

NUMSI1:	IDIVI A,8
	HRLM B,(P)
	SKIPE A
	CALL NUMSI1
	HLRZ A,(P)
	ADDI A,20
	IDPB A,C
	RET

;ROUTINE TO MAKE SURE DEVICE IS AVAILABLE TO THE JOB.  IT PRESERVES
;A,B,C,D (T1,T2,T3,T4).
;CALL:	B		;AS SET UP BY CHKDES
;	DEV		;"
;	CALL DEVAV	;IS DEVICE AVAILABLE TO THIS JOB ?
;RETURN:
;	+1		;NO.
;	+2		;YES

DEVAV::	SAVET		;PRESERVE TEMPS FOR CALLER
	SE1CAL
	HLRZ D,DEVUNT(B);GET ASSIGNER'S JOB #
	CAMN D,JOBNO	;ASSIGNED BY THIS JOB ?
	RETSKP		;YES, SO DEVICE IS AVAILABLE.
	CAIE D,-1	;IS DEVICE UNASSIGNED ?
	JRST DEVAV9	;ASSIGNED TO SOMEONE ELSE, INVESTIGATE PTY POSSIBILITY
	MOVEI B,0(DEV)	;GET DEVICE TYPE OF UNASSIGNED DEVICE
	CAIN B,PTYDTB	;A PTY?
	JRST DEVAV1	;YES.
	CAIN B,TTYDTB	;TTY?
	JRST DEVAV2	;YES, MAYBE A PTY.
	CAIN B,MTADTB		;IS THIS A MAGTAPE?
	JRST [	HLRZ B,DEV	;YES, SEE IF IT IS REALLY THERE
		SKIPN MTCUTB(B)	;IS THERE A DRIVE PHYSICALLY THERE?
		RET		;NO
		JRST .+1]	;YES
	RETSKP		;DEVICE IS O.K.
DEVAV1:	HLRZ B,DEV	;GET UNIT # OF PTY
	CALL PTYTTY	;CONVERT TO TTY NUMBER
	MOVEI A,.TTDES(B) ;GET TERMINAL DESIGNATOR (400000+N)
DEVAV3:	PUSH P,DEV	;SAVE ORIGINAL DEVICE
	CALL CHKDES	;GET INDEX FOR TABLES
	BUG(CHK,DEVUCF,<DEVAV - UNEXPECTED CHKDES FAILURE>)
	POP P,DEV	;RESTORE ORIGINAL DEVICE
	HLRZ A,DEVUNT(B)	;SEE WHO ASSIGNED THE TTY
	CAME A,JOBNO	;THIS JOB?
	CAIN A,-1	;OR NOONE?
	RETSKP		;YES, SO IT'S AVAILABLE
	RET		;DEVICE NOT AVAILABLE
DEVAV2:	HLRZ A,DEV	;GET TTY UNIT #
	CALL CHKPTY	;IS IT A PTY?
	 RETSKP		;NO, SO IT'S AVAILABLE
	HRLI A,.DVDES+.DVPTY ;MAKE PTY DEVICE DESIGNATOR
	JRST DEVAV3	;GO CHECK FOR PTY AVAILABILITY
DEVAV9:	MOVEI A,TTYDTB
	CAIE A,(DEV)	;IS THIS DEVICE A TERMINAL?
	RET		;NO SO DEVICE IS DEFINITELY NOT AVAILABLE
	HLRZ A,DEV	;YES, GET ITS LINE NO
	CALL PTCHKA	;SEE IF THIS TTY CONTROLLED BY OUR OWN PTY
	JUMPGE A,R	;NO, SO IT'S UNAVAILABLE
	RETSKP		;YES SO IT'S AVAILABLE
; Routine to convert ascii to sixbit
; Call:	A	; Lookup pointer
;	CALL ASCSIX	; For six characters
; Or
;	CALL ASC3SX	; For three characters
;RETURNS +1: ERROR, TOO MANY CHARS OR NON-SIXBIT CHAR ENCOUNTERED
;	+2: SUCCESS, A/ SIXBIT, B/ MASK

ASCSIX::SKIPA C,[6]
ASC3SX::MOVEI C,3
	HRLI A,(<POINT 7,0,35>)
	PUSH P,A
	SETZB A,B
	PUSH P,D
ASCSX1:	ILDB D,-1(P)
	JUMPE D,ASCSX3		; Null, done
	SOJL C,ASCSXR		; Too many characters, error
	SUBI D,40
	JUMPL D,ASCSXR		; Not sixbit
	CAIL D,100
	JRST ASCSXR
	ROTC A,6
	IOR A,D
	IORI B,77
	JRST ASCSX1

ASCSX4:	ROTC A,6
ASCSX3:	TLNN B,770000	;TEST MASK FOR COMPLETION
	JUMPN A,ASCSX4
	AOS -2(P)
ASCSXR:	POP P,D
	POP P,C
	RET
;DUMMY ROUTINES FOR BIDIRECTIONAL I/O

BIOINP::TQOE <FILINP>		;ALREADY DOING INPUT?
	RET			;YES. ALL DONE THEN
	TQZ <FILOUP>		;NO. SO NOT DOING OUTPUT ANYMORE
	RET			;AND DONE

;FO OUTPUT NOW

BIOOUT::TQOE <FILOUP>		;NOW DOING OUTPUT?
	RET			;YES. DONE
	TQZ <FILINP>		;NO. SO NOT DOING OUTPUT ANYMORE
	RET			;AND DONE

	TNXEND
	END