	.title	scrft	screen package for foreign terminals
	.ident	/V03-002/
;;;	Eric P. Scott, Caltech/Jet Propulsion Laboratory, December 1982
;;;	DECUS version adapted from JPL-VLSI.ARPA sources, November 1983
;;;	for VAX/VMS V3.2 or later
;;;
;;; WARNING: This package utilizes "unnatural knowledge" in a number of
;;; areas!
;;;
;;; Compilation/Installation:
;;; $ MACRO SCRFT
;;; $ LINK/NOTRACE/EXE=SYS$LIBRARY: SCRFT
;;; $ RUN SYS$SYSTEM:INSTALL
;;; SYS$LIBRARY:SCRFT/OPEN/SHARE
;;;
;;; Setup for Teleray 1060:
;;; $ Set Terminal/Device_Type=FT1/Tab
;;; $ esc="#"
;;; $ esc[0,8]=27
;;; $ Write Sys$Output esc,"G",esc,"Y9(",esc,"F",esc,"Y90",esc,"F",esc,-
;;; "Y98",esc,"F",esc,"Y9@",esc,"F",esc,"Y9H",esc,"F",esc,"Y9P",esc,-
;;; "F",esc,"Y9X",esc,"F",esc,"Y9`",esc,"F",esc,"Y9h",esc,"F",esc,"A"
;;; 
;;; Setup for Televideo 912/920:
;;; $ Set Terminal/Device_Type=FT3/Tab/Form
;;; $ esc="#"
;;; $ esc[0,8]=27
;;; $ unprotect:="''esc''"
;;; $ reset:="''esc'3"
;;; $ tab:="        ''esc'1"
;;; $ Write Sys$Output unprotect,reset,tab,tab,tab,tab,tab,tab,tab,tab,-
;;; tab
;;; 
;;; Setup for Otrona Attache (1200 baud max!):
;;; $ Set Terminal/Device_Type=VT52
;;; $ Set Terminal/Device_Type=FT4/LFFill=3
;;; $ esc="#"
;;; $ esc[0,8]=27
;;; $ Write Sys$Output esc,"^",esc,"A"

	.sbttl	dispatcher

	$libdef
	$ssdef

lf=^o12
vt=^o13
cr=^o15
esc=^o33
rs=^o36
us=^o37

;;; Offsets into Terminal Control Block indexed off (r6)
scr$b_type=10
scr$w_devpagsiz=14
scr$l_line=36
scr$l_column=40

	.default	displacement,word

	.psect	scrft,nowrt,exe,shr,pic,long

	.entry	scrft,^m<r2,r3,r4,r5,r7,r8,r9,r10,r11,iv>
	.enabl	lsb
	cmpb	(ap),#7		; make sure called via LIB$CALL_IMAGE
	blssu	6$
	cmpb	scr$b_type(r6),#4	; type must be FT
	bneq	7$
	movl	28(ap),r11	; r11 <- SCRFT argument list
	movl	4(r11),r10	; r10 <- SCR$ argument list
	pushab	b^8$
	caseb	8(r11),#0,#10-0	; case on request type
3$:	.word	put_screen-3$	; PUT_SCREEN
	.word	get_screen-3$	; GET_SCREEN
	.word	erase_page-3$	; ERASE_PAGE
	.word	erase_line-3$	; ERASE_LINE
	.word	set_cursor-3$	; SET_CURSOR
	.word	down_scroll-3$	; DOWN_SCROLL
	.word	4$-3$		; SCREEN_INFO (handled by SCRPKG)
	.word	put_line-3$	; PUT_LINE
	.word	move_cursor-3$	; MOVE_CURSOR
	.word	set_scroll-3$	; SET_SCROLL
	.word	up_scroll-3$	; UP_SCROLL
4$:	movzwl	#1,r0
	ret
6$:	movzwl	#ss$_insfarg,r0
	ret
7$:	movl	#lib$_intlogerr,r0
	ret
