Google
 

Trailing-Edge - PDP-10 Archives - BB-X116A-BB_1984 - tsc.mac
There are 3 other files named tsc.mac in the archive. Click here to see a list.
	TITLE	TSC	NFT Terminal Services Controller module
	SUBTTL	Robert Houk/RDH

	SEARCH	JOBDAT,MACTEN,UUOSYM	;STANDARD DEFINITIONS
	SEARCH	NFTDEF			;NFT-WIDE DEFINITIONS
	SEARCH	SWIL			;SWIL PACKAGE DEFINITIONS

	SALL				;PRETTY LISTINGS
	.DIREC	FLBLST			;PRETTIER LISTINGS

	TWOSEG	400000			;NICE PURE CODE

Copyright (C) Digital Equipment Corporation 1984.

	COMMENT	\

TSC  --  NFT "Terminal Service Controller" module

Copyright (C) 1984
Digital Equipment Corporation, Maynard, Massachusetts, U.S.A.

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.

\
	SUBTTL	Revision history

;INITIAL VERSION CREATED FROM NIK 25-MAR-80
	SUBTTL	External linkages

;TO NFT ERROR ROUTINES

EXTERN	ERRMSG			;ERROR MESSAGE PROCESSOR


;TO NFT/SCAN INTERFACE

EXTERN	INX,	OUX		;ALLOCATE FSB'S
EXTERN	CLRFIL,	CLRALL		;CLEAR FOR NEW SPECS
EXTERN	CLRSTK,	MEMSTK,	APLSTK	;STICKY DEFAULT PROCESSORS
	SUBTTL	Symbol definitions

COMMENT	\

