Google
 

Trailing-Edge - PDP-10 Archives - BB-M080V-SM_1990 - monitor-sources/device.mac
There are 53 other files named device.mac in the archive. Click here to see a list.
; Edit= 8880 to DEVICE.MAC on 10-Aug-88 by RASPUZZI
;Update BUG. documentation. 
; UPD ID= 8501, RIP:<7.MONITOR>DEVICE.MAC.2,   9-Feb-88 14:52:00 by GSCOTT
;TCO 7.1218 - Update copyright notice.
; UPD ID= 2062, SNARK:<6.1.MONITOR>DEVICE.MAC.14,   3-Jun-85 14:28:39 by MCCOLLUM
;TCO 6.1.1406  - Update copyright notice.
; UPD ID= 1892, SNARK:<6.1.MONITOR>DEVICE.MAC.13,   4-May-85 15:30:02 by MCCOLLUM
;TCO 6.1.1238 - Fix more BUG. documentation
; UPD ID= 1870, SNARK:<6.1.MONITOR>DEVICE.MAC.12,   4-May-85 11:21:20 by MCCOLLUM
;TCO 6.1.1238 - Fix more BUG. documentation
; UPD ID= 1815, SNARK:<6.1.MONITOR>DEVICE.MAC.11,  24-Apr-85 15:22:42 by MCCOLLUM
;TCO 6.1.1238 - Fix BUG. documentation
; UPD ID= 4529, SNARK:<6.MONITOR>DEVICE.MAC.10,  14-Jul-84 09:32:26 by PURRETTA
;Update copyright statement
; UPD ID= 2859, SNARK:<6.MONITOR>DEVICE.MAC.9,  23-Aug-83 15:06:00 by LOMARTIRE
;TCO 6.1692 - Change macro name from LCKINI to INILCK so routine is usable
; UPD ID= 2438, SNARK:<6.MONITOR>DEVICE.MAC.8,   6-May-83 11:29:06 by LOMARTIRE
;TCO 6.1628 - Try to prevent NOFNDU in FNDUNT.  If FILDEV=0, use DEV instead.
;  	      DEV is setup by CHKJFN to contain FILDEV.
; UPD ID= 1391, SNARK:<6.MONITOR>DEVICE.MAC.7,  29-Oct-82 14:03:49 by COBB
;TCO 6.1337 - Check FILDEV on entry to FNDUNT.  If 0, give NOFNDU BUGHLT
; UPD ID= 1025, SNARK:<6.MONITOR>DEVICE.MAC.6,   2-Aug-82 11:12:14 by PAETZOLD
;TCO 6.1203 - Rewrite NUMSIX so it does not put us into section zero
; UPD ID= 857, SNARK:<6.MONITOR>DEVICE.MAC.5,   7-Jun-82 09:38:38 by MURPHY
;TCO 6.1147 - Move bugdefs from BUGS.MAC to here and put them in-line.
; UPD ID= 214, SNARK:<6.MONITOR>DEVICE.MAC.4,  20-Nov-81 16:46:13 by MCINTEE
;correction of TCO 6.1030; make MDDOK & TSTCHR safer - HRRZ instead of MOVE
; UPD ID= 130, SNARK:<6.MONITOR>DEVICE.MAC.3,  19-Oct-81 15:04:36 by COBB
;TCO 6.1029 - CHANGE SE1CAL TO EA.ENT
;<6.MONITOR>DEVICE.MAC.2, 16-Oct-81 17:49:55, EDIT BY MURPHY
;TCO 6.1030 - Node names in filespecs; etc.
;Revise DTB format; get rid of double skips on NLUKD, etc.
; 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

;	COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1976, 1988.
;	ALL RIGHTS RESERVED.
;
;	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 THAT IS NOT SUPPLIED BY DIGITAL.
	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::EA.ENT
	INILCK 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.(HLT,TTNAC8,DEVICE,SOFT,<Cannot assign terminal at DEVINI>,,<

Cause:	The monitor could not assign a terminal to a job because
	    1.  It failed to get resident storage.
	    2.  The line is not fully active; it is okay for system messages
		and sendalls.  Need a CNTRL/C on line.
	    3.  Or a programming error.
>)
	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:: EA.ENT
	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::EA.ENT
	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
	EA.ENT
	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
	EA.ENT
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
;DSKOK - SEE IF THE DEVICE IS DSK
; BLCAL. DSKOK,<X>
;	WHERE X IS A DEVICE DISPATCH TABLE ADDRESS, E.G. FILDEV(JFN)
; RETURN +1: NOT DSK
;	+2: DSK