8$:	pushab	b^4$
	caseb	12(r11),#1,#8-1	; case on terminal type
9$:	.word	t1060-9$	; /FT1
	.word	loser-9$	; /FT2
	.word	tvi-9$		; /FT3
	.word	otrona-9$	; /FT4
	.word	loser-9$	; /FT5
	.word	loser-9$	; /FT6
	.word	loser-9$	; /FT7
	.word	loser-9$	; /FT8
	brb	7$
	.sbttl	terminal-independent preprocessing

;;; common PUT_SCREEN
;;; returns  r1,r2: text; r7: attributes; r8,r9: line,column
put_screen:
	clrl	r7		; assume no attributes
	caseb	(r10),#1,#4-1	; case on number of arguments
11$:	.word	13$-11$
	.word	12$-11$
	.word	15$-11$
	.word	14$-11$
12$:	movl	#lib$_invarg,r0
	ret
13$:	clrl	r8		; one argument--don't move cursor
	movl	scr$l_column(r6),r9
	brb	16$
14$:	movl	16(r10),r7	; attributes were specified
	bitl	r7,#^c15	; make sure valid
	bneq	12$
15$:	movq	8(r10),r8
	bsbb	optcur		; optional cursor position
16$:	movl	4(r10),r0	; determine length and address of text
	jsb	g^lib$analyze_sdesc_r2
	blbc	r0,20$
17$:	rsb

optcur:	bisl3	r8,r9,r0	; if both zero, don't move cursor
	beql	17$
reqcur:	mull3	r8,r9,r0	; both must be nonzero
	beql	19$
valcur:	cmpl	r8,#24		; must lie on screen
	bgtru	19$
	cmpl	r9,#80
	blequ	17$
19$:	movl	#lib$_invscrpos,r0
20$:	ret

;;; common GET_SCREEN
get_screen:
	callg	(r10),g^lib$get_input
	ret

;;; common ERASE_PAGE
;;; returns  r8,r9: line,column
erase_page:
	caseb	(r10),#0,#2-0	; case on number of arguments
21$:	.word	23$-21$
	.word	22$-21$
	.word	24$-21$
22$:	movl	#lib$_invarg,r0
	ret
23$:	clrq	r8		; no arguments--don't move cursor
	rsb
24$:	movq	4(r10),r8	; if two arguments
	bisl3	r8,r9,r0	; and both are zero
	bneq	reqcur
	incl	r8		; pretend we were called
	incl	r9		; with (1,1)
	rsb			; this gets around a bug in SYSGEN

;;; common ERASE_LINE
;;; returns  r8,r9: line,column
erase_line=erase_page

;;; common SET_CURSOR
;;; returns  r8,r9: line,column
set_cursor:
	cmpb	(r10),#2	; must have exactly two arguments
	bneq	22$
	movq	4(r10),r8
	brb	reqcur

;;; common DOWN_SCROLL
;;; returns  r8: one less than current line on screen
down_scroll:
	tstb	(r10)		; must have no arguments
	bneq	32$
	subl3	#1,scr$l_line(r6),r8
	beql	27$
	movl	r8,scr$l_line(r6)
27$:	rsb

;;; common PUT_LINE
;;; returns  r1,r2: text; r7: attributes; r8: # lines to scroll
put_line:
	clrl	r7		; assume no attributes
	caseb	(r10),#1,#3-1	; case on number of arguments
31$:	.word	33$-31$
	.word	35$-31$
	.word	34$-31$
32$:	movl	#lib$_invarg,r0
	ret
33$:	movl	#1,r8		; default scroll one line
	brw	16$
34$:	movl	12(r10),r7	; attributes were specified
	bitl	r7,#^c15	; check validity
	bneq	32$
35$:	movl	8(r10),r8
	brw	16$

;;; common MOVE_CURSOR
;;; returns  r8,r9: absolute line,column
move_cursor:
	cmpb	(r10),#2	; must have exactly two arguments
	bneq	32$
	movq	4(r10),r8
	mull3	r8,r9,r0	; both must be nonzero
	beql	38$
	addl2	scr$l_line(r6),r8
	addl2	scr$l_column(r6),r9
	brw	valcur
