	.title	k11con	terminal emu
	.ident	/8.0.01/
	.psect


;	Brian Nelson  29-Dec-83  16:00:09  initial version
;	Brian Nelson  23-Jan-84  16:19:49  RSX mods
;
;	 This is the  module that handles the CONNECT command for a Kermit
;	running in local mode on a RSTS or RSX system.  The method used is
;	simply to try a read  without stall on the remote's line,  echo to
;	the user's  terminal if there was data,  read without stall on the
;	users local terminal and send that data to the remote if there was
;	data to be read. If neither terminal  had data to get, then Kermit
;	will suspend itself for 1 second  (RSTS) or 500 milliseconds (RSX)
;	and try again.
;	 While  this could be  rewritten by using asynch i/o for RSX, this
;	is the only way it can really be done for RSTS since RSTS does not
;	know about asynch i/o. It works well on RSTS since the .SLEEP exec
;	directive will terminate whenever a terminator comes in, which for
;	binary i/o, means anything. For RSX it comes off a bit slow as the
;	the mark time (MRKT$S) directive can not be stopped if we wait for
;	it via the WTSE$S  directive.  This means,  for RSX, that whenever
;	the SF.GMC QIO finds both  type ahead buffers empty Kermit will do
;	a MRKT$S and wait until it expires before looking at the typeahead
;	buffers again.  As noted, this is currently set to 30 ticks.




	.include	/IN:K11MAC.MAC/
	.iif ndf	,k11inc	,.error	; missing INCLUDE for K11MAC.MAC

	locmod	=	ter$cc ! ter$bi	; for the 11's console
	remmod	=	ter$cc

;	note:	vt125's are a problem as they don't send xon when you type one

	.psect	$code

	.sbttl	connect code for kermit
	.enabl	gbl
	.enabl	lsb



doconn::tstb	ttname			; insure that a device name is set
	bne	1$			; ok
	message	<Please use the SET LINE command>
	message
	return

1$:	calls	noecho	,<#ttname>	; don't want echoing please
	calls	gttnam	,<#ttcons>	; get the 11's terminal name
	calls	ttyini	,<#ttcons,#lun.co,#locmod>
	tst	r0			; did it work
	bne	2$			; no, exit with error
	calls	ttysav	,<#ttcons>	; save terminal settings
	calls	ttyset	,<#ttcons>	; set terminal up
	tst	r0			; did the initialization work ?
	bne	2$			; no, exit
	calls	ttyini	,<#ttname,#lun.ti,#remmod>
	tst	r0			; did the initialization work ?
	bne	2$			; no, exit
	calls	ttyset	,<#ttname>	; ok, set some useful things up
	clr	-(sp)			; allocate a single character buffer
	mov	sp	,r3		; use r3 to point to it please
	br	5$
2$:	jmp	90$			; handle br's too far away

5$:	clr	r2			; assume a short nap is needed
	calls	binrea	,<#lun.ti,#-1>	; try to get a charater from remote
	call	errchk			; insure error is correct one
	tst	r0			; did it work ?
	bne	10$			; no
	movb	r1	,@r3		; yes, get the character and print
	calls	binwri	,<r3,#1,#lun.co>; it out on the local terminal
	call	dumplo			; dump to a log file perhaps
	mov	sp	,r2		; and say we don't want to sleep

10$:	calls	binrea	,<#lun.co,#-1>	; see if any input is pending from
	tst	r0			; the local terminal
	bne	20$			; no
	movb	r1	,@r3		; yes, get it and send it to the

	cmpb	r1	,conesc		; other system unless it's the escape
	bne	15$
	calls	binrea	,<#lun.co,#10>	; char. get the next one please
	tst	r0			; but wait for it. did it work  ?
	bne	20$			; no
	cmpb	r1	,conesc		; really send the escape ?
	beq	15$			; yes
	call	concmd			; yes, do the command
	tst	r0			; exit ?
	bne	100$			; yes, bye
	br	20$			; no, next please

15$:	calls	binwri	,<r3,#1,#lun.ti>; the data is for the remote system
	mov	sp	,r2		; flag that no wait is needed
20$:	tst	r2			; should we take a short nap ?
	bne	30$			; no
	calls	suspend	,<#0,#30>	; yes, sleep 1/2 second
30$:	br	5$			; and back for more


		
90$:	direrr	r0			; problems in getting the connection
	br	100$			; print out possibly useful message

100$:	tst	(sp)+			; pop 1 char buffer and exit
	calls	ttyfin	,<#ttcons,#lun.co>	
	calls	ttyrst	,<#ttcons>	; restore terminal settings
	calls	ttyfin	,<#ttname,#lun.ti>
	return

	.dsabl	lsb

	global	<conesc	,ttcons	,ttname	,lun.co	,lun.ti>


	.sbttl	errchk	check for allowable errors on the link