DSKOK::	BLSUB. <DTB>
	SAVEAC <T1>
	HRRZ T1,DTB
	CAIE T1,DSKDTB		;THE DSK DTB?
	RET			;NO
	RETSKP			;YES

	ENDBS.

;MDDOK - SEE IF THE DEVICE SUPPORTS MULTIPLE-DIRECTORY FUNCTIONS
; BLCAL. MDDOK,<X>
;	WHERE X IS A DEVICE DISPATCH TABLE ADDRESS, E.G. FILDEV(JFN)
; RETURN +1: NOT MDD
;	+2: MDD

MDDOK::	BLSUB. <DTB>
	SAVEAC <T1>
	HRRZ T1,DTB
	CALL FNDUX		;GET DEVICE TABLE INDEX
	 TDZA T1,T1		;NO SUCH, USE  0
	MOVE T1,DEVCHR(T1)	;GET CHARACTERISTICS
	TXNN T1,DV%MDD		;MDD DEVICE?
	RET			;NO
	RETSKP			;YES

	ENDBS.

;TSTCHR - TEST FOR SPECIFIED BITS IN DEVCHR, SKIP IF NOT 0
; BLCAL. TSTCHR,<[BITS],DEV>
;	WHERE BITS IS A MASK TO BE USED
;		X IS A DEVICE DISPATCH TABLE ADDRESS, E.G. FILDEV(JFN)
; RETURN +1: ALL MASKED BITS 0
;	+2: NOT ALL MASKED BITS 0

TSTCHR::BLSUB. <CBITS,DTB>
	SAVEAC <T1>
	HRRZ T1,DTB
	CALL FNDUX		;GET DEVICE TABLE INDEX
	 TDZA T1,T1		;NO SUCH, USE 0
	MOVE T1,DEVCHR(T1)	;GET CHARACTERISTICS
	TDNN T1,CBITS		;TEST AGAINST ARG
	RET
	RETSKP

	ENDBS.
;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::SKIPN T1,FILDEV(JFN)	;GET DEVICE INFO
	SKIPE T1,DEV		;FILDEV=0, SO TRY DEV INSTEAD
	CALL FNDUX		;LOOKUP
	 BUG.(HLT,NOFNDU,DEVICE,SOFT,<FNDUNT - Cannot find device for JFN>,,<

Cause:	The block that describes the JFN, or the table used to initialize
	the device for the JFN, is clobbered or zero.  If this JFN is not
	locked, another fork may have closed this JFN or otherwise modified
	FILXXX variables, causing this situation.
>)
	RET			;SUCCESS

FNDUX:	SASUBR <FNDA,FNDB,FNDC,FNDD>
	MOVSI B,-<NINIDV/DVTSTP>;SETUP TO SCAN INITIAL DEVICE TABLE
FNDU1:	HRRZ C,FNDA		;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
	RET			;NOT FOUND

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

FNDU2:	HLRZ A,FNDA		;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
	MOVEM A,FNDA
	RETSKP

;NOT A UNIT DEVICE

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

NUMSIX:				;CONVERT NUMBER IN T1 TO SIXBIT
	SAVEAC <T2,T3,T4>	;SAVE OTHER ACS
	ANDI T1,777		;TURN OFF UNWANTED BITS
	SETZ T4,		;ZERO THE COUNT
NUMSXL:				;LOOP FOR GETTING CHARACTERS
	IDIVI T1,10		;GET AN OCTAL DIGIT
	ADDI T2,20		;CONVERT TO SIXBIT
	PUSH P,T2		;SAVE IT ON THE STACK
	SKIPE T1		;ARE WE DONE?
	 AOJA T4,NUMSXL		;NO SO KEEP GETTING DIGITS
	MOVE T3,[POINT 6,T1]	;YES SO GET BYTE POINTER
NUMSX2:				;LOOP FOR SOTRING SIXBIT
	POP P,T2		;GET A CHARACTER OFF THE STACK
	IDPB T2,T3		;PUT IT WHERE IT BELONGS
	SOJGE T4,NUMSX2		;LOOP FOR ALL THE CHARACTERS
	RET			;RETURN TO CALLER

;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
	EA.ENT
	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,DEVICE,SOFT,<DEVAV - Unexpected CHKDES failure>,,<

Cause:	While checking to see if a device is available to the job,
	an invalid device designator was passed to a subroutine.

Action:	If this problem persists, submit a dump provided by the DOB%
	facility or create a dump by changing this to a BUGHLT. Look
	at the dump and see who the caller is that is passing in bad
	information.
>)
	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