	.title	scdsp	terminal dispatching for SC
	.ident	/bdn002/
	.psect	$scdsp	,ro,d,gbl,rel,con



;	Copyright (C) 1978 1979 1980 1981 1982 1983   Change Software, Inc.
;	
;	
;	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 other-
;	wise made available to any other person.  No title
;	to and ownership of the software is hereby  trans-
;	ferred.
;	
;	The information in this  software  is  subject  to
;	change  without notice and should not be construed
;	as a commitment by the author.


	.include	/IN:SCTERM.MAC/

	.iif ndf, maxvt, .error ; include for SCTERM is FUBAR



;	Declare the terminal based dispatching to be exported to
;	SC.MAC
;	Due to obvious reasons this module CAN NOT be overlayed.


	global	<sc.tbl,sc.mas,	sc.gma,	vtetbl,	vteked,	teltbl	>
	global	<telked,anstbl,	ansked,	sc.chr,	etbl,	esiz	>
	global	<esclet,letsiz,	spchar,	splen,	spdsp	>


	.macro	setscr	bot,top
	mov	bot	,-(sp)
	mov	top	,-(sp)
	call	scrreg
	global	<scrreg>
	.endm	setscr


	nogbl	=	0
	gbl	=	1


	.macro	vector	disp,default,g	; define dispatch vector for function
	disp:
	.if nb,  g
	.ift
	 .iif eq, <g-gbl>, global <disp>
	.iff
	 global	<disp>
	.endc
	.rept	<maxvt/2>+1		; fill in with address(null_string)
	.word	default			; usual for non-addresses
	.endr				;
	.word	default			; use passed default?
	$$vect	=	disp		; save the base address
	$$vend	=	.
	.endm				; all done



	.macro	dispatch termty,where
	. = $$vect + termty
	.word	where
	. = $$vend
	.endm	dispatch


	.sbttl	dispatch table for escape seq commands

	.dsabl	lc



;	command table for vt52's and vt100's
;
; key		noop	up	down	right	left
; key		PF2	PF3	PF4	PF1	ESC H	ESC ESC	 ESC H

vtetbl:	.ascii	/ABCDQRSPH/<27.>
	.byte	'h!40


; key		'0'	'1'	'2'	'3'	'4'	'5'	'6'
; key		'7'	'8'	'9'	'-'	','	'.'	'enter'

vteked:	.byte	'p!40	,'q!40	,'r!40	,'s!40	,'t!40	,'u!40	,'v!40
	.byte	'w!40	,'x!40	,'y!40	,'m!40	,'l!40	,'n!40	,'M

vtesiz	=	. - vtetbl
	.even
	.dsabl	lc




;	special command table for televideo (m. horton, St. Ambrose Col)

teltbl:	.byte	33	,33	,33	,33
	.byte	'j&37	,'h&37	,'k&37	,'^&37	,'H	,33	,'h!40
telked:	.byte	'0	,'1	,'2	,'3	,'4	,'5	,'6
	.byte	'7	,'8	,'9	,'-	,',	,'.	,'m&37
telsiz	=	. - teltbl
	.even


	.sbttl	command table for h19 (ansi terminal type)
;
; key		noop	up	down	right	left
; key		PF2	PF3	f1	PF1	ESC H	ESC ESC	 ESC H

anstbl:	.ascii	/ABCDQRSPH/<27.>
	.byte	'h!40


; key		'0'	'1'	'2'	'3'	'4'	'5'	'6'
; key		'7'	'8'	'9'	'f2'	'f3'	'.'	'enter'

ansked:	.byte	'p!40	,'q!40	,'r!40	,'s!40	,'t!40	,'u!40	,'v!40
	.byte	'w!40	,'x!40	,'y!40	,'T&137	,'U&137	,'n!40	,'M&137

anssiz	=	. - anstbl
.assume	anssiz eq vtesiz
	.even
	.dsabl	lc




	.sbttl	command tables, continued


