Google
 

Trailing-Edge - PDP-10 Archives - bb-m780a-sm - monitor-sources/device.mac
There are 53 other files named device.mac in the archive. Click here to see a list.
; UPD ID= 175, SNARK:<5.MONITOR>DEVICE.MAC.8,  15-Sep-81 11:51:34 by MOSER
;TCO 5.1511 MOVE 5.1499 TO IO.MAC WHERE IT BELONGS IT CAUSES PROBLEMS HERE.
; UPD ID= 158, SNARK:<5.MONITOR>DEVICE.MAC.7,   9-Sep-81 15:56:38 by MOSER
;TCO 5.1499 WHEN SETTING UP FOR READ AFTER WRITING INSURE THAT FILCNT IS
; CORRECT FOR READ SO EOF WILL BE SEEN.
; UPD ID= 1223, SNARK:<5.MONITOR>DEVICE.MAC.6,   3-Nov-80 14:53:15 by DONAHUE
;MORE TCO 5.1164 - DELETE CHANGES TO THIS MODULE, FIX IS IN GTJFN
; UPD ID= 1123, SNARK:<5.MONITOR>DEVICE.MAC.5,   3-Oct-80 16:49:36 by DONAHUE
;ADD TCO NUMBER TO COMMENT AT DEVLKE
; UPD ID= 1109, SNARK:<5.MONITOR>DEVICE.MAC.4,   2-Oct-80 13:49:25 by DONAHUE
;TCO 5.1164 - DON'T CHECK PARSE ONLY BIT AT DEVLKE
; UPD ID= 960, SNARK:<5.MONITOR>DEVICE.MAC.3,  25-Aug-80 16:25:38 by ENGEL
;TCO 5.1136 - ADD DEVLKK
; UPD ID= 653, SNARK:<5.MONITOR>DEVICE.MAC.2,  16-Jun-80 17:00:04 by OSMAN
;tco 5.1050 - Make jfn on TTY: use fork's controlling terminal
;<OSMAN.MON>DEVICE.MAC.1, 10-Sep-79 15:21:02, EDIT BY OSMAN
;TCO 4.2412 - Move definition of BUGHLTs, BUGCHKs, and BUGINFs to BUGS.MAC
;<4.MONITOR>DEVICE.MAC.108, 27-Jul-79 15:00:52, EDIT BY HELLIWELL
;FIX BUG AT DEVLK7 WHICH SCREWED UP DEVICE DESIGNATOR FOR MOUNTABLE DEVICES (DECTAPE)
;<4.MONITOR>DEVICE.MAC.107, 26-Apr-79 10:51:57, Edit by KONEN
;<4.MONITOR>DEVICE.MAC.106, 22-Apr-79 21:29:01, Edit by KONEN
;CHANGE INITING JOB IN SDB TO INITING FORK
;<4.MONITOR>DEVICE.MAC.105,  4-Mar-79 15:00:49, EDIT BY KONEN
;UPDATE COPYRIGHT FOR RELEASE 4


;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,1979 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
	LCKINI DEVLKK		;INIT THE LOCK
	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
	ANDI A,DV%UNT		;MASK OFF UNIT BITS
	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(TTNAC8)
	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
	MOVE A,FORKN		;SEE WHICH FORK OF JOB WE ARE
	LOAD A,FRKTTY,(A)	;GET OUR CONTROLLING TERMINAL
	CAIE A,-1		;OTHER THAN JOB CONTROLLING TERMINAL?
	JRST [	TXZ A,.TTDES	;YES, MAKE TERMINAL NUMBER
		JRST DEVLK4]	;USE FORK'S TERMINAL AS "TTY"
	HLRZ A,JOBPT(B)		;NO FORK TERMINAL, USE JOB'S.
	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)
	ANDI A,DV%UNT
	CAIN A,DV%UNT
	MOVEI A,-1		;SET TO -1
	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)
	HRRZ D,DEVUNT(B)	;SET UP UNIT NUMBER IN DEV
	ANDI D,DV%UNT
	CAIN D,DV%UNT		;CHECK FOR -1
	SETO D,0		;MAKE IT -1
	HRL DEV,D
	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 FORK INITING STR
	CAMN D,FORKX		;THIS FORK?
	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 A,777000		;YES. CONSTRUCT DEV DESIG
	TLO A,.DVDES
	HRR A,DEVUNT(B)
	TRC A,DV%UNT		;TOGGLE UNIT NUMBER
	TRCN A,DV%UNT		;TOGGLE BACK, TEST FOR ALL 1'S
	TRO A,-1		;AND MAKE ENTIRE HW 1'S
	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
	ANDI D,DV%UNT
	CAIN D,DV%UNT		;CHECK FOR -1
	SETO D,0		;MAKE IT -1
	MOVE D,STRTAB(D)	;POINT TO START OF SDB FOR THIS STRUCTURE
	LOAD D,STRJB,(D)	;GET FORK THAT IS ININIALIZING
	CAMN D,FORKX		;IS IT THIS FORK?
	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:	STKVAR <CHKDVD,CHKDVU,CHKCSZ>
CHKDS1:	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)

	MOVSI D,-NINIDV		;NUMBER OF DEVICES
	MOVEM A,CHKDVD		;SAVE DEVICE DESCRIPTOR
	ANDI A,DV%UNT		;GET UNIT
	CAIN A,DV%UNT		;CHECK FOR -1
	SETZ A,0		;SET TO UNIT 0
	HRRZM A,CHKDVU		;SAVE UNIT REQUESTED
	SETZB B,CHKCSZ		;GET SIZE
CHKDVL:	HLLZ A,CHKDVD		;GET DESCRIPTOR
	ADD B,CHKCSZ		;POINT TO NEXT UNIT SET
	HRRZ C,INIDVT+3(D)	;GET COUNT OF UNITS
	ANDI C,DV%UNT		;MASK OFF UNIT BITS
	CAIE C,DV%UNT		;CHECK FOR DV%UNT (-1)
	SKIPN C			;CHECK FOR 0
	MOVEI C,1		;SET FOR 1 UNIT
	MOVEM C,CHKCSZ		;SAVE SIZE
	CAMG C,CHKDVU		;GGAL UNIT SIZE?
	JRST CHKDV1		;NOT LEGAL UNIT
	HLLZ C,INIDVT+2(D)	;GET DEVICE DESCRIPTOR
	TLZ C,777000		;MASK UNITS
	CAME A,C		;MATCH?
CHKDV1:	JRST [	ADD D,BHC+DVTSTP-1 ;UPDATE COUNT
		AOBJN D,CHKDVL	;TRY NEXT UNIT
		JRST CHKDV4]	;NONE FOUND
	MOVE C,B		;GET UNIT REQUESTED
	ADD C,CHKDVU		;GET CURRENT UNIT
	HRR A,DEVUNT(C)		;GET CURRENT UNIT AND FLAGS
	HLL A,DEVCHR(C)		;GET CHARACTERISTICS
	TLZ A,777000		;GET RID OF .DV BITS
	CAME A,CHKDVD		;CHECK TO SEE IF DEVICE MATCH
	JRST CHKDV1		;NO TRY NEXT ONE

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

	MOVE B,C		;GET OFFSET INTO TABLES
	MOVE A,DEVCH1(B)	;GET SECOND CHARACTERISTICS WORD
	TXNE A,D1%NIU		;IS SLOT IN USE?
	JRST CHKDV4		;NO
	HRRZ A,CHKDVU		; 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 CHKDS1		; 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

CHKDV4:	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(NOFNDU)

;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(DEVUCF)
	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