errchk:	mov	r0	,-(sp)		; save the error code
	cmpb	r0	,#nodata	; check error codes out please
	beq	210$			; that is what we wanted (no data)
	tst	r0			; any other kind of error ?
	beq	210$			; no
	calls	syserr	,<r0,#errtxt>	; yes, get the error text please
	strlen	#errtxt			; ok
	add	#errtxt	,r0		; get the length, point to the end
	movb	#cr	,(r0)+		; and stuff a carriage return and
	movb	#lf	,(r0)+		; a line feed in
	clrb	@r0			; insure .asciz please
	strlen	#errtxt			; the length once again
	calls	binwri	,<#errtxt,r0,#lun.co> ; try to print error on TI
	tst	r0			; did that also fail ?
	beq	210$			; no
	mov	@sp	,r0		; yes
	direrr	r0			; yes, print on default TI: lun
210$:	mov	(sp)+	,r0		; pop saved r0 and exit
	return				; bye

	global	<errtxt	,lun.co	,nodata>




	.sbttl	concmd	terminal emulation escape commands

concmd:	scan	r1,#200$		; look for a match here
	asl	r0			; word offsets
	jsr	pc	,@210$(r0)	; dispatch to the correct routine
	return


200$:	.byte	'C&137	,'c!40		; drop connection ctrl \ C
	.byte	'I&137	,'i!40		; init the line
	.byte	'Q&137	,'q!40		; quit logging but leave file open
	.byte	'R&137	,'r!40		; resume logging if file is open
	.byte	'X&137	,'X!40		; control Q and then thats all
	.byte	'?	,177		; help, rub for send break
	.byte	0
	.even

210$:	.word	con.$			; unknown escape command
	.word	con.c	,con.c		; drop connection
	.word	con.i	,con.i		; get modems attention
	.word	con.q	,con.q		; turn console logging off
	.word	con.r	,con.r		; turn it back on please
	.word	con.x	,con.x		; send XON
	.word	con.hl	,con.br		; print out commands



con.$:	clr	r0			; NOP
	return


con.c:	mov	sp	,r0		; set flag to exit connect code
	return				; simple


con.i:	calls	ttydtr	,<#ttname>	; try to force DTR up on the line
	clr	r0
	return


con.q:	bic	#log$co	,trace		; turn off console logging
	clr	r0
	return


con.r:	bit	#log$op	,trace		; if the file is open do it
	beq	100$			; no
	bis	#log$co	,trace		; yes, enable this
100$:	clr	r0
	return


con.x:	calls	binwri	,<#200$,#1,#lun.ti>; insure a control Q goes down
	clr	r0
	return

200$:	.byte	'Q&37
	.even


con.br:	calls	ttspee	,<#ttname>	; get the remotes terminal speed
	mov	r0	,r2		; save the old speed
	calls	setspd	,<#ttname,#50.>	; try to set it down to 50 baud
	tst	r0			; did it work ?
	bne	100$			; no, forget it
	calls	binwri	,<#200$,#1,#lun.ti>; yes, send a null over
	calls	setspd	,<#ttname,r2>	; restore the terminal's speed
	br	110$
100$:	strlen	#210$			; speed change failed. say so
	calls	binwri	,<#210$,r0,#lun.co>
110$:	clr	r0			; not done
	return

200$:	.byte	0,0
210$:	.asciz	/XMIT speed change to 50 Baud failed/<cr><lf>
	.even



con.hl:	strlen	#200$
	calls	binwri	,<#200$,r0,#lun.co>
	clr	r0
	return

200$:	.ascii	/C	Connect back to the local Kermit-11/<cr><lf>
	.ascii	/I	Drop  and raise DTR (for RSTS only)/<cr><lf>
	.ascii	/Q	Quit console logging.   See SET LOG/<cr><lf>
	.ascii	/R	Resume console logging. See SET LOG/<cr><lf>
	.ascii	/X	Send XON to the remote system/<cr><lf>
	.asciz	/RUBOUT	Try to fake a break to the remote/<cr><lf>
	.ascii	/?	Print this message/<cr><lf>
	.byte	0
	.even




	.sbttl	dump i/o to a log file ?


dumplo:	bit	#log$co	,trace		; is this enabled ?
	beq	100$			; no
	bit	#log$op	,trace		; is it open
	beq	100$			; no
	save	<r0,r1>			; yes, save temps please
	mov	r1	,r0		; call simple version
	mov	#lun.lo	,r1		; unit number
	call	putcr0			; thats it folks
	unsave	<r1,r0>
100$:	return


	global	<lun.lo	,putcr0	,trace>



	.end