;	use escape command table based on the terminal type
;
;	tty =   0	ansi	 = 2	microbee  = 4
;	vt100 = 6	vt52	 = 8	hazeltine = 10
;	tel912= 12
;
;	default to the vt100/vt52 table

	vector	etbl,default=vtetbl

	dispatch ansi	,anstbl
	dispatch tel912	,teltbl


	vector	esiz,default=vtesiz

	dispatch ansi	,anssiz
	dispatch tel912	,telsiz

sc.chr	=	etbl


	.enabl	lc

esclet:	.ascii	/*hH/<33>
letsiz	=	. - esclet
	.even
	.dsabl	lc




	.sbttl	list of supportted tt's and keypad leadin (usually 33>


;	 Vtedit initialization code scans this list and compares
;	the actual termianl type to see if the screen editor can
;	support the terminal in full screen mode.

supvt::	.word	 vt52	,vt100	,ansi	,tel912	,-1

	global	<esc>



;	 CMD$CH  is indexed via terminal type to see if the next
;	incoming character is  a leadin  to a command  character
;	sequence as in:
;
;	mov	scope	,r0
;	cmpb	cmd$ch(r0),@r4


	vector	cmd$ch,default=33

	dispatch tel912,1


	.sbttl	ctl char input table control based on term type

;	Some non-DEC and non-ANSI terminals use control characters
;	like  form feed and line feed for cursor control, and also
;	like to send these characters for the arrow keys. In order
;	to trap  them (since we  normally want them) we must check 
;	based on terminal type to see if we need them  for control
;	purposes.

	global	<ermove	,elmove	,mvup	,mvdown>

	vector	spchar,default=200$

	dispatch	tty	,200$
	dispatch	ansi	,210$
	dispatch	mbee	,220$
	dispatch	vt100	,230$
	dispatch	vt52	,240$
	dispatch	tel912	,260$
	
200$:					; nothing for most types
210$:					; beehive
220$:					; beehive
230$:					; vt100
240$:					; vt52
250$:	.byte	0			; hazeltine
260$:	.byte	'L&37,'H&37,'K&37,'J&37	; special ctls for televideo
	.even



	vector	splen,default=0

	dispatch	tel912,4



	vector	spdsp,default=300$

	dispatch	tel912,310$

300$:	.word	spnop			; no entry for hard copy
310$:	.word	spnop,ermove,elmove,mvup,mvdown	; televideo ?
spnop:	return

	.psect	vtedit

	.sbttl	read an esacpe command sequence from the terminal


	vector	vtread,default=r$nop

	dispatch	ansi	,r$h19
	dispatch	vt100	,r$vt10
	dispatch	vt52	,r$vt52
	dispatch	tel912	,r$tel



sc$crd::movb	scope	,r0		; now dispatch based on terminal
	jsr	pc	,@vtread(r0)	; type to read the escape sequence.
	return				; bye




r$nop:	sec				; unsupported typed
	return


r$h19:
r$vt10:	call	vtgetc			; vt100's and ansi (h19)
	call	letchk			; check for ESC letter or
	bcc	10$			; ESC ESC first
	call	vtgetc			; no, we read a '[' or 'O'
10$:	clc				; read the 3rd character which
	return				; is the command character and exit



r$vt52:	call	vtgetc			; vt52's
	call	letchk			; check for ESC letter or
	bcc	10$			; ESC ESC first
	cmpb	@r4	,#'?		; was it a keypad key or a PFn
	bne	10$			; was a PFn key sending 2 chars.
	call	vtgetc			; no, we read a '?'
10$:	clc				; read the 3rd character which
	return				; is the command character and exit



r$tel:	call	vtgetc			; televideo 912 ala MIKE HORTON
	clc
	return


letchk:	mov	#esclet	,r0		; check for ESC letter and whatever
	mov	#letsiz	,r1		; before we read the rest of the cmd
10$:	cmpb	@r4	,(r0)+		; loop
	beq	20$			;  exit if lettertbl[i] = ch ;
	sob	r1	,10$		;  i := succ(i)
	sec				; end
	return				; return(failure)
20$:	clc				; return(success)
	return


	global	<vtgetc>

	.sbttl	turn alternate keymode on and off


;	note that these are dispatched by terminal type
;
;	vt100 = 6.	vt52 = 8.	tel912 = 12.
;
;	note that for all but vt52 and vt100 the call are no-ops

	global	<kp.app	,kp.num>

kp.app:	mov	r0	,-(sp)
	mov	scope	,r0
	.print	5$(r0)
	br	kp.exi

	vector	5$,default=10$,g=nogbl

	dispatch	ansi	,20$
	dispatch	vt100	,20$
	dispatch	vt52	,20$

10$:	.byte	0
20$:	.byte	esc,'=,0,0
	.even

kp.num:	mov	r0	,-(sp)
	mov	scope	,r0
	.print	5$(r0)
	br	kp.exi


	vector	5$,default=10$,g=nogbl

	dispatch	ansi	,20$
	dispatch	vt100	,20$
	dispatch	vt52	,20$

10$:	.byte	0
20$:	.byte	esc,'>,esc,'>,0,0
	.even

kp.exi:	mov	(sp)+	,r0
	return


pcr:	.print	#100$
	return

100$:	.byte	15,0


	.sbttl	delete a line from the display

vtdell::mov	scope	,r0		; terminal type
	jsr	pc	,@200$(r0)	; dispatch on tt type
	return

	global	<sc$red	,sc$mov	,sc$loa	,dmplin	,redolx>
	global	<lkill	,cdown	,sc$rff>
	global	<curlin	,scswi	,.nolin>

;	 Attempt to  do something intelligent about deleting lines
;	from  the display.  For  vt100's we will  simply alter the
;	scrolling  region to be from  currentline to lastline  and
;	then  force a scroll  of the new screen, then printing the
;	new last line in the right place.
;	 For H19's and other ansi-only  terminals, we will attempt
;	to use the deleteline_in_display control sequence and then
;	jump down to the last line to print the bottom line.
;	 For VT52s and televideo we are forced to repaint the rest
;	of the screen since those terminals are rather dumb types.
;	 This  code is currently  (15-Dec-82  16:54:07) only  used
;	for deletions of a single line (ie, ^D or PF4).
;
;		tty	ansi	mbee	vt100	vt52	haz	tel

	vector	200$,default=300$,g=nogbl

	dispatch	ansi	,310$
	dispatch	vt100	,330$


300$:
320$:
340$:
350$:
360$:	call	sc$red			; vt52 and televideo
	movb	#177	,@r4		; repaint to eos and flag
	return				; currentline reprint next



	.sbttl	special cases for vt100's and h19's

310$:	cmp	r2	,#3		; decide on a reasonable
	bgt	311$			; cutoff for scrolling
	mov	lochi	,r0		; too many. are we close to
	sub	r2	,r0		; the bottom of the screen?
	ble	311$			; consistancy check
	cmp	r0	,curlin(r4)	; if so, simply repaint
	bgt	312$			; if not, then scroll
311$:	call	400$			; no, call repainting code
	br	315$


312$:	tst	r2			; any more lines to do ?
	ble	313$			; no
	call	sc$mov
	.print	#319$			; delete line in display
	mov	curlin(r4),-(sp)	; save current line number
	mov	lochi	,curlin(r4)	; and goto the bottom
	call	sc$mov			; get to bottom of display
	sub	r2	,curlin(r4)
	inc	curlin(r4)
	call	sc$loa			; load workbuffer with it
	mov	curlin(r4),r0		; get set to print it
	call	pcr			; move back to left all way
	call	dmplin			; simple
	mov	(sp)+	,curlin(r4)	; restore current line number
	call	sc$loa			; insure line is in workbuffer
	call	sc$mov			; get back to where we were
	dec	r2
	br	312$

313$:	bit	#.nolin	,scswi(r4)	; line numbering off or on?
	bne	314$			; off
	call	redolx			; on, must renumber things
314$:	clrb	@r4
315$:	return

319$:	.byte	esc,'[,'m&137,0



	.sbttl	delete screen reprinting for VT100's and VT125's


;	Delete a line or lines from display for VT100's
;
;	input:	r2	number of lines deleted
;		r1	0 for normal mode



330$:	cmp	r2	,#3		; decide on a reasonable
	bgt	331$			; cutoff for scrolling
	mov	lochi	,r0		; too many. are we close to
	sub	r2	,r0		; the bottom of the screen?
	ble	331$			; consistancy check
	cmp	r0	,curlin(r4)	; if so, simply repaint
	bgt	332$			; if not, then scroll
331$:	call	400$			; no, call repainting code
	br	335$


332$:	tst	r2			; how many times to loop
	ble	333$			; time to go
	call	sc$mov			; vt100 and lookalikes
	call	lkill			; erase current line from screen
	mov	curlin(r4),r0		; get the current line number
	sub	loclow	,r0		; convert into relative address
	inc	r0			; fix for 1..23
	inc	r0			; fix for 2..23
	setscr	r0,#23.			; alter scrolling region now
	call	sc$mov			; reposition ourselves
	mov	curlin(r4),-(sp)	; save current line number
	mov	lochi	,curlin(r4)	; say we want the last line
	call	sc$mov			; position ourselves at bottom
	call	cdown			; force cursor down
	call	$pcrlf			; once more time cause of 2..23
	call	sc$mov			; scrolling region
	sub	r2	,curlin(r4)
	inc	curlin(r4)
	call	sc$loa			; insure we have it in workbuff
	mov	curlin(r4),r0		; print the last line in display
	call	pcr			; insure at leftmost side
	call	dmplin			; ...
	mov	(sp)+	,curlin(r4)	; restore correct line number
	setscr	#2,#23.			; restore correct scrolling reg
	dec	r2			; more lines to put up ?
	br	332$			; yes

333$:	bit	#.nolin	,scswi(r4)	; noline mode currently on ?
	bne	334$			; yes
	call	redolx			; no, must fix line numbers up
334$:	call	sc$loa			; insure currentline is loaded
	clrb	@r4			; say we do not want it printed
335$:	return				; and exit (at last)


400$:	call	sc$red
	movb	#177	,@r4
	return



vtrevs::cmpb	scope	,#vt100		; reverse scrolling for last page
	bne	510$			; and vt100 line deletes
	cmp	loclow	,#1		; backed up to top of the file ?
	beq	510$			; yes, need to reprint entire thing
	bit	#vtnlin	,edsta1
	beq	510$
	call	vt1sdn			; no, just scroll top of screen down
	br	520$
510$:	call	sc$rff			; not a vt100 or page_top is line #1
	call	sc$loa
520$:	return

	global	<$pcrlf	,sc$loa	,sc$red	,sc$rff>

	.sbttl	change scrolling region for vt100's


;	S C R R E G
;
;	input:	4(sp)	low limit for region
;		2(sp)	high limit



scrreg::save	<r0,r2,r3>
	sub	#20	,sp		; allocate a buffer to use
	mov	sp	,r0		; and setup a pointer to it
	mov	<20+6+4>(sp),r3		; low limit (4(sp))
	clr	r2			; setup for divide
	div	#10.	,r2		; get pos mod 10 and pos rem 10
	add	#'0	,r2		; convert to ascii
	add	#'0	,r3		; same thing here
	movb	#155.	,(r0)+		; leadin, escape
	movb	#'[	,(r0)+		; standard command leadin
	movb	r2	,(r0)+		; insert relative curlin
	movb	r3	,(r0)+		;  ...
	movb	#';	,(r0)+		; terminate it
	mov	<20+6+2>(sp),r3
	clr	r2
	div	#10.	,r2		; get pos mod 10 and pos rem 10
	add	#'0	,r2		; convert to ascii
	add	#'0	,r3		; same thing here
	movb	r2	,(r0)+		; top of the new scolling
	movb	r3	,(r0)+		; region
	movb	#'r!40	,(r0)+		; change scrolling region
	clrb	@r0			; .asciz
	mov	sp	,r0		; point to it
	.print	r0			; and now change scolling reg
	add	#20	,sp
	unsave	<r3,r2,r0>
	mov	@sp	,4(sp)		; pop over the arg list
	add	#4	,sp		; and move return address up
	return				; bye


	.sbttl	VT100 reverse partial screen scrolling


;	V T 1 S D N
;
;	Vt100 partial screen scroll down
;
;	Erase the currentline from the display (curlin(r4)) and scroll
;	the lines above it down one line. It is presumed that the page
;	limits (loclow and lochi) are off by one from what is actually
;	on the screen, as in:
;
;	   dec loclow
;	   dec lochi
;	   dec curlin(r4)
;	   call vt1sdn
;
;
;
;	For VT100's and compatibles only.
;
;	11-Mar-83  14:38:19   BDN


vt1sdn::cmpb	scope	,#vt100		; don't try this if not a vt100
	bne	100$			; bye
	mov	r0	,-(sp)		; save registers we will be using
	mov	curlin(r4),-(sp)	; save current line number
	call	sc$mov			; insure correct position on screen
	call	lkill			; erase the line from the display
	mov	curlin(r4),r0		; now compute the size of the new
	sub	loclow	,r0		; scrolling region
	beq	10$			; no need if current_line is page_top
	inc	r0			; size := curent_line-page_top + 2
	inc	r0			;  and so on
	setscr	#2,r0			; set new vt100 scrolling region
	call	home			; move to home (really at 2,1)
	.print	#200$			; and do a reverse index to scroll
10$:	mov	loclow	,curlin(r4)	; now put the real page_top line up
	call	sc$mov			; insure position is correct
	call	sc$loa			; make the line current
	mov	curlin(r4),r0		; and print it
	call	dmplin			;
	mov	(sp)+	,curlin(r4)	; restore old current line number
	setscr	#2,#23.			; restore normal screen scrolling
	call	sc$loa			; insure old line is resident @r3
	mov	(sp)+	,r0		; and pop the register we used
100$:	return				; bye

200$:	.byte	esc,'M&137,0
	.even

	global	<home>


	.sbttl	postion cursor on x-axis


	global	<curlin	,curpos	,fastio	,lasty	,lastx	,rltime>
	global	<lm	,e$ttyo>

sc$mov::
move:	save	<r0,r1,r2>
	sub	#16.	,sp
	mov	sp	,r2
	cmpb	scope	,#tel912
	beq	5$
	cmpb	scope	,#vt52
	bne	10$
5$:	call	vt52mo
	br	190$

;	V T 1 0 0     scope type


10$:	tstb	fastio(r4)		; be correct due to noise and
	beq	30$			; broadcasts to the terminal.
	cmp	curlin(r4),lasty(r4)	; is current line number same as
	bne	30$			; no, we must do direct cursor
	mov	curpos(r4),r0		; yes, see if the movement is 1
	sub	lastx(r4),r0		; character left or right then.
	bge	20$			; positive, ok for compare then
	neg	r0			; do the absolute value thing now
20$:	dec	r0			; if difference - 1 eq 0 then we
	bne	30$			; will try doing simple left/right
	inc	rltime(r4)		; been doing this type of move often?
	cmp	rltime(r4),#5		; this is a rather arbitrary count.
	blos	130$			; no, still try a move left/right cmd

30$:	clr	rltime(r4)		; clear number of times since last dca
	cmpb	scope	,#vt100		; if a vt100 then adjust for scrolling
	beq	100$			; region else assume h19 and use normal
	mov	#1	,-(sp)		; sized screen please
	br	110$
100$:	mov	#2	,-(sp)		; point to a work buffer
110$:	mov	curlin(r4),r1		; get current line number.
	sub	loclow	,r1		; offset from top of the page.
	clr	r0			; the usual for 16 bit divide.
	add	(sp)+	,r1		; correct for scrolling region
	div	#10.	,r0		; get line number in ascii.
	add	#'0	,r0		; convert high part
	add	#'0	,r1		; convert low  part
	movb	#esc	,(r2)+		; buffer. Prefix is <ESC>
	movb	#'[	,(r2)+		; ANSI mode here !
	movb	r0	,(r2)+
	movb	r1	,(r2)+
	movb	#';	,(r2)+
	mov	curpos(r4),r1		; get the current cursor positio
	add	lm(r4)	,r1		; add in the fake left margin
	cmp	r1	,#100.		; past the end of all things?
	blo	120$			; no
	clr	r0			; yes, divide by 100 first
	div	#100.	,r0		; r0 := int(position/100)
	add	#'0	,r0		; and convert to ascii
	movb	r0	,(r2)+
120$:	clr	r0			; convert 2 digit binary number
	div	#10.	,r0		; to two ascii characters for 
	add	#'0	,r0		; the vt100. Most significant.
	add	#'0	,r1		; and 
	movb	r0	,(r2)+		; r0:=chr((pos div 10)+ord('0'))
	movb	r1	,(r2)+		; r1:=chr((pos mod 10)+ord('0'))
	movb	#'H	,(r2)+		; this says we are doing dca.
	br	190$			; and dump the positioning command

130$:	movb	#esc	,(r2)+
	movb	#'[	,(r2)+		; set for simple left/right command
	mov	curpos(r4),r0		; get the current positoin on line
	sub	lastx(r4),r0		; and get offset from last time
	movb	#'C	,@r2		; assume forward movement (right)
	tst	r0			; check for amount of movment
	beq	200$			; if same then do nothing
	bgt	140$			; if eq 1 then forward is the thing
	movb	#'D	,@r2		; if eq -1 then stuff move left in
140$:	inc	r2
	br	190$			; and dump the command to the vt100
	

190$:	clrb	@r2			; make it .asciz
	mov	sp	,r1		; restore the buffer's address
	sub	r1	,r2		; compute length to speed things
	mov	r5	,-(sp)		; note: the .print macro has a
	mov	r2	,-(sp)		; fairly high executive overhead
	mov	r1	,-(sp)		; as a result of expanding into
	mov	sp	,r5		;
	call	e$ttyo			; an emt which is trapped @ p.emt
	cmp	(sp)+	,(sp)+		; so for routines that are called
	mov	(sp)+	,r5		; often, hard code the call in.

200$:	add	#16.	,sp		; pop print buffer from stack
	unsave	<r2,r1,r0>		; pop temp registers
	mov	curpos(r4),lastx(r4)	; update last x axis position
	mov	curlin(r4),lasty(r4)	; update last y axis position
	return				; and finally leave




	.sbttl	cursor positioning for non vt100 and ansi terminals


vt52mo::movb	#155.	,(r2)+
	movb	#'Y	,(r2)+
	cmpb	scope	,#tel912
	bne	10$
	 movb	#'=	,-1(r2)
10$:	mov	curlin(r4),r0
	sub	loclow	,r0
	add	#40	,r0
	movb	r0	,(r2)+
	mov	curpos(r4),-(sp)
	add	#37	,(sp)
	add	lm(r4)	,(sp)
	movb	(sp)+	,(r2)+
	return



	.sbttl	setup scrolling for new line insertion

	.enabl	lc

;	to use old method for VT100's, patch s.nld offset 6 to sc$nl0

	global	<sc.nld>		; gbl iif globalpatching needed


;		tty	ansi	mbee	vt100	vt52	junk	tel912

	vector	sc.nld,default=sc$nl0

	dispatch	ansi	,sc$nl2
	dispatch	vt100	,sc$nl1

	newlds = maxvt+2



sc$xnl::save	<r2,r3>			; save temps
	movb	scope	,r2		; get terminal type
	cmpb	r2	,#newlds-2	; insure range checks
	bhi	100$			; oops
	jsr	pc	,@sc.nld(r2)	; dispatch on terminal type
100$:	unsave	<r3,r2>			; pop temps and exit
	return


;	for non-vt100 type terminals now.

	global	<sc$nl0>		; gbl iif globalpatching needed

sc$nl0:	movb	#377	,doiref(r4)	; set flag saying screen was cleared
	tstb	dopage(r4)		; need to scroll past page end?
	beq	10$			; no
	call	sc$mov			; resposition to absolute left
	call	$pcrlf			; yes please do
	call	lnext			; all done
	call	sc$mov			; reposition please
	call	skill			; and clear to end of screen
	br	20$			; bye
10$:	call	lnext			; still within current display
	call	lpos			; resposition to absolute left
	call	skill			; and clear to end of screen
20$:	call	sc.pln			; line numbering
100$:	return



	.sbttl	newline scrolling for vt100's and their derivatives

	global	<sc$nl1>		; gbl iif globalpatching needed

sc$nl1:	clrb	doiref(r4)		; say screen was not cleared
	movb	#377	,vt100x(r4)	; flag it
	tstb	dopage(r4)		; need to scroll off the page?
	beq	10$			; no
	call	sc$mov			; yes, insure cursor is correct
	call	$pcrlf			; and do it
	call	lnext			; next line in display
	call	sc$mov			; insure correct position
	call	lkill			; erase line
	clrb	dopage(r4)		; clear oneshot
	br	90$			; and exit

10$:
20$:	tst	cnt.ln(r4)		; if this is the first of many
	bne	50$			; lines to be inserted, erase
	bit	#vtnlin	,edsta1		; the line numbers if present.
	bne	50$			; noline mode, not needed
	mov	r0	,r2		; get curlin
	.print	#220$

30$:	cmp	r2	,lochi		; and erase linenumbers to eos
	bhi	40$			; all done
	tst	sc.eof			; need to keep dummy <eof> in
	beq	35$			; mind. not using it today.
	mov	toplin	,-(sp)		; get toplin
	dec	@sp			; less one
	cmp	(sp)+	,r2		; at the eof record ?
	beq	40$			; yes, please stop
35$:	.print	#230$			; erase to start of line
	inc	r2			; next please
	br	30$			;

40$:	call	sc$mov			; insure correct positioning
50$:	clr	r2			; setup for divide
	mov	r0	,r3		; curlin(r4) is current line #
	sub	loclow	,r3		; get the line # within display
	inc	r3			; correct for 0..22 to 1..23
	inc	r3			; correct for 2..23
	setscr	r3,#23.			; change scrolling region
	call	sc$mov			; reposition the cursor
	.print	#200$			; and force a scoll down
	setscr	#2,#23.			; restore correct region now
	call	sc$mov			; and restore the cursor
	cmp	r0	,lochi		; were we at end of page?
	blo	90$			; no
	call	skill			; yes, erase rest of display
90$:	call	sc.pln			; print line number
100$:	return				; bye


	esc = 155.
200$:	.byte	esc,'M,0
220$:	.byte	cr,esc,'[,'6,'C,0
230$:	.byte	esc,'[,'1,'K,lf,0
	.even

	.dsabl	lc

	.sbttl	newline scrolling for ansi mode (h19's)

	global	<sc$nl2>


sc$nl2:	clrb	doiref(r4)		; say screen was not cleared
	tstb	dopage(r4)		; need to fall off the bottom?
	bne	20$			; yes
	bit	#.nolin	,scswi(r4)	; no, line numbering currently on?
	beq	30$			; yes, use old way (i'm lazy)

	movb	#377	,vt100x(r4)	; signal that we used firmware
	call	sc$mov			; setup for h19
	.print	#200$			; insert a blank line
	call	sc$mov			; go back
	br	100$			; and exit

20$:	call	sc$mov			; yes, force screen scroll
	call	$pcrlf			;
	call	lnext
	call	sc$mov
	call	skill
	call	sc.pln
	clrb	dopage(r4)
	br	100$

30$:	call	lnext
	call	lpos
	call	skill
	call	sc.pln

100$:	return

200$:	.byte	esc,'[,'l&137,0
	.even

	global	<sc.eof	,sc.pln	,dopage	,cnt.ln	,doiref>
	global	<lnext	,$pcrlf	,lpos	,skill	,vt100x>



lpos:	mov	curpos(r4),-(sp)
	mov	#1.	,curpos(r4)
	call	move
	mov	(sp)+	,curpos(r4)
	return


	.sbttl	setup screen for keypad system command


;	S C S Y S
;
;	input:	@r5	1	setup to do system command
;			0	restore screen back to proper state


scsys::	save	<r1,r2>			; save temps

5$:	call	ceol			; position to bottom line
	.print	#240$			; print a prompt out
	mov	#line$	,r1		; buffer address for command
	mov	#100	,r2		; line to sys_command
	clr	r5			; length
	movb	#'$	,(r1)+		; fake a system command prefix
	inc	r5			; correct for the length also please

10$:	call	vtgetc			; read a character from termianl
	cmpb	@r4	,#'U&37		; start the read over for ^U
	beq	5$			; yes
	cmpb	@r4	,#177		; same thing as control U for <rub>
	beq	5$
	movb	@r4	,(r1)+		; and copy it to the line buffer
	cmpb	@r4	,#'C&37		; control C?
	beq	100$			; yes, exit
	cmpb	@r4	,#'Z&37		; control Z?
	beq	100$			; yes
	cmpb	@r4	,#cr		; carriage return ?
	beq	20$			; yes, exit loop
	.print	r4	,#1		; echo the character
	inc	r5			; len := succ(len)
	sob	r2	,10$		; next please

20$:	clrb	@r1			; insure .asciz
	call	cantyp			; cancel anything in tt buffers
	mov	r5	,line$-4	; stuff line length where syscmd
					; expects it to be

	cmpb	scope	,#vt100		; if vt100 then split the screen up
	bne	30$			; otherwise not

	setscr	#4.,#23.		; use bottom half of screen for vt100
	.print	#200$			; position cursor
	.print	#210$			; clear to end of screen
	.print	#200$			; reposition cursor
	dec	r5			; any command text to execute?
	bne	25$			; yes, return is automatic
	.print	#220$			; print abort msg
25$:	.print	#230$			; position cursor at eos
	br	50$	

30$:	call	home			; not a vt100
	call	sclear

50$:	mov	r5	,-(sp)		; r5 = 0 if no command line passed
	call	syscmd			; and go to the executive for a while
	tst	(sp)+			; should we pause to let the user read
	beq	60$			; the screen
	.print	#250$			; print a message
	call	vtgetc			; read a character from the terminal
	call	cantyp			; cancel any remaining text in buffer
60$:	cmpb	scope	,#vt100		; set the scrolling region back
	bne	90$			; no
	setscr	#2,#23.
90$:	call	move			; insure cursor correct
	call	sc$rff			; put screen back up
100$:	unsave	<r2,r1>
	return				; and exit


	.enabl	lc
200$:	.byte	esc
	.ascii	/[2;1/
	.byte	'H&137,0

210$:	.byte	esc,'[,'0,'J&137,0

220$:	.asciz	/Type control D to return to TED (for RSTS)/<cr><lf>
230$:	.byte	esc
	.ascii	/[23;1/
	.byte	'H&137,0
240$:	.asciz	/Command ? /
250$:	.asciz	/Type a carriage return to continue editing /
	.even


	global	<cantyp	,ceol	,esc	,home	>
	global	<sc$rff	,sclear	,syscmd	,vtgetc	>

	.end
