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