Google
 

Trailing-Edge - PDP-10 Archives - steco_19840320_1er_E35 - 10,5676/teco/newsrc/tecdec.mac
There are 5 other files named tecdec.mac in the archive. Click here to see a list.
	SUBTTL	Introduction

; Copyright (c) 1980 Stevens Institute of Technology, Hoboken, New Jersey
; 07030.

; This software may be used and copied provided that this copyright notice
;is included, and provided that copies of all modifications are sent to:
;
;	TECO Project
;	Computer Center
;	Stevens Institute of Technology
;	Castle Point Station
;	Hoboken, New Jersey    07030
;
;
; The information in this software is subject to change without notice
; and should not be construed as a commitment by Stevens Institute of
; Technology.

  ; Search needed universals

	SEARCH	TECUNV		; TECO universal file

  ; Generate the prologue


	TECVER==200		; Major version number
	TECMIN==1		; Minor version number
	TECEDT==1163		; Edit level
	TECWHO==0		; Last editor


	PROLOGUE(DEC,<TECO DEC terminal support>)	; Generate the TITLE and other stuff

	$CODE			; Put into code PSECT
	SUBTTL	Table of Contents

;+
;.pag.lit

;		Table of Contents for TECDEC - DEC terminal support
;
;
;			   Section			      Page
;   1. Introduction . . . . . . . . . . . . . . . . . . . . .    1
;   2. Table of Contents. . . . . . . . . . . . . . . . . . .    2
;   3. Revision History . . . . . . . . . . . . . . . . . . .    3
;   4. Tables
;        4.1.   VT50. . . . . . . . . . . . . . . . . . . . .    5
;        4.2.   VT52. . . . . . . . . . . . . . . . . . . . .    5
;        4.3.   VT05. . . . . . . . . . . . . . . . . . . . .    6
;        4.4.   VT100 . . . . . . . . . . . . . . . . . . . .    7
;        4.5.   VT100A (Native or ANSI mode). . . . . . . . .    8
;   5. Support routines
;        5.1.   VT05
;             5.1.1.     XY positioning . . . . . . . . . . .    9
;             5.1.2.     Control U. . . . . . . . . . . . . .   10
;             5.1.3.     Delete a line feed . . . . . . . . .   11
;             5.1.4.     Delete a vertical tab. . . . . . . .   12
;             5.1.5.     Delete a form feed . . . . . . . . .   13
;        5.2.   VT50
;             5.2.1.     XY positioning . . . . . . . . . . .   14
;        5.3.   VT52
;             5.3.1.     Control U. . . . . . . . . . . . . .   15
;             5.3.2.     XY positioning . . . . . . . . . . .   16
;             5.3.3.     Move cost calculation. . . . . . . .   17
;             5.3.4.     Delete a line feed . . . . . . . . .   18
;             5.3.5.     Delete a vertical tab. . . . . . . .   19
;             5.3.6.     Delete a form feed . . . . . . . . .   20
;             5.3.7.     Delete to End of line. . . . . . . .   21
;        5.4.   VT100A
;             5.4.1.     XY positioning . . . . . . . . . . .   22
;             5.4.2.     Control U. . . . . . . . . . . . . .   23
;             5.4.3.     Delete a line feed . . . . . . . . .   24
;             5.4.4.     Delete a vertical tab. . . . . . . .   25
;             5.4.5.     Delete a form feed . . . . . . . . .   26
;             5.4.6.     Delete to end of line. . . . . . . .   27
;             5.4.7.     Scroll up lines. . . . . . . . . . .   28
;             5.4.8.     Cause lines to scroll down . . . . .   29
;   6. Low segment. . . . . . . . . . . . . . . . . . . . . .   30
;   7. End of TECDEC. . . . . . . . . . . . . . . . . . . . .   31

;.end lit.pag
;-
	SUBTTL	Revision History
COMMENT	|

1000	Start of this version

1005	By: Nick Bush		On: 21-July-1980
	Add capability for scrolling the screen downwards on terminals with
	the function. This currently works only for VT-52's, but provides
	the necessary support for any terminal with a scrolling region.
	Modules: TECDEC,TECVID

1025	By: Nick Bush		On: 20-August-1980
	Finish support for DEC VT-100 terminals. There are two flavors.
	EVVT100$ uses ANSI mode sequences for 80 character wide VT-100.
	EVVT132$ uses ANSI mode sequences for 132 character wide VT-100.
	Modules: TECTBL,TECDUM,TECDEC

1050	By: Robert McQueen		On: 28-October-1980
	Add support for VT05s and hope it works.
	Modules: TECDEC

1064	By: Robert McQueen		On: 23-December-1980
	VT100s are strange in that after clearing the screen the cursor is left on
	the bottom of the screen.  Add a new word to the $CRxxx blocks $CRERY to
	be the Y position after the screen is erased.
	Modules: TECUNV,TECDEC,TECVID