Throughout this program the two terms "controlling terminal" and
"dataset terminal" appear. Controlling terminal is used to refer
to the logically controlling terminal of the linked pair (which
is typically the job's controlling terminal). Dataset terminal is
used to refer to the linked or controlled terminal, which is pre-
sumed to be a dataset terminal with a Bell 801 autodialer.
\

;THE ACS

	CM=14	;CHARACTER/DATA MUNGING
	FL=15	;FLAGS
;PROGRAM FLAGS

PSISON==1B00	;PSI SYSTEM IS ON (USED AS INITIALIZATION FLAG)
IOCOPN==1B01	;CONTROLLING TERMINAL I/O CHANNEL OPEN
IODOPN==1B02	;DATASET TERMINAL I/O CHANNEL OPEN
LGIOPN==1B03	;INPUT (TYPEIN) LOGGING CHANNEL OPEN
LGINOW==1B04	;INPUT (TYPEIN) LOGGING NOW IN EFFECT
LGOOPN==1B05	;OUTPUT (TYPEOUT) LOGGING CHANNEL OPEN
LGONOW==1B06	;OUTPUT (TYPEOUT) LOGGING NOW IN EFFECT

;I/O CONTROL FLAGS

IOXFLG==1B18	;SOMETHING SOMEWHERE HAPPENED (AT INTERRUPT LEVEL)

IOCINP==1B19	;CONTROLLING TERMINAL HAS INPUT PENDING
IOCOUF==1B20	;CONTROLLING TERMINAL NEEDS AN OUT UUO
IOCOUP==1B21	;CONTROLLING TERMINAL HAS OUTPUT PENDING
IOCEOF==1B22	;CONTROLLING TERMINAL "EOF" (I.E., ^\ TYPED)
IOCIOE==1B23	;CONTROLLING TERMINAL I/O ERROR
  IOCCLR==IOCOPN!IOCINP!IOCOUF!IOCOUP!IOCEOF!IOCIOE

IODINP==1B24	;DATASET TERMINAL HAS INPUT PENDING
IODOUF==1B25	;DATASET TERMINAL NEEDS AN OUT UUO
IODOUP==1B26	;DATASET TERMINAL HAS OUTPUT PENDING
IODIOE==1B27	;DATASET TERMINAL I/O ERROR
IODPNM==1B28	;DATASET TERMINAL DIALED OUT
  IODCLR==IODOPN!IODINP!IODOUF!IODOUP!IODIOE!IODPNM


;OTHER STUFF

	PDLEN==^D50

;I/O CHANNELS OF INTEREST

	IOC==2		;CONTROLLING TTY
	IOD==3		;DATASET (CONTROLLED) TTY
	LGI==4		;INPUT (TYPEIN) LOGGING CHANNEL
	LGO==5		;OUTPUT (TYPEOUT) LOGGING CHANNEL OPEN
	SUBTTL	Command base table

	DEFINE	CMNDS,<

CM	DLINK,DLI,<Establish DATA link via [dataset/remote] terminal line>
CM	RESET,TRES,<Reset all I/O, return to initial state>
CM	TLINK,TLI,<Establish TTY link via [dataset/remote] terminal line>

IFN FT$FAL,<
CM	FAL,TFAL,<Enter FAL mode>
>

IFN FT$NIP,<
CM	NIP,TNIP,<Enter NIP mode>
>

> ;END OF COMMANDS MACRO


;NOW BUILD THE TSC COMMAND BASE TABLE

DOCMND(TSC)
	SUBTTL	TSC Command

TSC::	PUSHJ	P,TSC00		;DO TSC-STARTUP STUFF
	 JFCL			;HUH?
	PUSHJ	P,.CLEOL##	;CLEAR UP ANY JUNK LEFT OVER IN COMMAND
	JRST	.POPJ1##	;SUCCESSFUL RETURN


;TSC STARTUP STUFF

TSC00:	MOVEI	CM,PSIVEC	;BASE OF PSI VECTORS
	PIINI.	CM,		;INITIALIZE THE PSI SYSTEM
	 ERROR	PIF,<PIINI. failed>,PSIER,CM

;SELECT COMMAND DISPATCH

	MOVEI	T1,TSCBAS	;TSC COMMAND BASE
	MOVEM	T1,CMDBAS##	;SET NEW COMMAND BASE
	SETZ	FL,		;INITIALIZE ALL TSC FLAGS
	SETOM	IGNRFF##	;IGNORE .JBFF FOR AWHILE
	XMOVEI	T1,TSCEX	;OUR VERY OWN "EXIT" PROCESSOR
	MOVEM	T1,NFTXRT##	;INTERCEPT "EXIT" COMMANDS

;ALL DONE, READY FOR NORMAL TSC COMMAND PROCESSING

	JRST	.POPJ1##	;START PARSING COMMANDS
	SUBTTL	DLINK command

DLINK::	PUSHJ	P,TSC00		;SWITCH TO TSC MODE
	 POPJ	P,		;DUH?

DLI:	ERROR	DNY,<DLINK command not yet implemented>
	SUBTTL	TLINK command

;TLINK - EXTERNAL ENTRY FROM NIP MODE

TLINK::	PUSHJ	P,TSC00		;SWITCH TO TSC MODE
	 POPJ	P,		;DUH?

;TLINK - INTERNAL COMMAND DISPATCH POINT

TLI:	TXNN	FL,IODOPN	;DATASET TERMINAL ALREADY OPEN?
	JRST	TLI20		;NO, READ IN DATASET TERMINAL SPEC

;DATASET TERMINAL IS ALREADY OPEN (PREVIOUS TLINK COMMAND)
;JUST REENTER I/O LINK LOOP

	SKIPE	SIFIR##		;STILL GOT INPUT
	SKIPN	SOFIR##		;AND OUTPUT FILE SPECS?
	ERROR	TLS,<TLINK command lost old SCAN blocks>
	JUMPLE	CH,TLI50	;YES, COMMAND SHOULD HAVE ENDED HERE
	ERROR	DAO,<Dataset terminal already TLINKed>

;READ IN SPEC FOR DATASET TERMINAL

TLI20:	JUMPLE	CH,ERRNIF##	;EOL HERE IS JUNK
	SKIPN	SIFIR##		;ALREADY HAVE INPUT
	SKIPE	SOFIR##		;AND/OR OUTPUT SPECS?
	ERROR	THS,<TLINK command still has SCAN blocks>
	PUSHJ	P,TLIC		;FINISH OFF THE TLINK COMMAND LINE
	 JRST	TLIER		;JUNK
	PUSHJ	P,TLID		;SET UP ANY DEFAULTS
	 JRST	TLIER		;JUNK
TLI50:	PUSHJ	P,TLIL		;LINK THE TWO TERMINALS TOGETHER
	 JRST	TLIER		;JUNK

;ALL DONE WITH TLINK COMMAND (BUT NOTE TERMINAL MAY STILL BE OPEN
;AWAITING FURTHER BLABBING

	JRST	.POPJ1##	;RETURN HAPPILY


;HERE ON ERROR

TLIER:	PUSHJ	P,TRES		;SEE WHAT WE CAN RECLAIM
	 JFCL			;DUH?
	POPJ	P,		;ERROR RETURN
;HERE TO READ REST OF TLINK COMMAND (TERMINAL SPECS)

TLIC:;	SKIPE	SIFIR##		;JUST CHECKING
;	STOPCD			;SOMEONE LEFT SOMETHING LYING AROUND
	PUSHJ	P,.REEAT##	;ALREADY HAVE FIRST CHARACTER IN CH!
	MOVE	T1,[TLITL,,TLITS]  ;.TSCAN BLOCK
	PUSHJ	P,.TSCAN##	;READ A COMMAND LINE
	PUSHJ	P,CLRFIL	;CLEAR FILE ANSWERS BEFORE SWITCH.INI
	MOVE	T1,[TLIOL,,TLIOS]  ;.OSCAN BLOCK
	PUSHJ	P,.OSCAN##	;CHECK SWITCH.INI

;ALL FOR NOW

	JRST	.POPJ1##	;SUCCESSFUL RETURN
;HERE TO SUPPLY ANY TLINK DEFAULTS

TLID:	SKIPN	P1,SIFIR##	;ADDRESS OF FIRST INPUT FILE SPEC BLOCK
	JRST	ERRNIF##	;NO INPUT (DATASET) TERMINAL?

;SETUP INPUT OR DATASET TERMINAL DEFAULTS

TLID02:	MOVE	T1,P1		;ADDRESS OF CURRENT INPUT SPEC
	MOVEI	T2,.FXLEN	;AND ITS LENGTH
	PUSHJ	P,DOOSDF##	;APPLY SWITCH.INI DEFAULTS
	MOVE	T1,.FXNAM(P1)	;GET NAME IN CASE NO DEVICE
	SKIPN	.FXDEV(P1)	;EXPLICIT DEVICE SPECIFIED?
	MOVEM	T1,.FXDEV(P1)	;USE FILENAME THEN (USER DIDN'T TYPE ":")
	SKIPN	.FXDEV(P1)	;HAVE A DEVICE?
	  ERROR	DNS,<Device not specified>,,,
	ADDI	P1,.FXLEN	;STEP TO NEXT SPEC
	CAMG	P1,SILAS##	;REACHED LAST ONE YET?
	JRST	TLID02		;NOPE, LOOP BACK FOR MORE DEFAULTS

;NOW SETUP OUTPUT OR CONTROLLING TERMINAL DEFAULTS

	SKIPE	P2,SOFIR##	;GET OUTPUT (CONTROLLING) TERMINAL FSB
	JRST	TLID20		;AND SET IT UP

;NO OUTPUT TERMINAL, USE DEVICE "TTY:"

	PUSHJ	P,CLRFIL	;CLEAR FILE SWITCHES/ETC.
	PUSHJ	P,OUX		;GET AN OUTPUT FILE SPEC BLOCK
	MOVE	P2,SOFIR##	;GET IT'S ADDRESS

TLID20:	SKIPN	T1,.FXNAM(P2)	;GET NAME IN CASE NO DEVICE
	MOVSI	T1,'TTY'	;USE CONTROLLING TTY IF NOTHING GIVEN
	SKIPN	.FXDEV(P2)	;EXPLICIT DEVICE GIVEN?
	MOVEM	T1,.FXDEV(P2)	;NO, USE NAME THEN

;ALL DEFAULTS SETUP

	JRST	.POPJ1##	;SUCCESSFUL RETURN
;HERE TO ENTER MAIN TERMINAL LINK LOOP

TLIL:	MOVEI	T1,10		;PRESET DATASET TERMINAL ABORT LIMIT
	MOVEM	T1,IODECT	; . . .
	MOVE	P1,SIFIR##	;DATASET TERMINAL SCAN BLOCK
	MOVE	P2,SOFIR##	;CONTROLLING TERMINAL SCAN BLOCK
	PUSHJ	P,OPIOD		;OPEN DATASET TERMINAL FOR I/O
	 POPJ	P,		;DIED, BACK TO COMMAND LEVEL
	PUSHJ	P,OPIOC		;OPEN CONTROLLING TERMINAL FOR I/O
	 POPJ	P,		;DIED, BACK TO COMMAND LEVEL
	PUSHJ	P,OPPSI		;ENABLE PSI, GENERAL FINAL INITIALIZATION
	 POPJ	P,		;DIED, BACK TO COMMAND LEVEL
	INFRM	TLC,<Terminal link complete and ready for I/O>
	PUSHJ	P,TLIO		;GO TO TTY TRANSFER LOOP
	 POPJ	P,		;DIED, BACK TO COMMAND LEVEL

;ALL DONE, LOOK FOR MORE COMMANDS (BUT NOTE THAT THE DATASET TERMINAL
;IS STILL OPENED FOR I/O)

	JRST	.POPJ1##	;RETURN TO COMMAND SCANNER
;TLINK SWITCH DEFINITIONS

DEFINE	SWTCHS,<
SP	DIAL,<POINT <^D65-2>,S.DIAL##>,.SWPNM##,,
>

DOSCAN(TLISW)


;"TLINK" TSCAN PARAMETER BLOCK

TLITS:	EXP	FXVRSN		;PROTOCOL VERSION WORD
	IOWD	TLISWL,TLISWN	;IOWD POINTER FOR SWITCH NAMES
	XWD	TLISWD,TLISWM	;DEFAULT TABLE,,PROCESSOR TABLE
	XWD	0,TLISWP	;<FUTURE>,,STORAGE POINTERS
	SIXBIT	/TSC/		;HELP
	XWD	CLRALL,CLRFIL	;CLEAR ALL,,CLEAR FILE
	XWD	INX,OUX		;ALLOC INPUT AREA,,ALLOC OUTPUT AREA
	XWD	MEMSTK,APLSTK	;MEMORIZE STICKY,,APPLY STICKY
	XWD	CLRSTK,0	;CLEAR STICKY,,FLAGS
	Z			;<FUTURE>,,SWITCH VALUE STORAGE RTN

	TLITL==.-TLITS


;OSCAN BLOCK

TLIOS:	EXP	FXVRSN		;PROTOCOL VERSION WORD
	IOWD	TLISWL,TLISWN	;IOWD POINTER FOR SWITCH NAMES
	XWD	TLISWD,TLISWM	;DEFAULT TABLE,,PROCESSOR TABLE
	XWD	0,TLISWP	;<FUTURE>,,STORAGE POINTERS
	SIXBIT	/TSC/		;HELP
	XWD	TLIOSL,TLIOSN	;OPTIONS NAME(S)

	TLIOL==.-TLIOS


TLIOSN:	SIXBIT	\TLINK\
	SIXBIT	\TSC\

	TLIOSL==.-TLIOSN
	SUBTTL	RESET command

TRES:	TXZN	FL,PSISON	;PSI SYSTEM ON?
	JRST	TRES2		;NO
	MOVX	CM,PS.FOF	;PSI CONTROL FLAGS TO
	PISYS.	CM,		;TURN OFF THE PSI SYSTEM
	  WARN	PFF,<PISYS. to turn off the PSI system failed>,PSIER,CM

TRES2:	TXZN	FL,IOCOPN	;CONTROLLING TERMINAL OPEN FOR I/O?
	JRST	TRES4		;NO
	PUSHJ	P,CLIOC		;YES, CLOSE IT OFF
	 JFCL			;DUH?

TRES4:	TXZN	FL,IODOPN	;DATASET TERMINAL OPEN FOR I/O?
	JRST	TRES9		;NO
	PUSHJ	P,CLIOD		;YES, CLOSE IF OFF
	 JFCL			;DUH?

TRES9:	PUSHJ	P,FRESB##	;FREE UP THE FILE SPEC BLOCKS
	 JFCL			;HUH?
	SETZ	FL,		;NO MORE FLAGS OF INTEREST
	JRST	.POPJ1##	;ALL DONE HERE
	SUBTTL	NIP and FAL commands

IFN FT$FAL,<
TFAL:	MOVEI	T1,FAL##	;ADDRESS OF FAL-MODE ENTRY
	JRST	TNIP00		;GO SWITCH COMMAND MODES
> ;END IFN FT$FAL

IFN FT$NIP,<
TNIP:	MOVEI	T1,NIP##	;ADDRESS OF NIP-MODE ENTRY
	JRST	TNIP00		;GO SWITCH COMMAND MODES
> ;END IFN FT$NIP

TNIP00:	PUSH	P,T1		;SAVE DISPATCH ADDRESS
	PUSHJ	P,TRES		;DO A GENERIC "RESET"
	 JFCL			;DUH?
TNIP20:	SETZM	IGNRFF##	;.JBFF SHOULD BE BACK IN SYNC NOW
	SETZM	NFTXRT##	;CLEAR "EXIT" INTERCEPT
	POPJ	P,		;"DISPATCH" TO NIP OR FAL MODE PROCESSOR
SUBTTL	Command support routines

;TSCEX - "EXIT" PROCESSOR
;
;Called from SCAN on any sort of EXIT condition ("EXIT/^Z" command,
;or whatever).

TSCEX:	PUSHJ	P,TRES		;SHUT DOWN ALL I/O CONNECTIONS
	 JFCL			;WELL, WE TRIED ANYWAY
	PJRST	.MNRET##	;CAN NOW SAFELY GO TO MONITOR LEVEL
	SUBTTL	I/O support routines

;OPEN CONTROLLING TERMINAL FOR I/O

OPIOC:	TXNE	FL,IOCOPN	;CONTROLLING TERMINAL ALREADY OPEN?
	JRST	.POPJ1##	;YES, ALL SET THEN
	MOVE	T1,P2		;CONTROLLING TERMINAL SCAN BLOCK
	PUSHJ	P,TTNAM		;GENERATE SIXBIT NAME FOR OPEN
	  ERROR	CNA,<Controlling terminal not available >,CDTER,P2
	MOVE	T2,T1		;COPY IT
	MOVEM	T1,TTCNAM	;REMEMBER IT FOR ERRORS ETC.
	MOVX	T1,UU.AIO+.IOPIM;USE PACKED IMAGE MODE FOR HIM TOO
	MOVE	T3,[IOCOBH,,IOCIBH]  ;BUFFER RING CONTROL BLOCKS
	OPEN	IOC,T1		;OPEN CONTROLLING TTY
	  ERROR	COC,<Can't OPEN controlling terminal >,.TSIXN##,TTCNAM
	MOVEI	T1,IOC		;ALLEGED TERMINAL CHANNEL
	DEVCHR	T1,		;SNIFF ABOUT IT
	TXNN	T1,DV.DSK	;IF DISK (OR NUL:)
	TXNN	T1,DV.TTY	;NO, TTY?
	  ERROR	CTT,<Controlling terminal not a TTY >,.TSIXN##,TTCNAM,OPIOCE
	MOVEI	T1,IOC		;CHANNEL NUMBER
	IONDX.	T1,		;GET IT'S TERMINAL UDX
	  ERROR	ICF,<IONDX. for controlling terminal failed>,,,OPIOCE
	MOVEM	T1,TTCUDX	;SAVE IT FOR LATER TRMOP.S
	MOVEI	T1,IOCINT	;CONTROLLING TERMINAL INTERRUPT SERVICE
	MOVEM	T1,IOCVEC+.PSVNP;SET IN VECTOR BLOCK
	MOVX	T1,PS.VTO	;CONTROL MODE BIT
	MOVEM	T1,IOCVEC+.PSVFL;SET IN VECTOR BLOCK
	MOVE	CM,[PS.FAC+IOCARG]  ;ARG BLOCK TO
	PISYS.	CM,		;CONNECT CONTROLLING TERMINAL TO PSI
	  ERROR	PCF,<PISYS. for controlling terminal failed>,PSIER,CM,OPIOCE
	MOVE	T1,.JBFF	;.JBFF BEFORE IOC BUFFERS ALLOCATED
	INBUF	IOC,1		;ONLY WANT ONE-BUFFER RINGS
	OUTBUF	IOC,1		; . . .
	MOVE	T2,.JBFF	;.JBFF AFTER IOC BUFFERS ALLOCATED
	DMOVEM	T1,IOCFF	;REMEMBER FOR LATER DEALLOCATION
	TXO	FL,IOCOPN	;CONTROLLING TERMINAL READY FOR I/O
	JRST	.POPJ1##	;SUCCESSFUL RETURN


;HERE ON "OPEN" CLASS ERROR

OPIOCE:	PUSHJ	P,CLIOC		;CLOSE OFF THE CHANNEL
	 JFCL			;DUH?
	POPJ	P,		;AND ERROR RETURN
;CLOSE CONTROLLING TERMINAL CHANNEL

CLIOC:	CLOSE	IOC,		;GENTLY
	RELEAS	IOC,		; LEGGO

;TRY TO RECLAIM BUFFER(S)

	DMOVE	T1,IOCFF	;GET BACK .JBFF(S)
	JUMPE	T1,CLIOC9	;ALL DONE IF NO BUFFERS ALLOCATED YET
	CAMN	T2,.JBFF	;STILL WHAT WE LAST LEFT IT?
	MOVEM	T1,.JBFF	;YES, RECLAIM IOC BUFFERS
	SETZB	T1,T2		;CLEAR BUFFER .JBFF(S)
	DMOVEM	T1,IOCFF	;SO NO ONE ELSE LOOKS AT THEM
	SETZM	IOCIBH+.BFADR	;CLEAR OUT OLDE LINK WORD
	SETZM	IOCOBH+.BFADR	;YET ANOTHER OLDE LINK WORD

;MARK IOC AS DEFUNCT

CLIOC9:	TXZ	FL,IOCCLR	;CLEAR ALL IOC FLAGS
	JRST	.POPJ1##	;RETURN SUCCESSFULLY
;OPEN DATASET TERMINAL FOR I/O

OPIOD:	TXNE	FL,IODOPN	;DATASET TERMINAL ALREADY OPEN?
	JRST	.POPJ1##	;YES, ALL DOEN THEN
	MOVE	T1,P1		;DATASET TERMINAL SCAN BLOCK
	PUSHJ	P,TTNAM		;GET SIXBIT DEVICE NAME FOR OPEN
	  ERROR	DNA,<Dataset terminal not available >,CDTER,P1
	MOVE	T2,T1		;IN CASE DEVICE IS OK, SAVE ITS NAME
	MOVEM	T2,TTDNAM	;REMEMBER NAME USED
	MOVX	T1,UU.AIO+.IOPIM;A REAL TTY, USE PACKED IMAGE MODE
	MOVE	T3,[IODOBH,,IODIBH]  ;USER BUFFER CONTROL BLOCKS
	OPEN	IOD,T1		;OPEN DATASET TERMINAL
	  ERROR	COD,<Can't OPEN dataset terminal >,.TSIXN##,TTDNAM
	MOVEI	T1,IOD		;ALLEGED-TERMINAL CHANNEL
	DEVCHR	T1,		;ENQUIRE ABOUT IT
	TXNN	T1,DV.DSK	;A DISK (OR NUL:)?
	TXNN	T1,DV.TTY	;NO, A REAL TTY?
	  ERROR	DNT,<Dataset terminal not a TTY >,.TSIXN##,TTDNAM,OPIODE
	MOVEI	T1,IOD		;I/O CHANNEL
	IONDX.	T1,		;GET DATASET UDX
	  ERROR	IDF,<IONDX. for dataset terminal failed>,,,OPIODE
	MOVEM	T1,TTDUDX	;SAVE FOR TRMOP.S
	SKIPN	.FXPNM(P1)	;USER WANT TO DIAL A PHONE FIRST?
	JRST	OPIOD6		;NO
	INFRM	DIA,<Dialing . . .>
	MOVEI	T1,.TODSC	;TRMOP. DIAL FUNCTION
	MOVE	T2,TTDUDX	;FOR DATASET TERMINAL
	DMOVE	T3,.FXPNM(P1)	;PHONE NUMBER TO DIAL
	MOVE	CM,[4,,T1]	;TRMOP. ARG POINTER TO
	TRMOP.	CM,		;DIAL A PHONE NUMBER
	  ERROR	TFD,<TRMOP. failure dialing out>,TRMER,CM,OPIODE
	TXO	FL,IODPNM	;REMEMBER DIALED OUT SO CAN HANG UP LATER
	MOVSI	T4,-10		;WAIT 10 (8) SECONDS FOR CARRIER TO APPEAR
	TDZA	T1,T1		;SKIP INTO LOOP
OPIOD4:	MOVEI	T1,1		;ONE SECOND
	SLEEP	T1,		;WAIT FOR PHONE TO BE ANSWERED
	MOVEI	T2,.TODSS	;DATASET STATUS
	MOVE	T3,TTDUDX	;FOR DATASET TERMINAL
	MOVE	CM,[2,,T2]	;TRMOP. ARG POINTER TO
	TRMOP.	CM,		;READ DATASET STATUS
	  ERROR	CRS,<Can't read dataset status>,TRMER,CM,OPIOD6
	MOVEM	CM,DSSOLD	;REMEMBER LAST DATASET STATUS
	JUMPL	CM,OPIOD5	;IF CARRIER PRESENT, ALL SET
	TRNN	T4,-1		;IF FIRST TIME ALERT USER
	INFRM	WFC,<Waiting for carrier . . .>
	AOBJN	T4,OPIOD4	;TRY AGAIN IN A SECOND
	ERROR	TWC,<Timeout waiting for carrier>,,,OPIODE
OPIOD5:;INFRM	CAD,<Carrier detected>

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

OPIOD6:	MOVEI	T1,IODINT	;DATASET TERMINAL INTERRUPT SERVICE
	MOVEM	T1,IODVEC+.PSVNP;SET IN VECTOR BLOCK
	MOVX	T1,PS.VTO	;CONTROL MODE BIT
	MOVEM	T1,IODVEC+.PSVFL;SET IN VECTOR BLOCK
	MOVE	CM,[PS.FAC+IODARG]  ;ARG BLOCK TO
	PISYS.	CM,		;CONNECT IOD CHANNEL TO PSI SYSTEM
	  ERROR	PDF,<PISYS. for dataset terminal failed>,PSIER,CM,OPIODE
	MOVEI	T1,DSSINT	;DATASET STATUS INTERRUPT SERVICE
	MOVEM	T1,DSSVEC+.PSVNP;SET IN VECTOR BLOCK
	MOVX	T1,PS.VTO	;CONTROL MODE BIT
	MOVEM	T1,DSSVEC+.PSVFL;SET IN VECTOR BLOCK
	MOVE	CM,[PS.FAC+DSSARG]  ;ARG BLOCK TO
	PISYS.	CM,		;CONNECT TO PSI SYSTEM
	  ERROR	PDS,<PISYS. for dataset status failed>,PSIER,CM,OPIODE
	MOVE	T1,.JBFF	;.JBFF BEFORE IOD BUFFER(S)
	INBUF	IOD,1		;ALLOCATE ONE INPUT BUFFER
	OUTBUF	IOD,1		;ALLOCATE ONE OUTPUT BUFFER
	MOVE	T2,.JBFF	;.JBFF AFTER IOD BUFFERS
	DMOVEM	T1,IODFF	;SAVE FOR LATER DEALLOCATION
	TXO	FL,IODOPN	;FLAG DATASET CHANNEL READY FOR I/O
	JRST	.POPJ1##	;SUCCESSFUL RETURN


;"OPEN" TYPE OF ERROR, RESET CHANNEL AND ABORT

OPIODE:	PUSHJ	P,CLIOD		;CLOSE OFF THE CHANNEL
	 JFCL			;DUH?
	POPJ	P,		;AND ERROR RETURN
;CLOSE DATASET TERMINAL

CLIOD:	TXNN	FL,IODPNM	;DATASET TERMINAL DIALED OUT?
	JRST	CLIOD6		;NO
	MOVEI	T1,.TODSF	;YES, TRMOP. HANGUP FUNCTION
	MOVE	T2,TTDUDX	;FOR DATASET TERMINAL
	MOVE	CM,[2,,T1]	;TRMOP. ARG POINTER TO
	TRMOP.	CM,		;HANGUP CALL
	  WARN	MNH,<Dataset modem may not have hung up>,TRMER,CM
CLIOD6:	CLOSE	IOD,		;CAREFULLY
	RELEAS	IOD,		;RELEASE DATASET TERMINAL

;TRY TO RECLAIM BUFFER(S)

	DMOVE	T1,IODFF	;GET BACK .JBFF(S)
	JUMPE	T1,CLIOD9	;ALL DONE IF NO BUFFERS
	CAMN	T2,.JBFF	;STILL WHAT WE LAST LEFT IT?
	MOVEM	T1,.JBFF	;YES, RECLAIM IOD BUFFERS
	SETZB	T1,T2		;CLEAR BUFFER .JBFF(S)
	DMOVEM	T1,IODFF	;SO NO ONE ELSE LOOKS AT THEM
	SETZM	IODIBH+.BFADR	;CLEAR OUT OLDE LINK WORD
	SETZM	IODOBH+.BFADR	;YET ANOTHER OLDE LINK WORD

;MARK IOD AS DEFUNCT

CLIOD9:	TXZ	FL,IODCLR	;CLEAR ALL IOC FLAGS
	JRST	.POPJ1##	;RETURN SUCCESSFULLY
;"OPEN" PSI SYSTEM - ENABLE FOR INTERRUPTS

OPPSI:	TXNE	FL,PSISON	;ALREADY BEEN HERE?
	JRST	.POPJ1##	;YES, THEN ALL SET
	MOVX	CM,PS.FON	;PSI CONTROL FLAGS TO
	PISYS.	CM,		;TURN ON THE PSI SYSTEM
	  ERROR	PNF,<PISYS. to turn on the PSI system failed>,PSIER,CM
	TXO	FL,PSISON	;FLAG ALL INITIALIZED
	JRST	.POPJ1##	;SUCCESSFUL RETURN
	SUBTTL	Main TTY I/O loop

TLIO:	MOVX	T1,HB.RWJ!HB.RIO;WAKE ONLY ON I/O COMPLETION
	HIBER	T1,		;WAIT FOR SOMETHING IOXCITING TO HAPPEN
	  ERROR	HBF,<HIBER failed>
	TXZ	FL,IOXFLG	;WERE WE AWAKENED LEGITIMATELY?
;	WARN	SHW,<Spurious HIBER wakeup>

TLIO10:	TXNE	FL,IOCINP	;CONTROLLING TERMINAL INPUT TO PROCESS?
	PUSHJ	P,LOOPC		;YES, DO WHAT WE CAN
	TXNE	FL,IOCIOE!IODIOE;I/O ERROR ABORTION?
	POPJ	P,		;YES, PROPAGATE ERROR
	TXNE	FL,IOCEOF	;TIME TO QUIT?
	JRST	TLIO90		;YES
	TXNE	FL,IODOUF!IODOUP;ANY OUTPUT LEFT LYING AROUND?
	PUSHJ	P,DOTRY		;YEAH, TRY TO OUTPUT IT

TLIO30:	TXNE	FL,IODINP	;DATASET TERMINAL INPUT TO PROCESS?
	PUSHJ	P,LOOPD		;YES, DO WHAT WE CAN
	TXNE	FL,IOCIOE!IODIOE;I/O ERROR ABORTION?
	POPJ	P,		;YES, PROPAGATE ERROR
	TXNE	FL,IOCOUF!IOCOUP;ANY OUTPUT LEFT LYING AROUND?
	PUSHJ	P,COTRY		;YEAH, TRY TO OUTPUT IT

	TXZN	FL,IOXFLG	;SOMETHING EXCITING HAPPEN HERE?
	JRST	TLIO		;NO, WAIT AROUND
	JRST	TLIO10		;YES, SKIP HIBERING


;HERE ON ^\ FROM CONTROLLING TERMINAL, POP BACK INTO COMMAND MODE
;BUT LEAVE DATASET TERMINAL OPEN

TLIO90:	SETZM	IOCIBH+.BFCTR	;EAT ANYTHING LEFT IN THE BUFFER
	PUSHJ	P,CIBYT		;TRY TO READ ANOTHER BYTE
	 CAIA			;NO MORE (MAYBE)
	JRST	TLIO90		;KEEP EATING
	TXZE	FL,IOCEOF	;ANOTHER ^\ ?
	JRST	TLIO90		;YEAH, JUST EAT IT TOO

;INPUT EATEN, LEAVE PIM MODE AND RETURN THE CONTROLLING TERMINAL
;TO A SEMBLANCE OF SANITY (ECHOING, ASCII, ETC.)

	PUSHJ	P,CLIOC		;CLOSE OFF CONTROLLING TERMINAL
	 JFCL			;DUH?
	JRST	.POPJ1##	;ALL DONE
	SUBTTL	I/O subroutines

LOOPC:	PUSHJ	P,CIBYT		;GET CONTROLLING TERMINAL INPUT BYTE
	  POPJ	P,		;NO MORE (OR I/O ERROR)
	PUSHJ	P,DOBYT		;SEND IT TO DATASET TERMINAL
	  CAIA			;DATASET TERMINAL FULL (OR I/O ERROR)
	JRST	LOOPC		;LOOP FOR MORE CHARACTERS
	HRROM	CM,CISAV	;SAVE CHARACTER NOT YET OUTPUT
	TXO	FL,IOCINP	;NOTE INPUT STILL PENDING
	POPJ	P,		;THAT'S ALL WE CAN DO HERE

LOOPD:	PUSHJ	P,DIBYT		;GET DATASET TERMINAL INPUT BYTE
	  POPJ	P,		;NO MORE (OR I/O ERROR)
	PUSHJ	P,COBYT		;SEND IT TO CONTROLLING TERMINAL
	  CAIA			;CONTROLLING TERMINAL FULL (OR I/O ERROR)
	JRST	LOOPD		;LOOP FOR MORE CHARACTERS
	HRROM	CM,DISAV	;SAVE CHARACTER NOT YET OUTPUT
	TXO	FL,IODINP	;NOTE INPUT STILL PENDING
	POPJ	P,		;THAT'S ALL WE CAN DO HERE
;CONTROLLING TERMINAL I/O

CIBYT:	SKIPN	CM,CISAV	;SAVED INPUT CHARACTER STASHED AWAY?
	JRST	CIBYT2		;NO
	ANDI	CM,377		;YES, STRIP OFF GARBAGE
	SETZM	CISAV		;NOTE WE GOT IT BACK
	POPJ	P,		;RETURN WITH INPUT CHARACTER

CIBYT1:	TXO	FL,IOCINP	;FLAG INPUT PENDING
CIBYT2:	SOSGE	IOCIBH+.BFCTR	;ANY CHARACTERS IN BUFFER?
	JRST	CIBYT5		;NO, ASK FOR ANOTHER BUFFER
	ILDB	CM,IOCIBH+.BFPTR;YES, READ NEXT CHARACTER
	CAIE	CM,"D"-100	;^D TYPED?
	CAIN	CM,"D"-100+200	;^D (OTHER PARITY)?
CD:	JFCL			;YES (NICE PLACE FOR A BREAKPOINT)
	CAIE	CM,"\"-100	;ESCAPE TIME?
	CAIN	CM,"\"-100+200	;ESCAPE TIME (ODD PARITY)?
	TXOA	FL,IOCEOF	;FLAG TIME TO ESCAPE
	AOS	(P)		;RETURN I/O CHARACTER
	POPJ	P,		;RETURN WITH CHARACTER IN CH

CIBYT5:	TXZ	FL,IOCINP	;CLEAR INPUT PENDING
	IN	IOC,		;ASK MONITOR FOR ANOTHER BUFFER
	JRST	CIBYT1		;OH HO - GOT ONE, PROCESS INPUT
	STATO	IOC,IO.EOF!IO.ERR  ;NO INPUT, ANY ERRORS?
	POPJ	P,		;NO, JUST NOTHING THERE
	GETSTS	IOC,IOSWRD	;YES, GET I/O ERROR STATUS BITS
	TXO	FL,IOCIOE	;NOTE CONTROLLING TERMINAL I/O ERROR
	ERROR	CIE,<Controlling terminal input error, >,IOERM
COBYT:	TXZN	FL,IOCOUF	;NEED AN OUT UUO FIRST?
	JRST	COBYT5		;NO, BUFFER IS AVAILABLE
COBYT2:	OUT	IOC,		;YES, OUTPUT BUFFER, ADVANCE TO NEXT
	JRST	COBYT5		;DO STUFF CHARACTER IN OUTPUT BUFFER
COBYT3:	TXO	FL,IOCOUF	;MONITOR STUFFED, FLAG NEED AN OUT
	STATO	IOC,IO.EOF!IO.ERR  ;UNLESS I/O ERROR
	POPJ	P,		; (NO)
	GETSTS	IOC,IOSWRD	;GET I/O ERROR STATUS BITS
	TXO	FL,IOCIOE	;FLAG I/O ERROR FOR CONTROLLING TERMINAL
	ERROR	COE,<Controlling terminal output error, >,IOERM

COBYT5:	SOSGE	IOCOBH+.BFCTR	;ROOM IN OUTPUT BUFFER FOR ANOTHER CHARACTER?
	JRST	COBYT2		;NO, OUTPUT BUFFER AND GET ANOTHER
	IDPB	CM,IOCOBH+.BFPTR;YES, STUFF CHARACTER IN BUFFER
	TXO	FL,IOCOUP	;FLAG OUTPUT PENDING
	AOS	(P)		;SKIP RETURN
	POPJ	P,		; IS SUCCESSFUL RETURN



COTRY:	TXZN	FL,IOCOUF!IOCOUP;NEED TO DO CONTROLLING TERMINAL OUTPUT?
	POPJ	P,		;NO, JUST RETURN
	OUT	IOC,		;YES, TRY TO OUTPUT BUFFER
	POPJ	P,		;OUTPUT DONE, WE HAVE A BUFFER AVAILABLE
	JRST	COBYT3		;COULDN'T DO OUTPUT, CHECK FOR I/O ERROR
;DATASET TERMINAL I/O

DIBYT:	SKIPN	CM,DISAV	;SAVED INPUT CHARACTER STASHED AWAY?
	JRST	DIBYT2		;NO
	ANDI	CM,377		;YES, STRIP OFF GARBAGE
	SETZM	DISAV		;NOTE WE GOT IT BACK
	POPJ	P,		;RETURN WITH INPUT CHARACTER

DIBYT1:	TXO	FL,IODINP	;FLAG INPUT PENDING
DIBYT2:	SOSGE	IODIBH+.BFCTR	;ANY CHARACTERS IN BUFFER?
	JRST	DIBYT5		;NO, ASK FOR ANOTHER BUFFER
	ILDB	CM,IODIBH+.BFPTR;YES, READ NEXT CHARACTER
	AOS	(P)		;SKIP RETURN
	POPJ	P,		;RETURN WITH CHARACTER IN CH

DIBYT5:	TXZ	FL,IODINP	;CLEAR INPUT PENDING
	IN	IOD,		;ASK MONITOR FOR ANOTHER BUFFER
	JRST	DIBYT1		;OH HO - GOT ONE, PROCESS INPUT
	STATO	IOD,IO.EOF!IO.ERR  ;NO INPUT, ANY ERRORS?
	POPJ	P,		;NO, JUST NOTHING THERE
	GETSTS	IOD,IOSWRD	;YES, GET I/O ERROR STATUS BITS
	ERROR	DIE,<Dataset terminal input error, >,IOERM,,.+1
	EXCH	T1,IOSWRD	;GET I/O STATUS BACK
	TXZ	T1,IO.ERR	;CLEAR OUT ERROR BITS
	SETSTS	IOD,(T1)	;TELL MONITOR TO CLEAR ERROR STATUS
	TXNE	T1,IO.EOF	;EOF SET?
	CLOSE	IOD,		;YES (BUT . . . BUT . . .)
	MOVE	T1,IOSWRD	;RESTORE T1
	SOSL	IODECT		;COUNT DATASET TERMINAL ERRORS
	JRST	DIBYT1		;GO PROCESS WHATEVER WE GOT
	TXO	FL,IODIOE	;TOO MANY ERRORS - ABORT DATASET LINE
	POPJ	P,		;POP UP A LEVEL TO HANDLE ABORT
DOBYT:	TXZN	FL,IODOUF	;NEED AN OUT UUO FIRST?
	JRST	DOBYT5		;NO, BUFFER IS AVAILABLE
DOBYT2:	OUT	IOD,		;YES, OUTPUT BUFFER, ADVANCE TO NEXT
	JRST	DOBYT5		;GO STUFF CHARACTER IN OUTPUT BUFFER
DOBYT3:	TXO	FL,IODOUF	;MONITOR STUFFED, FLAG NEED AN OUT
	STATO	IOD,IO.EOF!IO.ERR  ;UNLESS I/O ERROR
	POPJ	P,		; (NO)
	GETSTS	IOD,IOSWRD	;GET I/O ERROR STATUS BITS
	ERROR	DOE,<Dataset terminal output error, >,IOERM,,.+1
	EXCH	T1,IOSWRD	;GET BACK I/O STATUS
	TXZ	T1,IO.ERR	;CLEAR ERROR BITS
	SETSTS	IOD,(T1)	;TELL MONITOR TO CLEAR ERROR STATUS
	TXNE	T1,IO.EOF	;END OF FILE?
	CLOSE	IOD,		;YES - DUH?
	MOVE	T1,IOSWRD	;RESTORE CALLER'S T1
	SOSGE	IODECT		;COUNT ERRORS
	TXO	FL,IODIOE	;FLAG DATASET TERMINAL I/O ERROR
	POPJ	P,		;POP UP A LEVEL TO HANDLE

DOBYT5:	SOSGE	IODOBH+.BFCTR	;ROOM IN OUTPUT BUFFER FOR ANOTHER CHARACTER?
	JRST	DOBYT2		;NO, OUTPUT BUFFER AND GET ANOTHER
	IDPB	CM,IODOBH+.BFPTR;YES, STUFF CHARACTER IN BUFFER
	TXO	FL,IODOUP	;FLAG OUTPUT PENDING
	AOS	(P)		;SKIP RETURN
	POPJ	P,		; IS SUCCESSFUL RETURN



DOTRY:	TXZN	FL,IODOUF!IODOUP;NEED TO DO DATASET TERMINAL OUTPUT?
	POPJ	P,		;NO, JUST RETURN
	OUT	IOD,		;YES, TRY TO OUTPUT BUFFER
	POPJ	P,		;OUTPUT DONE, WE HAVE A BUFFER AVAILABLE
	JRST	DOBYT3		;COULDN'T DO OUTPUT, CHECK FOR I/O ERROR
	SUBTTL	Interrupt service routines

IOCINT:	PUSH	P,T1		;NEED AN AC
	HRRZ	T1,IOCVEC+.PSVFL;GET INTERRUPT FLAGS WORD
	TXNE	T1,PS.RID	;INPUT AVAILABLE?
	TXO	FL,IOCINP	;YES, FLAG CONTROLLING TERMINAL HAS INPUT
	TXO	FL,IOXFLG	;NOTE SOMETHING HAPPENED
	POP	P,T1		;RESTORE STOMPED-UPON AC
	DEBRK.			;DISMISS INTERRUPT
	  HALT	.		;DUH?
	  HALT	.		;DUH?

IODINT:	PUSH	P,T1		;NEED AN AC
	HRRZ	T1,IODVEC+.PSVFL;INTERRUPT FLAGS WORD
	TXNE	T1,PS.RID	;INPUT AVAILABLE?
	TXO	FL,IODINP	;FLAG DATASET TERMINAL HAS INPUT
	TXO	FL,IOXFLG	;NOTE SOMETHING HAPPENED
	POP	P,T1		;RESTORE USED AC
	DEBRK.			;DISMISS INTERRUPT
	  HALT	.		;DUH?
	  HALT	.		;DUH?

DSSINT:	PUSHJ	P,.PSH4T##	;SAVE THE T ACS
	MOVE	T1,DSSVEC+.PSVIS;GET NEW DATASET STATUS WORD
	MOVE	T2,DSSOLD	;AND PREVIOUS DATASET STATUS
	MOVEM	T1,DSSOLD	;NEW NOW BECOMES OLD FOR NEXT TIME
	CAMN	T1,T2		;DID ANYTHING REALLY HAPPEN?
	JRST	DSSIN9		;NO, DISMISS THE INTERRUPT
	TXNN	T2,1B1		;DID WE HAVE DTR?
	JRST	DSSIN4		;NO, MUST HAVE BEEN EARLY MONITOR
	TXNE	T1,1B1		;YES, DO WE STILL HAVE IT?
	JRST	DSSIN4		;YES, CHECK CONDITION OF CARRIER
	TXO	FL,IODINP!IODIOE;NO, THIS ERROR IS FATAL
	SETZM	IODECT		;MAKE LOOP LEVEL ABORT ON ERROR
	INFRM	DHU,<Dataset terminal hung up>,,,DSSIN9

DSSIN4:	TXNN	T2,1B0		;DID WE HAVE CARRIER BEFORE?
	JRST	DSSIN6		;YES, SEE IF STILL THERE
	TXNN	T1,1B0		;YES, DO WE STILL HAVE IT?
	INFRM	DCL,<Dataset carrier lost>
	TXNE	T1,1B1		;DO WE HAVE DTR STILL PRESENT?
	JRST	DSSIN9		;YES, WAIT FOR CARRIER TO COME BACK
	TXO	FL,IODINP!IODIOE;NO, EARLY MONITOR, THIS ERROR IS FATAL THEN
	SETZM	IODECT		;MAKE LOOP LEVEL ABORT ON ERROR
	JRST	DSSIN9		;DISMISS THE INTERRUPT

DSSIN6:	TXNE	T1,1B0		;HAS CARRIER COME BACK YET?
	INFRM	DCR,<Dataset carrier returned>

DSSIN9:	PUSHJ	P,.POP4T##	;RESTORE THE T ACS
	DEBRK.			;AND DISMISS THE INTERRUPT
	  HALT	.		;DUH?
	  HALT	.		;DUH?
	SUBTTL	Support routines

;TTNAM  --  GENERATE SIXBIT TERMINAL NAME FROM SCAN BLOCK
;CALL IS:
;
;	MOVX	T1,<SCB>
;	PUSHJ	P,TTNAM
;	 ERROR
;	NORMAL
;
;WHERE <SCB> IS THE ADDRESS OF A SCAN BLOCK.
;
;ON ERROR RETURN THE TERMINAL REPRESENTED BY THE NODE AND DEVICE
;WORDS IN THE SCAN BLOCK IS UNAVAILABLE (E.G., ASSIGNED TO ANOTHER
;NODE).
;
;ON NORMAL RETURN T1 CONTAINS THE SIXBIT TTY NAME USABLE IN (E.G.,)
;OPEN BLOCKS.
;
;USES T1 - T4

TTNAM:	MOVE	T4,T1		;SAVE SCAN BLOCK ADDRESS
	SKIPE	T1,.FXNOD(T4)	;NODE SPEC SUPPLIED?
	JRST	TTNAM4		;YES, MORE COMPLICATED
TTNAM1:	MOVE	T1,.FXDEV(T4)	;NO, GET DEVICE NAME TYPED
	MOVE	T2,T1		;COPY TO
	DEVCHR	T2,		; ASK MONITOR IF DEVICE EXISTS
	PJUMPN	T2,.POPJ1##	;IF SO USE IT AS IS
	PUSHJ	P,IS6OC		;NO SUCH DEVICE, SEE IF SIXBIT OCTAL NUMBER
	  POPJ	P,		;NO, NO SUCH DEVICE IN ANY FORM
	MOVS	T1,.FXDEV(T4)	;STRAIGHT OCTAL NUMBER,
	TLNE	T1,-1		;GREATER THAN 777 (OCTAL)
	POPJ	P,		;YES, CAN'T BE A TTY THEN
	HRLI	T1,'TTY'	;NO, MAKE INTO TTYNNN
	MOVE	T2,T1		;COPY TO
	DEVCHR	T2,		; ASK MONITOR IF DEVICE EXISTS
	PJUMPN	T2,.POPJ1##	;IT DOES, RETURN IT
	POPJ	P,		;NO SUCH DEVICE OF ANY TYPE
;HERE FOR "NODE_DEV" CONSTRUCTION (ALTHOUGH WE MUST WATCH OUT FOR THE
;"FREE" HOST NODE NAME DEFAULTED INTO THE FILE SPEC BLOCK)

TTNAM4:	CAMN	T1,.MYNOD##	;HOST-RESIDENT DEVICE?
	JRST	TTNAM1		;YES, TREAT AS IF NO NODE TYPED
	MOVE	T3,T1		;POSITION NODE NAME TYPED
	PUSHJ	P,.NDNAM##	;GET NODE NAME AND NUMBER
	JUMPLE	T2,.POPJ##	;NO SUCH NODE KNOWN HERE
	HRLZ	T3,T2		;PUT NODE NUMBER IN L.H.
	HLRZ	T1,.FXDEV(T4)	;GET GENERIC DEVICE SPECIFIED
	CAIE	T1,'TTY'	;DID USER SPECIFY TTYXXX?
	SKIPA	T1,.FXDEV(T4)	;NO, PICK UP DEVICE VERBATIM
	HRLZ	T1,.FXDEV(T4)	;YES, GET JUST XXX
	PUSHJ	P,IS6OC		;IS IT A SIXBIT OCTAL LINE NUMBER?
	  POPJ	P,		;NO, NO SUCH DEVICE ANYWHERE
	CAILE	T2,777		;GREATER THAN 777 (OCTAL)?
	POPJ	P,		;YES, THEN CAN'T POSSIBLY BE A TTY
	IOR	T2,T3		;MAKE NODE NUMBER,,LINE NUMBER
	MOVEI	T1,2		;LENGTH OF NODE. BLOCK
	MOVE	CM,[.NDTCN,,T1]	;ARG BLOCK POINTER TO
	NODE.	CM,		;CONNECT TO REMOTE TERMINAL
	  POPJ	P,		;NOT AVAILABLE
	MOVE	T1,CM		;RETURN DEVICE NAME IN T1
	JRST	.POPJ1##	;SUCCESSFUL RETURN
;IS6OC  --  CONVERT SIXBIT IN T1 INTO OCTAL NUMBER
;CALL IS:
;
;	MOVX	T1,<NAME>
;	PUSHJ	P,IS6OC
;	 ERROR
;	NORMAL
;
;WHERE <NAME> IS THE SIXBIT NAME FORM OF AN OCTAL NUMBER.
;
;ON ERROR RETURN THE <NAME> WAS NOT A VALID OCTAL DIGIT STRING.
;
;ON NORMAL RETURN THE OCTAL NUMBER IS RETURNED IN T2.
;
;USES T1 - T2.

IS6OC:	SETZ	T2,		;CLEAR RETURN VALUE
IS6OC0:	TLC	T1,200000	;CLEAR ASCII BITS
	TLNE	T1,700000	;VALID OCTAL DIGIT?
	POPJ	P,		;NO
	LSH	T1,3		;STRIP OFF ASCII BITS
	ROTC	T1,3		;ADD IN THIS OCTADE
	JUMPN	T1,IS6OC0	;LOOP BACK FOR REST OF NUMBER
	JRST	.POPJ1##	;ALL DONE, VALID OCTAL NUMBER
;AUXILIARY ERROR ROUTINES

;ERCOD  --  LIST ERROR CODE (OCTAL) AND TEXT STRING (OPTIONAL)
;CALL IS:
;
;	MOVX	T1,<CODE>
;	MOVX	T2,<STRG>
;	PUSHJ	P,ERCOD
;	RETURN
;
;WHERE <CODE> IS THE OCTAL ERROR CODE TO BE PRINTED AND <STRG>, IF
;NON-ZERO, IS THE ADDRESS OF AN ASCIZ STRING TO BE PRINTED AFTER THE
;ERROR CODE.
;
;USES T1 - T3.

ERCOD:	PUSH	P,T2		;SAVE ADDRESS (IF ANY)
	PUSH	P,T1		;AND ERROR CODE
	MOVEI	T1,[ASCIZ\ - (\];PREFIX ERROR CODE
	PUSHJ	P,.TSTRG##	;TYPE IT OUT
	POP	P,T1		;RETRIEVE ERROR CODE
	PUSHJ	P,.TOCTW##	;AND PRINT IT IN OCTAL
	MOVEI	T1,[ASCIZ\) \]  ;CAP OFF ERROR CODE
	PUSHJ	P,.TSTRG##	;WITH A CLOSING PARENTHESIS
	POP	P,T1		;ADDITIONAL TEXT STRING
	PJUMPN	T1,.TSTRG##	;TYPE IT IF ANYTHING TO TYPE
	POPJ	P,		;ELSE RETURN HAVING PRINTED ONLY ERROR CODE
;IOERM  --  TYPE I/O ERROR STATUS
;CALL IS:
;
;	PUSHJ	P,IOERM
;	RETURN
;
;LOCATION IOSWRD IS EXPECTED TO CONTAIN THE I/O STATUS TO BE TYPED.

IOERM:	PUSHJ	P,.PSH4T##	;SAVE THE T ACS
	MOVEI	T1,[ASCIZ\I/O status = \]
	PUSHJ	P,.TSTRG##	;TYPE PRETTY TEXT
	MOVE	T1,IOSWRD	;GET I/O STATUS WORD
	PUSHJ	P,.TOCTW##	;TYPE IT OUT IN OCTAL
	PUSHJ	P,.POP4T##	;RESTORE T ACS
	POPJ	P,		;ALL DONE HERE



;CDTER  --  TYPE CONTROLLING OR DATASET TERMINAL ON ERROR
;CALL IS:
;
;	MOVE	T1,<SCB>
;	PUSHJ	P,CDTER
;	RETURN
;
;WHERE <SCB> IS THE ADDRES OF THE SCAN BLOCK.

CDTER:	MOVE	T4,T1		;SAVE ADDRESS OF SCAN BLOCK
	SKIPN	T1,.FXNOD(T4)	;USER GIVE A NODE SPEC?
	JRST	CDTER4		;NO
	PUSHJ	P,.TSIXN##	;YES, TYPE NODE NAME
	MOVEI	T1,"_"		;SEPARATE NODE NAME FROM DEVICE NAME
	PUSHJ	P,.TCHAR##	;WITH THE USUAL -10 CONVENTION

CDTER4:	MOVE	T1,.FXDEV(T4)	;GET THE USER-TYPED DEVICE
	PUSHJ	P,.TSIXN##	;AND TYPE IT OUT
	MOVEI	T1,":"		;DEVICE SEPARATOR
	PJRST	.TCHAR##	;AND TYPE IT OUT TOO.
;NODER  --  TYPE NODE. ERROR CODE
;CALL IS:
;
;	MOVX	T1,<CODE>
;	PUSHJ	P,NODER
;	RETURN
;
;WHERE <CODE> IS THE ERROR CODE RETURNED BY THE NODE. MONITOR CALL.

NODER:	CAIL	T1,1		;MINIMUM ERROR CODE
	CAIL	T1,NODLN	;MAXIMUM ERROR CODE
	TDZA	T2,T2		;UNKNOWN ERROR CODE
	MOVE	T2,NODTB(T1)	;TEXT STRING
	PJRST	ERCOD		;TYPE IT ALL OUT

NODTB:	0
	[ASCIZ\illegal argument block\]
	[ASCIZ\illegal node name or number\]
	[ASCIZ\insufficient privileges\]
	[ASCIZ\node not available\]
	[ASCIZ\job is not locked\]
	[ASCIZ\timeout error\]
	[ASCIZ\word 2 is not zero\]

	NODLN==.-NODTB
;PSIER  --  TYPE PSI ERROR CODE
;CALL IS:
;
;	MOVX	T1,<CODE>
;	PUSHJ	P,PSIER
;	RETURN
;
;WHERE <CODE> IS THE ERROR CODE RETURNED FROM A PIINI. OR PISYS.
;MONITOR CALL.

PSIER:	CAIL	T1,0		;MINIMUM ERROR CODE
	CAIL	T1,PSILN	;MAXIMUM ERROR CODE
	TDZA	T2,T2		;UNKNOWN ERROR CODE
	MOVE	T2,PSITB(T1)	;TEXT STRING
	PJRST	ERCOD		;TYPE CODE AND TEXT

PSITB:	[ASCIZ\extraneous argument(s) provided\]
	[ASCIZ\no function bits set\]
	[ASCIZ\unknown function bits set\]
	[ASCIZ\both "ON" and "OFF" specified\]
	[ASCIZ\illegal address\]
	[ASCIZ\I/O device not OPENed for I/O\]
	[ASCIZ\illegal condition(s) specified\]
	[ASCIZ\illegal vector offset\]
	[ASCIZ\illegal bit set in arg block\]
	[ASCIZ\reserved\]
	[ASCIZ\reserved bits not zero\]
	[ASCIZ\PSI system not initialized\]
	[ASCIZ\both "ADD" and "REMOVE" specified\]

	PSILN==.-PSITB
;TRMER  --  TYPE TRMOP. ERROR CODE
;CALL IS:
;
;	MOVX	T1,<CODE>
;	PUSHJ	P,TRMER
;	RETURN
;
;WHERE <CODE> IS THE ERROR CODE FROM A TRMOP. MONITOR CALL.

TRMER:	CAIL	T1,0		;MINIMUM ERROR CODE
	CAIL	T1,TRMLN	;MAXIMUM ERROR CODE
	TDZA	T2,T2		;UNKNOWN ERROR CODE
	MOVE	T2,TRMTB(T1)	;TEXT STRING
	PJRST	ERCOD		;GO TYPE ERROR CODE AND TEXT

TRMTB:	[ASCIZ\function not implemented\]
	[ASCIZ\insufficient privileges\]
	[ASCIZ\argument out of range\]
	[ASCIZ\illegal address\]
	[ASCIZ\not a dataset terminal\]
	[ASCIZ\dialout failed\]
	[ASCIZ\terminal not available\]

	TRMLN==.-TRMTB
;PSI BLOCKS

IOCARG:	EXP	IOC		;CONTROLLING TERMINAL I/O CHANNEL
	IOCVEC-PSIVEC,,PS.RID!PS.ROD  ;VECTOR OFFSET,,INPUT OR OUTPUT DONE
	0			;PRIORITY,,0

IODARG:	EXP	IOD		;DATASET TERMINAL I/O CHANNEL
	IODVEC-PSIVEC,,PS.RID!PS.ROD  ;VECTOR OFFSET,,INPUT OR OUTPUT DONE
	0			;PRIORITY,,0

DSSARG:	EXP	.PCDSC		;DATASET TERMINAL I/O CHANNEL
	DSSVEC-PSIVEC,,0	;VECTOR OFFSET,,DATASET STATUS
	0			;PRIORITY,,0
	XLIST			;THE LITERALS GO IN THE HIGH SEG
	LIT
	LIST

	RELOC	0

IODECT:	BLOCK	1		;DATASET TERMINAL ERROR ABORT COUNTER
DSSOLD:	BLOCK	1		;DATASET STATUS (LAST TIME WE LOOKED)
IOSWRD:	BLOCK	1		;TEMP USED IN I/O ERROR TYPEOUT


;BUFFER RING CONTROL BLOCKS

IOCIBH:	BLOCK	3		;CONTROLLING TERMINAL INPUT
IOCOBH:	BLOCK	3		;CONTROLLING TERMINAL OUTPUT

IODIBH:	BLOCK	3		;DATASET TERMINAL INPUT
IODOBH:	BLOCK	3		;DATASET TERMINAL OUTPUT
;DATA STORAGE INITIALLY ZEROED

BZCOR:				;START OF INITIALLY ZEROED AREA

TTCNAM:	BLOCK	1		;CONTROLLING TERMINAL DEVICE NAME
TTDNAM:	BLOCK	1		;DATASET TERMINAL DEVICENAME
TTCUDX:	BLOCK	1		;CONTROLLING TERMINAL UDX
TTDUDX:	BLOCK	1		;DATASET TERMINAL UDX

IOCFF:	BLOCK	2		;.JBFF FOR IOC BUFFERS
IODFF:	BLOCK	2		;.JBFF FOR IOD BUFFERS

CISAV:	BLOCK	1		;.NE. 0 THEN SAVED CIBYT INPUT CHARACTER
DISAV:	BLOCK	1		;.NE. 0 THEN SAVED DIBYT INPUT CHARACTER

;PSI VECTORS

PSIVEC:	BLOCK	4		;BASE OF INTERRUPT VECTORS
IOCVEC:	BLOCK	4		;CONTROLLING TERMINAL
IODVEC:	BLOCK	4		;DATASET TERMINAL
DSSVEC:	BLOCK	4		;DATASET STATUS

ZZCOR:	BLOCK	1		;LAST LOCATION INITIALLY ZEROED
	END