Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: utzoo!mnetor!uunet!seismo!husc6!think!ames!ucbcad!ucbvax!ENGVAX.SCG.HAC.COM!KVC
From: KVC@ENGVAX.SCG.HAC.COM (Kevin Carosso)
Newsgroups: comp.os.vms
Subject: CMU pseudo-terminal drivers (part 3 of 3) [DCL archive format]
Message-ID: <8707200010.AA02274@ucbvax.Berkeley.EDU>
Date: Thu, 16-Jul-87 19:51:00 EDT
Article-I.D.: ucbvax.8707200010.AA02274
Posted: Thu Jul 16 19:51:00 1987
Date-Received: Mon, 20-Jul-87 03:37:13 EDT
Sender: daemon@ucbvax.BERKELEY.EDU
Distribution: world
Organization: The ARPA Internet
Lines: 630
$ show default
$ check_sum = 1276286148
$ write sys$output "Creating TPDRIVER.MAR"
$ create TPDRIVER.MAR
$ DECK/DOLLARS="$*$*EOD*$*$"
.TITLE TPDRIVER - Pseudo terminal driver for Front End and ethernet
.IDENT 'V04-007'
;
;++
; FACILITY:
;
; VAX/VMS TERMINAL DRIVER
;
; ABSTRACT:
;
; PSEUDO TERMINAL ROUTINES.
;
; AUTHOR:
;
; 19-NOV-1982 Dale Moore (dwm) at CMU
; Redone for VMS V3.0
;
; This program has been granted to the public domain by the author.
;
; MODIFICATIONS:
; Version 'V03-001':
; DWM - Added .Page above each .sbttl
; - added modem transition routines in disco and init
; - removed $ACBDEF external def's
; - restored timeout to resume
; - added ioc$initiate call in xoff and xon routines.
; Version V03-002 - Changed TP startio to clear TIM in UCB$W_STS
; Version V03-003 - Changed TP$RESUME to not set timeout bit in sts
;
; Version V03-004 (Thu Dec 9 12:43:17 1982) D. Kashtan
; Made into a TEMPLATE driver.
; (***WARNING*** -- LOOK AT COMMENTS FOR ROUTINE
; TP$SET_LINE. THERE IS IMPORTANT INFORMATION
; ABOUT CHANGES TO VMS THAT WILL AFFECT THE TPDRIVER)
; Version V03-005 - (14-Jun-1983 )Dale Moore
; Add R4 to masks on calls to ioc$initiate.
; TTY$STARTIO clobber R4.
; Version V03-006 - Change TP$XON and TP$XOFF routines from
; unconditionally calling IOC$INITIATE.
; IOC$INITIATE will branch to PY$STARTIO,
; Which will call TTY$GETNEXTCHAR (UCB$L_TT_GETNEXT),
; Which will branch to EOLSEEN,
; which calls TTY$READONE,
; which calls the PORT_XOFF routine which is TP$XOFF.
; This cycle was eating up all of the kernel stack.
; Version V03-007 - (12-Jul-1983) Mark London
; Set default of TP to TERM to allow REPLY/USERS.
; Make TP owned and not a TEMPLATE in order that
; SHO TERM TPA0 does not cause a crash (SHOW attempts
; an ASSIGN to the device.)
; Verison V04-001 - ( 9-Nov-1984 ) L. Bellamy and D. Davis
; In order of appearance:
;
; Added Object Rights Block offset definitions.
; Add TEMPLATE bit to UCB$W_STS.
; Add ORB definitions in prologue.
; Modify to allow vector definitions using VEC macro.
; Use CLASS_CTRL_INIT and CLASS_UNIT_INIT to locate
; vector table.
; Update powerfail routines.
; Use new methodology for XON/XOFF flow control.
; Get rid of all the SET_LINE stack manipulation
; since the terminal driver does not do anything
; malicious as suggested.
;
; NOTE - Comments in subroutine preambles not altered
; to reflect changes in most places.
;
; Version V04-003 (24-Jun-1985) Kevin Carosso, Hughes Aircraft Co., S&CG
; Cleaned this thing up quite a bit.
; - Got rid of MBX characteristic on the devices. This
; was a holdover to before cloned devices really
; existed.
; - Leave the TP template device OFFLINE. This is what
; other TEMPLATE devices do, to indicate that you
; really cannot do I/O to the template. Also left
; it UNAVAILABLE, since the only way it is supposed to
; get used is by cloning in the PY device.
; - Got rid of all modem operations. Improper use tended
; to crash the system and they are not necessary. TP
; device is always NOMODEM. HANGUP works as you want
; it to without the modem stuff.
; - Setup forced characteristics and default permanent
; characteristics. Forced are: NOAUTOBAUD, and NODMA.
; Default is HANGUP.
; - Fixed up TP$DISCONNECT to properly send a message
; to PY device's associated mailbox only if we are
; actually doing a hangup. It used to do it every
; time. Changed the message to MSG$_TRMHANGUP.
; - Got rid of the BRDCST on/off stuff. It doesn't seem
; to be necessary any more. It also had a bug in it
; somewhere that caused the terminal to start off
; NOBRDCST when it shouldn't.
; - General house-cleaning. Got rid of commented out
; lines from VMS V3 version. Fixed up typos in
; comments.
;
; Version V04-004 (10-Feb-1986) Kevin Carosso, Hughes Aircraft Co., S&CG
; Changed all references to PTDRIVER to TPDRIVER because
; DEC (bless their little hearts) invented the %*%#$%
; TU81 and use PTA0: now.
;
; Version V04-005 (3-Sep-1986) Kevin Carosso, Hughes Aircraft Co., S&CG
; Fixed bug whereby the sequence ^S followed by ^Y
; would cause a system hang. Apparently the class
; driver calls the port RESUME routine when doing
; an ABORT and again when canceling the ^S. Calling
; RESUME twice like this is bad. In general, the
; port RESUME routine should not restart the output.
; In this driver, the RESUME and STOP routines aren't
; needed, so I got rid of them completely.
;
; Now on ^Y the ^S state is not cleared. You still
; need to type ^Q to get your output (including the
; *INTERRUPT* echo string. I thought this was another
; bug, but it's how my DHU-11 based terminals act
; and makes sense, because only a ^Q should really
; cancel a ^S.
;
; Also removed the TEMPLATE bit from the TPA0: template
; device since it was allowing people to $ASSIGN channels
; and get unhappy (lonely) TP devices that could crash
; the system. Now, the only way to clone TP devices
; is through the code in PYDRIVER, hence by assigning
; a channel to PYA0:. You can still $ASSIGN to TPA0:,
; but since the device is offline that shouldn't hurt
; anything. This fixed crashes caused by KERMIT and
; other things attempting to use TPA0:. You now get
; an error "DEVOFFLINE".
;
; Fixed a bug that caused a system crash from SHOW
; DEVICE/FULL of TPA0:. The ACL_QUEUE bit was set
; in the ORB but the ACL queue was invalid (was zeroed).
; I got rid of the bit, now all is well.
;
; Version V04-006 (5-Dec-1986) Kevin Carosso, Hughes Aircraft Co., S&CG
; Fixed the infamous character munging bug. The fix
; is really in PYDRIVER.
;
; Version V04-007 (10-JUL-1987) Kevin Carosso, Hughes Aircraft Co., S&CG
; In TP$INITLINE make sure to tell the class driver
; never to time out. This fix from Forest Kenney
; at DEC.
;
; Also, while we're in here, lets make the device
; acquire "NODE$" prefixes, since all the other
; terminal drivers do.
;--
.PAGE
.SBTTL Declarations
.LIBRARY /SYS$LIBRARY:LIB.MLB/
;
; EXTERNAL DEFINITIONS:
;
.NOCROSS
$CRBDEF ; DEFINE CRB
$DCDEF ; DEVICE CLASSES AND TYPES
$DDBDEF ; DEFINE DDB
$DDTDEF ; DEFINE DDT
$DEVDEF ; DEVICE CHARACTERISTICS
$DYNDEF ; Dynamic structure definitions
$IDBDEF ; DEFINE IDB OFFSETS
$IODEF ; I/O Function Codes
$IRPDEF ; IRP definitions
$MSGDEF ; Message types
$ORBDEF ; Define Object's Rights Block offsets
$TTYDEF ; DEFINE TERMINAL DRIVER SYMBOLS
$TTDEF ; DEFINE TERMINAL TYPES
$TT2DEF ; Define Extended Characteristics
$UCBDEF ; DEFINE UCB
$VECDEF ; DEFINE VECTOR FOR CRB
$TTYMACS ; DEFINE TERMINAL DRIVER MACROS
$TTYDEFS ; DEFINE TERMINAL DRIVER SYMBOLS
.CROSS
;
; LOCAL DEFINITIONS
;
DT$_TP = ^XFF
;
; Definitions that follow the standard UCB fields for TP driver
; This will all probably have to be the same as the standard term
$DEFINI UCB ; Start of UCB definitions
.=UCB$K_TT_LENGTH ; Position at end of UCB
$DEF UCB$L_TP_XUCB .BLKL 1 ; UCB of corresponding
; control/application unit
$DEF UCB$K_TP_LEN ; Size of UCB
$DEFEND UCB ; End of UCB definitions
;
; Definitions that follow the standard UCB fields in PY devices
;
$DEFINI UCB ; Start of UCB definitions
.=UCB$K_LENGTH ; position at end of UCB
$DEF UCB$L_PY_XUCB .BLKL 1 ; UCB of terminal part of pseudo terminal
$DEF UCB$K_PY_LEN ; Size of UCB
$DEFEND UCB ; end of UCB definitions
;
; LOCAL STORAGE
;
.PSECT $$$105_PROLOGUE
.PAGE
.SBTTL Standard Tables
;
; Driver prologue table:
;
TP$DPT::
DPTAB - ; DRIVER PROLOGUE TABLE
END=TP_END,- ; End and offset to INIT's vectors
UCBSIZE=UCB$K_TP_LEN,- ; SIZE OF UCB
FLAGS=DPT$M_NOUNLOAD,- ; Do not allow unload
ADAPTER=NULL,- ; ADAPTER TYPE
NAME=TPDRIVER,- ; NAME OF DRIVER
VECTOR=PORT_VECTOR
DPT_STORE INIT
DPT_STORE UCB,UCB$W_UNIT_SEED,W,0 ; SET UNIT # SEED TO ZERO
DPT_STORE UCB,UCB$B_FIPL,B,8 ; FORK IPL
DPT_STORE UCB,UCB$L_DEVCHAR,L,<-; CHARACTERISTICS
DEV$M_REC!- ;
DEV$M_IDV!- ;
DEV$M_ODV!- ;
DEV$M_TRM!- ;
DEV$M_CCL>
DPT_STORE UCB,UCB$L_DEVCHAR2,L, - ; Device characteristics
; prefix with "NODE$"
DPT_STORE UCB,UCB$B_DEVCLASS,B,DC$_TERM ;
DPT_STORE UCB,UCB$B_TT_DETYPE,B,TT$_UNKNOWN ; TYPE
DPT_STORE UCB,UCB$W_TT_DESIZE,@W,TTY$GW_DEFBUF ; BUFFER SIZE
DPT_STORE UCB,UCB$L_TT_DECHAR,@L,TTY$GL_DEFCHAR ; DEFAULT CHARACTERS
DPT_STORE UCB,UCB$L_TT_DECHA1,@L,TTY$GL_DEFCHAR2; DEFAULT CHARACTERS
DPT_STORE UCB,UCB$W_TT_DESPEE,@B,TTY$GB_DEFSPEED; DEFAULT SPEED
DPT_STORE UCB,UCB$W_TT_DESPEE+1,@B,TTY$GB_RSPEED; DEFAULT SPEED
DPT_STORE UCB,UCB$B_TT_DEPARI,@B,TTY$GB_PARITY ; DEFAULT PARITY
DPT_STORE UCB,UCB$B_TT_PARITY,@B,TTY$GB_PARITY ; DEFAULT PARITY
DPT_STORE UCB,UCB$B_DEVTYPE,B,TT$_UNKNOWN ; TYPE
DPT_STORE UCB,UCB$W_DEVBUFSIZ,@W,TTY$GW_DEFBUF ; BUFFER SIZE
DPT_STORE UCB,UCB$L_DEVDEPEND,@L,TTY$GL_DEFCHAR ; DEFAULT CHARACTERS
DPT_STORE UCB,UCB$L_TT_DEVDP1,@L,TTY$GL_DEFCHAR2; Default Characters
DPT_STORE UCB,UCB$W_TT_SPEED,@B,TTY$GB_DEFSPEED ; DEFAULT SPEED
DPT_STORE UCB,UCB$W_TT_SPEED+1,@B,TTY$GB_RSPEED ; DEFAULT SPEED
DPT_STORE UCB,UCB$B_DIPL,B,8 ; DEV IPL (no device)
DPT_STORE UCB,UCB$L_TT_WFLINK,L,0 ; Zero write queue.
DPT_STORE UCB,UCB$L_TT_WBLINK,L,0 ; Zero write queue.
DPT_STORE UCB,UCB$L_TT_RTIMOU,L,0 ; Zero read timed out disp.
;
; Added ORB definitions
;
DPT_STORE ORB, ORB$B_FLAGS, B,
DPT_STORE ORB, ORB$W_PROT, @W, TTY$GW_PROT
DPT_STORE ORB, ORB$L_OWNER, @L, TTY$GL_OWNUIC
DPT_STORE DDB,DDB$L_DDT,D,TP$DDT
DPT_STORE REINIT
DPT_STORE CRB,CRB$L_INTD+VEC$L_INITIAL,D,TP$INITIAL; CONTROLLER INIT
DPT_STORE CRB,CRB$L_INTD+VEC$L_UNITINIT,D,TP$INITLINE; UNIT INIT
DPT_STORE END
DDTAB DEVNAM = TP,- ; Dummy TP port Driver Dispatch table
START = 0,-
FUNCTB = 0
.PSECT $$$115_DRIVER,LONG
; The associated class driver uses this table to command the port driver.
; The address of the table is contained in the terminal UCB extension area.
; The offset definitions are defined by the ttydefs.
;
; TP specific dispatch table
;
PORT_VECTOR:
;
; Added port vector table using VEC macros
;
$VECINI TP,TP$NULL
$VEC STARTIO,TP$STARTIO
$VEC DISCONNECT,TP$DISCONNECT
$VEC SET_LINE,TP$SET_LINE
$VEC XON,TP$XON
$VEC XOFF,TP$XOFF
$VEC ABORT,TP$ABORT
$VECEND
TP$NULL: ; Null port routine
RSB
.PAGE
.SBTTL TP$INITIAL - Initialize pseudo terminal interface
;++
; TP$INITIAL - INITIALIZE INTERFACE
;
; FUNCTIONAL DESCRIPTION:
;
; This routine is entered at device CONNECT time and power recovery.
; All we do is connect ourselves up to the class driver.
;
; INPUTS:
;
; R4 = ADDRESS OF THE UNIT CSR
; R5 = IDB OF UNIT
; R8 = ADDRESS OF THE UNIT CRB
;
; OUTPUTS:
;
; R0, R1, R2, R3 are destroyed.
;
; IMPLICIT INPUTS:
;
; IPL = IPL$_POWER
;
;--
TP$INITIAL::
CLASS_CTRL_INIT TP$DPT,PORT_VECTOR
MOVB #DT$_TP,CRB$B_TT_TYPE(R8)
RSB
.PAGE
.SBTTL TP$INITLINE - RESET INDIVIDUAL LINE
;++
; TP$INITLINE - RESET pseudo terminal control state
;
; FUNCTIONAL DESCRIPTION:
;
; This routine performs a simple unit initialization.
;
;
; INPUTS:
;
; R5 = UCB ADDRESS
;
; OUTPUTS:
;
; R2,R5 ARE PRESERVED.
;--
TP$INITLINE:: ; RESET SINGLE LINE
MOVAL TP$VEC,R0 ; Set TP port vector table
CLASS_UNIT_INIT
TSTL UCB$W_UNIT(R5) ; Skip initialization of TEMPLATE
BEQL 40$ ; Unit #0 = Template: Skip everything!
BBS #UCB$V_POWER,UCB$W_STS(R5),- ; Skip if powerfail recovery
20$
movl UCB$L_TT_LOGUCB(r5), r1 ; Look at logical term UCB
beql 10$ ; If none, then has no refs
tstw UCB$W_REFC(r1) ; See if TP has any references
BNEQ 20$ ; If so don't reinit ucb
10$: bsb set_forced_chars ; Set required characteristics
BISL #TT2$M_HANGUP,- ; Set default characteristics
UCB$L_TT_DECHA1(R5)
MOVL UCB$L_TT_CLASS(R5),R1 ; Address class vector table
JSB @CLASS_SETUP_UCB(R1) ; Init ucb fields
bisw #TTY$M_PC_NOTIME, -
UCB$W_TT_PRTCTL(r5) ; Class driver not to time out
20$: BBC #UCB$V_POWER,UCB$W_STS(R5),40$ ; Powerfail handler
MOVL UCB$L_TT_CLASS(R5),R0
JMP @CLASS_POWERFAIL(R0)
40$: RSB
;
; This little routine sets certain required characteristics. It is called by
; the INITLINE code to set them at the outset and by the SETLINE code to reset
; them unconditionally if someone tries to set them.
;
set_forced_chars:
bicl2 #, -
UCB$L_TT_DEVDP1(R5)
bicl2 #, -
UCB$L_TT_DECHA1(R5)
rsb
;++
; TP$SET_LINE - Used to Reset SPEED and UCB
;
; FUNCTIONAL DESCRIPTION:
;
; Called whenever someone tries to set terminal modes/characteristics.
; All we do is reset anything that we think should never be changed.
;
; INPUTS:
;
; R5 = UCB ADDRESS of TP
;
; OUTPUTS:
;
; none
;--
TP$SET_LINE::
brb set_forced_chars
.Page
;++
; TP$DISCONNECT - SHUT OFF UNIT
;
; FUNCTIONAL DESCRIPTION:
;
; This routine is used when for some reason the unit must be disconnected.
; This can be at hangup or last deassign. If the PY device has an associated
; mailbox, signal an MSG$_TRMHANGUP in it.
;
; Although we are disconnecting a virtual device, we don't do anything
; more than send a hangup message because we want to allow the device to
; be reusable. It's really only if the control device (PY) goes away
; that we mark the TP offline and delete it's UCB. That code's all in
; PYDRIVER.
;
; INPUTS:
;
; R0 = (0 for hangup, 1 for nohangup)
; R5 = UCB ADDRESS of TP
;
; OUTPUTS:
;
; R3,R4 ARE USED.
;--
TP$DISCONNECT::
blbs r0, 99$ ; If no hangup, skip all this.
PUSHR #^M ; Save the registers
MOVL UCB$L_TP_XUCB(R5),R5 ; Get PY UCB
BEQL 10$ ; If disconnected, ignore
MOVL UCB$L_AMB(R5),R3 ; Load Associated Mailbox of PY UCB
BEQL 10$ ; If EQL then no mailbox
MOVZWL #MSG$_TRMHANGUP,R4 ; Load Message Type
JSB G^EXE$SNDEVMSG ; Send the message
10$: POPR #^M ; Restore everything
99$: RSB
.PAGE
.SBTTL TP START I/O ROUTINE
;++
; TP$STARTIO - START I/O OPERATION ON TP
;
; FUNCTIONAL DESCRIPTION:
;
; This routine is entered from the device independent terminal startio
; routine to enable output interrupts on an idle TP unit
;
; INPUTS:
;
; R3 = Character AND CC = Plus (N EQL 0)
; R3 = Address AND CC = Negative (N EQL 1)
;
; R5 = UCB ADDRESS
;
; OUTPUTS:
;
; R5 = UCB ADDRESS
;--
TP$STARTIO:: ; START I/O ON UNIT
BGEQ 20$ ; Single character
BISW #TTY$M_TANK_BURST,- ; Signal burst active
UCB$W_TT_HOLD(R5)
10$:
;
; Here we must do something to notify our mate device that
; there is data to pick up
;
PUSHR #^M ; Save TP UCB
MOVL UCB$L_TP_XUCB(R5),R5 ; Switch to PY UCB
BEQL 17$ ; PY is disconnected: skip
DSBINT UCB$B_FIPL(R5)
BBC #UCB$V_BSY,- ; If the device isn't busy,
UCB$W_STS(R5),15$ ; then dont do i/o
MOVL UCB$L_IRP(R5),R3 ; Get IRP address
JSB G^IOC$INITIATE ; IOC$INITIATE needs IRP addr
15$: ENBINT
16$: POPR #^M ; Switch back to TP UCB
RSB
;
; Come here if we have no PY control device to send stuff to. Just
; suck all the data we can out of the class driver and throw it away.
;
17$: POPR #^M ; Switch back to TP UCB
18$: bicb #UCB$M_INT, UCB$W_STS(r5)
jsb @UCB$L_TT_GETNXT(r5)
tstb UCB$B_TT_OUTYPE(r5)
bneq 18$
rsb
20$:
MOVB R3,UCB$W_TT_HOLD(R5) ; Save output character
BISW #TTY$M_TANK_HOLD,- ; Signal charater in tank
UCB$W_TT_HOLD(R5)
BRB 10$
.PAGE
.SBTTL Port Routines Stop,Resume,XON,XOFF
;++
; TP$XOFF - Send Xoff
; TP$XON - Send Xon
; TP$ABORT - Abort current output
;
; Functional Description:
;
; These routines are used by the terminal class driver to
; control output on the port
;
; Inputs:
;
; R5 = UCB Address
;
; Outputs:
;
; R5 = UCB Address
;--
.ENABLE LSB
;
; Schedule xon/xoff to be sent
;
TP$XOFF:
TP$XON:
;
; Changed schedule bit mask
;
BISW #TTY$M_TANK_PREMPT,UCB$W_TT_HOLD(R5) ; Schedule xon
MOVB R3,UCB$B_TT_PREMPT(R5) ; Save character
20$:
RSB
.DISABLE LSB
;
; Abort any port currently active
;
TP$ABORT:
5$: BBCC #TTY$V_TANK_BURST,UCB$W_TT_HOLD(R5),- ; reset burst active
10$
10$: RSB
TP_END: ; End of driver
.END
$*$*EOD*$*$
$ checksum TPDRIVER.MAR
$ if checksum$checksum .ne. check_sum then -
$ write sys$output "Checksum failed, file probably corrupted"
$ exit