38$:	movl	#lib$_invscrpos,r0
	ret

;;; common SET_SCROLL
;;; returns  r8,r9: begin,end
set_scroll:
	caseb	(r10),#0,#2-0
41$:	.word	43$-41$
	.word	32$-41$
	.word	44$-41$
	brb	32$
43$:	clrq	r8
	rsb
44$:	movq	4(r10),r8
	mull3	r8,r9,r0	; both must be non-zero
	beql	32$
	cmpl	r8,#24		; both must be on screen
	bgtru	32$
	cmpl	r9,#24
	bgtru	32$
	rsb

;;; common UP_SCROLL
up_scroll:
	tstb	(r10)		; must have no arguments
	bneq	32$
	cmpw	scr$l_line(r6),scr$w_devpagsiz(r6)
	bgequ	46$
	incl	scr$l_line(r6)
46$:	movq	@16(r11),r0
	movw	#1,@20(r11)
	movb	#lf,(r1)
	rsb

loser:	bpt			; for now

	.dsabl	lsb

	.sbttl	common support routines

	.enabl	lsb
;;; append string described by r1,r2 to output buffer
append:	movq	@16(r11),r4
	movzwl	@20(r11),r0
	subw2	r0,r4
	cmpw	r1,r4
	bgtru	54$
	addl2	r0,r5
	addw3	r1,r0,@20(r11)
	movc3	r1,(r2),(r5)
	rsb
54$:	movzwl	#ss$_bufferovf,r0
	ret
;;; append (r1) copies of the byte in r2 to output buffer
cappend:
	movq	@16(r11),r4
	movzwl	@20(r11),r0
	subw2	r0,r4
	cmpw	r1,r4
	bgtru	54$
	addl2	r0,r5
	addw3	r1,r0,@20(r11)
	movc5	#0,(sp),r2,r1,(r5)
	rsb
;;; cursor address, ADM3a/Televideo style
adm_cursor:
	movq	@16(r11),r3
	movw	#<esc!<^a/=/@8>>,(r4)+
	addb3	#31,r8,(r4)+
	addb3	#31,r9,(r4)
	decl	r4
	cmpw	(r4)+,#^a/  /
	bneq	64$
	subl2	#4,r4
	movb	#rs,(r4)+
	movw	#1,@20(r11)
	rsb
64$:	movw	#4,@20(r11)
	rsb
;;; cursor address, VT52/IBM3101/Teleray style
vt52_cursor:
	movq	@16(r11),r3
	movw	#<esc!<^a/Y/@8>>,(r4)+
	addb3	#31,r8,(r4)+
	addb3	#31,r9,(r4)
	decl	r4
	cmpw	(r4)+,#^a/  /
	bneq	64$
	subl2	#4,r4
	movw	#<esc!<^a/H/@8>>,(r4)+
	movw	#2,@20(r11)
	rsb
	.dsabl	lsb

	.sbttl	t1060	Teleray 1060
;;; For this code to work properly, the terminal must not wrap
;;; at column 80 (check the switch on the back)
	.enabl	lsb
t1060:	caseb	8(r11),#0,#10-0	; case on request type
1$:	.word	t10_ps-1$	; PUT_SCREEN
	.word	2$-1$		; GET_SCREEN
	.word	t10_ep-1$	; ERASE_PAGE
	.word	t10_el-1$	; ERASE_LINE
	.word	t10_sc-1$	; SET_CURSOR
	.word	t10_ds-1$	; DOWN_SCROLL
	.word	2$-1$		; SCREEN_INFO (handled by SCRPKG)
	.word	t10_pl-1$	; PUT_LINE
	.word	t10_mc-1$	; MOVE_CURSOR
	.word	2$-1$		; SET_SCROLL
	.word	2$-1$		; UP_SCROLL