1065	By: Robert McQueen		On: 29-December-1980
	Remove the previous edit since it is easier to just add a home sequence
	after the erase function.  The erase sequence is now: <esc>[2J<esc>[H
	Modules: TECUNV,TECDEC,TECVID

1067	By: Robert McQueen/Nick Bush		On: 6-January-1981
	The cost algorithms where wrong for a few cases (ANSII mode positioning
	only).  Fix them.
	Modules: TECDEC,TECHEA,TECTEK

1115	By: Nick Bush		On: 5-August-1981
	More VT-100 work.  The scroll up and down routines must remember that the
	cursor is HOMEd when the scroll region is changed.  Also, the VT-100 cannot
	handle a scroll region only 1 line long, so just use the erase line
	function instead.  When a scroll region (margins) is set, the CUU and CUD
	operations (cursor up and down) will not cross the top and bottom margins
	(respectively), and therefore we cannot reliably use these in doing a
	cursor positioning.  Resort to doing more aboslute addressing.
	Modules: TECDEC

1116	By: Nick Bush		On: 10-August-1981
	More work on VT-100's.  Get size of scrolling region right, and also make
	sure the region is properly set when we do a LF in the command echoing
	section.
	Modules: TECVID,TECDEC

1124	By: Robert McQueen		On: 31-August-1981
	Incorporate the VT61 support (written by Nick Tamburri from DEC) and the
	corrected VT05 support (by Vern Brownell).
	Modules: TECTBL,TECDEC

Start of Version 200A(1126)

1151	By: Nick Bush		On: 24-March-1982
	Add Q-register 'EXIT-BUFFER' to be executed whenever TECO is exiting.
	Also remove the string to set VT-100's to smooth scroll on exit.  This
	can now be done by putting the correct macro in 'EXIT-BUFFER'.
	Modules: TECUNV,TECECM,TECPRS,TECTBL,TECDEC

1154	By: Nick Bush		On: 8-April-1982
	Add debugging routine to output the cost matrix for the section update costs.
	Fix VT-100 insert and delete cost routines to count the costs for setting
	the scroll region in the correct places.  This should make VT-100's update
	a bit faster, and make the update seem less strange to the user.
	Modules: TECUPD,TECDEC

1163	By: Nick Bush		On: 19-May-1982
	Fix ill mem ref when terminal length is set so that command buffer is
	not displayed.
	
	Also add VK100 (GIGI) support from Nick Tamburri at DEC.
	Modules: TECUPD,TECTBL,TECDEC
|
	SUBTTL	Default parameters

ND	V05MSF,	^D12		; Number of milli seconds VT05s need for fill
ND	V61MSF,	^D500		; Time to sleep on insert/delete line
; Macro to define a word of five characters

	DEFINE	TB(A<.CHNUL>,B<.CHNUL>,C<.CHNUL>,D<.CHNUL>,E<.CHNUL>)
<	BYTE	(7)A,B,C,D,E>
	SUBTTL	Tables -- VT50
	SUBTTl	Tables -- VT52

	ENTRY	VVT50TBL
VVT50TBL:
	CRTINI	VVT52
	CRTENT	BCK,<TB(.CHCNH)>
	CRTENT	SPC,<TB(.CHESC,"C")>
	CRTENT	DBS,<TB(" ",.CHCNH)>
	CRTENT	DLF,<PUSHJ P,V52DLF>
	CRTENT	DVT,<PUSHJ P,V52DVT>
	CRTENT	DFF,<PUSHJ P,V52DFF>
	CRTENT	CRB,<TB(.CHCNH)>
	CRTENT	CTU,<PUSHJ P,V52CTU>
	CRTENT	ERS,<TB(.CHESC,"H",.CHESC,"J")>
	CRTENT	TCH,<PUSHJ P,SC$CHR>	; Type a character
	CRTENT	DEL,<PUSHJ P,V52DEL>	; Delete to end of line
	CRTENT	CPP,<PUSHJ P,V52CPP>	; Cost to position
	CRTENT	CDE,<MOVEI T1,2>	; Cost to delete to end of line
	CRTENT	CIL,<MOVEI T1,2>	; Cost of a reverse scroll operation
	CRTENT	SDN,<PUSHJ P,V52SDN>	; Perform a reverse scroll operation
	CRTENT	DSP,.CHSPC
	CRTENT	XYP,<PUSHJ P,V52XY>
	CRTENT	LIN,^D24
	CRTENT	WID,^D79
	CRTEND

VVT50FLG==:VVT52FLG
	SUBTTL	Tables -- VT05

CRTINI	VVT05
	CRTENT	CDE,<PUSHJ P,V05CDE>	; Delete to end of line
	CRTENT	CPP,<PUSHJ P,V05CPP>	; Cost to position
	CRTENT	DEL,<PUSHJ P,V05DEL>	; Delete to end of line
	CRTENT	WID,<EXP ^D71>
	CRTENT	LIN,<EXP ^D20>
	CRTENT	BCK,<TB(.CHCNH)>
	CRTENT	SPC,<TB(.CHCNX)>
	CRTENT	DSP," "
	CRTENT	DBS,<TB(" ",.CHCNH)>
	CRTENT	DLF,<PUSHJ P,V05DLF>
	CRTENT	DVT,<PUSHJ P,V05DVT>
	CRTENT	DFF,<PUSHJ P,V05DFF>
	CRTENT	DCR,<TB(.CHCNZ)>
	CRTENT	CRB,<TB(.CHCNH)>
	CRTENT	ERS,<TB(.CHCRB,.CHCUN)>
	CRTENT	CTU,<PUSHJ P,V05CTU>
	CRTENT	TCH,<PUSHJ P,SC$CHR>	; Type a character
	CRTENT	XYP,<PUSHJ P,V05XY>
	CRTEND
	SUBTTL	Tables -- VT100 (Native or ANSI mode)

CRTINI	VV100
 CRTENT	INT,<PUSHJ P,V10INT>	; Routine to initialize terminal
 CRTENT	FIN,<PUSHJ P,V10FIN>	; Routine to finish up for exiting
 CRTENT	SDN,<PUSHJ P,V10SDN>	; Routine to scroll down
 CRTENT	SUP,<PUSHJ P,V10SUP>	; Routine to scroll up
 CRTENT	CPP,<PUSHJ P,V10CPP>	; Cost to do a position
 CRTENT	CIL,<PUSHJ P,V10CIL>	; Cost to do an insert line
 CRTENT	CDL,<PUSHJ P,V10CDL>	; Cost to do a delete line
 CRTENT	BCK,<TB(.CHCNH)>
 CRTENT	SPC,<TB(.CHESC,"[","C")>
 CRTENT	DBS,<TB(" ",.CHCNH)>
 CRTENT	DLF,<PUSHJ P,V10DLF>
 CRTENT	DVT,<PUSHJ P,V10DVT>
 CRTENT	DFF,<PUSHJ P,V10DFF>
 CRTENT	CRB,<TB(.CHCNH)>
 CRTENT	TCH,<PUSHJ P,SC$CHR>		; Type a character
 CRTENT CTU,<PUSHJ P,V10CTU>
 CRTENT	ERS,<EXP [$STRING(<>)]>
 CRTENT	DEL,<PUSHJ P,V10DEL>
 CRTENT	DSP,.CHSPC
 CRTENT	XYP,<PUSHJ P,V10XY>
 CRTENT	LIN,^D24
 CRTENT	WID,^D79
CRTEND
	SUBTTL	Tables -- VK100 (Gigi terminal)

CRTINI	VK100
 CRTENT	CPP,<PUSHJ P,V10CPP>	; Cost to do a position
 CRTENT	BCK,<TB(.CHCNH)>
 CRTENT	SPC,<TB(.CHESC,"[","C")>
 CRTENT	DBS,<TB(" ",.CHCNH)>
 CRTENT	DLF,<PUSHJ P,V10DLF>
 CRTENT	DVT,<PUSHJ P,V10DVT>
 CRTENT	DFF,<PUSHJ P,V10DFF>
 CRTENT	CRB,<TB(.CHCNH)>
 CRTENT	TCH,<PUSHJ P,SC$CHR>		; Type a character
 CRTENT CTU,<PUSHJ P,V10CTU>
 CRTENT	ERS,<EXP [$STRING(<>)]>
 CRTENT	CDE,<MOVEI T1,3>		; Cost delete to end of line
 CRTENT	DEL,<PUSHJ P,V10DEL>		; Delete to end of line function
 CRTENT	CIL,<MOVEI T1,2>		; Cost to scroll down
 CRTENT	SDN,<PUSHJ P,K10SDN>		; Perform it
 CRTENT	DSP,.CHSPC
 CRTENT	XYP,<PUSHJ P,V10XY>
 CRTENT	LIN,^D24
 CRTENT	WID,^D83
CRTEND
	SUBTTL	Tables -- VT61

; VT61 terminal

CRTINI	VVT61
 CRTENT	INT,<PUSHJ P,V61INT>	; Initialize the terminal handling
 CRTENT	WID,^D79		; 80 by
 CRTENT	LIN,^D24		; 25 lines
 CRTENT	CIN,<PUSHJ P,V61CIN>	; Cost initialization
 CRTENT	CRP,<PUSHJ P,V61CRP>	; Cost of replace character
 CRTENT	CIC,<PUSHJ P,V61CIC>	; Cost of insert character
 CRTENT	CDC,<PUSHJ P,V61CDC>	; Cost of delete character
 CRTENT	CIL,<MOVX T1,<<INSVL.($OPICH,CS$OPR)>!<INSVL.(2,CS$CST)>>> ; Cost of insert line
 CRTENT	CDL,<MOVX T1,<<INSVL.($OPDCH,CS$OPR)>!<INSVL.(2,CS$CST)>>> ; Cost of delete line
 CRTENT	CPP,<PUSHJ P,V61CPP>	; Cost of point to point move
 CRTENT	BCK,<TB(.CHCNH)>
 CRTENT	SPC,<TB(.CHESC,"C")>
 CRTENT	DBS,<TB(" ",.CHCNH)>
 CRTENT	DLF,<PUSHJ P,V61DLF>	; Delete a line feed
 CRTENT	DVT,<PUSHJ P,V61DVT>	; Delete a vertical tab
 CRTENT	DFF,<PUSHJ P,V61DFF>	; Delete a form feed
 CRTENT	CRB,<TB(.CHCNH)>
 CRTENT	CTU,<PUSHJ P,V61CTU>	; Routine to do control U processing
 CRTENT	FIN,<PUSHJ P,V61FIN>
 CRTENT	ERS,<TB(.CHESC,"H",.CHESC,"J")>
 CRTENT	DEL,<PUSHJ P,V61DEL>	; Routine to delete to the end of a line
 CRTENT	DSP,.CHSPC
 CRTENT	INL,<PUSHJ P,V61INL>	; Routine to insert lines
 CRTENT	DLL,<PUSHJ P,V61DLL>	; Routine to delete lines
 CRTENT	TCH,<PUSHJ P,V61TCH>	; Type a character
 CRTENT	DCH,<PUSHJ P,V61DCH>	; Routine to delete a character
 CRTENT	ICH,<PUSHJ P,V61ICH>	; Routine to insert a character
 CRTENT	XYP,<PUSHJ P,V61XY>	; Routine to do XY positioning
 CRTENT CDE,<MOVEI T1,2>	; Cost of 2
CRTEND
	SUBTTL	Support routines -- VT61 -- Initialization routine

;+
;.HL1 V61INT
;This routine will initialize the terminal handling routines for the
;specific terminal.  It will also initialize the VT61 terminal
;.literal
;
; Usage:
;	MOVEI	CRT,CRT.block.address
;	XCT	$CRINT(CRT)
;	(Return)
;
;.end literal
;-

V61INT:	SETZM	INSFLG		; Flag not in insert mode
	MOVEI	T1,[$STRING(<Pi>)] ; Get the string to put terminal
				; in VT-52 mode, not insert
	PJRST	SC$STR		; And output it
	SUBTTL	Support routines -- VT61 -- Reset terminal

;+
;.HL1 V61FIN
;This routine will reset the terminal to set up for exiting from
;TECO.
;.literal
;
; Usage:
;	MOVEI	CRT,CRT.block.address
;	XCT	$CRFIN(CRT)
;	(Return)
;
;.end literal
;-

V61FIN:	SKIPN	INSFLG		; In insert mode?
	 POPJ	P,		; No, just return
	SETZM	INSFLG		; Flag not in insert mode
	MOVX	T1,<BYTE(7).CHESC,"P","i",.CHNUL> ; Get string to take out of insert mode
	PJRST	SC$STR		; And output it
	SUBTTL	Support routines -- VT61 -- Delete a line feed

;+
;.HL1 V61DLF
;This routine will send the character string to delete a line feed.
;.literal
;
; Usage:
;	MOVE	CRT,CRT.block.address
;	PUSHJ	P,@$CRDLF(CRT)
;	(Return)
;.end literal
;-

V61DLF:	MOVX	T1,<BYTE (7).CHESC,"A"> ; Get the string
	PJRST	SC$STR		; And output it
	SUBTTL	Support routines -- VT61 -- Delete a vertical tab

;+
;.HL1 V61DVT
;This routine will send the character string to delete a vertical tab.
;.literal
;
; Usage:
;	MOVE	CRT,CRT.block.address
;	PUSHJ	P,@$CRDVT(CRT)
;	(Return)
;
;.end literal
;-


V61DVT:	$SAVE	<P1>		; Save P1
	MOVX	P1,4		; Get the number of times to repeat
V61CMN:	MOVX	T1,<BYTE (7).CHESC,"A"> ; Get the string
	PUSHJ	P,SC$STR	; Output the string
	SOJG	P1,V61CMN	; Loop until done
	POPJ	P,		; Return to the caller

	SUBTTL	Support routines -- VT61 -- Delete a form feed

;+
;.HL1 V61DFF
;This routine will send the character string to delete a form feed.
;.literal
;
; Usage:
;	MOVE	CRT,CRT.block.address
;	PUSHJ	P,$CRDFF(CRT)
;	(Return)
;
;.end literal
;-

V61DFF:	$SAVE	<P1>		; Save P1
	MOVX	P1,10		; Get the number of times to repeat
	PJRST	V61CMN		; Go to the common routine
	SUBTTL	Support routines -- VT61 -- Control-U

;+
;.HL1 V61CTU
;This routine will process the control U in the command parser.  It
;may be called without CRT being set up.
;.literal
;
; Usage:
;	MOVE	CRT,CRT.block.address
;	PUSHJ	P,@$CRCTU(CRT)
;	(Return)
;
;.end literal
;-

V61CTU:	MOVX	T1,<BYTE(7).CHESC,"P","D"> ; Get the characters
	PJRST	CTUFIN		; Finish up
	SUBTTL	Support routines -- VT61 -- Insert character

;+
;.HL V61ICH
;This routine will cause a character to be inserted.  It is called
;with the character.  It is assumed that the positioning has been done
;before this routine is called.
;.literal
;
; Usage:
;	MOVX	CH,Character
;	MOVEI	CRT,CRT.block.address
;	XCT	$CRICH(CRT)
;
;.end literal
;-

V61ICH:	PUSH	P,T1		; Save from destruction
	SKIPE	INSFLG		; In insert mode ?
	 PJRST	V61ICX		; Yes, then just type it
	MOVX	T1,<BYTE (7).CHESC,"P","I"> ; Enter insert mode string
	PUSHJ	P,SC$STR	; Type the string
	SETOM	INSFLG		; Flag we are now in insert mode
V61ICX:	MOVX	T1,<BYTE(7)" ",.CHCNH> ; Get space-backspace
	PUSHJ	P,SC$STR	; Type it
	POP	P,T1		; Restore T1
	PJRST	SC$CHR		; Type the character
	SUBTTL	Support routines -- VT61 -- Type a character

;+
;.HL1 V61TCH
;This routine will type a character on the terminal.  It will first check
;to see if the terminal is in insert character mode and take it out if it
;is in insert character mode.
;.literal
;
; Usage:
;	MOVX	CH,Character
;	MOVEI	CRT,CRT.block.address
;	XCT	$CRTCH(CRT)
;	(Return)
;
;.end literal
;-

V61TCH:	SKIPN	INSFLG		; In insert character mode ?
	 PJRST	SC$CHR		; No - Type the character
	PUSH	P,T1		; Save T1
	MOVX	T1,<BYTE (7).CHESC,"P","i"> ; Get the string
	PUSHJ	P,SC$STR	; Type the string
	POP	P,T1		; And return
	SETZM	INSFLG		; Not in insert mode now
	PJRST	SC$CHR		; Type the character
	SUBTTL	Support routines -- VT61 -- Delete N lines

;+
;.HL1 V61DLL
;This routine will cause N lines to be deleted from the screen.  It is
;called with a repeat count.
;.literal
;
; Usage:
;	MOVEI	T1,Repeat.count
;	MOVEI	CRT,CRT.block.address
;	XCT	$CRDLL(CRT)
;	(Return)
;
;.end literal
;-

V61DLL:	$SAVE	<P1,P2>		; Save P1
	MOVE	P1,T1		; Copy the repeat count
V61DL0:	MOVX	T1,<BYTE (7).CHESC,"P","D"> ; Get the text to send
	PUSHJ	P,SC$STR	; Output the string
;	MOVEI	T1,V61MSF	; Get the time to fill
;	PUSHJ	P,SC$FIL	; For the slow baud rates
	SOJG	P1,V61DL0	; Loop for all the lines
	POPJ	P,		; Return
	SUBTTL	Support routines -- VT61 -- Insert N lines

;+
;.HL1 V61INL
;This routine will cause N lines to be inserted on the screen.  It is
;called with a repeat count.
;.literal
;
; Usage:
;	MOVEI	T1,Repeat.count
;	MOVEI	CRT,CRT.block.address
;	XCT	$CRINL(CRT)
;	(Return)
;
;.end literal
;-

V61INL:	$SAVE	<P1>		; Save P1
	MOVE	P1,T1		; Copy the count
V61IN0:	MOVX	T1,<BYTE (7).CHESC,"P","F"> ; Get the text to
	PUSHJ	P,SC$STR	; Output the string
;	MOVEI	T1,V61MSF	; Get the time to sleep for slow
;	PUSHJ	P,SC$FIL	;  operations
	SOJG	P1,V61IN0	; Loop for all the lines
	POPJ	P,		; Return to the caller
	SUBTTL	Support routines -- VT61 -- Delete a character

;+
;.HL1 V61DCH
;This routine will cause n characters to be deleted from the screen.
;It is assumed that all cursor positioning has been done before this
;routine is called.
;.literal
;
; Usage:
;	MOVX	T1,Number.of.character.to.delete
;	MOVEI	CRT,CRT.block.address
;	XCT	$CRDCH(CRT)
;	(Return)
;
;.end literal
;-

V61DCH:	$SAVE	<P1>		; Save P1
	MOVE	P1,T1		; Copy the value
V61CI0:	MOVX	T1,<BYTE (7).CHESC,"P","S",177,177,177,177,177,177,177,0> ; Get the string
				;  to delete a char (with filler)
	PUSHJ	P,SC$STR	; Type it
	SOJG	P1,V61CI0	; Loop back
	POPJ	P,		; Return to the caller
	SUBTTL	Support routines -- VT61 -- Cost initialization routine

;+
;.hl 1 V61CIN
; This routine will return the initial cost word for the character
;by character comparison of a line.
;.b.lit
;
; Usage:
;	MOVE	CRT,CRTTYP
;	PUSHJ	P,@$CRCIN(CRT) or XCT $CRCIN(CRT)
;	 (return, first array element in T1)
;
;.end literal
;-

	CS$INS==1		; Term dependent info - terminal in insert mode

V61CIN:	MOVX	T1,<INSVL.(0,CS$DEP)>!<INSVL.($OPACH,CS$OPR)>
	SKIPE	INSFLG		; In insert mode?
	 MOVX	T1,<INSVL.(CS$INS,CS$DEP)>!<INSVL.($OPACH,CS$OPR)>
	POPJ	P,		; Return the cost word
	SUBTTL	Support routines -- VT61 -- Replacement cost calculation

;+
;.hl 1 V61CRP
; This routine will return the cost of replacing a character in the
;line.
;.b.lit
;
; Usage:
;	MOVE	T1,CST entry
;	MOVE	X,[-n,,Column]
;	MOVE	Y,[-n,,Row]
;	MOVE	CRT,CRTTYP
;	XCT	$CRCRP(CRT)
;	 (return, T1=CST entry
;
;.end literal
;-

V61CRP:	MOVE	T2,T1		; Copy the old word
	MOVX	T1,<<INSVL.($OPRCH,CS$OPR)>!<INSVL.(1,CS$CST)>> ; Get the operation
	TXNN	T2,<INSVL.(CS$INS,CS$DEP)> ; Check if in insert mode
	 POPJ	P,		; No, return now
	STORI.	4,T2,CSTCST,+T1	; Store the cost if we are coming from insert mode
	POPJ	P,		; And return
	SUBTTL	Support routines -- VT61 -- Insert cost calculation

;+
;.hl 1 V61CIC
; This routine will return the cost of inserting a character in the
;line.
;.b.lit
;
; Usage:
;	MOVE	T1,CST entry
;	MOVE	X,[-n,,Column]
;	MOVE	Y,[-n,,Row]
;	MOVE	CRT,CRTTYP
;	XCT	$CRCIC(CRT)
;	 (return, T1=CST entry
;
;.end literal
;-

V61CIC:	MOVE	T2,T1		; Get a copy of the old entry
	MOVX	T1,<<INSVL.(CS$INS,CS$DEP)>!<INSVL.($OPICH,CS$OPR)>!<INSVL.(3,CS$CST)>>
	TXNE	T2,<INSVL.(CS$INS,CS$DEP)> ; Already in insert mode?
	 POPJ	P,		; Yes, return
	STORI.	5,T2,CSTCST,+T1	; Store the cost if we must put into insert mode
	POPJ	P,		; And return
	SUBTTL	Support routines -- VT61 -- Delete cost calculation

;+
;.hl 1 V61CDC
; This routine will return the cost of deleting a character in the
;line.
;.b.lit
;
; Usage:
;	MOVE	T1,CST entry
;	MOVE	X,[-n,,Column]
;	MOVE	Y,[-n,,Row]
;	MOVE	CRT,CRTTYP
;	XCT	$CRCDC(CRT)
;	 (return, T1=CST entry
;
;.end literal
;-

V61CDC:	ANDX	T1,CS$DEP	; Keep only the dependant portion
	TXO	T1,<<INSVL.($OPDCH,CS$OPR)>!<INSVL.(^D10,CS$CST)>> ; Store the operation
	POPJ	P,		; And return
	SUBTTL Support routines -- VT61 -- Delete to End of line

;+
;.hl1 V61DEL
;This routine will delete to the end of the line.
;.literal
;
; Usage:
;	MOVEI	T1,# of characters to delete
;	XCT	$CRDEL(CRT)
;
;.end literal
;-

V61DEL:	MOVX	T1,<BYTE (7) .CHESC,"K">
	PJRST	SC$STR		; Print out the string
	SUBTTL	Support routines -- VT05 -- XY positioning

;+
;.HL V05XY
;This routine will do the positioning for the VT05 terminal.
;.literal
;
; Usage:
;	MOVE	X,X.postion
;	MOVE	Y,Y.postion
;	MOVE	CRT,CRT.block.index
;	PUSHJ	P,@$CRXYP(CRT)
;	(Return)
;
;.end literal
;-


V05XY:	DMOVE	T1,CURPOS	; Get the current position
	DMOVEM	X,CURPOS	; Save the current position
	SUB	T1+$OFSX,X	; Determine if it is an up/down/right/left by one
	SUB	T1+$OFSY,Y	;  movement
	SKIPE	T1+$OFSX	; Is the X zero ?
	 SKIPN	T1+$OFSY	; Or the Y ?
	  SKIPA			; Yes - Handle differently
	JRST	V05XYA		; No - Handle normally
	SKIPN	T1+$OFSY	; No change in the Y offset ?
	 JUMPE	X,V05XYC	; Yes - Only need a CR
	MOVM	T3,T1+$OFSX	; Get the X offset
	SOJE	T3,V05XYX	; Just X by one
	MOVM	T3,T1+$OFSY	; Get the Y offset
	SOJE	T3,V05XYY	; Just the Y by one
V05XYA:	SKIPN	X		; Is this non-zero ?
	 JUMPE	Y,V05XYH	; Just home it
V05XYD:	ADDX	X," "		; Convert to a position
	ADDX	Y," "		; Convert to a position
	MOVEI	T1,[$STRING(<^8/Y/>)] ; Get the start of the string
	PUSHJ	P,SC$STR	; Output it
	PUSHJ	P,V05FIL	; Fill for a bit
	MOVEI	T1,[$STRING(<^N^8/X/>)]
	PJRST	SC$STR		; Output the string

; Here to output the string and fill

V05XYF:	PUSHJ	P,SC$STR	; Do the addressing
	PJRST	V05FIL		; Do the filling

; Here to just home the cursor

V05XYH:	MOVX	T1,<BYTE(7).CHCRB> ; Get the home string
	PJRST	V05XYF		; Output string and fill

; Here to just output a CR

V05XYC:	$SAVE	<CH>		; Save the current character
	MOVX	CH,.CHCRT	; Just output a CR
	PJRST	SC$IMG		; . . .

; Here to move in the X direction by one

V05XYX:	SKIPG	T1+$OFSX	; Is this negative ?
	 JRST	V05XYD		; Do direct cursor addressing
	  MOVX	T1,<BYTE (7).CHCNH> ; Yes, to the left
	PJRST	SC$STR		; Output the string

; Here to move in the Y direction by one

V05XYY:	SKIPL	T1+$OFSY	; Is this negative ?
	 MOVX	T1,<BYTE (7).CHCNZ> ; Move the cursor up
	  MOVX	T1,<BYTE (7).CHLFD> ; Yes, Move down
	PJRST	V05XYF		; Output the string
	SUBTTL Support routines -- VT05 -- Delete to End of line

;+
;.hl V05DEL
;This routine will output a string of characters to delete
;from the current position to the end of the line.
;.literal
;
; Usage:
;	MOVEI	T1,# of characters to delete
;	XCT	$CRDEL(CRT)
;.end literal
;-

V05DEL:	$SAVE	<CH>		; Save the current character
	MOVX	CH,.CHCCF	; Get the delete character
	PUSHJ	P,SC$CHR	; Output the character

; Alternate entry point to just generate the fill

V05FIL:	MOVX	T1,V05MSF	; Get the number of milliseconds
	PJRST	SC$FIL		; Do the filling
	SUBTTL	Support routines -- VT05 -- Delete to end of line cost


;+
;.hl1 V05CDE
; This routine will calculate the cost to delete to the end of a line
;for VT05s.
;.b.literal
;
; Usage:
;	MOVE	CRT,Function block address
;	XCT	$CRCDE(CRT)
;	(Return - Cost in T1)
;
;.end literal
;-

V05CDE:	MOVX	T1,V05MSF	; Determine the number of milliseconds fill
	PUSHJ	P,SC$CFL	; Determine the cost
	AOJA	T1,.POPJ	; Give the answer back
	SUBTTL	Support routines -- VT05 -- Move cost calculation

;+
;.hl 1 V05CPP
; This routine will return the cost of moving the cursor from
;one point to another.
;.b.lit
;
; Usage:
;	MOVE	T1,[XWD X pos,Y pos] ; Source position
;	MOVE	X,[-n,,Column]
;	MOVE	Y,[-n,,Row]
;	MOVE	CRT,CRTTYP
;	XCT	$CRCPP(CRT)
;	 (return, T1= cost in characters)
;
;.end literal
;-

V05CPP:	MOVE	T3,T2		; Get a copy of where we are moving to
	JUMPE	T3,.RET0	; Return a zero if not moving
	XOR	T3,T1		; Xor together
	TXNN	T3,LH.ALF	; Same X position line ?
	 JRST	V05CPY		; Yes - Check more
	TXNN	T3,RH.ALF	; Same Y position ?
	 JRST	V05CPX		; Yes - Check more
V05CP1:	SKIPA	T1,[EXP 1]	; Cost of moving home is one
V05CPA:	MOVX	T1,3		; Have to type four characters

V05CP0:	PUSH	P,T1		; Save T1
	MOVX	T1,V05MSF	; Get the amount to fill by
	PUSHJ	P,SC$CFL	; Calculate the cost to fill
	ADD	T1,(P)		; Add in the other number
	POP	P,(P)		; Remove the junk
	POPJ	P,		; Return

; Here if possible same column movement

V05CPY:	MOVEI	T2,(T2)		; Get just the Y position
	SUBI	T2,(T1)		; Determine if just one line movement
	MOVM	T1,T2		; . . .
	SOJG	T1,V05CPA	; More than one - use four
	JUMPE	T2,V05CP1	; Else return one plus fill
	MOVEI	T1,2		; Else return two plus fill
	PJRST	V05CP0		; Add in fill

; Here if possible same line movement

V05CPX:	HLRZ	T2,T2		; Get just the X position
	JUMPE	T2,V05CP1	; If moving to the beginning of the line
				;  then return one
	HLRZ	T1,T1		; See if moving only one position
	SUBI	T1,T2		; . . .
	MOVM	T2,T1		; Get the magntude
	SOJG	T2,V05CPA	; If more than one - return four
	JUMPL	T1,V05cp1	; If backing up then only one
	MOVEI	T1,2		; Just use two
	PJRST	V05CP0		; Add in the fill
	SUBTTL	Support routines -- VT05 -- Control U

;+
;.HL1 V05CTU
;This routine will process the control U in the command parser.  It
;may be called without CRT being set up.
;.literal
;
; Usage:
;	MOVE	CRT,CRT.block.address
;	PUSHJ	P,@$CRCTU(CRT)
;	(Return)
;
;.end literal
;-

V05CTU:	MOVX	T1,<BYTE(7).CHCRT,.CHCCF> ; Get the string

; Here from control-U routines to output basic text an the extra carriage
;return

CTUFIN:	PUSHJ	P,SC$STR	; Output the string
	MOVX	CH,.CHCRT	; Finally give a carriage return to show where we are
	PJRST	T$OCHR		;  .  .  .
	SUBTTL	Support routines -- VT05 -- Delete a line feed

;+
;.HL1 V05DLF
;This routine will send the character string to delete a line feed.
;.literal
;
; Usage:
;	MOVE	CRT,CRT.block.address
;	PUSHJ	P,@$CRDLF(CRT)
;	(Return)
;.end literal
;-

V05DLF:	MOVX	CH,.CHCNZ	; Get the character
	PJRST	SC$IMG		; And output it
	SUBTTL	Support routines -- VT05 -- Delete a vertical tab

;+
;.HL1 V05DVT
;This routine will send the character string to delete a vertical tab.
;.literal
;
; Usage:
;	MOVE	CRT,CRT.block.address
;	PUSHJ	P,@$CRDVT(CRT)
;	(Return)
;
;.end literal
;-


V05DVT:	MOVX	T1,4		; Get the number of line feeds to delete

V05D.0:	MOVX	CH,.CHCNZ	; Get the character
	PUSHJ	P,SC$IMG	; output the character
	SOJG	T1,.-1		; Do them all
	POPJ	P,		; And return
	SUBTTL	Support routines -- VT05 -- Delete a form feed

;+
;.HL1 V05DFF
;This routine will send the character string to delete a form feed.
;.literal
;
; Usage:
;	MOVE	CRT,CRT.block.address
;	PUSHJ	P,$CRDFF(CRT)
;	(Return)
;
;.end literal
;-

V05DFF:	MOVX	T1,^D8		; Get the number of line feeds this is
	PJRST	V05D.0		; And go delete them
	SUBTTL	Support routines -- VT50 -- XY positioning

;+
;.HL V50XY
;This routine will do the positioning for the VT50 terminal.
;.literal
;
; Usage:
;	MOVE	X,X.postion
;	MOVE	Y,Y.postion
;	MOVE	CRT,CRT.block.index
;	PUSHJ	P,@$CRXYP(CRT)
;	(Return)
;
;.end literal
;-


	V50XY==V52XY		; Same as 52
	SUBTTL	Support routines -- VT52 -- Control U

;+
;.HL1 V52CTU
;This routine will process the control U in the command parser.  It
;may be called without CRT being set up.
;.literal
;
; Usage:
;	MOVE	CRT,CRT.block.address
;	PUSHJ	P,@$CRCTU(CRT)
;	(Return)
;
;.end literal
;-

V52CTU:	MOVX	T1,<BYTE(7).CHCRT,.CHESC,"K"> ; Get the string
	PJRST	CTUFIN		; And go finish up
	SUBTTL	Support routines -- VT52 -- XY positioning

;+
;.HL V52XY
;This routine will do the positioning for the VT52 terminal.
;.literal
;
; Usage:
;	MOVE	X,X.postion
;	MOVE	Y,Y.postion
;	MOVE	CRT,CRT.block.index
;	PUSHJ	P,@$CRXYP(CRT)
;	(Return)
;
;.end literal
;-

V61XY:
V52XY:	DMOVE	T1,CURPOS	; Get the current position
	DMOVEM	X,CURPOS	; Save the current position
	SUB	T1+$OFSX,X	; Determine if it is an up/down/right/left by one
	SUB	T1+$OFSY,Y	;  movement
	SKIPE	T1+$OFSX	; Is the X zero ?
	 SKIPN	T1+$OFSY	; Or the Y ?
	  SKIPA			; Yes - Handle differently
	JRST	V52XYA		; No - Handle normally
	SKIPN	T1+$OFSY	; No change in the Y offset ?
	 JUMPE	X,V52XYC	; Yes - Only need a CR
	MOVM	T3,T1+$OFSX	; Get the X offset
	SOJE	T3,V52XYX	; Just X by one
	MOVM	T3,T1+$OFSY	; Get the Y offset
	SOJE	T3,V52XYY	; Just the Y by one
V52XYA:	SKIPN	X		; Is this non-zero ?
	 JUMPE	Y,V52XYH	; Just home it
	ADDX	X," "		; Convert to a position
	ADDX	Y," "		; Convert to a position
	MOVEI	T1,[$STRING(<Y^8/Y/^8/X/>)]
	PJRST	SC$STR		; Output the string

; Here to just home the cursor

V52XYH:	MOVX	T1,<BYTE (7).CHESC,"H"> ; Get the home string
	PJRST	SC$STR		; Send it

; Here to just output a CR

V52XYC:	$SAVE	<CH>		; Save the current character
	MOVX	CH,.CHCRT	; Just output a CR
	PJRST	SC$IMG		; . . .

; Here to move in the X direction by one

V52XYX:	SKIPG	T1+$OFSX	; Is this negative ?
	 SKIPA	T1,[BYTE (7).CHESC,"C"] ; No - To the right
	  MOVX	T1,<BYTE (7).CHCNH> ; Yes, to the left
	PJRST	SC$STR		; Output the string

; Here to move in the Y direction by one

V52XYY:	SKIPL	T1+$OFSY	; Is this negative ?
	 SKIPA	T1,[BYTE (7).CHESC,"A"] ; No - Move up
	  MOVX	T1,<BYTE (7).CHLFD> ; Yes, Move down
	PJRST	SC$STR		; Output the string
	SUBTTL	Support routines -- VT52 -- Move cost calculation

;+
;.hl 1 V52CPP
; This routine will return the cost of moving the cursor from
;one point to another.
;.b.lit
;
; Usage:
;	MOVE	T1,[XWD X pos,Y pos] ; Source position
;	MOVE	X,[-n,,Column]
;	MOVE	Y,[-n,,Row]
;	MOVE	CRT,CRTTYP
;	XCT	$CRCPP(CRT)
;	 (return, T1= cost in characters)
;
;.end literal
;-

V61CPP:
V52CPP:	MOVE	T3,T2		; Get a copy of where we are moving to
	JUMPE	T3,.RET0	; Return a zero if not moving
	XOR	T3,T1		; Xor together
	TXNN	T3,LH.ALF	; Same X position line ?
	 JRST	V52CPY		; Yes - Check more
	TXNN	T3,RH.ALF	; Same Y position ?
	 JRST	V52CPX		; Yes - Check more
	JUMPE	T2,.RET2	; If moving home return cost of two
V52CPA:	MOVX	T1,4		; Have to type four characters
	POPJ	P,		; Return

; Here if possible same column movement

V52CPY:	MOVEI	T2,(T2)		; Get just the Y position
	SUBI	T2,(T1)		; Determine if just one line movement
	MOVM	T1,T2		; . . .
	SOJG	T1,V52CPA	; More than one - use four
	JUMPL	T2,.RET2	; If less than zero return two
	JRST	.RET1		; Else return one

; Here if possible same line movement

V52CPX:	HLRZ	T2,T2		; Get just the X position
	JUMPE	T2,.RET1	; If moving to the beginning of the line
				;  then return one
	HLRZ	T1,T1		; See if moving only one position
	SUBI	T1,T2		; . . .
	MOVM	T2,T1		; Get the magntude
	SOJG	T2,V52CPA	; If more than one - return four
	JUMPL	T1,.RET1	; If backing up then only one
	JRST	.RET2		; Else return two
	SUBTTL	Support routines -- VT52 -- Delete a line feed

;+
;.HL1 V52DLF
;This routine will send the character string to delete a line feed.
;.literal
;
; Usage:
;	MOVE	CRT,CRT.block.address
;	PUSHJ	P,@$CRDLF(CRT)
;	(Return)
;.end literal
;-

V52DLF:	MOVX	T1,<BYTE(7).CHESC,"A"> ; Get the string
	PJRST	SC$STR		; And output it
	SUBTTL	Support routines -- VT52 -- Delete a vertical tab

;+
;.HL1 V52DVT
;This routine will send the character string to delete a vertical tab.
;.literal
;
; Usage:
;	MOVE	CRT,CRT.block.address
;	PUSHJ	P,@$CRDVT(CRT)
;	(Return)
;
;.end literal
;-


V52DVT:	$SAVE	<P1>		; Save P1
	MOVX	P1,4		; Get the number to delete

V52D.0:	PUSHJ	P,V52DLF	; Delete a line feed
	SOJG	P1,.-1		; And again
	POPJ	P,		; All done
	SUBTTL	Support routines -- VT52 -- Delete a form feed

;+
;.HL1 V52DFF
;This routine will send the character string to delete a form feed.
;.literal
;
; Usage:
;	MOVE	CRT,CRT.block.address
;	PUSHJ	P,$CRDFF(CRT)
;	(Return)
;
;.end literal
;-

V52DFF:	$SAVE	<P1>		; Save P1
	MOVX	P1,^D8		; Get the number of line feeds to delete
	PJRST	V52D.0		; And do it
	SUBTTL Support routines -- VT52 -- Delete to End of line

;+
;.hl V52DEL
;This routine will output a string of characters to delete
;from the current position to the end of the line.
;.literal
;
; Usage:
;	MOVEI	T1,# of characters to delete
;	XCT	$CRDEL(CRT)
;.end literal
;-

V52DEL:	MOVX	T1,<BYTE (7) .CHESC,"K">
	PJRST	SC$STR		; Output the string and return

	SUBTTL	Support routines -- VT52 -- Reverse scroll

;+
;.hl1 V52SDN
; This routine will do reverse scroll operations for the VT52.
;.literal
;
; Usage:
;	MOVE	T1,Number of reverse scrolls to perform
;	XCT	$CRSDN(CRT)
;	 (return with screen shifted down)
;
;.end literal
;-

V52SDN:	$SAVE	<P1>		; Save P1
	$SAVE	<X,Y>		; Also X and Y
	SETZB	X,Y		; Home is a good place to output the string
	PUSHJ	P,SC$POS	; Position there
	MOVE	P1,T1		; Get the repeat count

V52S.0:	MOVX	T1,<BYTE(7).CHESC,"I"> ; Get the string
	PUSHJ	P,SC$STR	; Output it
	SOJG	P1,V52S.0	; The needed number of times

	POPJ	P,		; And return
	SUBTTL	Support routines -- VT100 -- Initialization

;+
;.hl1 V10INT
; This routine will initialize a VT-100 terminal in ansi mode.
;.literal
;
; Usage:
;	XCT	$CRINT(CRT)
;	 (return)
;
;.end literal
;-

V10INT:	SETZM	SCRTOP		; Top of scrolling region is on first line
	MOVE	T1,$CRLIN(CRT)	; Get the number of lines
	SOJ	T1,		; Minus one
	MOVEM	T1,SCRBTM	;  .  .  .
	MOVEI	T1,[$STRING(<^A78[?4;6l>)] ; Get the string
	PJRST	SC$STR		; Output the string
	SUBTTL	Support routines -- VT100 -- Exit reset code

;+
;.hl1 V10FIN
; This routine will be called on exit to reset the terminal parameters.
;.literal
;
; Usage:
;	XCT	$CRFIN(CRT)
;	 (return)
;
;.end literal
;-

V10FIN:	SETZM	SCRTOP		; Top of scrolling region is on first line
	MOVE	T1,$CRLIN(CRT)	; Get the number of lines
	SOJ	T1,		; Minus one
	MOVEM	T1,SCRBTM	;  .  .  .
	MOVEI	T1,[$STRING(<78>)] ; Get the string
	PJRST	SC$STR		; Output the string
	SUBTTL	Support routines -- VT-100 -- XY positioning

;+
;.hl1 V10XY
; This routine will do the positioning.
;.literal
;
; Usage:
;	MOVE	X,X.postion
;	MOVE	Y,Y.postion
;	MOVE	CRT,CRT.block.index
;	XCT	$CRXYP(CRT)
;	(Return)
;
;.end literal
;-

V10XY:				; VT-100 in ANSI mode
	$SAVE	<X,Y>		; Save X and Y
	DMOVE	T1,CURPOS	; Get the current position
	DMOVEM	X,CURPOS	; Save the current position
	SUB	T1+$OFSX,X	; Determine if it is an up/down/right/left by one
	SUB	T1+$OFSY,Y	;  movement
	SKIPE	T1+$OFSX	; Is the X zero ?
	 SKIPN	T1+$OFSY	; Or the Y ?
	  SKIPA			; Yes - Handle differently
	JRST	V10XYA		; No - Handle normally
	JUMPN	T1+$OFSX,V10XYX	; Just moving in the X direction
	JUMPN	T1+$OFSY,V10XYY	; Just moving in the Y direction
	POPJ	P,		; If we get here, we don't have to move at all

; Here to do a full address

V10XYY:
V10XYA:	SKIPN	X		; Going home?
	 JUMPE	Y,V10XYH	;  .  .  .
	ADDI	X,1		; Bump both of the coordinates so home is 1,1
	ADDI	Y,1		;  .  .  .
	 MOVEI	T1,[$STRING(<[^D/Y/;^D/X/H>)] ; Get the string address
	PJRST	SC$STR		; And go position the cursor

; Here if we are just going to home the cursor

V10XYH:	MOVX	T1,<BYTE (7).CHESC,"[","H"> ; Get the string
	PJRST	SC$STR		; Type the string

; Here to move only in the X direction

V10XYX:	TXNE	X,7		; Heading for a tab stop?
	 JRST	HAXY.9		; No, do normal movement
	JUMPG	T1,HAXY.9	; Going forward?
	CAXGE	T1,-^D8		; Yes, is it the next tab stop?
	 JRST	HAXY.9		; No, do the full address
	$SAVE	<CH>		; Yes, save CH
	MOVX	CH,.CHTAB	; Get a tab
	PJRST	SC$IMG		; And type it

; Here if we are not going to a tab stop

HAXY.9:	MOVM	X,T1		; Get the number of spaces to move
	CAXN	X,1		; Only one space?
	 JRST	V10X.1		; Yes, go handle it
	SKIPL	T1+$OFSX	; Load the offset and check the string
	 SKIPA	T1,[[$STRING(<[^D/X/D>)]] ; Get the string to type
	  MOVEI	T1,[$STRING(<[^D/X/C>)] ; Get the other way
	PJRST	SC$STR		; Output the string

; Here to move in the X direction one position

V10X.1:	SKIPG	T1		; Backwards
	 SKIPA	T1,[BYTE(7).CHESC,"[","C"] ; Go forward one
	  MOVX	T1,<BYTE(7).CHCNH> ; Go backwards one
	PJRST	SC$STR		; Go output the string

REPEAT 0,<			; Since we cannot move past scroll region limits
; Here to move only in the Y direction

V10XYY:	MOVM	Y,T1+$OFSY	; Get the number to move
	CAXN	Y,1		; Only one line?
	 JRST	V10Y.1		; Yes, go handle it
	SKIPL	Y,T1+$OFSY	; Is this negative ?
	 SKIPA	T1,[[$STRING(<[^D/Y/A>)]] ; No - Move up
	  MOVEI	T1,[$STRING(<[^D/Y/B>)] ; Yes - Move down
	MOVMS	Y		; Make this positive
	PJRST	SC$STR		; Output the string

; Here to move one position in the Y direction

V10Y.1:	SKIPL	T2		; Up or down?
	 SKIPA	T1,[BYTE(7).CHESC,"[","A"] ; Up, use escape seqeunce
	  MOVX	T1,<BYTE(7).CHLFD> ; Down, use a line feed
	PJRST	SC$STR		; All done
> ; End of REPEAT 0 for Y movement
	SUBTTL	Support routines -- VT100 -- Control U

;+
;.HL1 V10CTU
;This routine will process the control U in the command parser.  It
;may be called without CRT being set up.
;.literal
;
; Usage:
;	MOVE	CRT,CRT.block.address
;	PUSHJ	P,@$CRCTU(CRT)
;	(Return)
;
;.end literal
;-

V10CTU:	MOVX	T1,<BYTE(7).CHCRT,.CHESC,"[","K"> ; Get the string
	PJRST	CTUFIN		; Finish up
	SUBTTL	Support routines -- VT100 -- Delete a line feed

;+
;.HL1 V10DLF
;This routine will send the character string to delete a line feed.
;.literal
;
; Usage:
;	MOVE	CRT,CRT.block.address
;	PUSHJ	P,@$CRDLF(CRT)
;	(Return)
;.end literal
;-

V10DLF:	MOVX	T1,<BYTE(7).CHESC,"[","A"> ; Get the string
	PJRST	SC$STR		; And output it
	SUBTTL	Support routines -- VT100 -- Delete a vertical tab

;+
;.HL1 V10DVT
;This routine will send the character string to delete a vertical tab.
;.literal
;
; Usage:
;	MOVE	CRT,CRT.block.address
;	PUSHJ	P,@$CRDVT(CRT)
;	(Return)
;
;.end literal
;-


V10DVT:	MOVX	T1,<BYTE(7).CHESC,"[","4","A"> ; Get the string
	PJRST	SC$STR		; And go delete the vertical tab
	SUBTTL	Support routines -- VT100 -- Delete a form feed

;+
;.HL1 V10DFF
;This routine will send the character string to delete a form feed.
;.literal
;
; Usage:
;	MOVE	CRT,CRT.block.address
;	PUSHJ	P,$CRDFF(CRT)
;	(Return)
;
;.end literal
;-

V10DFF:	MOVX	T1,<BYTE(7).CHESC,"[","8","A"> ; Get the string
	PJRST	SC$STR		; And output it to delete the form feed
	SUBTTL Support routines -- VT100 -- Delete to end of line

;+
;.hl1 V10DEL
;This routine will delete from the current cursor position to the 
;end of the line.
;.literal
;
; Usage:
;	MOVEI	T1,# of characters to delete
;	XCT	$CRDEL(CRT)
;
;.end literal
;-

V10DEL:	MOVX	T1,<BYTE (7) .CHESC,"[","K">
	PJRST	SC$STR		; Print out the string

	SUBTTL Support routines -- VT100 -- Scroll up lines

;+
;.HL1 V10SUP
;This routne will cause lines to be scrolled up on the screen.  It will
;be used mainly to simulate the insert and delete line functons for
;the VT100 terminal support.
;.literal
;
; Usage:
;	MOVE	CRT,CRT.block.addrss
;	MOVE	T1,Number.of.lines.to.scroll
;	MOVE	T2,Top.line.number
;	MOVE	Y,Bottom.line.number
;	XCT	$CRSUP(CRT)
;	(Return)
;
;.end literal
;-

V10SUP:	JUMPE	T1,V1SU.C	; If we don't really want to move, just check if ok
	CAMN	T2,Y		; Top and bottom lines the same?
	 JRST	V1SU.K		; Yes, just kill the line

	CAMN	T2,SCRTOP	; Is this the current top of the region?
	 CAME	Y,SCRBTM	; And the current bottom?
	  PUSHJ	P,V1SU.1	; No, must set the region first
V1SU.0:	$SAVE	<CH>		; Save CH
	MOVX	CH,.CHLFD	; Get the character to do the scrolling
	MOVE	X,CURPOS+$OFSX	; Get the current X position (for minimal addressing)
	PUSHJ	P,SC$POS	; Position to the correct place
	PUSHJ	P,SC$IMG	; Output the line feed
	SOJG	T1,.-1		; For as many times as as needed
	POPJ	P,		; And return

; Here to set the scrolling region to the correct thing

V1SU.1:	$SAVE	<T1,T2,P1,Y>	; Save the args
	MOVEM	T2,SCRTOP	; Set as the new top
	MOVEM	Y,SCRBTM	; And bottom lines
	AOS	P1,T2		; Bump for the terminals lines
	AOJ	Y,		; Since they are from 1 to 24
	MOVEI	T1,[$STRING(<7[^D/P1/;^D/Y/r8>)] ; Set the region
	PJRST	SC$STR		; And output the string

; Here if we want to scroll a single line.  The terminal cannot actually do
;this, so we will fake it with a kill line.


V1SU.K:	PUSHJ	P,SC$POS	; Position to correct place
	MOVEI	T1,[$STRING(<>)] ; Get the string
	PJRST	SC$STR		; And output it

; Here to check to make sure that the scrolling region will not affect
;line feeds given in a given range of lines.  This is used by
;command echoing to avoid random scrolling.

V1SU.C:	CAML	Y,SCRTOP	; Is this section totally above
	 CAMLE	T2,SCRBTM	; Or totally below the region?
	  POPJ	P,		; Yes, all done
	PJRST	V1SU.1		; Go set the region to be the limits of this
				; section
	SUBTTL	Support routines -- VT100 -- Cause lines to scroll down

;+
;.HL1 V10SDN
;This routine will cause lines to be scrolled down the screen.
;It is used to process the insert/delete line processing for the VT100.
;.literal
;
; Usage:
;	MOVEI	CRT,CRT.block.address
;	MOVE	Y,Top.line.number
;	MOVEI	T1,Number.of.lines.to.scroll.down
;	MOVEI	T2,Bottom.line.number
;	XCT	$CRSDN(CRT)
;	(Return)
;.end literal
;-

V10SDN:	CAMN	T2,Y		; Top and bottom the same line?
	 PJRST	V1SU.K		; Yes, just kill to end of line
	CAMN	Y,SCRTOP	; Same as current top line?
	 CAME	T2,SCRBTM	; Yes, bottom also the same?
	  PUSHJ	P,V1SD.1	; No, must set the region

	MOVE	T2,T1		; Get the number of times to repeat the operation
	MOVEI	T1,[$STRING(<M>)] ; Get the reverse index string
	MOVE	X,CURPOS+$OFSX	; Get the current X pos to make addressing quick
	PUSHJ	P,SC$POS	; Position the cursor
	PUSHJ	P,SC$STR	; Output the string
	SOJG	T2,.-1		; As many times as needed
	POPJ	P,		; ANd return

; Here to set the scrolling region

V1SD.1:	$SAVE	<T1,T2,P1,Y>	; Save the args
	MOVEM	T2,SCRBTM	; Save as the current region also
	MOVEM	Y,SCRTOP	;  .  .  .
	AOS	P1,T2		; And change to the terminals line numbers
	AOJ	Y,		;  .  .  .
	MOVEI	T1,[$STRING(<7[^D/Y/;^D/P1/r8>)] ; Get the string to set the region
	PJRST	SC$STR		; And go set it
	SUBTTL	Support routines -- VT100 -- Insert line cost calculation

;+
;.hl 1 V10CIL
; This routine will return the cost of inserting a line in the
;screen.
;.b.lit
;
; Usage:
;	MOVE	T1,CST entry
;	MOVX	X,[XWD -n,Column]
;	MOVE	Y,[XWD -n,Row]
;	MOVE	CRT,CRTTYP
;	XCT	$CRCIL(CRT)
;	 (return, T1=CST entry
;
;.end literal
;-

; Definition of terminal dependent portion of the cost word
;This will hold the net number of inserts/deletes that have
;been done on this path. It will also have a flag as to whether the
;number represents inserts of deletes.

	CS$DCN==<INSVL.(<^O37>,CS$DEP)> ; Number of lines screen is shifted
	DEFST.(CSTDCN,$CSDEP,CS$DCN)	; Define the pointer

	CS$DIN==LFTBT.(CS$DEP)	; Flag for whether the count is up or down
				; If CS$DIN is on, the count is number inserted above

; To calculate the insert (or delete) cost, we must take into consideration whether
;the scrolling region will have to be set, as well as the actual cost of
;doing the scroll. We will assume that the operation which sets the region
;will also be performing the actual scrolling.
;We will need to set the scrolling region only under the following cases:
;
;	1) Performing this operation will cause the insert/delete count
;	   to become negative. Note that this will catch the initial
;	   insert or delete.
;
;	2) If the previous operation was not the same type of operation, and
;	   we are doing the same operation as the last insert/delete.
;
;We will need to account to the scrolling operation under the following
;cases:
;
;	1) Anytime the scrolling region is being set.
;
;	2) If we are doing the same operation as the previous operation
;	   and as the last insert/delete. This indicates that this
;	   operation is one in a series of like operations that included
;	   setting the scrolling region.
;


V10CIL:	MOVEI	T2,1		; Get a one
	TXNN	T1,CS$DIN	; Counting inserts currently?
	 MOVN	T2,T2		; No, deletes, make it a minus one
	LOAD.	T3,CSTDCN,+T1	; Get the previous count
	JUMPN	T3,.+2		; First of a set?
	 TXOA	T3,-1		; Yes, remember we must do the set
	  ADD	T3,T2		; And account for this operation
	MOVM	T2,T3		; Get the magnitude
	STOR.	T2,CSTDCN,+T1	; And store it back
	JUMPL	T3,V1CI.C	; Must do the set, go account for that
	TXNN	T1,CS$DIN	; Last up/down operation an insert?
	 JRST	V1CI.1		; No, don't need to set region
	LOAD.	T2,CSTOPR,+T1	; Get the previous operation
	CAXN	T2,$OPICH	; Or insert operation last?
	 JRST	V1CI.1		; Yes, don't need to set region
	JRST	V1CI.S		; Go set the cost for the whole thing

; Here if we must set the region. We will assume a cost of 7 for doing
;the set, since the string is actually dependent on the top and bottom
;line numbers.

V1CI.C:	TXO	T1,CS$DIN	; Flag we are now in inserts
V1CI.S:	STORI.	<7+2>,T2,CSTCST,+T1 ; Store the cost for this operation
	STORI.	$OPICH,T2,CSTOPR,+T1 ; And the operation
	POPJ	P,		; And return

; Here if we don't need to perform the set, check if we need to
;count the the scroll operation.

V1CI.1:	TXNE	T1,CS$DIN	; Are we on the top of a region?
	 CAXE	T2,$OPICH	; Previous operation an insert also?
	  TDZA	T2,T2		; No, this is a free operation
	MOVEI	T2,2		; Yes, get the cost for a reverse index
	STOR.	T2,CSTCST,+T1	; Store the cost
	STORI.	$OPICH,T2,CSTOPR,+T1 ; Store the operation
	POPJ	P,		; And return
	SUBTTL	Support routines -- VT100 -- Delete line cost calculation

;+
;.hl 1 V10CDL
; This routine will return the cost of deleting a line in the
;screen.
;.b.lit
;
; Usage:
;	MOVE	T1,CST entry
;	MOVX	X,[XWD -n,Column]
;	MOVE	Y,[XWD -n,Row]
;	MOVE	CRT,CRTTYP
;	XCT	$CRCDL(CRT)
;	 (return, T1=CST entry
;
;.end literal
;-

V10CDL:	MOVEI	T2,1		; Get a one
	TXNE	T1,CS$DIN	; Counting deletes currently?
	 MOVN	T2,T2		; No, inserts, make it a minus one
	LOAD.	T3,CSTDCN,+T1	; Get the previous count
	JUMPN	T3,.+2		; First of a set?
	 TXOA	T3,-1		; Yes, remember we must do the set
	  ADD	T3,T2		; And account for this operation
	MOVM	T2,T3		; Get the magnitude
	STOR.	T2,CSTDCN,+T1	; And store it back
	JUMPL	T3,V1CD.C	; Must do the set, go account for that
	TXNE	T1,CS$DIN	; Last up/down operation an insert?
	 JRST	V1CD.1		; No, don't need to set region
	LOAD.	T2,CSTOPR,+T1	; Get the previous operation
	CAXN	T2,$OPDCH	; Delete operation
	 JRST	V1CD.1		; Yes, don't need to set region
	JRST	V1CD.S		; Must set the region

; Here if we must set the region. We will assume a cost of 7 for doing
;the set, since the string is actually dependent on the top and bottom
;line numbers.

V1CD.C:	TXZ	T1,CS$DIN	; Flag we are now in inserts
V1CD.S:	STORI.	<7+1>,T2,CSTCST,+T1 ; Store the cost for this operation
	STORI.	$OPDCH,T2,CSTOPR,+T1 ; And the operation
	POPJ	P,		; And return

; Here if we don't need to perform the set, check if we need to
;count the the scroll operation.

V1CD.1:	TXNN	T1,CS$DIN	; Are we on the top of a region?
	 CAXE	T2,$OPDCH	; Previous operation an insert also?
	  TDZA	T2,T2		; No, this is a free operation
	MOVEI	T2,1		; Yes, get the cost for a reverse index
	STOR.	T2,CSTCST,+T1	; Store the cost
	STORI.	$OPDCH,T2,CSTOPR,+T1 ; Store the operation
	POPJ	P,		; And return
	SUBTTL	Support routines -- VT100 -- Move cost calculation

;+
;.hl 1 V10CPP
; This routine will return the cost of moving the cursor from
;one point to another.
;.b.lit
;
; Usage:
;	MOVE	T1,[XWD X pos,Y pos] ; Source position
;	MOVE	T2,[XWD X pos,Y pos]
;	MOVE	CRT,CRTTYP
;	XCT	$CRCPP(CRT)
;	 (return, T1= cost in characters)
;
;.end literal
;-

V10CPP:	CAMN	T1,T2		; Really moving somewhere?
	 PJRST	.RET0		; No, return a zero

	HRRZ	T3,T1		; Get the X positions
	HRRZ	T4,T2		; Of both
	HLRZ	T1,T1		; Keep only the Y positions
	HLRZ	T2,T2		; . . .
	CAIE	T3,(T4)		; Same line?
	 JRST	V1CP.1		; No, go check for same column
	JUMPE	T2,.RET1	; Going to column 0 takes only 1 char
	MOVE	T3,T2		; Get the destination column
	SUB	T2,T1		; Get the dest-source positions
	MOVE	T4,T1		; Get the destination column
	MOVM	T1,T2		; Get the magnitude
	JUMPL	T2,V1CP.3	; Skip if going backwards

; Check if we can use a tab

	TXNN	T3,7		; Going to a tab stop?
	 CAXLE	T1,^D8		; Yes, is it the next one?
	  JRST	V1CP.4		; No, figure out how many chars it will take
	PJRST	.RET1		; Yes, return a one

; Here for either a forward cursor or an up cursor

V1CP.4:	MOVEI	T1,3		; Assume simple case of one char
	CAIE	T2,1		; Is it?
	 AOJ	T1,		; No, need at least one more
V1CP.0:	CAIL	T2,^D10		; Need two digits
	 AOJ	T1,		; Yes, count the second
	CAIL	T2,^D100	; Going more than 100 columns?
	 AOJ	T1,		; Yes, count one more
	POPJ	P,		; And return

; Here if position is on the same line before current position
; or is in the same column, but below the current line

V1CP.3:	MOVE	T2,T1		; Get the number of columns to move
	MOVEI	T1,1		; Assume one
	CAIE	T2,1		; Is it?
	 ADDI	T1,3		; No, need the relative movement
	JRST	V1CP.0		; Go count the digits we need

; Here if new position is on a different line.

V1CP.1:
REPEAT 0,<
	CAIE	T1,(T2)		; Same column?
	 JRST	V1CP.2		; No, try for home
	SUB	T4,T3		; Yes, get the number to move
	MOVM	T1,T4		; And the magnitude
	JUMPGE	T4,V1CP.3	; Going down?
	JRST	V1CP.4		; No, go handle like forward cursor
> ; End of REPEAT 0 for vertical movement

; Here if not the same column or line

V1CP.2:	SKIPN	T1		; Is the destination home?
	 SKIPE	T3		;  .  .  .
	  JRST	V1CP.5		; No, go handle it
	MOVEI	T1,3		; Yes, only takes two chars
	POPJ	P,		; All done

; Here if we must do the cursor position

V1CP.5:	MOVE	T2,T1		; Get the destination column
	MOVEI	T1,4		; Get the basic cost
	CAIL	T3,^D9		; Before line 10?
	 AOJ	T1,		; No, takes another digit
	CAIL	T2,^D9		; Before column 10
	 AOJ	T1,		; No, another digit
	CAIL	T2,^D99		; Before column 100 ?
	 AOJA	T1,.POPJ	; No, another digit
	POPJ	P,		; All done
	SUBTTL	Support routines -- VK100 -- Reverse scroll

;+
;.hl1 K10SDN
; This routine will do reverse scroll operations for the VK100.
;.literal
;
; Usage:
;	MOVE	T1,Number of reverse scrolls to perform
;	XCT	$CRSDN(CRT)
;	 (return with screen shifted down)
;
;.end literal
;-

K10SDN:	$SAVE	<P1>		; Save P1
	$SAVE	<X,Y>		; Also X and Y
	SETZB	X,Y		; Home is a good place to output the string
	PUSHJ	P,SC$POS	; Position there
	MOVE	P1,T1		; Get the repeat count

K10S.0:	MOVX	T1,<BYTE(7).CHESC,"M"> ; Get the string
	PUSHJ	P,SC$STR	; Output it
	SOJG	P1,K10S.0	; The needed number of times

	POPJ	P,		; And return
	SUBTTL	Low segment

	$IMPURE			; Put in correct place

DECBEG:!

SCRTOP:	BLOCK	1		; Top of scrolling region
SCRBTM:	BLOCK	1		; Bottom of scrolling region (VT100)
INSFLG:	BLOCK	1		; Flag whether we are in insert mode (0 if not)

	LOWVER(DEC,<.-DECBEG>); Define the version number
	SUBTTL	End of TECDEC

	END			; End of TECDEC