[comp.os.vms] New PTY drivers 5/5

KVC@BUSTER.NRC.COM (Kevin Carosso) (07/31/88)

+-+-+-+ Beginning of part 5 +-+-+-+
X`009JMP`009G^EXE$FINISHIO`009`009; COMPLETE REQUEST IOSB WORD 0,1
X`012
X;`009This routine verifies that the user buffer is accessable
X
XVERIFY_SENSE:`009`009`009`009;
X`009MOVL`009P1(AP),R1`009`009; ADDRESS USER BUFFER
X`009IFNOWRT`009#8,(R1),20$`009`009; BR IF NO ACCESS TO QUADWORD BUFFER
X`009MOVL`009#8,R0`009`009`009; INIT DEFAULT ARGUMENT SIZE
X`009CLRQ`009(R1)`009`009`009; INIT RETURN DATA
X`009MOVZWL`009P2(AP),R2`009`009; GET SIZE ARGUMENT
X`009CMPL`009R2,#12`009`009`009; ROOM FOR SECOND DEVDEPEND SPECIFIED?
X`009BLSSU`00910$`009`009`009; NO
X`009IFNOWRT`009#12,(R1),20$`009`009; CHECK IF WRITE ACCESS
X`009MOVW`009#12,R0`009`009`009; SAVE ARGUMENT SIZE
X`009CLRL`0098(R1)`009`009`009; INIT RETURN FIELD
X10$:
X`009RSB
X20$:
X`009MOVZWL`009#SS$_ACCVIO,R0`009`009; SET ERROR STATUS
X`009JMP`009G^EXE$ABORTIO`009`009; ABORT THE IO
X`012
X`009.SBTTL`009PY$END - End of driver
XPY$END:
X`009`009`009`009`009; End of driver
X`009.END
$ GOSUB UNPACK_FILE
$ FILE_IS = "TWDRIVER.MAR"
$ CHECKSUM_IS = 1332422334
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
X`009.TITLE`009TWDRIVER - Pseudo terminal driver for Front End and ethernet
X`009.IDENT`009'V05-005A'
X
X;++
X; FACILITY:
X;
X;`009VAX/VMS TERMINAL DRIVER
X;
X; ABSTRACT:
X;
X;`009PSEUDO TERMINAL ROUTINES.
X;
X; AUTHOR:
X;
X;`00919-NOV-1982`009Dale Moore (dwm) at CMU
X;`009`009Redone for VMS V3.0
X;
X;`009This program has been granted to the public domain by the author.
X;
X; MODIFICATIONS:
X;
X;`009Version V05-005A Kevin Carosso @ Network Research Co.
X;`009`009Make the conditional assembly for VMS V5 automatic
X;`009`009driven off existence of SS$_INVLICENSE.
X;
X;`009V05-004A Kevin Carosso @ Network Research Co.
X;`009`009Conditionalize assembly for VMS V4 or V5.  There
X;`009`009is a magic symbol at the top that is commented
X;`009`009out for VMS V5.
X;
X;`009V05-004`009Digital Equipment Corp.`00924-May-1988
X;`009`009Add code to delivered ASTs if PORT XON, PORT XOFF, or
X;`009`009PORT SET_LINE routines are called.
X;
X;`009V05-003`009Digital Equipment Corp.`00913-May-1988
X;`009`0091) Add hooks to indicate if line is XOFFed.
X;`009`0092) Set TTY$M_PC_NOMODEM bit in UCB$W_TT_PRTCTL.
X;`009`0093) Set device to HOSTSYNC.
X;
X;`009V05-002`009Digital Equipment Corp.`00915-Feb-1988
X;`009`009Add TTY$M_PC_MULTISESSION bit to UCB$W_TT_PRTCTL so that
X;`009`009this device is not counted as a user in LOGIN.
X;
X;---------- Previous history ---------------------
X;
X;`009`009DWM`009- Added .Page above each .sbttl
X;`009`009`009- added modem transition routines in disco and init
X;`009`009`009- removed $ACBDEF external def's
X;`009`009`009- restored timeout to resume
X;`009`009`009- added ioc$initiate call in xoff and xon routines.
X;`009Version V03-002 - Changed TP startio to clear TIM in UCB$W_STS
X;`009Version V03-003 - Changed TW$RESUME to not set timeout bit in sts
X;
X;`009Version V03-004 (Thu Dec  9 12:43:17 1982) D. Kashtan
X;`009`009`009  Made into a TEMPLATE driver.
X;`009`009`009  (***WARNING*** -- LOOK AT COMMENTS FOR ROUTINE
X;`009`009`009   TW$SET_LINE.  THERE IS IMPORTANT INFORMATION
X;`009`009`009   ABOUT CHANGES TO VMS THAT WILL AFFECT THE TWDRIVER)
X;`009Version V03-005 - (14-Jun-1983 )Dale Moore
X;`009`009`009  Add R4 to masks on calls to ioc$initiate.
X;`009`009`009  TTY$STARTIO clobber R4.
X;`009Version V03-006`009- Change TW$XON and TW$XOFF routines from
X;`009`009`009  unconditionally calling IOC$INITIATE.
X;`009`009`009  IOC$INITIATE will branch to PY$STARTIO,
X;`009`009`009  Which will call TTY$GETNEXTCHAR (UCB$L_TT_GETNEXT),
X;`009`009`009  Which will branch to EOLSEEN,
X;`009`009`009  which calls TTY$READONE,
X;`009`009`009  which calls the PORT_XOFF routine which is TW$XOFF.
X;`009`009`009  This cycle was eating up all of the kernel stack.
X;`009Version V03-007 - (12-Jul-1983) Mark London
X;`009`009`009  Set default of TW to TERM to allow REPLY/USERS.
X;`009`009`009  Make TW owned and not a TEMPLATE in order that
X;`009`009`009  SHO TERM TWA0 does not cause a crash (SHOW attempts
X;`009`009`009  an ASSIGN to the device.)
X;`009Verison V04-001 - ( 9-Nov-1984 ) L. Bellamy and D. Davis
X;`009`009`009  In order of appearance:
X;
X;`009`009`009  Added Object Rights Block offset definitions.
X;`009`009`009  Add TEMPLATE bit to UCB$W_STS.
X;`009`009`009  Add ORB definitions in prologue.
X;`009`009`009  Modify to allow vector definitions using VEC macro.
X;`009`009`009  Use CLASS_CTRL_INIT and CLASS_UNIT_INIT to locate
X;`009`009`009   vector table.
X;`009`009`009  Update powerfail routines.
X;`009`009`009  Use new methodology for XON/XOFF flow control.
X;`009`009`009  Get rid of all the SET_LINE stack manipulation
X;`009`009`009  since the terminal driver does not do anything
X;`009`009`009  malicious as suggested.
X;
X;`009`009`009  NOTE - Comments in subroutine preambles not altered
X;`009`009`009  to reflect changes in most places.
X;
X;`009Version V04-003 (24-Jun-1985) Kevin Carosso, Hughes Aircraft Co., S&CG
X;`009`009`009Cleaned this thing up quite a bit.
X;`009`009`009- Got rid of MBX characteristic on the devices.  This
X;`009`009`009  was a holdover to before cloned devices really
X;`009`009`009  existed.
X;`009`009`009- Leave the TW template device OFFLINE.  This is what
X;`009`009`009  other TEMPLATE devices do, to indicate that you
X;`009`009`009  really cannot do I/O to the template.  Also left
X;`009`009`009  it UNAVAILABLE, since the only way it is supposed to
X;`009`009`009  get used is by cloning in the PY device.
X;`009`009`009- Got rid of all modem operations.  Improper use tended
X;`009`009`009  to crash the system and they are not necessary.  TW
X;`009`009`009  device is always NOMODEM.  HANGUP works as you want
X;`009`009`009  it to without the modem stuff.
X;`009`009`009- Setup forced characteristics and default permanent
X;`009`009`009  characteristics.  Forced are: NOAUTOBAUD, and NODMA.
X;`009`009`009  Default is HANGUP.
X;`009`009`009- Fixed up TW$DISCONNECT to properly send a message
X;`009`009`009  to PY device's associated mailbox only if we are
X;`009`009`009  actually doing a hangup.  It used to do it every
X;`009`009`009  time.  Changed the message to MSG$_TRMHANGUP.
X;`009`009`009- Got rid of the BRDCST on/off stuff.  It doesn't seem
X;`009`009`009  to be necessary any more.  It also had a bug in it
X;`009`009`009  somewhere that caused the terminal to start off
X;`009`009`009  NOBRDCST when it shouldn't.
X;`009`009`009- General house-cleaning.  Got rid of commented out
X;`009`009`009  lines from VMS V3 version.  Fixed up typos in
X;`009`009`009  comments.
X;
X;`009Version V04-004 (10-Feb-1986) Kevin Carosso, Hughes Aircraft Co., S&CG
X;`009`009`009Changed all references to PTDRIVER to TPDRIVER because
X;`009`009`009DEC (bless their little hearts) invented the %*%#$%
X;`009`009`009TU81 and use PTA0: now.
X;
X;`009Version V04-005 (3-Sep-1986) Kevin Carosso, Hughes Aircraft Co., S&CG
X;`009`009`009Fixed bug whereby the sequence ^S followed by ^Y
X;`009`009`009would cause a system hang.  Apparently the class
X;`009`009`009driver calls the port RESUME routine when doing
X;`009`009`009an ABORT and again when canceling the ^S.  Calling
X;`009`009`009RESUME twice like this is bad.  In general, the
X;`009`009`009port RESUME routine should not restart the output.
X;`009`009`009In this driver, the RESUME and STOP routines aren't
X;`009`009`009needed, so I got rid of them completely.
X;
X;`009`009`009Now on ^Y the ^S state is not cleared.  You still
X;`009`009`009need to type ^Q to get your output (including the
X;`009`009`009*INTERRUPT* echo string.  I thought this was another
X;`009`009`009bug, but it's how my DHU-11 based terminals act
X;`009`009`009and makes sense, because only a ^Q should really
X;`009`009`009cancel a ^S.
X;
X;`009`009`009Also removed the TEMPLATE bit from the TWA0: template
X;`009`009`009device since it was allowing people to $ASSIGN channels
X;`009`009`009and get unhappy (lonely) TW devices that could crash
X;`009`009`009the system.  Now, the only way to clone TW devices
X;`009`009`009is through the code in PYDRIVER, hence by assigning
X;`009`009`009a channel to PYA0:.  You can still $ASSIGN to TWA0:,
X;`009`009`009but since the device is offline that shouldn't hurt
X;`009`009`009anything.  This fixed crashes caused by KERMIT and
X;`009`009`009other things attempting to use TWA0:.  You now get
X;`009`009`009an error "DEVOFFLINE".
X;
X;`009`009`009Fixed a bug that caused a system crash from SHOW
X;`009`009`009DEVICE/FULL of TWA0:.  The ACL_QUEUE bit was set
X;`009`009`009in the ORB but the ACL queue was invalid (was zeroed).
X;`009`009`009I got rid of the bit, now all is well.
X;
X;`009Version V04-006 (5-Dec-1986) Kevin Carosso, Hughes Aircraft Co., S&CG
X;`009`009`009Fixed the infamous character munging bug.  The fix
X;`009`009`009is really in PYDRIVER.
X;
X;`009Version V04-007 (10-JUL-1987) Kevin Carosso, Hughes Aircraft Co., S&CG
X;`009`009`009In TW$INITLINE make sure to tell the class driver
X;`009`009`009never to time out.  This fix from Forrest Kenney
X;`009`009`009at DEC.
X;
X;`009`009`009Also, while we're in here, lets make the device
X;`009`009`009acquire "NODE$" prefixes, since all the other
X;`009`009`009terminal drivers do.
X;
X;`009Version V04-008`009(2-NOV-1987) Kevin Carosso, Network Research Co.
X;`009`009`009Only a version change here to keep in sync with
X;`009`009`009TWDRIVER which has the real change.
X;
X;`009`009`009Fix thanks to Gerard K Newman @ San Diego
X;`009`009`009Supercomputer Center.
X;
X;`009Version V05-001 (21-Dec-1987) Digital Equipment Corp.
X;`009`009`009Add support for Symmetric Multiprocessing.
X;
X;`009Version V05-002 Digital Equipment Corp.
X;`009`009`009Change TP driver names to TW. (TP driver it turns
X;`009`009`009out, conflicted with the VAX/PSI terminal driver.)
X;`009`009`009TWDRIVER and PYDRIVER are now registered with SQM
X;`009`009`009so there will be no more conflicts.
X;--
X`012
X`009.PAGE
X`009.SBTTL`009Declarations
X
X`009.LIBRARY`009/SYS$LIBRARY:LIB.MLB/
X
X;
X; EXTERNAL DEFINITIONS:
X;
X.NOCROSS
X`009$ACBDEF`009`009`009`009; AST control block definitions
X`009$CRBDEF`009`009`009`009; DEFINE CRB
X`009$DCDEF`009`009`009`009; DEVICE CLASSES AND TYPES
X`009$DDBDEF`009`009`009`009; DEFINE DDB
X`009$DDTDEF`009`009`009`009; DEFINE DDT
X`009$DEVDEF`009`009`009`009; DEVICE CHARACTERISTICS
X`009$DYNDEF`009`009`009`009; Dynamic structure definitions
X`009$IDBDEF`009`009`009`009; DEFINE IDB OFFSETS
X`009$IODEF`009`009`009`009; I/O Function Codes
X`009$IRPDEF`009`009`009`009; IRP definitions
X`009$MSGDEF`009`009`009`009; Message types
X`009$ORBDEF`009`009`009`009; Define Object's Rights Block offsets
X`009$SSDEF`009`009`009`009; DEFINE System Status
X;
X; If SS$_INVLICENSE exists, we must be building on V5.  Go ahead and
X; define our conditionals so we can build a V5 driver.
X;
X.IF`009DEFINED`009SS$_INVLICENSE
X`009VMS_V5 = 1
X`009.PRINT`009`009; TWDRIVER -- Building VMS V5 compatible driver
X.IF_FALSE
X`009.PRINT`009`009; TWDRIVER -- Building VMS V4 compatible driver
X.ENDC
X
X.IF`009DEFINED`009VMS_V5
X`009$SPLCODDEF`009`009`009; Spin lock code definitions
X.ENDC
X
X`009$TTDEF`009`009`009`009; DEFINE TERMINAL TYPES
X`009$TT2DEF`009`009`009`009; Define Extended Characteristics
X`009$TTYDEF`009`009`009`009; DEFINE TERMINAL DRIVER SYMBOLS
X`009$TTYDEFS`009`009`009; DEFINE TERMINAL DRIVER SYMBOLS
X`009$TTYMACS`009`009`009; DEFINE TERMINAL DRIVER MACROS
X`009$UCBDEF`009`009`009`009; DEFINE UCB
X`009$VECDEF`009`009`009`009; DEFINE VECTOR FOR CRB
X.CROSS
X
X;
X; LOCAL DEFINITIONS
X;
XDT$_TW = ^XFF
X;
X; Definitions that follow the standard UCB fields for TW driver
X;  This will all probably have to be the same as the standard term
X
X`009$DEFINI`009UCB`009`009`009; Start of UCB definitions
X
X`009.=UCB$K_TT_LENGTH`009`009; Position at end of UCB
X
X$DEF`009UCB$L_TW_XUCB`009.BLKL`0091`009; UCB of corresponding
X`009`009`009`009`009;  control/application unit
X$DEF`009UCB$L_TW_XON_AST .BLKL`0091`009; AST list for XON event notification
X$DEF`009UCB$L_TW_XOFF_AST .BLKL`0091`009; AST list for XOFF event notification
X$DEF`009UCB$L_TW_SET_AST .BLKL`0091`009; AST list for notification of SET_LINE
X$DEF`009UCB$K_TW_LEN`009`009`009; Size of UCB
X
X`009$DEFEND`009UCB`009`009`009; End of UCB definitions
X;
X; Definitions that follow the standard UCB fields in PY devices
X;
X
XBUFFER_SIZE = 32
X
X`009$DEFINI UCB`009`009`009; Start of UCB definitions
X `009.=UCB$K_LENGTH`009`009`009; position at end of UCB
V$DEF`009UCB$L_PY_XUCB`009.BLKL 1`009`009; UCB of terminal part of pseudo termin
Xal
V$DEF`009UCB$T_PY_BUFFER`009.BLKB`009BUFFER_SIZE ; Buffer to store characters to
X be transmitted
X$DEF`009UCB$K_PY_LEN`009`009`009; Size of UCB
X
X `009$DEFEND UCB`009`009`009; end of UCB definitions
X
X;
X; LOCAL STORAGE
X;
X`009.PSECT`009$$$105_PROLOGUE
X`012
X`009.PAGE
X`009.SBTTL`009Standard Tables
X
X;
X; Driver prologue table:
X;
XTW$DPT::
X`009DPTAB`009-`009`009`009; DRIVER PROLOGUE TABLE
X`009`009END=TW_END,-`009`009; End and offset to INIT's vectors
X`009`009UCBSIZE=UCB$K_TW_LEN,- `009; SIZE OF UCB
X`009`009FLAGS=DPT$M_NOUNLOAD,-`009; Do not allow unload
X`009`009ADAPTER=NULL,-`009`009; ADAPTER TYPE
X`009`009NAME=TWDRIVER,-`009`009; NAME OF DRIVER
X`009`009VECTOR=PORT_VECTOR
X`009DPT_STORE INIT
X`009DPT_STORE UCB,UCB$W_UNIT_SEED,W,0`009; SET UNIT # SEED TO ZERO
X
X.IF`009NOT_DEFINED`009VMS_V5
X`009DPT_STORE UCB,UCB$B_FIPL,B,8 `009`009; FORK IPL
X.IF_FALSE
X`009DPT_STORE UCB,UCB$B_FLCK,B,SPL$C_IOLOCK8 ; FORK LOCK
X.ENDC
X
X`009DPT_STORE UCB,UCB$L_DEVCHAR,L,<-; CHARACTERISTICS
X`009`009`009DEV$M_REC!-`009;
X`009`009`009DEV$M_IDV!-`009;
X`009`009`009DEV$M_ODV!-`009;
X`009`009`009DEV$M_TRM!-`009;
X`009`009`009DEV$M_CCL>
X`009DPT_STORE UCB,UCB$L_DEVCHAR2,L, -`009`009; Device characteristics
X`009`009`009<DEV$M_NNM>`009`009`009; prefix with "NODE$"
X`009DPT_STORE UCB,UCB$B_DEVCLASS,B,DC$_TERM`009`009;
X`009DPT_STORE UCB,UCB$B_TT_DETYPE,B,TT$_UNKNOWN`009; TYPE
X`009DPT_STORE UCB,UCB$W_TT_DESIZE,@W,TTY$GW_DEFBUF`009; BUFFER SIZE
X`009DPT_STORE UCB,UCB$L_TT_DECHAR,@L,TTY$GL_DEFCHAR`009; DEFAULT CHARACTERS
X`009DPT_STORE UCB,UCB$L_TT_DECHA1,@L,TTY$GL_DEFCHAR2; DEFAULT CHARACTERS
X`009DPT_STORE UCB,UCB$W_TT_DESPEE,@B,TTY$GB_DEFSPEED; DEFAULT SPEED
X`009DPT_STORE UCB,UCB$W_TT_DESPEE+1,@B,TTY$GB_RSPEED; DEFAULT SPEED
X`009DPT_STORE UCB,UCB$B_TT_DEPARI,@B,TTY$GB_PARITY`009; DEFAULT PARITY
X`009DPT_STORE UCB,UCB$B_TT_PARITY,@B,TTY$GB_PARITY`009; DEFAULT PARITY
X`009DPT_STORE UCB,UCB$B_DEVTYPE,B,TT$_UNKNOWN`009; TYPE
X`009DPT_STORE UCB,UCB$W_DEVBUFSIZ,@W,TTY$GW_DEFBUF`009; BUFFER SIZE
X`009DPT_STORE UCB,UCB$L_DEVDEPEND,@L,TTY$GL_DEFCHAR`009; DEFAULT CHARACTERS
X`009DPT_STORE UCB,UCB$L_TT_DEVDP1,@L,TTY$GL_DEFCHAR2; Default Characters
X`009DPT_STORE UCB,UCB$W_TT_SPEED,@B,TTY$GB_DEFSPEED`009; DEFAULT SPEED
X`009DPT_STORE UCB,UCB$W_TT_SPEED+1,@B,TTY$GB_RSPEED`009; DEFAULT SPEED
X`009DPT_STORE UCB,UCB$B_DIPL,B,8`009`009`009; DEV IPL (no device)
X`009DPT_STORE UCB,UCB$L_TT_WFLINK,L,0`009; Zero write queue.
X`009DPT_STORE UCB,UCB$L_TT_WBLINK,L,0`009; Zero write queue.
X`009DPT_STORE UCB,UCB$L_TT_RTIMOU,L,0`009; Zero read timed out disp.
X;
X; Added ORB definitions
X;
X`009DPT_STORE ORB, ORB$B_FLAGS, B, <ORB$M_PROT_16>
X`009DPT_STORE ORB, ORB$W_PROT, @W, TTY$GW_PROT
X`009DPT_STORE ORB, ORB$L_OWNER, @L, TTY$GL_OWNUIC
X
X`009DPT_STORE DDB,DDB$L_DDT,D,TW$DDT
X
X`009DPT_STORE REINIT
X`009DPT_STORE CRB,CRB$L_INTD+VEC$L_INITIAL,D,TW$INITIAL; CONTROLLER INIT
X`009DPT_STORE CRB,CRB$L_INTD+VEC$L_UNITINIT,D,TW$INITLINE; UNIT INIT
X`009DPT_STORE END
X
X`009DDTAB`009DEVNAM`009= TW,-`009`009; Dummy TW port Driver Dispatch table
X`009`009START`009= 0,-
X`009`009FUNCTB`009= 0
X
X`009.PSECT $$$115_DRIVER,LONG
X
X; The associated class driver uses this table to command the port driver.
X; The address of the table is contained in the terminal UCB extension area.
X; The offset definitions are defined by the ttydefs.
X
X;
X; TW specific dispatch table
X;
XPORT_VECTOR:
X;
X; Added port vector table using VEC macros
X;
X`009$VECINI`009TW,TW$NULL
X`009$VEC`009STARTIO,TW$STARTIO
X`009$VEC`009DISCONNECT,TW$DISCONNECT
X`009$VEC`009SET_LINE,TW$SET_LINE
X`009$VEC`009XON,TW$XON
X`009$VEC`009XOFF,TW$XOFF
X`009$VEC`009ABORT,TW$ABORT
X`009$VECEND
X
XTW$NULL:`009`009`009`009; Null port routine
X`009RSB
X
X`012
X`009.PAGE
X`009.SBTTL`009TW$INITIAL - Initialize pseudo terminal interface
X;++
X; TW$INITIAL - INITIALIZE INTERFACE
X;
X; FUNCTIONAL DESCRIPTION:
X;
X; This routine is entered at device CONNECT time and power recovery.
X; All we do is connect ourselves up to the class driver.
X;
X; INPUTS:
X;
X;`009R4 = ADDRESS OF THE UNIT CSR
X;`009R5 = IDB OF UNIT
X;`009R8 = ADDRESS OF THE UNIT CRB
X;
X; OUTPUTS:
X;
X;`009R0, R1, R2, R3 are destroyed.
X;
X; IMPLICIT INPUTS:
X;
X;`009IPL = IPL$_POWER
X;
X;--
XTW$INITIAL::
X
X`009CLASS_CTRL_INIT TW$DPT,PORT_VECTOR
X`009MOVB`009#DT$_TW,CRB$B_TT_TYPE(R8)
X`009RSB
X`012
X`009.PAGE
X`009.SBTTL`009TW$INITLINE - RESET INDIVIDUAL LINE
X;++
X; TW$INITLINE - RESET pseudo terminal control state
X;
X; FUNCTIONAL DESCRIPTION:
X;
X; This routine performs a simple unit initialization.
X;
X;
X; INPUTS:
X;
X;`009R5 = UCB ADDRESS
X;
X; OUTPUTS:
X;
X;`009R2,R5 ARE PRESERVED.
X;--
XTW$INITLINE::`009`009`009`009; RESET SINGLE LINE
X`009MOVAL`009TW$VEC,R0`009`009; Set TW port vector table
X`009CLASS_UNIT_INIT
X`009TSTL`009UCB$W_UNIT(R5)`009`009; Skip initialization of TEMPLATE
X`009BEQL`00940$`009`009`009; Unit #0 = Template: Skip everything!
X
X`009BBS`009#UCB$V_POWER,UCB$W_STS(R5),-`009; Skip if powerfail recovery
X`009`00920$
X`009MOVL`009UCB$L_TT_LOGUCB(r5), r1`009`009; Look at logical term UCB
X`009BEQL`00910$`009`009`009`009; If none, then has no refs
X`009TSTW`009UCB$W_REFC(R1)`009`009`009; See if TW has any references
X`009BNEQ`00920$`009`009`009`009; If so don't reinit ucb
X10$:`009BSB`009SET_FORCED_CHARS`009`009; Set required characteristics
X`009BISL`009#TT2$M_HANGUP,-`009`009`009; Set default characteristics
X`009`009UCB$L_TT_DECHA1(R5)`009`009;
X`009MOVL`009UCB$L_TT_CLASS(R5),R1`009`009; Address class vector table
X
X.IF`009NOT_DEFINED`009VMS_V5
X`009BISW`009#<TTY$M_PC_NOTIME!`009-`009; Tell class driver not to time out,
X`009`009  TTY$M_PC_MULTISESSION>,-`009; and do not count as user
X`009`009UCB$W_TT_PRTCTL(R5)`009`009;
X.IF_FALSE
X`009BISW`009#<TTY$M_PC_NOTIME!`009-`009; Tell class driver not to time out,
X`009`009  TTY$M_PC_NOMODEM!`009-`009; do not allow modem processing,
X`009`009  TTY$M_PC_MULTISESSION>,-`009; and do not count as user
X`009`009UCB$W_TT_PRTCTL(R5)`009`009;
X.ENDC
X
V`009BICL2`009#TT$M_MODEM,UCB$L_DEVDEPEND(R5) ; Do not allow modem bit to ever b
Xe
X`009BICL2`009#TT$M_MODEM,UCB$L_TT_DECHAR(R5) ; set.
X`009BISL2`009#TT$M_HOSTSYNC,UCB$L_DEVDEPEND(R5) ; Always set device to HOSTSYNC
X`009BISL2`009#TT$M_HOSTSYNC,UCB$L_TT_DECHAR(R5) ;
X`009JSB`009@CLASS_SETUP_UCB(R1)`009`009; Init ucb fields
X20$:`009BBC`009#UCB$V_POWER,UCB$W_STS(R5),40$`009; Powerfail handler
X`009MOVL`009UCB$L_TT_CLASS(R5),R0`009`009;
X`009JMP`009@CLASS_POWERFAIL(R0)`009`009;
X
X40$:`009RSB
X
X
X`012
X;++
X; TW$SET_LINE - Used to Reset SPEED and UCB
X;
X; FUNCTIONAL DESCRIPTION:
X;
X;`009Called whenever someone tries to set terminal modes/characteristics.
X;`009All we do is reset anything that we think should never be changed.
X;
X; INPUTS:
X;
X;`009R5 = UCB ADDRESS of TW
X;
X; OUTPUTS:
X;
X;`009none
X;--
XTW$SET_LINE::
X`009MOVAB`009UCB$L_TW_SET_AST(R5),R4`009`009; Get list head address
X`009TSTL`009(R4)`009`009`009`009; See if list is empty
X`009BEQL`009SET_FORCED_CHARS`009`009; Empty do not deliver ASTs
X`009JSB`009G^COM$DELATTNAST`009`009; Delliver all ASTs
X
XSET_FORCED_CHARS:
X;
X; This little routine sets certain required characteristics.  It is called by
X; the INITLINE code to set them at the outset and by the SETLINE code to reset
X; them unconditionally if someone tries to set them.
X;
X`009BICL2`009#<TT2$M_DMA ! TT2$M_AUTOBAUD>, -
X`009`009UCB$L_DEVDEPND2(R5)
X`009BICL2`009#<TT2$M_DMA ! TT2$M_AUTOBAUD>, -
X`009`009UCB$L_TT_DECHA1(R5)
X
X.IF`009NOT_DEFINED`009VMS_V5
V`009BICL2`009#TT$M_MODEM,UCB$L_DEVDEPEND(R5) ; Do not allow modem bit to ever b
Xe
X`009BICL2`009#TT$M_MODEM,UCB$L_TT_DECHAR(R5) ; set.
X.ENDC
X
X`009RSB
X
X`012
X
X`009.Page
X;++
X; TW$DISCONNECT - SHUT OFF UNIT
X;
X; FUNCTIONAL DESCRIPTION:
X;
X; This routine is used when for some reason the unit must be disconnected.
X; This can be at hangup or last deassign.  If the PY device has an associated
X; mailbox, signal an MSG$_TRMHANGUP in it.
X;
X; Although we are disconnecting a virtual device, we don't do anything
X; more than send a hangup message because we want to allow the device to
X; be reusable.  It's really only if the control device (PY) goes away
X; that we mark the TW offline and delete it's UCB.  That code's all in
X; PYDRIVER.
X;
X; INPUTS:
X;
X;`009R0 = (0 for hangup, 1 for nohangup)
X;`009R5 = UCB ADDRESS of TW
X;
X; OUTPUTS:
X;
X;`009R3,R4 ARE USED.
X;--
XTW$DISCONNECT::
X`009blbs`009r0, 99$`009`009`009; If no hangup, skip all this.
X
X`009PUSHR`009#^M<R0,R1,R2,R3,R4,R5>`009; Save the registers
X
X`009MOVL`009UCB$L_TW_XUCB(R5),R5`009; Get PY UCB
X`009BEQL`00910$`009`009`009; If disconnected, ignore
X`009MOVL`009UCB$L_AMB(R5),R3`009; Load Associated Mailbox of PY UCB
X`009BEQL`00910$`009`009`009; If EQL then no mailbox
X`009MOVZWL`009#MSG$_TRMHANGUP,R4`009; Load Message Type
X`009JSB`009G^EXE$SNDEVMSG`009`009; Send the message
X10$:`009POPR`009#^M<R0,R1,R2,R3,R4,R5>`009; Restore everything
X99$:`009RSB
X
X
X`012
X`009.PAGE
X`009.SBTTL`009TW START I/O ROUTINE
X;++
X; TW$STARTIO - START I/O OPERATION ON TW
X;
X; FUNCTIONAL DESCRIPTION:
X;
X;`009This routine is entered from the device independent terminal startio
X;`009routine to enable output interrupts on an idle TW unit
X;
X; INPUTS:
X;
X;`009R3 =`009Character`009AND`009CC = Plus (N EQL 0)
X;`009R3 =`009Address`009`009AND`009CC = Negative (N EQL 1)
X;
X;`009R5 = UCB ADDRESS
X;
X; OUTPUTS:
X;
X;`009R5 = UCB ADDRESS
X;--
XTW$STARTIO::`009`009`009`009; START I/O ON UNIT
X`009BGEQ`00920$`009`009`009; Single character
X`009BISW`009#TTY$M_TANK_BURST,-`009; Signal burst active
X`009`009UCB$W_TT_HOLD(R5)
X10$:
X;
X; Here we must do something to notify our mate device that
X; there is data to pick up
X;
X`009PUSHR`009#^M<R0,R2,R3,R4,R5>`009; Save TW UCB
X`009MOVL`009UCB$L_TW_XUCB(R5),R5`009; Switch to PY UCB
X`009BEQL`00917$`009`009`009; PY is disconnected: skip
X
X.IF`009NOT_DEFINED`009VMS_V5
X`009DSBINT`009UCB$B_FIPL(R5)
X.IF_FALSE
X`009FORKLOCK`009`009-`009; Take out PY device FORK LOCK
X`009`009LOCK=UCB$B_FLCK(R5), -`009;
X`009`009SAVIPL=-(SP),`009-`009;
X`009`009PRESERVE=NO
X.ENDC
X
X`009BBC`009#UCB$V_BSY,-`009`009; If the device isn't busy,
X`009`009UCB$W_STS(R5),15$`009; then dont do i/o
X`009MOVL`009UCB$L_IRP(R5),R3`009; Get IRP address
X`009JSB`009G^IOC$INITIATE`009`009; IOC$INITIATE needs IRP addr
X15$:
X
X.IF`009NOT_DEFINED`009VMS_V5
X`009ENBINT
X.IF_FALSE
X`009FORKUNLOCK`009`009-`009; Release PY drvice FORK LOCK
X`009`009LOCK=UCB$B_FLCK(R5), -`009;
X`009`009NEWIPL=(SP)+,`009-`009;
X`009`009PRESERVE=NO,`009-`009;
X`009`009CONDITION=RESTORE`009;
X.ENDC
X
X16$:`009POPR`009#^M<R0,R2,R3,R4,R5>`009; Switch back to TW UCB
X`009RSB
X;
X; Come here if we have no PY control device to send stuff to.  Just
X; suck all the data we can out of the class driver and throw it away.
X;
X17$:`009POPR`009#^M<R0,R2,R3,R4,R5>`009; Switch back to TW UCB
X18$:`009BICB`009#UCB$M_INT, UCB$W_STS(r5)
X`009JSB`009@UCB$L_TT_GETNXT(r5)
X`009TSTB`009UCB$B_TT_OUTYPE(r5)
X`009BNEQ`00918$
X`009RSB
X
X20$:
X`009MOVB`009R3,UCB$W_TT_HOLD(R5)`009; Save output character
X`009BISW`009#TTY$M_TANK_HOLD,-`009; Signal charater in tank
X`009`009UCB$W_TT_HOLD(R5)
X`009BRB`00910$
X`012
X`009.PAGE
X`009.SBTTL`009Port Routines Stop,Resume,XON,XOFF
X;++
X; TW$XOFF -`009Send Xoff
X; TW$XON -`009Send Xon
X; TW$ABORT -`009Abort current output
X;
X; Functional Description:
X;
X;`009These routines are used by the terminal class driver to
X;`009control output on the port
X;
X; Inputs:
X;
X;`009R5 = UCB Address
X;
X; Outputs:
X;
X;`009R5 = UCB Address
X;--
X`009TTY$M_TP_XOFF = 8
X`009TTY$V_TP_XOFF = 3
X`009ASSUME`009TTY$M_TP_XOFF EQ TTY$M_TP_DLLOC+4
X`009ASSUME  TTY$V_TP_XOFF EQ TTY$V_TP_DLLOC+1
X
XTW$XOFF:
X`009PUSHR`009#^M<R0,R1,R4> `009`009; Save registers
X`009MOVAB`009UCB$L_TW_XOFF_AST(R5),R4 ; Get address of AST list
X`009CMPB`009R3,#^X13`009`009; Is XOFF
X`009BNEQ`009TW$XON_XOFF_CMN`009; NEQ not XONN use common rotuine
X`009BISB`009#TTY$M_TP_XOFF,`009-`009; Set XOFF bit in UCB
X`009`009UCB$B_TP_STAT(R5)`009;
X`009BRB`009TW$XON_XOFF_CMN`009`009; Do common processing
X
XTW$XON:
X`009PUSHR`009#^M<R0,R1,R4>`009`009; Save registers
X`009MOVAB`009UCB$L_TW_XON_AST(R5),R4 ; Get address of AST list
X`009CMPB`009R3,#^X11`009`009; Is it XON
X`009BNEQ`009TW$XON_XOFF_CMN`009; NEQ not XONN use common rotuine
X`009BICB`009#TTY$M_TP_XOFF,`009-`009; Clear XOFF bit in UCB
X`009`009UCB$B_TP_STAT(R5)`009;
X;
X; Schedule xon/xoff to be sent, and changed schedule bit mask
X;
XTW$XON_XOFF_CMN:`009`009`009; Common XONN/XOFF code
X`009TSTL`009(R4)`009`009`009; See if AST present
X`009BEQL`00930$`009`009`009; EQL no AST to deliver
X`009MOVL`009R4,R0`009`009`009; Copy list address
X
X10$:
X`009MOVL`009(R0),R0`009`009`009; Get next entry
X`009BEQL`00920$`009`009`009; All done so deliver ASTs
X`009MOVZBW`009R3,ACB$L_KAST+4(R0)`009; Store new param value
X`009BRB`00910$`009`009`009; Look for another entry
X20$:
X`009JSB`009G^COM$DELATTNAST`009; Deliver the ASTs
X30$:
X`009POPR`009#^M<R0,R1,R4>`009`009; Restore registers
X`009BISW`009#TTY$M_TANK_PREMPT,UCB$W_TT_HOLD(R5)`009; Schedule xon
X`009MOVB`009R3,UCB$B_TT_PREMPT(R5)`009`009`009; Save character
X`009RSB
X
X;
X; Abort any port currently active
X;
XTW$ABORT:
X`009BBCC`009#TTY$V_TANK_BURST, -`009; reset burst active
X`009`009UCB$W_TT_HOLD(R5),10$`009;
X10$:
X`009RSB
X`012
XTW_END:`009`009`009`009; End of driver
X
X`009.END
$ GOSUB UNPACK_FILE
$ EXIT
-+-+-+-+-+ End of part 5 +-+-+-+-+-