2$:	rsb
;;; Teleray PUT_SCREEN
t10_ps:	tstl	r8		; output cursor address, if any
	beql	6$
	bsbw	vt52_cursor
	movl	r8,scr$l_line(r6)
6$:	addl3	r1,r9,r0	; account for text
	cmpl	r0,#80
	blequ	10$
	movzbl	#80,scr$l_column(r6)
	brb	11$
10$:	movl	r0,scr$l_column(r6)
11$:	brw	append		; move text into buffer
;;; Teleray ERASE_PAGE
t10_ep:	tstl	r8		; cursor address specified?
	bneq	23$
	movq	@16(r11),r0	; no, erase EOS
	movw	#2,@20(r11)
	movw	#<esc!<^a/J/@8>>,(r1)
	rsb
23$:	bsbw	vt52_cursor
	movq	r8,scr$l_line(r6)
	cmpw	-(r4),#<esc!<^a/H/@8>>
	bneq	25$
	movw	#<esc!<^a/j/@8>>,(r4)	; yes, there's a better way
	movw	#2,@20(r11)
	rsb
25$:	movw	#<esc!<^a/J/@8>>,2(r4)
	movw	#6,@20(r11)
	rsb
;;; Teleray ERASE_LINE
t10_el:	tstl	r8		; cursor address specified?
	bneq	33$
	movq	@16(r11),r0
	movw	#2,@20(r11)
	movw	#<esc!<^a/K/@8>>,(r1)
	rsb
33$:	bsbw	vt52_cursor
	movw	#<esc!<^a/K/@8>>,(r4)
	addl2	#2,@20(r11)
	brb	35$
;;; Teleray SET_CURSOR
t10_sc:	bsbw	vt52_cursor
35$:	movq	r8,scr$l_line(r6)
	rsb
;;; Teleray DOWN_SCROLL
t10_ds:	movq	@16(r11),r0
	movw	#2,@20(r11)
	tstl	r8
	beql	39$
	movw	#<esc!<^a/A/@8>>,(r1)	; cursor up
	rsb
39$:	movw	#<esc!<^a/L/@8>>,(r1)	; insert line
	rsb
;;; Teleray PUT_LINE
t10_pl:	bsbw	append		; output text
	movl	#1,scr$l_column(r6)	; move to leftmost column
	addl3	r8,scr$l_line(r6),r0	; adjust internal cursor
	movl	#1,r1
	tstl	r8		; which way to index?
	blss	54$		; reverse, bleah
	beql	49$		; shortcut
	cmpw	r0,scr$w_devpagsiz(r6)
	blequ	48$
	movzwl	scr$w_devpagsiz(r6),scr$l_line(r6)
	brb	49$
48$:	movl	r0,scr$l_line(r6)
49$:	movzbl	#cr,r2		; output a CR
	bsbw	cappend
	movl	r8,r1		; output enough LFs
	beql	56$
	movzbl	#lf,r2
	brw	cappend
54$:	cmpl	r0,#1		; on screen or off?
	blss	57$
	movl	r0,scr$l_line(r6)	; on, output enough cursor ups
	movzbl	#cr,r2
	bsbw	cappend
55$:	movl	#2,r1
	movaw	i^#<esc!<^a/A/@8>>,r2
	bsbw	append
	aoblss	#0,r8,55$
56$:	rsb
57$:	movl	#1,scr$l_line(r6)	; off => top line
	movl	r0,r8
	movaw	i^#<esc!<^a/H/@8>>,r2
	bsbw	append
58$:	movl	#2,r1		; output enough ILs
	movaw	i^#<esc!<^a/L/@8>>,r2
	bsbw	append
	aobleq	#0,r8,58$
	rsb
;;; Teleray MOVE_CURSOR
t10_mc=t10_sc
	.dsabl	lsb

	.sbttl	tvi	Televideo 912/920
;;; For this code to work properly, the terminal must have the
;;; jumper at W33 installed (disable auto newline in column 80)
	.enabl	lsb
tvi:	caseb	8(r11),#0,#10-0	; case on request type
1$:	.word	tvi_ps-1$	; PUT_SCREEN
	.word	2$-1$		; GET_SCREEN
	.word	tvi_ep-1$	; ERASE_PAGE
	.word	tvi_el-1$	; ERASE_LINE
	.word	tvi_sc-1$	; SET_CURSOR
	.word	tvi_ds-1$	; DOWN_SCROLL
	.word	2$-1$		; SCREEN_INFO (handled by SCRPKG)
	.word	tvi_pl-1$	; PUT_LINE
	.word	tvi_mc-1$	; MOVE_CURSOR
	.word	2$-1$		; SET_SCROLL
	.word	2$-1$		; UP_SCROLL
2$:	rsb
;;; TVI PUT_SCREEN
tvi_ps:	tstl	r8		; output cursor address, if any
	beql	5$
	bsbw	adm_cursor
	movl	r8,scr$l_line(r6)
5$:	tstl	r7		; if any attributes were specified,
	beql	6$		; display text at half intensity
	movw	#<esc!<^a/)/@8>>,(r4)
	addw2	#2,@20(r11)
6$:	addl3	r1,r9,r0	; account for text
	cmpl	r0,#80
	blequ	10$
	movzbl	#80,scr$l_column(r6)
	brb	11$
10$:	movl	r0,scr$l_column(r6)
11$:	bsbw	append		; move text into buffer
	tstl	r7		; if in half intensity,
	beql	22$
	movl	#2,r1
	movaw	i^#<esc!<^a/(/@8>>,r2
	brw	append
;;; TVI ERASE_PAGE
tvi_ep:	tstl	r8		; cursor address specified?
	bneq	23$
	movq	@16(r11),r0	; no, erase EOS
	movw	#2,@20(r11)
	movw	#<esc!<^a/y/@8>>,(r1)
22$:	rsb
23$:	bsbw	adm_cursor
	movq	r8,scr$l_line(r6)
	cmpb	-(r4),#rs	; home position?
	bneq	25$
	movw	#<esc!<^a/*/@8>>,(r4)	; yes, there's a better way
24$:	movw	#2,@20(r11)
	rsb
25$:	incl	r4
	movw	#<esc!<^a/y/@8>>,(r4)
26$:	movw	#6,@20(r11)
	rsb
;;; TVI ERASE_LINE
tvi_el:	tstl	r8		; cursor address specified?
	bneq	33$
	movq	@16(r11),r0
	movw	#2,@20(r11)
	movw	#<esc!<^a/t/@8>>,(r1)
	rsb
33$:	bsbw	adm_cursor
	movw	#<esc!<^a/t/@8>>,(r4)
	addl2	#2,@20(r11)
	brb	35$
;;; TVI SET_CURSOR
tvi_sc:	bsbw	adm_cursor
35$:	movq	r8,scr$l_line(r6)
	rsb
;;; TVI DOWN_SCROLL
tvi_ds:	movq	@16(r11),r0
	tstl	r8
	beql	39$
	movw	#1,@20(r11)	; cursor up
	movb	#vt,(r1)
	rsb
39$:	movw	#<esc!<^a/E/@8>>,(r1)+	; insert line
	movl	scr$l_column(r6),r9	; IL on TVIs does an implied CR
	cmpl	r9,#1		; which is usually NOT what we want
	beql	24$		; usually
	movw	#<esc!<^a/=/@8>>,(r1)+
	movb	#^a/ /,(r1)+
	addb3	#31,r9,(r1)
	brb	26$
;;; TVI PUT_LINE
tvi_pl:	tstl	r7		; if any attributes were specified,
	beql	43$		; display text at half intensity
	movq	@16(r11),r3
	movw	#2,@20(r11)
	movw	#<esc!<^a/)/@8>>,(r4)
43$:	bsbw	append		; output text
	tstl	r7
	beql	45$
	movl	#2,r1
	movaw	#<esc!<^a/)/@8>>,r2
	bsbw	append
45$:	movl	#1,scr$l_column(r6)	; move to leftmost column
	addl3	r8,scr$l_line(r6),r0	; adjust internal cursor
	movl	#1,r1
	tstl	r8		; which way to index?
	blss	54$		; reverse, bleah
	beql	53$		; shortcut
	cmpw	r0,scr$w_devpagsiz(r6)
	blequ	48$
	movzwl	scr$w_devpagsiz(r6),scr$l_line(r6)
	brb	49$
48$:	movl	r0,scr$l_line(r6)
49$:	movzbl	#us,r2		; output a newline
	bsbw	cappend
	subl3	#1,r8,r1	; output enough LFs
	beql	59$
	movzbl	#lf,r2
	brw	cappend
53$:	movzbl	#cr,r2		; output a CR
	brw	cappend
54$:	cmpl	r0,#1		; on screen or off?
	blss	57$
	movl	r0,scr$l_line(r6)	; on, output enough cursor ups
	movzbl	#cr,r2
	bsbw	cappend
	mnegl	r8,r1
	movzbl	#vt,r2
	brw	cappend
57$:	movl	#1,scr$l_line(r6)	; off => top line
	movl	r0,r8
	movzbl	#rs,r2
	bsbw	cappend
58$:	movl	#2,r1		; output enough ILs
	movaw	i^#<esc!<^a/E/@8>>,r2
	bsbw	append
	aobleq	#0,r8,58$
59$:	rsb
;;; TVI MOVE_CURSOR
tvi_mc=tvi_sc
	.dsabl	lsb

	.sbttl	otrona	Otrona Attache
	.enabl	lsb
otrona:	caseb	8(r11),#0,#10-0	; case on request type
1$:	.word	otr_ps-1$	; PUT_SCREEN
	.word	2$-1$		; GET_SCREEN
	.word	otr_ep-1$	; ERASE_PAGE
	.word	otr_el-1$	; ERASE_LINE
	.word	otr_sc-1$	; SET_CURSOR
	.word	otr_ds-1$	; DOWN_SCROLL
	.word	2$-1$		; SCREEN_INFO (handled by SCRPKG)
	.word	otr_pl-1$	; PUT_LINE
	.word	otr_mc-1$	; MOVE_CURSOR
	.word	otr_ss-1$	; SET_SCROLL
	.word	2$-1$		; UP_SCROLL
2$:	rsb
otratr:	.ascii	\ $!%"&#'(,)-*.+/\
;;; Otrona PUT_SCREEN
otr_ps:	tstl	r8		; output cursor address, if any
	beql	5$
	bsbw	vt52_cursor
	movl	r8,scr$l_line(r6)
5$:	tstl	r7		; if any attributes were specified,
	beql	6$		; map to Otrona codes
	movw	#<esc!<^a/U/@8>>,(r4)+
	movb	otratr[r7],(r4)
	addw2	#3,@20(r11)
6$:	addl3	r1,r9,r0	; account for text
	cmpl	r0,#80
	blequ	10$
	movzbl	#80,scr$l_column(r6)
	brb	11$
10$:	movl	r0,scr$l_column(r6)
11$:	bsbw	append		; move text into buffer
	tstl	r7		; if attributes were specified,
	beql	22$
	movl	#3,r1
	moval	i^#<esc!<^a/U /@8>>,r2
	brw	append
;;; Otrona ERASE_PAGE
otr_ep:	tstl	r8		; cursor address specified?
	bneq	23$
	movq	@16(r11),r0	; no, erase EOS
	movw	#2,@20(r11)
	movw	#<esc!<^a/J/@8>>,(r1)
22$:	rsb
23$:	bsbw	vt52_cursor
	movq	r8,scr$l_line(r6)
	cmpw	-(r4),#<esc!<^a/H/@8>>	; home position?
	bneq	25$
	movw	#esc!<^a/\/@8>,(r4)+	; yes, there's a better way
	movc5	#0,(sp),#0,#10,(r4)	; but it requires 10 nuls
	movw	#esc!<^a/^/@8>,(r3)+	; at 1200 baud (ugh!)
	movw	#14,@20(r11)	; and sets wrap (double-ugh!)
	rsb
25$:	movw	#<esc!<^a/J/@8>>,2(r4)
26$:	movw	#6,@20(r11)
	rsb
;;; Otrona ERASE_LINE
otr_el:	tstl	r8		; cursor address specified?
	bneq	33$
	movq	@16(r11),r0
	movw	#2,@20(r11)
	movw	#<esc!<^a/K/@8>>,(r1)
	rsb
33$:	bsbw	vt52_cursor
	movw	#<esc!<^a/K/@8>>,(r4)
	addl2	#2,@20(r11)
	brb	35$
;;; Otrona SET_CURSOR
otr_sc:	bsbw	vt52_cursor
35$:	movq	r8,scr$l_line(r6)
	rsb
;;; Otrona DOWN_SCROLL
otr_ds:	movq	@16(r11),r0
	movw	#2,@20(r11)	; cursor up
	movw	#<esc!<^a/I/@8>>,(r1)
	rsb
;;; Otrona PUT_LINE
otr_pl:	tstl	r7		; if any attributes were specified,
	beql	43$		; map to Otrona codes
	movq	@16(r11),r3
	movw	#3,@20(r11)
	movw	#<esc!<^a/U/@8>>,(r4)+
	movb	otratr[r7],(r4)
43$:	bsbw	append		; output text
	tstl	r7
	beql	45$
	movl	#3,r1
	moval	#<esc!<^a/U /@8>>,r2
	bsbw	append
45$:	movl	#1,scr$l_column(r6)	; move to leftmost column
	addl3	r8,scr$l_line(r6),r0	; adjust internal cursor
	movl	#1,r1
	movzbl	#cr,r2		; output a CR
	bsbw	cappend
	tstl	r8		; which way to index?
	blss	54$		; reverse, bleah
	beql	59$		; shortcut
	cmpw	r0,scr$w_devpagsiz(r6)
	blequ	48$
	movzwl	scr$w_devpagsiz(r6),scr$l_line(r6)
	brb	49$
48$:	movl	r0,scr$l_line(r6)
49$:	movl	r8,r1		; output enough LFs
	movzbl	#lf,r2
	brw	cappend
54$:	cmpl	r0,#1		; on screen or off?
	bgtr	55$
	movl	#1,r0
55$:	movl	r0,scr$l_line(r6)
58$:	movl	#2,r1
	movaw	i^#<esc!<^a/I/@8>>,r2
	bsbw	append
	aoblss	#0,r8,58$
59$:	rsb
;;; Otrona MOVE_CURSOR
otr_mc=otr_sc
;;; Otrona SET_SCROLL
otr_ss:	movab	-64(sp),sp	; the Otrona's concept of "active
	pushab	(sp)		; region" isn't quite the same thing
	movzbl	#64,-(sp)	; as DEC's "scrolling region"
	pushab	b^otr_ss_ok	; We'll try it if OTRONA_SET_SCROLL_OK
	pushl	s^#otr_ss_ok_len	; is defined

	clrl	-(sp)
	clrq	-(sp)
	pushaq	20(sp)
	clrl	-(sp)
	pushaq	20(sp)
	calls	#6,@#sys$trnlog
	movab	80(sp),sp
	cmpw	r0,#ss$_normal
	bneq	67$

	movq	@16(r11),r0
	movw	#4,@20(r11)
	movw	#esc!<^a/X/@8>,(r1)+	; can't use save/recall
	addb3	#31,r8,(r1)+	; parameters since it includes
	addb3	#31,r9,(r1)+	; active region (sigh)
67$:	rsb
otr_ss_ok:
	.ascii	/OTRONA_SET_SCROLL_OK/
otr_ss_ok_len=.-otr_ss_ok
	.dsabl	lsb

	.end	scrft
